From 5d72664f0c4e52a223c2f6facd59b485508b5324 Mon Sep 17 00:00:00 2001 From: Daniel Nachun Date: Fri, 23 Oct 2026 00:45:44 -0400 Subject: [PATCH 1/5] colocboost fixes --- .github/environment/pixi.toml | 6 +- .github/workflows/ci.yml | 38 +- NAMESPACE | 6 + R/AllClasses.R | 57 ++- R/AllGenerics.R | 29 +- R/ColocBoostResult.R | 124 +++++- R/ColocResult.R | 73 ++-- R/GwasFineMappingResult.R | 31 +- R/JointGroup.R | 7 + R/QtlFineMappingResult.R | 38 +- R/RangedTupleList.R | 54 ++- R/causalInferencePipeline.R | 138 ++++--- R/colocPipeline.R | 97 +++-- R/colocboostPipeline.R | 170 ++++---- R/ctwasPipeline.R | 94 +++-- R/exampleData.R | 7 +- R/fineMappingPipeline.R | 93 +++-- R/fineMappingWrappers.R | 33 +- R/gwasSumStats.R | 65 +-- R/jointEngine.R | 125 +++--- R/jointSpecification.R | 60 ++- R/ld.R | 380 +++++++++++++++++- R/manifestLoaders.R | 242 ++++++----- R/qtlEnrichmentPipeline.R | 35 +- R/qtlSumStats.R | 55 +-- R/resultWriters.R | 35 +- R/sumstatsQc.R | 48 ++- R/tupleSelectors.R | 252 ++++++------ R/twasWeights.R | 35 +- R/twasWeightsPipeline.R | 130 +++--- _pkgdown.yml | 1 + data/colocboostResultExample.rda | Bin 2968 -> 2968 bytes data/ctwasWeightsExample.rda | Bin 6528 -> 6552 bytes data/fsusieFineMappingExample.rda | Bin 22180 -> 22184 bytes data/gwasFineMappingExample.rda | Bin 651664 -> 650656 bytes data/gwasFineMappingLbfExample.rda | Bin 41356 -> 41292 bytes data/gwasSumStatsS4Example.rda | Bin 7344 -> 7348 bytes data/mvsusieFineMappingExample.rda | Bin 117592 -> 116924 bytes data/qtlFineMappingExample.rda | Bin 211696 -> 212444 bytes data/qtlFineMappingLbfExample.rda | Bin 79176 -> 78140 bytes data/qtlFineMappingPairedExample.rda | Bin 19336 -> 19332 bytes data/qtlSumStatsExample.rda | Bin 8304 -> 8328 bytes data/qtlSumStatsMulticontextExample.rda | Bin 16384 -> 16436 bytes data/twasWeightsExample.rda | Bin 10132 -> 10136 bytes inst/scripts/build_ctwas_examples.R | 6 +- man/ColocBoostResult-class.Rd | 17 +- man/ColocBoostResult.Rd | 11 +- man/ColocResult-class.Rd | 13 +- man/ColocResult.Rd | 8 +- man/ColocResultBase-class.Rd | 15 +- man/FineMappingResultBase-class.Rd | 14 +- man/GwasFineMappingResult.Rd | 13 +- man/GwasSumStats-class.Rd | 7 +- man/GwasSumStats.Rd | 11 +- man/QtlFineMappingResult.Rd | 20 +- man/QtlSumStats-class.Rd | 8 +- man/QtlSumStats.Rd | 12 +- man/SumStatsBase-class.Rd | 14 +- man/TwasWeights-class.Rd | 11 +- man/TwasWeights.Rd | 7 +- man/causalInferencePipeline.Rd | 19 +- man/colocBoostOutcomes.Rd | 4 +- man/colocPipeline.Rd | 14 +- man/colocboostPipeline.Rd | 16 +- man/combineFineMappingResults.Rd | 8 +- man/combineGwasSumStats.Rd | 23 +- man/combineQtlSumStats.Rd | 12 +- man/combineTwasWeights.Rd | 8 +- man/computeLd.Rd | 2 +- man/ctwasPipeline.Rd | 7 +- man/fineMappingPipeline.Rd | 8 +- man/gwasSumStatsS4Example.Rd | 3 +- man/ldReference.Rd | 40 +- man/loadGwasSumStatsFromManifest.Rd | 11 +- man/loadQtlSumStatsFromManifest.Rd | 10 +- man/qtlEnrichmentPipeline.Rd | 12 +- man/qtlSumStatsExample.Rd | 4 +- man/twasWeightsPipeline.Rd | 11 +- man/updateObject-methods.Rd | 39 ++ tests/testthat/helper-h2Classes.R | 5 +- tests/testthat/test_ColocBoostResult.R | 100 +++++ tests/testthat/test_ColocResult.R | 50 ++- tests/testthat/test_GwasSumStats.R | 47 ++- tests/testthat/test_QtlFineMappingResult.R | 10 +- tests/testthat/test_RangedTupleList.R | 47 +++ tests/testthat/test_causalInferencePipeline.R | 137 ++++++- tests/testthat/test_colocPipeline.R | 47 ++- tests/testthat/test_colocboostPipeline.R | 214 ++++++---- tests/testthat/test_ctwasPipeline.R | 61 ++- tests/testthat/test_fineMappingPipeline.R | 97 ++++- tests/testthat/test_fineMappingWrappers.R | 51 ++- tests/testthat/test_jointEngine.R | 84 +++- tests/testthat/test_jointSpecification.R | 4 +- tests/testthat/test_ld.R | 145 +++++++ tests/testthat/test_manifestLoaders.R | 48 ++- tests/testthat/test_qtlEnrichmentPipeline.R | 15 +- tests/testthat/test_qtlSumStats.R | 33 +- tests/testthat/test_resultWriters.R | 33 +- tests/testthat/test_sumstatsQc.R | 39 +- tests/testthat/test_tupleSelectors.R | 103 ++++- tests/testthat/test_twasWeights.R | 3 +- tests/testthat/test_twasWeightsPipeline.R | 45 ++- vignettes/coloc-pipeline.Rmd | 7 +- vignettes/colocboost-pipeline.Rmd | 11 +- vignettes/constructing-qtl-datasets.Rmd | 4 +- vignettes/constructing-sumstats.Rmd | 24 +- vignettes/fine-mapping.Rmd | 9 +- vignettes/ld-infrastructure.Rmd | 20 +- vignettes/rss-qc.Rmd | 2 +- vignettes/twas-weights.Rmd | 8 +- vignettes/twas-zscore.Rmd | 15 +- vignettes/xqtl-enrichment.Rmd | 2 +- 112 files changed, 3190 insertions(+), 1326 deletions(-) create mode 100644 man/updateObject-methods.Rd diff --git a/.github/environment/pixi.toml b/.github/environment/pixi.toml index 45e30589..19aed404 100644 --- a/.github/environment/pixi.toml +++ b/.github/environment/pixi.toml @@ -11,9 +11,9 @@ platforms = [ devtools_document = "cd $GITHUB_WORKSPACE; R -e 'devtools::document()'" devtools_test = "cd $GITHUB_WORKSPACE; R -e 'devtools::test(stop_on_failure = TRUE)'" codecov = "cd $GITHUB_WORKSPACE; R -e 'covr::codecov(quiet = FALSE)'" -rcmdcheck = "cd $GITHUB_WORKSPACE; R -e 'rcmdcheck::rcmdcheck()'" -bioccheck_git_clone = "cd $GITHUB_WORKSPACE; R -e 'BiocCheck::BiocCheckGitClone()'" -bioccheck = "cd $GITHUB_WORKSPACE; R -e 'BiocCheck::BiocCheck()'" +rcmdcheck = "cd $GITHUB_WORKSPACE; R -e 'rcmdcheck::rcmdcheck(error_on = \"error\")'" +bioccheck_git_clone = "cd $GITHUB_WORKSPACE; R -e 'BiocCheck::BiocCheckGitClone(\"quit-with-status\" = TRUE)'" +bioccheck = "cd $GITHUB_WORKSPACE; R -e 'BiocCheck::BiocCheck(\"quit-with-status\" = FALSE)'" use_major_version = "cd $GITHUB_WORKSPACE; R -e 'usethis::use_version(which = \"major\", push = FALSE)'" use_minor_version = "cd $GITHUB_WORKSPACE; R -e 'usethis::use_version(which = \"minor\", push = FALSE)'" use_patch_version = "cd $GITHUB_WORKSPACE; R -e 'usethis::use_version(which = \"patch\", push = FALSE)'" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24000827..604ff1a4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,23 +12,21 @@ concurrency: jobs: ci: - name: CI (${{ matrix.platform }} / ${{ matrix.environment }}) + name: ${{ matrix.name }} (${{ matrix.platform }} / ${{ matrix.environment }}) runs-on: ${{ matrix.runner }} env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} strategy: fail-fast: false matrix: - runner: [ubuntu-latest, macos-latest, ubuntu-24.04-arm] - environment: ["r45"] include: - - runner: ubuntu-latest - platform: linux-64 - - runner: ubuntu-24.04-arm - platform: linux-aarch64 - - runner: macos-latest - platform: osx-arm64 - + - { name: Run unit tests, task: devtools_test, platform: linux-aarch64, runner: ubuntu-24.04-arm, environment: r45 } + - { name: Run unit tests, task: devtools_test, platform: osx-arm64, runner: macos-latest, environment: r45 } + - { name: Run unit tests, task: devtools_test, platform: linux-64, -aarch64, runner: ubuntu-24.04-arm, environment: r45 } + - { name: Check code coverage with covr, task: codecov, platform: linux-64, runner: ubuntu-latest, environment: r45 } + - { name: Run R CMD check, task: rcmdcheck, platform: linux-64, runner: ubuntu-latest, environment: r45 } + - { name: Run BiocCheckGitClone, task: bioccheck_git_clone, platform: linux-64, runner: ubuntu-latest, environment: r45 } + - { name: Run BiocCheck, task: bioccheck, platform: linux-64, runner: ubuntu-latest, environment: r45 } steps: - name: Checkout pull request branch uses: actions/checkout@v7 @@ -46,20 +44,8 @@ jobs: with: manifest-path: /tmp/pixi/pixi.toml - - name: Run unit tests - run: | - pixi config set --manifest-path /tmp/pixi/pixi.toml --local run-post-link-scripts insecure - pixi run --environment ${{ matrix.environment }} --manifest-path /tmp/pixi/pixi.toml devtools_test - - - name: Check unit test code coverage - if: matrix.platform == 'linux-64' - run: pixi run --environment ${{ matrix.environment }} --manifest-path /tmp/pixi/pixi.toml codecov - - #- name: Run R CMD CHECK - #run: pixi run --environment ${{ matrix.environment }} --manifest-path /tmp/pixi/pixi.toml rcmdcheck - - #- name: Run BiocCheckGitClone - #run: pixi run --environment ${{ matrix.environment }} --manifest-path /tmp/pixi/pixi.toml bioccheck_git_clone + - name: Allow post-link scripts + run: pixi config set --manifest-path /tmp/pixi/pixi.toml --local run-post-link-scripts insecure - #- name: Run BiocCheck - #run: pixi run --environment ${{ matrix.environment }} --manifest-path /tmp/pixi/pixi.toml bioccheck + - name: ${{ matrix.name }} + run: pixi run --environment ${{ matrix.environment }} --manifest-path /tmp/pixi/pixi.toml ${{ matrix.task }} diff --git a/NAMESPACE b/NAMESPACE index ba225bc3..2ba6fc28 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -582,6 +582,7 @@ exportMethods(traitNames) exportMethods(traitPosition) exportMethods(twasWeights) exportMethods(twasWeightsPipeline) +exportMethods(updateObject) exportMethods(varY) exportMethods(variantIds) exportMethods(weightStandardized) @@ -602,6 +603,7 @@ importFrom(BiocGenerics, ncol, nrow, path, + updateObject, weights, width ) @@ -748,6 +750,7 @@ importFrom(methods, importFrom(purrr, compact, detect, + detect_index, discard, exec, imap, @@ -769,6 +772,7 @@ importFrom(purrr, partial, pmap, possibly, + pwalk, reduce, set_names, walk, @@ -793,8 +797,10 @@ importFrom(rlang, eval_bare, fn_env, fn_fmls, + hash, inform, is_named, + obj_address, try_fetch, warn ) diff --git a/R/AllClasses.R b/R/AllClasses.R index 044f16a6..83604164 100644 --- a/R/AllClasses.R +++ b/R/AllClasses.R @@ -65,12 +65,14 @@ setClassUnion( #' \code{x[[i]]} is that tuple's summary statistics and the identity columns #' live in \code{mcols(x)}. There is no \code{entry} column: what used to be #' \code{x$entry[[i]]} is now simply \code{x[[i]]}. -#' @slot ldReference The LD reference the collection was harmonized against -#' and every pipeline reads LD from: a genotype panel (see -#' \code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} or an -#' \code{\link{LdMatrix}}, or \code{NULL}. Optional: LD-free workflows -#' (e.g. mash, which operates across conditions per variant) carry -#' \code{NULL}; pipelines that need LD validate its presence when they +#' @slot ldReference A named list of the LD references the rows were +#' harmonized against and every pipeline reads LD from, each a genotype +#' panel (see \code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} +#' or an \code{\link{LdMatrix}}. Each distinct reference is stored once, and +#' the \code{ldReference} column of \code{mcols} names the entry each row +#' uses, so rows can sit on different references. Optional: an LD-free row +#' (e.g. for mash, which operates across conditions per variant) has +#' \code{NA} there; pipelines that need LD validate its presence when they #' consume the collection. #' @slot qcInfo A \code{list} recording which QC steps ran. Empty \code{list()} #' on construction; populated by \code{summaryStatsQc()} with a per-step audit @@ -83,11 +85,16 @@ setClass( "SumStatsBase", contains = c("VIRTUAL", "RangedTupleList"), representation( - ldReference = "LdReference_OR_NULL", + ldReference = "list", qcInfo = "list" - ) + ), + prototype(ldReference = list()) ) +methods::setValidity("SumStatsBase", function(object) { + .ldRefDictProblems(object@ldReference, .ldRefKeys(object)) %||% TRUE +}) + # TRUE when two elements share both their identity tuple AND their span. # Splitting a multi-chromosome study makes the tuple alone non-unique, so the # key is the tuple plus the element's range (spec 4.4: uniqueness is enforced @@ -223,9 +230,13 @@ setMethod("qcDiagnostics", "SumStatsBase", function(x, entry = 1L) { #' @rdname ldReference #' @examples #' data(qtlSumStatsExample) +#' # One entry per distinct reference; each row names its own. #' ldReference(qtlSumStatsExample) +#' qtlSumStatsExample$ldReference #' @export -setMethod("ldReference", "SumStatsBase", function(x) x@ldReference) +setMethod("ldReference", "SumStatsBase", function(x) { + .ldRefsInUse(x) +}) #' @rdname studyName #' @examples @@ -712,22 +723,29 @@ setMethod( #' @title Fine-Mapping Result Base Class #' @description Virtual base class for fine-mapping result collections. Concrete #' subclasses (\code{QtlFineMappingResult}, \code{GwasFineMappingResult}) -#' carry a \code{DFrame} of per-fit rows and a shared \code{ldReference} slot. +#' carry a \code{DFrame} of per-fit rows and an \code{ldReference} slot +#' listing the LD references those fits used. #' Downstream pipelines should dispatch on \code{FineMappingResultBase} for #' behaviors that apply to either flavour, and on the concrete subclass when #' the tuple shape matters. -#' @slot ldReference The LD reference the fits were computed against (a -#' genotype panel, a \code{GenotypeMixture} or an \code{LdMatrix}), or -#' \code{NULL} when the fits were derived from individual-level data. Used -#' downstream to check that pipelines combining results share one LD -#' reference. +#' @slot ldReference A named list of the LD references the fits were +#' computed against, each a genotype panel, a \code{GenotypeMixture} or an +#' \code{LdMatrix}, stored once apiece; the \code{ldReference} column of +#' \code{mcols} names the entry each row used (\code{NA} for a fit derived +#' from individual-level data). Used downstream to check that the rows a +#' pipeline combines share an LD reference. #' @export setClass( "FineMappingResultBase", contains = c("VIRTUAL", "RangedTupleList"), - representation(ldReference = "LdReference_OR_NULL") + representation(ldReference = "list"), + prototype(ldReference = list()) ) +methods::setValidity("FineMappingResultBase", function(object) { + .ldRefDictProblems(object@ldReference, .ldRefKeys(object)) %||% TRUE +}) + #' @rdname studyName #' @export setMethod("studyName", "FineMappingResultBase", function(x) { @@ -736,7 +754,9 @@ setMethod("studyName", "FineMappingResultBase", function(x) { #' @rdname ldReference #' @export -setMethod("ldReference", "FineMappingResultBase", function(x) x@ldReference) +setMethod("ldReference", "FineMappingResultBase", function(x) { + .ldRefsInUse(x) +}) #' @rdname methodNames #' @examples @@ -821,7 +841,8 @@ setMethod( GenomicRanges::GRangesList(map(entries, variants)), value = .withEntryPayload(mcols(x, use.names = FALSE), entries) ) - new(class(x), grl, ldReference = .asLdRef(ldReference(x))) + # The rows keep their keys in mcols, so the references go across as is. + new(class(x), grl, ldReference = x@ldReference) } # TRUE when an entry shares at least one variant with `keepVariants`, matched diff --git a/R/AllGenerics.R b/R/AllGenerics.R index deb1db41..ed7ec840 100644 --- a/R/AllGenerics.R +++ b/R/AllGenerics.R @@ -809,19 +809,26 @@ setGeneric("qcDiagnostics", function(x, entry = 1L, ...) { }) #' @title Get LD Reference -#' @description Return the LD reference of this object: a genotype panel -#' (see \code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} or -#' an \code{\link{LdMatrix}}. Defined on classes that embed an -#' \code{ldReference} slot: \code{GwasSumStats}, \code{QtlSumStats}, -#' \code{FineMappingResultBase}, \code{TwasWeights}, -#' \code{ColocResultBase} and \code{LdStatistic}, whose reference is the -#' panel it reads its blocks' LD from. Returns \code{NULL} when the slot is -#' unset (e.g. a \code{TwasWeights} fit from individual-level data via -#' \code{QtlDataset}, or an \code{LdStatistic} built from \code{LdMatrix} -#' blocks). +#' @description Return the LD references of this object, each a genotype +#' panel (see \code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} +#' or an \code{\link{LdMatrix}}. +#' +#' The collections whose rows can sit on different references -- +#' \code{GwasSumStats}, \code{QtlSumStats}, \code{FineMappingResultBase}, +#' \code{TwasWeights}, \code{ColocResult} and \code{ColocBoostResult} -- +#' return a named list holding each distinct reference their rows use, once. +#' The \code{ldReference} column of their \code{mcols} (of +#' \code{outcomeInfo} for a \code{ColocBoostResult}) names the entry each +#' row used, \code{NA} for one fit without LD (e.g. a \code{TwasWeights} +#' row learned from individual-level data via \code{QtlDataset}). The list +#' is empty when no row has a reference. +#' +#' An \code{LdStatistic} returns the one panel it reads its blocks' LD from, +#' or \code{NULL} when it was built from \code{LdMatrix} blocks. #' @param x An S4 object that carries an \code{ldReference} slot. #' @param ... Unused. -#' @return A \code{RangedSummarizedExperiment} genotype panel, a +#' @return A named list of LD references; for an \code{LdStatistic}, a +#' \code{RangedSummarizedExperiment} genotype panel, a #' \code{GenotypeMixture}, an \code{LdMatrix}, or \code{NULL}. #' @export setGeneric("ldReference", function(x, ...) standardGeneric("ldReference")) diff --git a/R/ColocBoostResult.R b/R/ColocBoostResult.R index 3db3f54a..f9c4ea1f 100644 --- a/R/ColocBoostResult.R +++ b/R/ColocBoostResult.R @@ -21,10 +21,12 @@ # ("given these two colocalize, this is the shared causal variant"); vcp is # a marginal per-variant colocalization probability over the region. # -# What the two DO share is the LD panel they were computed against and the -# projection surface, so both extend ColocResultBase -- which carries the -# ldReference slot and its accessor -- and both answer colocPairs() and -# colocVariants(). +# What the two DO share is the projection surface, so both extend +# ColocResultBase and both answer colocPairs() and colocVariants(). Each keeps +# its own LD references. A colocboost run matches every summary-statistic +# outcome against its own row's reference, so this class keeps a named list of +# them -- each reference once -- and outcomeInfo records the one every outcome +# used. # # element the member variants of one CoS # inner mcols per-variant: vcp @@ -32,7 +34,8 @@ # CharacterList -- native variable arity), purity, cosNpc, # minNpcOutcome, topVariable, topVariableVcp, focalOutcome, # isColocalized -# slots ldReference, outcomeInfo, regionVcp, computingTime +# slots ldReference (a named list), outcomeInfo, regionVcp, +# computingTime # # Uncolocalized (outcome-specific) sets are elements too, flagged # isColocalized = FALSE, rather than living in a second container: they have @@ -46,11 +49,19 @@ NULL #' @description A collection of ColocBoost results, one element per confidence #' set (CoS). Project it with \code{\link{colocPairs}}, #' \code{\link{colocVariants}} or \code{\link{colocBoostOutcomes}}. +#' @slot ldReference A named list of the LD references the summary statistics +#' were matched against, each a genotype panel, a \code{GenotypeMixture} or +#' an \code{LdMatrix}, and each stored once however many outcomes used it. +#' Empty when no summary statistics were analysed. #' @slot outcomeInfo A data frame mapping each outcome \code{name} to its -#' \code{study}, \code{context}, \code{trait} and \code{dataForm}. ColocBoost -#' is given outcome names as bare labels, and those labels are lossy -- a -#' trait is context-qualified only when ambiguous -- so the mapping is -#' recorded when the names are minted rather than parsed back out later. +#' \code{study}, \code{context}, \code{trait}, \code{dataForm} and +#' \code{ldReference}, the name of the \code{ldReference} entry its +#' summary statistics were matched against (\code{NA} for an +#' individual-level outcome, whose LD comes from its own genotypes). +#' ColocBoost is given outcome names as bare labels, and those labels are +#' lossy -- a trait is context-qualified only when ambiguous -- so the +#' mapping is recorded when the names are minted rather than parsed back +#' out later. #' @slot regionVcp A \code{GRanges} of every variant in the analysed region #' carrying the marginal \code{vcp}. Collection-level: it spans the region, #' not the elements, so it cannot live in \code{mcols}. @@ -62,11 +73,13 @@ setClass( "ColocBoostResult", contains = "ColocResultBase", representation( + ldReference = "list", outcomeInfo = "data.frame", regionVcp = "ANY", computingTime = "list" ), prototype( + ldReference = list(), regionVcp = NULL, computingTime = list() ) @@ -108,6 +121,12 @@ methods::setValidity("ColocBoostResult", function(object) { } coll$push(.cbrCheckVcpColumn(object)) coll$push(.cbrCheckOutcomeInfo(object)) + # The outcomes, not the sets, are what match against a reference, so + # their keys live in outcomeInfo rather than in mcols. + coll$push(.ldRefDictProblems( + object@ldReference, + object@outcomeInfo$ldReference + )) coll$getMessages() } @@ -188,6 +207,44 @@ setMethod("show", "ColocBoostResult", function(object) { invisible(NULL) }) +#' @rdname ldReference +#' @export +setMethod("ldReference", "ColocBoostResult", function(x) x@ldReference) + +# A ColocBoostResult keys its outcomes, not its sets, to its references, so +# its update is its own: the one reference an earlier version recorded was +# the one every summary-statistic outcome was matched against. +#' @rdname updateObject-methods +#' @export +setMethod( + "updateObject", + "ColocBoostResult", + function(object, ..., verbose = FALSE) { + methods::callNextMethod( + .cbrUpdateLdRefs(object), + ..., + verbose = verbose + ) + } +) + +# @noRd +.cbrUpdateLdRefs <- function(object) { + old <- methods::slot(object, "ldReference") + info <- .cbrWithLdKeys(object@outcomeInfo) + if (is.list(old) && !is.object(old)) { + return(`slot<-`(object, "outcomeInfo", value = info)) + } + dict <- .ldRefDict(list(.asLdRef(old))) + key <- if (length(dict$refs) == 0L) NA_character_ else dict$keys[[1L]] + info <- mutate( + info, + ldReference = if_else(.data$dataForm == "sumstats", key, NA_character_) + ) + updated <- `slot<-`(object, "ldReference", check = FALSE, value = dict$refs) + `slot<-`(updated, "outcomeInfo", value = info) +} + # ---- construction ----------------------------------------------------------- #' @title Build a ColocBoostResult @@ -203,9 +260,14 @@ setMethod("show", "ColocBoostResult", function(object) { #' @param gwasStudy Optional character vector, parallel to \code{results}, #' naming the GWAS study for the per-study \code{separate_gwas} runs. #' @param outcomeInfo Data frame mapping outcome \code{name} to \code{study}, -#' \code{context}, \code{trait} and \code{dataForm}. -#' @param ldReference Optional genotype panel (see -#' \code{\link{readGenotypes}}). +#' \code{context}, \code{trait} and \code{dataForm}, and optionally to +#' \code{ldReference}, the name of the \code{ldReference} entry the +#' outcome's summary statistics were matched against. Without that column +#' every outcome gets \code{NA}. +#' @param ldReference Optional named list of the LD references the summary +#' statistics were matched against: genotype panels (see +#' \code{\link{readGenotypes}}), \code{GenotypeMixture} or \code{LdMatrix} +#' objects. #' @param computingTime Optional list of per-analysis timings. #' @param includeUncolocalized Keep the outcome-specific (uncolocalized) sets #' as elements flagged \code{isColocalized = FALSE}. Default \code{TRUE}: @@ -255,13 +317,41 @@ ColocBoostResult <- function( unname() .cbrAssemble( rows, - outcomeInfo = as.data.frame(outcomeInfo), + outcomeInfo = .cbrWithLdKeys(as.data.frame(outcomeInfo)), regionVcp = .cbrRegionVcp(results), - ldReference = .asLdRef(ldReference), + ldReference = .cbrAsLdRefList(ldReference), computingTime = computingTime ) } +# The `ldReference` argument as the slot holds it: an empty list for NULL, or +# the named list with each entry normalised like any LD-reference input (a +# bare GenotypeHandle becomes a panel). A lone reference is refused rather +# than given a made-up name, since the name is what outcomeInfo keys on. +# @noRd +.cbrAsLdRefList <- function(ldReference) { + if (is.null(ldReference)) { + return(list()) + } + if (!is.list(ldReference) || is.object(ldReference)) { + abort(str_c( + "`ldReference` must be NULL or a named list of LD references, ", + "e.g. list(qtl = panel)." + )) + } + map(ldReference, .asLdRef) +} + +# outcomeInfo with its `ldReference` column, NA throughout when the caller's +# frame has none: no recorded reference is not the same as a shared one. +# @noRd +.cbrWithLdKeys <- function(info) { + if (is_in("ldReference", colnames(info))) { + return(info) + } + mutate(info, ldReference = NA_character_) +} + # Every set (colocalized, then uncolocalized) of one colocboost object, as a # list of one-row records. # @noRd @@ -480,7 +570,7 @@ ColocBoostResult <- function( obj <- new( "ColocBoostResult", grl, - ldReference = .asLdRef(ldReference), + ldReference = ldReference, outcomeInfo = outcomeInfo, regionVcp = regionVcp, computingTime = computingTime @@ -621,7 +711,9 @@ setMethod( #' @param ... Ignored. #' @return A tibble with one row per (set, outcome) and the set-level columns #' repeated, plus \code{outcome}, \code{study}, \code{context}, -#' \code{trait} and \code{dataForm}. +#' \code{trait}, \code{dataForm} and \code{ldReference} (the name of the +#' \code{\link{ldReference}} entry the outcome's summary statistics were +#' matched against). #' @examples #' # See colocboostPipeline(); a ColocBoostResult carries the mapping it needs. #' methods::existsMethod("colocBoostOutcomes", "ColocBoostResult") diff --git a/R/ColocResult.R b/R/ColocResult.R index 08188b43..6918ec30 100644 --- a/R/ColocResult.R +++ b/R/ColocResult.R @@ -46,33 +46,37 @@ NULL #' projection surface: both answer \code{\link{colocPairs}} and #' \code{\link{colocVariants}}, so code that only needs "which variants #' colocalized, and how strongly" works against either. -#' @slot ldReference The LD reference the underlying fits were computed -#' against (a genotype panel, a \code{GenotypeMixture} or an -#' \code{LdMatrix}), or \code{NULL}. Shared by both subclasses: coloc and -#' ColocBoost report different statistics, but both are computed against a -#' reference and both are asked for it the same way. -#' @export -setClass( - "ColocResultBase", - contains = c("VIRTUAL", "RangedTupleList"), - representation(ldReference = "LdReference_OR_NULL"), - prototype(ldReference = NULL) -) - -#' @rdname ldReference +#' +#' Each subclass carries its own LD reference, and both answer +#' \code{\link{ldReference}}: a \code{ColocResult} holds the one reference +#' its pairs were computed against, a \code{ColocBoostResult} one per +#' reference its summary statistics were matched against. #' @export -setMethod("ldReference", "ColocResultBase", function(x) x@ldReference) +setClass("ColocResultBase", contains = c("VIRTUAL", "RangedTupleList")) #' @title Colocalization Result #' @description A collection of colocalization results, one element per tested #' (QTL credible set, GWAS credible set, block) pair. Build the four views #' with \code{\link{colocPairs}}, \code{\link{colocVariants}}, #' \code{\link{colocCredibleSets}} and \code{\link{colocGenes}}. -#' @details The inherited \code{ldReference} is what -#' \code{colocCredibleSets()} uses to compute credible-set purity. +#' @details The \code{ldReference} is what \code{colocCredibleSets()} uses to +#' compute credible-set purity, each pair's from its own reference. +#' @slot ldReference A named list of the LD references the pairs were computed +#' against, each a genotype panel, a \code{GenotypeMixture} or an +#' \code{LdMatrix}, stored once apiece; the \code{ldReference} column of +#' \code{mcols} names the entry each pair used (\code{NA} for none). #' @seealso \code{\link{colocPipeline}} #' @export -setClass("ColocResult", contains = "ColocResultBase") +setClass( + "ColocResult", + contains = "ColocResultBase", + representation(ldReference = "list"), + prototype(ldReference = list()) +) + +#' @rdname ldReference +#' @export +setMethod("ldReference", "ColocResult", function(x) .ldRefsInUse(x)) methods::setValidity("ColocResult", function(object) { .validateColocResult(object) @@ -94,6 +98,7 @@ methods::setValidity("ColocResult", function(object) { if (!coll$isEmpty()) { return(coll$getMessages()) } + coll$push(.ldRefDictProblems(object@ldReference, .ldRefKeys(object))) coll$push(.crCheckPpColumns(object)) coll$push(.crCheckVariantColumn(object)) coll$getMessages() @@ -198,9 +203,11 @@ setMethod("show", "ColocResult", function(object) { #' columns are \code{NA} for it. #' @param variants A list, parallel to \code{pairs}' rows, of per-pair data #' frames with a \code{variant_id} column and a \code{SNP.PP.H4} column. -#' @param ldReference Optional genotype panel (see \code{\link{readGenotypes}}) -#' for the LD reference, used by \code{\link{colocCredibleSets}} to -#' compute purity. +#' @param ldReference Optional LD reference -- a genotype panel (see +#' \code{\link{readGenotypes}}), a \code{GenotypeMixture} or an +#' \code{LdMatrix} -- for every pair, or a list with one per pair; used by +#' \code{\link{colocCredibleSets}} to compute purity. Each distinct +#' reference is stored once. #' @return A \code{ColocResult}. #' @examples #' pairs <- data.frame( @@ -228,17 +235,19 @@ ColocResult <- function(pairs, variants, ldReference = NULL) { abort(msg) } elements <- map(variants, .crVariantsToGRanges) + dict <- .ldRefDict(.ldRefPerTuple(ldReference, nrow(pairs))) # Set unconditionally, including at zero rows: an empty result still has to # carry the column schema, or it fails validity and a caller reading # `result$PP.H4.abf` gets NULL exactly when there is nothing to report. + cols <- list_assign(as.list(pairs), ldReference = dict$keys) grl <- S4Vectors::`mcols<-`( GenomicRanges::GRangesList(elements), value = exec( S4Vectors::DataFrame, - !!!c(as.list(pairs), list(check.names = FALSE)) + !!!c(cols, list(check.names = FALSE)) ) ) - obj <- new("ColocResult", grl, ldReference = .asLdRef(ldReference)) + obj <- new("ColocResult", grl, ldReference = dict$refs) validObject(obj) obj } @@ -533,19 +542,21 @@ setMethod( } # Purity per credible set: the minimum absolute correlation among its members, -# one LD extraction per set (section 3.7). NA when there is no LD reference to -# extract from -- reported honestly rather than defaulted to a passing value. +# one LD extraction per set (section 3.7), each against its own pair's +# reference. NA when the pair has no LD reference to extract from -- reported +# honestly rather than defaulted to a passing value. # @noRd -.crPuritiesFor <- function(out, ldReference) { - if (is.null(ldReference)) { - return(rep(NA_real_, nrow(out))) - } - map_dbl(out$csVariants, .crPurityOne, ldReference = ldReference) +.crPuritiesFor <- function(out, refs) { + map2_dbl(out$csVariants, out$ldReference, .crPurityOne, refs = refs) } # @noRd #' @importFrom rlang try_fetch -.crPurityOne <- function(ids, ldReference) { +.crPurityOne <- function(ids, key, refs) { + ldReference <- .ldRefForKey(key, refs) + if (is.null(ldReference)) { + return(NA_real_) + } # A singleton set has no pair to correlate, and susie treats it as pure. if (length(ids) < 2L) { return(1) diff --git a/R/GwasFineMappingResult.R b/R/GwasFineMappingResult.R index db497836..ca186b65 100644 --- a/R/GwasFineMappingResult.R +++ b/R/GwasFineMappingResult.R @@ -8,7 +8,8 @@ # range -- the genome-wide-across-blocks shape that # qtlEnrichmentPipeline / colocPipeline expect when sweeping a study # across LD blocks. Class-level slots: -# * ldReference GenotypeHandle for the LD reference; required for the +# * ldReference the LD references the fits used, each stored once; the +# ldReference mcols column names each row's. Required for the # LD-block-indexed susieRSS workflow. # Methods that take per-row selectors accept (study, method) and ignore # context/trait (GWAS has no per-tuple context or trait axis). @@ -131,9 +132,9 @@ setClass( #' "methylation"), recorded as a per-row provenance column. Length 1 or #' one per row; \code{NULL} (default) omits the column. #' @param dataSource Optional per-row label for the kind of input the fit saw, -#' \code{"individual"} or \code{"sumstat"}. Recorded rather than derived: a -#' combined collection can hold rows of both kinds, and its single -#' \code{ldReference} cannot say which row came from which. +#' \code{"individual"} or \code{"sumstat"}. Where it is absent, the result +#' writers read a row's kind from its LD reference: a row with none saw +#' individual-level data. #' @param weightStandardized Optional per-row flag: whether the posterior #' effect is on the STANDARDIZED genotype scale. The posterior effect IS the #' prediction weight, so it carries the same scale question as a TWAS @@ -141,8 +142,11 @@ setClass( #' it standardizes genotypes before fitting, and the posterior mean is #' reported on the scale of the \code{X} the fit was given. The argument #' exists for a collection assembled by hand, where only the caller knows. -#' @param ldReference An optional genotype panel (see -#' \code{\link{readGenotypes}}). +#' @param ldReference The LD reference the fits were computed against -- a +#' genotype panel (see \code{\link{readGenotypes}}), a +#' \code{GenotypeMixture} or an \code{LdMatrix} -- used for every row, or +#' a list with one per row; \code{NULL} for none. Each distinct reference is +#' stored once. #' @param traitPos Optional per-row trait genomic anchor (a \code{GRanges} or #' \code{NULL}), carried forward as provenance; not part of the identity key. #' \code{NULL} (default) omits the column. @@ -187,7 +191,8 @@ GwasFineMappingResult <- function( .appendTraitPosCol(traitPos, n) |> .appendRegionCol(region, n) |> .appendFmProvenanceCols(dataType, dataSource, weightStandardized, n) - dfArgs <- c(cols, list(check.names = FALSE)) + dict <- .ldRefDict(.ldRefPerTuple(ldReference, n)) + dfArgs <- c(cols, list(ldReference = dict$keys, check.names = FALSE)) # Each entry's variants become one ELEMENT, its topLoci that element's # inner mcols, and its fit/cv payload outer mcols. A multi-seqname entry # splits by chromosome with its metadata row replicated. @@ -197,11 +202,7 @@ GwasFineMappingResult <- function( GenomicRanges::GRangesList(split$entry), value = md[split$fromIdx, , drop = FALSE] ) - obj <- new( - "GwasFineMappingResult", - grl, - ldReference = .asLdRef(ldReference) - ) + obj <- new("GwasFineMappingResult", grl, ldReference = dict$refs) validObject(obj) obj } @@ -334,10 +335,6 @@ setMethod("show", "GwasFineMappingResult", function(object) { .trim = FALSE )) } - ldSrc <- if (is.null(object@ldReference)) { - "NULL" - } else { - .ldRefLabel(object@ldReference) - } + ldSrc <- .ldRefsLabel(ldReference(object), "NULL") cat(glue(" LD reference: {ldSrc}\n", .trim = FALSE)) }) diff --git a/R/JointGroup.R b/R/JointGroup.R index 3be7be74..44b5e120 100644 --- a/R/JointGroup.R +++ b/R/JointGroup.R @@ -204,6 +204,13 @@ setClass("TwasJointPipeline", contains = "JointPipeline") # @noRd .jgN <- function(g) g@N +# The LD reference a group was fitted against: a summary-statistics group's +# own, NULL for an individual-level one, whose LD comes from its genotypes. +# @noRd +.jgLdRefOf <- function(g) { + if (methods::is(g, "SumStatsJointGroup")) .jgLdRef(g) else NULL +} + # The group restricted to the conditions `keep` marks: each condition's Y / Z # column goes with it, as does its trait position or sample size where those # are per condition. NULL when none is kept. Rebuilt through initialize(), so diff --git a/R/QtlFineMappingResult.R b/R/QtlFineMappingResult.R index d90de27e..4910ef1d 100644 --- a/R/QtlFineMappingResult.R +++ b/R/QtlFineMappingResult.R @@ -4,8 +4,9 @@ # DFrame-subclass collection keyed by the identity tuple (study, context, # trait, method). Each row holds a FineMappingRow payload. Class-level # slots: -# * ldReference GenotypeHandle (NULL for individual-level fits, the -# LD-sketch handle for RSS-derived fits). +# * ldReference the LD references RSS-derived fits used, each stored +# once; the ldReference mcols column names each row's (NA +# for an individual-level fit). # Optional columns jointStudies / jointContexts / jointTraits carry # semicolon-joined member identities for cross-axis joint fits emitted by # the joint dispatchers. @@ -39,8 +40,8 @@ setClass( # ---- QtlFineMappingResult validity helpers --------------------------------- # Collect all contract violations (empty vector = valid). The per-entry checks -# run only once the required columns are present; the ldReference check always -# runs. +# run only once the required columns are present; FineMappingResultBase's own +# validity checks the LD references. # @noRd #' @importFrom checkmate makeAssertCollection assertNames checkNames .validateQtlFineMappingResult <- function(object) { @@ -134,8 +135,6 @@ setClass( .tupleColumn(object, cn) } -# ldReference must be a GenotypeHandle or NULL. - # The identity-tuple vectors and the payload list are parallel: one entry per # (study, context, trait, method). A length mismatch would otherwise surface as # a recycling artefact deep inside the DataFrame assembly. @@ -159,9 +158,9 @@ setClass( #' @title Create a QtlFineMappingResult Collection #' @description Construct a \code{QtlFineMappingResult} DFrame-subclass #' collection from per-tuple vectors and a list of \code{FineMappingRow} -#' payloads (one per tuple). The optional \code{ldReference} slot records the -#' LD reference used for RSS-derived fits; pass \code{NULL} (the default) for -#' individual-level fits. +#' payloads (one per tuple). The optional \code{ldReference} records the LD +#' reference each RSS-derived fit used; leave it \code{NULL} (the default) +#' for individual-level fits. #' @param studyName Character vector of study identifiers (per tuple). Use the #' sentinel \code{"joint"} for rows produced by a cross-study joint fit. #' @param context Character vector of context labels (per tuple). Use @@ -182,9 +181,9 @@ setClass( #' "methylation"), recorded as a per-row provenance column. Length 1 or #' one per row; \code{NULL} (default) omits the column. #' @param dataSource Optional per-row label for the kind of input the fit saw, -#' \code{"individual"} or \code{"sumstat"}. Recorded rather than derived: a -#' combined collection can hold rows of both kinds, and its single -#' \code{ldReference} cannot say which row came from which. +#' \code{"individual"} or \code{"sumstat"}. Where it is absent, the result +#' writers read a row's kind from its LD reference: a row with none saw +#' individual-level data. #' @param weightStandardized Optional per-row flag: whether the posterior #' effect is on the STANDARDIZED genotype scale. The posterior effect IS the #' prediction weight, so it carries the same scale question as a TWAS @@ -192,9 +191,11 @@ setClass( #' it standardizes genotypes before fitting, and the posterior mean is #' reported on the scale of the \code{X} the fit was given. The argument #' exists for a collection assembled by hand, where only the caller knows. -#' @param ldReference An optional genotype panel (see -#' \code{\link{readGenotypes}}) (the LD reference for RSS-derived fits), or -#' \code{NULL} for individual-level fits. +#' @param ldReference The LD reference RSS-derived fits were computed +#' against -- a genotype panel (see \code{\link{readGenotypes}}), a +#' \code{GenotypeMixture} or an \code{LdMatrix} -- used for every row, or +#' a list with one per row; \code{NULL} for individual-level fits. Each +#' distinct reference is stored once. #' @param traitPos Optional per-row trait genomic anchor (a \code{GRanges} or #' \code{NULL}), carried forward as provenance; not part of the identity key. #' \code{NULL} (default) omits the column. @@ -499,10 +500,9 @@ setMethod("show", "QtlFineMappingResult", function(object) { .trim = FALSE )) } - ldSrc <- if (is.null(object@ldReference)) { + ldSrc <- .ldRefsLabel( + ldReference(object), "NULL (individual-level fit)" - } else { - .ldRefLabel(object@ldReference) - } + ) cat(glue(" LD reference: {ldSrc}\n", .trim = FALSE)) }) diff --git a/R/RangedTupleList.R b/R/RangedTupleList.R index 83b46fc1..bba1e95a 100644 --- a/R/RangedTupleList.R +++ b/R/RangedTupleList.R @@ -398,6 +398,51 @@ setMethod("endoapply", "RangedTupleList", function(X, FUN, ...) { ) } +# ----------------------------------------------------------------------------- +# updateObject +# ----------------------------------------------------------------------------- + +#' @title Update an Object Saved by an Earlier pecotmr +#' @description Bring a collection saved by an earlier version of pecotmr up +#' to date. Collections now keep their LD references per row: each distinct +#' reference once in the \code{ldReference} slot, and an \code{ldReference} +#' column naming the one every row uses (in \code{outcomeInfo} for a +#' \code{ColocBoostResult}). An object saved when it held a single reference +#' for all its rows is converted by keying every row to that reference (for +#' a \code{ColocBoostResult}, every summary-statistic outcome), and one that +#' held none by marking every row LD-free. An up-to-date object is returned +#' unchanged. +#' @param object A collection: summary statistics, fine-mapping results, TWAS +#' weights, or a colocalization result. +#' @param ... Passed on to the inherited method. +#' @param verbose Report the update. +#' @return \code{object} in the current representation. +#' @examples +#' data(qtlSumStatsExample) +#' # An object built by this version needs nothing. +#' identical(updateObject(qtlSumStatsExample), qtlSumStatsExample) +#' @name updateObject-methods +#' @rdname updateObject-methods +NULL + +#' @rdname updateObject-methods +#' @importFrom BiocGenerics updateObject +#' @export +setMethod( + "updateObject", + "RangedTupleList", + function(object, ..., verbose = FALSE) { + if (isTRUE(verbose)) { + message("updateObject(object = '", class(object)[[1L]], "')") + } + methods::callNextMethod( + .updateRowLdRefs(object), + ..., + verbose = verbose + ) + } +) + # ----------------------------------------------------------------------------- # subsetRegion # ----------------------------------------------------------------------------- @@ -433,13 +478,16 @@ setMethod("subsetRegion", "RangedTupleList", function(x, region) { # Build and validate a RangedTupleList subclass from its payloads and metadata # columns -- the shared tail of the TwasWeights and QtlFineMappingResult -# constructors. +# constructors. `ldReference` is one reference for every payload or a list +# with one per payload; each distinct one is stored once, and every row names +# its own in the `ldReference` column. # @noRd .rtlNewValidated <- function(Class, payloads, cols, ldReference) { + dict <- .ldRefDict(.ldRefPerTuple(ldReference, length(payloads))) obj <- new( Class, - .rtlGrlWithMetadata(payloads, cols), - ldReference = .asLdRef(ldReference) + .rtlGrlWithMetadata(payloads, c(cols, list(ldReference = dict$keys))), + ldReference = dict$refs ) validObject(obj) obj diff --git a/R/causalInferencePipeline.R b/R/causalInferencePipeline.R index 80ea97db..96875103 100644 --- a/R/causalInferencePipeline.R +++ b/R/causalInferencePipeline.R @@ -19,10 +19,13 @@ NULL #' MR computed from \code{fineMappingResult}. #' } #' -#' @section LD reference compatibility check: If a QTL input -#' (TwasWeights or QtlFineMappingResult) carries a non-\code{NULL} -#' \code{ldReference}, it must be the same LD reference as the -#' \code{ldReference} on \code{gwasSumStats}. +#' @section LD reference compatibility check: Per pair of rows scored +#' together: a QTL input row (TwasWeights or QtlFineMappingResult) that +#' carries an \code{ldReference} must be the same LD reference as the +#' \code{gwasSumStats} rows its region overlaps, and the rows of one GWAS +#' study that a QTL tuple overlaps must share one reference, since its TWAS +#' z reads one LD matrix. Rows that are never scored together may sit on +#' different references. #' The two must be the same kind of reference. Two genotype panels must #' share their samples and allele orientation; two \code{LdMatrix} objects #' must agree on the LD they share; two \code{GenotypeMixture} objects must @@ -30,8 +33,8 @@ NULL #' the same variants: QC-ing the two sides separately trims each reference #' to its own surviving variants, and a partial overlap only warns. A #' mismatch of any of those, or no shared variant at all, is a hard error. A -#' QTL input with \code{ldReference = NULL} (the fit was learned from -#' individual-level data) skips the validation for that input. +#' QTL input row with no reference (the fit was learned from +#' individual-level data) skips the validation. #' #' @section Output shape: #' A long-format \code{GRanges} with one row per @@ -50,7 +53,9 @@ NULL #' } #' #' @param gwasSumStats A \code{\link{GwasSumStats}} object. Must be QC'd -#' (\code{length(qcInfo(x)) > 0L}). +#' (\code{length(qcInfo(x)) > 0L}). A study may span many rows (one per +#' chromosome or LD block); each QTL tuple is scored once per study, over the +#' statistics of the rows its window overlaps. #' @param twasWeights Optional \code{\link{TwasWeights}} carrying per-(study, #' context, trait, method) weights. When supplied, drives the TWAS-Z #' computation. @@ -130,11 +135,7 @@ causalInferencePipeline <- function( mrParam ) { .cipValidateInputs(gwasSumStats, twasWeights, fineMappingResult) - gwasLd <- .cipCheckLdRefs( - gwasSumStats, - twasWeights, - fineMappingResult - ) + .cipCheckLdRefs(gwasSumStats, twasWeights, fineMappingResult) allRows <- .cipResolveWorkList(twasWeights, fineMappingResult) sel <- .cipCvSelection( qtlRows = allRows, @@ -149,7 +150,7 @@ causalInferencePipeline <- function( twasWeights = twasWeights, fineMappingResult = fineMappingResult, gwasSumStats = gwasSumStats, - gwasLd = gwasLd, + gwasIndex = .rowSpans(gwasSumStats), alleleFlip = alleleFlip, mrParam = mrParam )) @@ -198,26 +199,46 @@ causalInferencePipeline <- function( invisible(NULL) } -# Require the twasWeights / fineMappingResult LD sketches to match the GWAS one; -# returns the GWAS LD sketch. +# Require the twasWeights / fineMappingResult rows to share an LD reference +# with each GWAS row they are scored against -- the rows whose regions +# overlap; rows that never meet may sit on different references. # @noRd .cipCheckLdRefs <- function(gwasSumStats, twasWeights, fineMappingResult) { - gwasLd <- ldReference(gwasSumStats) if (!is.null(twasWeights)) { - .cipRequireMatchingLdRefs( - ldReference(twasWeights), - gwasLd, - label = "twasWeights" - ) + .cipRequireMatchingLdRefs(twasWeights, gwasSumStats, "twasWeights") } if (!is.null(fineMappingResult)) { .cipRequireMatchingLdRefs( - ldReference(fineMappingResult), - gwasLd, - label = "fineMappingResult" + fineMappingResult, + gwasSumStats, + "fineMappingResult" ) } - gwasLd + invisible(NULL) +} + +# The LD reference a (QTL tuple, GWAS study) pair's TWAS z reads: the one the +# study's `rows` -- those the tuple overlaps -- share. The z folds their +# variants into a single quadratic form, so they cannot sit on different +# references; that is refused rather than read from one of them. The study's +# other rows are not read and may. +# @noRd +.cipRowsLdRef <- function(gwasSumStats, rows, gStudy) { + keys <- unique(.ldRefKeys(gwasSumStats)[rows]) + if (length(keys) > 1L) { + abort(c( + glue( + "causalInferencePipeline: the rows of GWAS study '{gStudy}' ", + "a QTL tuple overlaps use {length(keys)} different LD ", + "references." + ), + i = str_c( + "Their statistics are scored together against one LD matrix; ", + "give them one LD reference." + ) + )) + } + .rowLdRef(gwasSumStats, rows[[1L]]) } # Build the (qtlStudy, context, trait, method) work list + the per-row @@ -300,8 +321,12 @@ causalInferencePipeline <- function( list(qtlRows = qtlRows, rsqLookup = rsqLookup, selectionActive = TRUE) } -# Score one QTL tuple against every GWAS study -> a list of result records -# (empty when the tuple has no usable weights). +# Score one QTL tuple against every GWAS study it overlaps -> a list of +# result records (empty when the tuple has no usable weights, or overlaps no +# GWAS row). Each study is scored once, over just the rows the tuple's window +# overlaps: a study split by chromosome or LD block has many rows, and +# pairing the tuple with every one of them scored it once per row. +# `gwasIndex` is .rowSpans(gwasSumStats), built once for the run. # @noRd .cipScoreQtlTuple <- function( qi, @@ -309,7 +334,7 @@ causalInferencePipeline <- function( twasWeights, fineMappingResult, gwasSumStats, - gwasLd, + gwasIndex, alleleFlip, mrParam ) { @@ -338,19 +363,35 @@ causalInferencePipeline <- function( tuple$qTrait, tuple$qMethod ) - compact(map( - seq_len(nrow(gwasSumStats)), + window <- .cipTupleWindow(weightsInfo, fmrEntry) + rows <- unique(gwasIndex$rows[.overlapsOnShared(gwasIndex$spans, window)]) + studies <- as.character(gwasSumStats$study)[rows] + compact(imap( + split(rows, factor(studies, levels = unique(studies))), .cipScoreGwasPair, tuple = tuple, weightsInfo = weightsInfo, fmrEntry = fmrEntry, gwasSumStats = gwasSumStats, - gwasLd = gwasLd, + window = window, alleleFlip = alleleFlip, mrParam = mrParam )) } +# The window a QTL tuple's GWAS statistics are read over: the span of its +# weight variants, widened to its fine-mapping variants, which MR reads too. +# @noRd +.cipTupleWindow <- function(weightsInfo, fmrEntry) { + fmrIds <- if (!is.null(fmrEntry)) { + .grVariantIds(unlist(fmrEntry, use.names = FALSE)) + } + range(.variantIdsToGRanges( + unique(c(weightsInfo$variantIds, fmrIds)), + what = "causalInferencePipeline variant id" + )) +} + # The tuple's single-row collection from `fineMappingResult` (NULL when it # lacks the tuple). # @noRd @@ -376,23 +417,29 @@ causalInferencePipeline <- function( } # Score one (qtl tuple, gwas study) pair -> a result record, or NULL when the -# TWAS Z cannot be computed (too little overlap). +# TWAS Z cannot be computed (too little overlap). `rows` are the study's rows +# the tuple's window overlaps; only their statistics inside the window are +# read, so a gene whose weights cross an LD-block boundary is scored once, +# over every block it reaches. # @noRd .cipScoreGwasPair <- function( - gi, + rows, + gStudy, tuple, weightsInfo, fmrEntry, gwasSumStats, - gwasLd, + window, alleleFlip, mrParam ) { - gStudy <- as.character(gwasSumStats$study)[[gi]] - gdf <- as.data.frame( - gwasSumStats, - studyName = gStudy, - require = c("SNP", "Z") + gwasLd <- .cipRowsLdRef(gwasSumStats, rows, gStudy) + gdf <- .entryToSumstatDf( + .ssStitchElements(gwasSumStats, rows, window), + require = c("SNP", "Z"), + derive = "none", + keepChrPrefix = TRUE, + label = glue("GwasSumStats[{gStudy}]") ) twasOut <- .cipComputeTwasZ( weights = weightsInfo$weights, @@ -527,12 +574,13 @@ causalInferencePipeline <- function( # Internal helpers # ============================================================================= -# Check two LD sketches for reference-panel compatibility. Thin wrapper over -# the shared `.requireMatchingLdRefs` helper (R/ld.R). -.cipRequireMatchingLdRefs <- function(qtlLd, gwasLd, label) { - .requireMatchingLdRefs( - qtlLd, - gwasLd, +# Check the QTL-side rows against the GWAS rows they overlap for +# reference-panel compatibility. Thin wrapper over the shared +# `.requireOverlapLdRefs` helper (R/ld.R). +.cipRequireMatchingLdRefs <- function(qtl, gwasSumStats, label) { + .requireOverlapLdRefs( + qtl, + gwasSumStats, pipelineName = "causalInferencePipeline", label = label ) diff --git a/R/colocPipeline.R b/R/colocPipeline.R index d297e226..c958639a 100644 --- a/R/colocPipeline.R +++ b/R/colocPipeline.R @@ -282,9 +282,11 @@ GwasFineMappingParam <- function( #' inline fine-mapping. #' } #' -#' @section LD reference compatibility check: If -#' \code{ldReference(qtlFineMappingResult)} is non-\code{NULL}, it must be -#' the same LD reference as the one on \code{gwasInput}. +#' @section LD reference compatibility check: Rows can sit on different LD +#' references, so the check is per pair of rows coloc scores against each +#' other -- a QTL row and a GWAS row whose regions overlap. Where the QTL +#' row carries a reference, it must be the same LD reference as the GWAS +#' row's; rows that are never paired may differ. #' The two must be the same kind of reference. Two genotype panels must #' share their samples and allele orientation; two \code{LdMatrix} objects #' must agree on the LD they share; two \code{GenotypeMixture} objects must @@ -293,9 +295,9 @@ GwasFineMappingParam <- function( #' two sides separately normally leaves each reference trimmed to its own #' surviving variants, and LD is looked up per variant, so a partial overlap #' only warns (once per session). No shared variant at all, or a mismatch of -#' any of those, is a hard error. When the first side's \code{ldReference} is -#' \code{NULL} (individual-level fit), the validation is skipped on that side -#' and the second side's panel is what the result carries forward. +#' any of those, is a hard error. When a first-side row has no reference +#' (individual-level fit), the validation is skipped for it and the second +#' side's panel is what the result carries forward for its pairs. #' #' @param qtlFineMappingResult The first side: a #' \code{\link{QtlFineMappingResult}} or a @@ -503,10 +505,7 @@ colocPipeline <- function( useEnrichment = useEnrichment ) rawGwasFmr <- .colocResolveGwasFmr(gwasInput, gwasFineMappingParam) - .colocRequireMatchingLdRefs( - ldReference(qtlFineMappingResult), - ldReference(rawGwasFmr) - ) + .colocRequireMatchingLdRefs(qtlFineMappingResult, rawGwasFmr) adjusted <- .colocMaybeAdjustPips( adjustPips = adjustPips, qtlFineMappingResult = qtlFineMappingResult, @@ -693,17 +692,6 @@ colocPipeline <- function( list(qtlFineMappingResult = both$x, gwasFmr = both$y) } -# The LD reference the result carries forward, so colocCredibleSets() can -# recompute purity (section 3.7) without being handed a sketch separately. The -# two sides' sketches are already required to match by -# .colocRequireMatchingLdRefs, so either one identifies the panel -- but a -# first side fit on individual-level data carries none, and then the second -# side's panel is the only one there is. -# @noRd -.colocLdRef <- function(qtlFineMappingResult, gwasFmr) { - ldReference(qtlFineMappingResult) %||% ldReference(gwasFmr) -} - # Empty-result early return (attaching the GWAS fine-mapping when requested). # @noRd .colocEarlyReturn <- function( @@ -713,10 +701,7 @@ colocPipeline <- function( gwasInput, returnGwasFineMapping ) { - out <- .colocEmptyResult( - enriched = useEnrichment, - ldReference = .colocLdRef(qtlFineMappingResult, gwasFmr) - ) + out <- .colocEmptyResult(enriched = useEnrichment) .colocAttachGwasFm(out, returnGwasFineMapping, gwasInput, gwasFmr) } @@ -769,7 +754,8 @@ colocPipeline <- function( ident, list( parts = .fmrRowParts(fmr, qi), - label = .fmrTupleLabel(.fmrSideName(fmr), ident) + label = .fmrTupleLabel(.fmrSideName(fmr), ident), + ldReference = .rowLdRef(fmr, qi) ) ) } @@ -853,9 +839,16 @@ colocPipeline <- function( # $results is the per-variant layer that process_coloc_results() used to # consume and that this pipeline silently dropped. It is pivoted here, the # only place that knows which results column belongs to which summary row. + # The pair's LD reference rides along for colocCredibleSets()' purity: + # the two sides' are required to match, but a QTL side fit on + # individual-level data has none, and then the GWAS side's is the one. list( rows = rows, - variants = .crPivotColocResults(pairRes$results, nrow(rows)) + variants = .crPivotColocResults(pairRes$results, nrow(rows)), + ldReference = rep( + list(q$ldReference %||% gInfo$ldReference), + nrow(rows) + ) ) } @@ -1048,11 +1041,7 @@ colocPipeline <- function( gwasInput, returnGwasFineMapping ) { - out <- .colocAssemble( - results, - useEnrichment, - .colocLdRef(qtlFineMappingResult, gwasFmr) - ) + out <- .colocAssemble(results, useEnrichment) .colocAttachGwasFm(out, returnGwasFineMapping, gwasInput, gwasFmr) } @@ -1066,18 +1055,20 @@ colocPipeline <- function( `attr<-`(out, "gwasFineMapping", gwasFmr) } -# Row-bind + column-order the per-pair summary rows (empty result when none). +# Row-bind + column-order the per-pair summary rows (empty result when none), +# each pair on the LD reference it was scored against. # @noRd -.colocAssemble <- function(results, useEnrichment, ldReference = NULL) { +.colocAssemble <- function(results, useEnrichment) { if (length(results) == 0L) { - return(.colocEmptyResult( - enriched = useEnrichment, - ldReference = ldReference - )) + return(.colocEmptyResult(enriched = useEnrichment)) } rows <- bind_rows(map(map(results, "rows"), .colocStandardiseRow)) variants <- list_c(map(results, "variants")) - ColocResult(.colocOrderColumns(rows, useEnrichment), variants, ldReference) + ColocResult( + .colocOrderColumns(rows, useEnrichment), + variants, + ldReference = list_flatten(map(results, "ldReference")) + ) } # Identity columns first, then everything coloc produced. @@ -1104,12 +1095,19 @@ colocPipeline <- function( # Internal helpers # ============================================================================= -# LD-sketch compatibility check. Thin wrapper over the shared -# `.requireMatchingLdRefs` helper (R/ld.R). Shared with -# qtlEnrichmentPipeline. +# LD-sketch compatibility check over the QTL / GWAS row pairs coloc scores +# against each other -- those whose regions overlap -- each of which must +# share an LD reference; rows that are never paired may sit on different +# ones. Thin wrapper over the shared `.requireOverlapLdRefs` helper +# (R/ld.R). # @noRd -.colocRequireMatchingLdRefs <- function(qtlLd, gwasLd) { - .requireMatchingLdRefs(qtlLd, gwasLd, pipelineName = "colocPipeline") +.colocRequireMatchingLdRefs <- function(qtlFineMappingResult, gwasFmr) { + .requireOverlapLdRefs( + qtlFineMappingResult, + gwasFmr, + pipelineName = "colocPipeline", + label = "qtlFineMappingResult" + ) } # SuSiE credible-set concentration filter. Given a trimmed SuSiE fit @@ -1349,7 +1347,8 @@ colocPipeline <- function( retainedMass = info$retainedMass, effect = info$effect, blockId = blockId, - label = label + label = label, + ldReference = .rowLdRef(gwasFmr, ri) ) ) } @@ -1395,7 +1394,7 @@ colocPipeline <- function( # do not have to special-case a NULL return. When `enriched = TRUE` the # enrichment + p12Used columns are appended (the enloc-mode schema). # @noRd -.colocEmptyResult <- function(enriched = FALSE, ldReference = NULL) { +.colocEmptyResult <- function(enriched = FALSE) { base <- tibble( study = character(0), context = character(0), @@ -1419,11 +1418,7 @@ colocPipeline <- function( qtlRetainedMass = numeric(0), gwasRetainedMass = numeric(0) ) - ColocResult( - mutate(base, !!!.colocEnrichmentCols(enriched, NULL)), - list(), - ldReference = ldReference - ) + ColocResult(mutate(base, !!!.colocEnrichmentCols(enriched, NULL)), list()) } # Look up this pair's enrichment factor in the user-supplied enrichment table. diff --git a/R/colocboostPipeline.R b/R/colocboostPipeline.R index 633b86df..b6dcf963 100644 --- a/R/colocboostPipeline.R +++ b/R/colocboostPipeline.R @@ -7,8 +7,8 @@ #' multi-context data. Per-context residualized X / Y are #' extracted from the dataset (filtering knobs on the #' constructor apply lazily inside the accessors). -#' \item \code{QtlSumStats} -- summary-statistic-only QTL data with a -#' shared LD reference (\code{ldReference}). Must already have +#' \item \code{QtlSumStats} -- summary-statistic-only QTL data with an +#' LD reference per row (\code{ldReference}). Must already have #' been passed through \code{\link{summaryStatsQc}} (the #' pipeline rejects inputs whose \code{qcInfo()} is empty). #' Every analysis variant is available on this input, including @@ -69,7 +69,12 @@ #' @param qtlData One of \code{QtlDataset}, \code{QtlSumStats}, or #' \code{MultiStudyQtlDataset}. #' @param gwasSumStats Optional \code{GwasSumStats} with the GWAS studies to -#' colocalize against. \code{NULL} to skip GWAS colocalization. +#' colocalize against. \code{NULL} to skip GWAS colocalization. Its +#' \code{ldReference} need not be the QTL side's: every row's summary +#' statistics are matched against that row's own reference. When some rows' +#' references are genotype panels and others' are \code{LdMatrix} objects, +#' the runs that combine them pass colocboost the panels' LD as matrices, +#' since colocboost takes LD matrices or reference genotypes but not both. #' @param contexts Optional character vector of context names to restrict the #' individual-level / QtlSumStats QTL analysis to. When \code{NULL} (default), #' every context present is used. @@ -156,7 +161,10 @@ #' \code{as.data.frame}), \code{\link{colocVariants}} or #' \code{\link{colocBoostOutcomes}}; timings are on #' \code{\link{computingTime}} and the region-wide marginal -#' probabilities on \code{\link{regionVcp}}. +#' probabilities on \code{\link{regionVcp}}. \code{\link{ldReference}} +#' returns the LD references the summary statistics were matched against, +#' each stored once, and the \code{ldReference} column of +#' \code{colocBoostOutcomes()} names the one each outcome used. #' @name colocboostPipeline #' @importFrom methods is setGeneric setMethod #' @importFrom S4Vectors mcols @@ -328,10 +336,13 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { YperCtx <- set_names(map(built, "Y"), map_chr(built, "ctx")) dedup <- .cbDedupX(XperCtx) split <- .cbSplitY(YperCtx, dedup$xMatch) + # An individual-level outcome's LD comes from its own genotypes, so it has + # no LD-reference entry to name. outcomeInfo <- mutate( split$outcomeInfo, study = studyName(qd), - dataForm = "individual" + dataForm = "individual", + ldReference = NA_character_ ) list( X = dedup$uniqueX, @@ -658,11 +669,14 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { keptIds <- attr(ld, "keptVariantIds") kept <- filter(df, is_in(variantIds, keptIds)) ss <- .cbSumstatFrame(kept, keptIds, nCase, nControl, varY) + # The reference rides with the pair, so the result can record the one + # each outcome was matched against. list( sumstat = ss, LD = `attr<-`(ld, "keptVariantIds", NULL), variantIds = keptIds, - isFactor = .ldIsGenotypeRef(ldReference) + isFactor = .ldIsGenotypeRef(ldReference), + ldReference = ldReference ) } @@ -741,7 +755,6 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { if (is.null(ss) || nrow(ss) == 0L) { return(list()) } - ldReference <- ldReference(ss) byContext <- if (!is.null(contexts) && length(contexts) > 0L) { is_in(as.character(ss$context), contexts) } else { @@ -759,13 +772,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { rows <- which(keepRow) compact(set_names( - map( - rows, - .cbQtlEntryPair, - ss = ss, - ldReference = ldReference, - cutoffs = cutoffs - ), + map(rows, .cbQtlEntryPair, ss = ss, cutoffs = cutoffs), map_chr(rows, .cbQtlEntryLabel, ss = ss) )) } @@ -780,9 +787,10 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { ) } -# One QTL entry's (sumstat, LD) pair, or NULL when it has no panel overlap. +# One QTL entry's (sumstat, LD) pair, against the entry's own LD reference, +# or NULL when it has no panel overlap. # @noRd -.cbQtlEntryPair <- function(i, ss, ldReference, cutoffs) { +.cbQtlEntryPair <- function(i, ss, cutoffs) { .cbSumstatPair( df = as.data.frame( ss, @@ -791,7 +799,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { trait = as.character(ss$trait)[[i]], require = "Z" ), - ldReference = ldReference, + ldReference = .rowLdRef(ss, i), varY = .cbTupleValue(ss, "varY", i), cutoffs = cutoffs ) @@ -814,29 +822,23 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { if (is.null(gws) || nrow(gws) == 0L) { return(list()) } - ldReference <- ldReference(gws) compact(set_names( - map( - seq_len(nrow(gws)), - .cbGwasEntryPair, - gws = gws, - ldReference = ldReference, - cutoffs = cutoffs - ), + map(seq_len(nrow(gws)), .cbGwasEntryPair, gws = gws, cutoffs = cutoffs), as.character(gws$study) )) } -# One GWAS entry's (sumstat, LD) pair, or NULL when it has no panel overlap. +# One GWAS entry's (sumstat, LD) pair, against the entry's own LD reference, +# or NULL when it has no panel overlap. # @noRd -.cbGwasEntryPair <- function(i, gws, ldReference, cutoffs) { +.cbGwasEntryPair <- function(i, gws, cutoffs) { .cbSumstatPair( df = as.data.frame( gws, studyName = as.character(gws$study)[[i]], require = "Z" ), - ldReference = ldReference, + ldReference = .rowLdRef(gws, i), varY = .cbTupleValue(gws, "varY", i), nCase = .cbTupleValue(gws, "nCase", i), nControl = .cbTupleValue(gws, "nControl", i), @@ -844,26 +846,16 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { ) } -# Check two LD sketches for the reference-panel compatibility contract. Thin -# wrapper over the shared `.requireMatchingLdRefs` helper (R/ld.R) -# using the "lenient" null policy: a NULL on either side skips the check -# (only colocboostPipeline allows that, since some bundles only have a -# QTL side or only a GWAS side). -.cbRequireMatchingLdRefs <- function(qtlLd, gwasLd) { - .requireMatchingLdRefs( - qtlLd, - gwasLd, - pipelineName = "colocboostPipeline", - nullPolicy = "lenient" - ) -} - # Combine sumstat bundles into the (sumstat-list, LD-list, dict) shape # colocboost expects. Deduplicates identical LD matrices so dict_sumstatLD # can point multiple sumstats at one LD, and records in `ldArg` whether the -# list holds LD matrices ("LD") or factors of them ("X_ref"). Every side of -# a run reads one LD reference (.cbRequireMatchingLdRefs()), so the bundles -# never mix the two. +# list holds LD matrices ("LD") or factors of them ("X_ref"). +# +# The QTL and GWAS sides each read their own LD reference, so a run can mix a +# genotype panel's factors with an LdMatrix's matrices. colocboost takes LD or +# X_ref but not both, so such a run gets every factor as its LD matrix -- the +# matrix colocboost would compute from it anyway once a panel has at least as +# many samples as variants. .cbMergeSumstatBundles <- function(bundles) { if (length(bundles) == 0L) { return(list( @@ -873,12 +865,9 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { ldArg = "LD" )) } - kinds <- unique(map_lgl(bundles, .cbPairIsFactor)) - if (length(kinds) > 1L) { - abort( - "colocboost inputs mix LD matrices and genotype factors.", - .internal = TRUE - ) + isFactor <- map_lgl(bundles, .cbPairIsFactor) + if (any(isFactor) && !all(isFactor)) { + bundles <- map(bundles, .cbPairAsLdMatrix) } # Same shape as .cbDedupX: every bundle resolves to the first bundle # carrying an identical LD matrix, so the unique set and the back-mapping @@ -893,7 +882,22 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { sumstat = seq_along(bundles), LD = match(firstIdx, keepIdx) ), - ldArg = if (kinds) "X_ref" else "LD" + ldArg = if (all(map_lgl(bundles, .cbPairIsFactor))) "X_ref" else "LD" + ) +} + +# A (sumstat, LD) pair with its LD held as the matrix. A factor F of a +# genotype reference gives crossprod(F) / (nrow(F) - 1), which is that +# reference's LD over the same variants (see .ldFactorFromRef()). +# @noRd +.cbPairAsLdMatrix <- function(p) { + if (!.cbPairIsFactor(p)) { + return(p) + } + list_assign( + p, + LD = crossprod(p$LD) / (nrow(p$LD) - 1L), + isFactor = FALSE ) } @@ -1090,7 +1094,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { separateGwas, focalTrait, methodArgs, - qtlLdReference = NULL, + ldRefs = list(refs = list(), keys = character(0)), qtlSumstatBundle = NULL, gwasRunBundles = list() ) { @@ -1127,8 +1131,8 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { results <- .cbMergeRuns(.cbEmptyResult(), runs) .cbToResultObject( results, - .cbOutcomeInfo(individualBundle, sumstatBundle, hasInd), - qtlLdReference + .cbOutcomeInfo(individualBundle, sumstatBundle, hasInd, ldRefs$keys), + ldRefs$refs ) } @@ -1178,7 +1182,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { # key: without it the separate-GWAS sets would be indistinguishable from each # other once flattened. # @noRd -.cbToResultObject <- function(results, outcomeInfo, ldReference = NULL) { +.cbToResultObject <- function(results, outcomeInfo, ldReference = list()) { sep <- results$separate_gwas sepRuns <- if (is.null(sep) || length(sep) == 0L) { list() @@ -1290,9 +1294,15 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { # ColocBoostResult answer "which contexts colocalized" instead of handing the # caller a string to parse. Sumstat outcomes are keyed by study name and carry # no context or trait of their own, which is recorded as NA rather than -# invented. +# invented. `ldKeys` names, per sumstat outcome, the result's LD-reference +# entry it was matched against (.cbResultLdRefs()). # @noRd -.cbOutcomeInfo <- function(individualBundle, sumstatBundle, hasInd) { +.cbOutcomeInfo <- function( + individualBundle, + sumstatBundle, + hasInd, + ldKeys = character(0) +) { ssNames <- names(sumstatBundle$sumstat) parts <- compact(list( if (isTRUE(hasInd)) individualBundle$outcomeInfo, @@ -1302,7 +1312,8 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { context = NA_character_, trait = NA_character_, study = ssNames, - dataForm = "sumstats" + dataForm = "sumstats", + ldReference = unname(ldKeys[ssNames]) ) } )) @@ -1319,7 +1330,8 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { context = character(0), trait = character(0), study = character(0), - dataForm = character(0) + dataForm = character(0), + ldReference = character(0) ) } @@ -1517,7 +1529,8 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { sumstat = ss, LD = ld, variantIds = canonical[ib], - isFactor = isFactor + isFactor = isFactor, + ldReference = p$ldReference ) } @@ -1603,7 +1616,6 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { separateGwas, focalTrait, methodArgs, - qtlLdReference = NULL, alleleFlip = TRUE, cutoffs = NULL ) { @@ -1614,7 +1626,6 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { combinedPairs <- .cbAppendGwasPairs( qtlPairs, gwasSumStats, - qtlLdReference, cutoffs = cutoffs ) harmonized <- .cbMaybeHarmonize( @@ -1634,12 +1645,21 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { separateGwas, focalTrait, methodArgs, - qtlLdReference = qtlLdReference, + ldRefs = .cbResultLdRefs(harmonized$pairs), qtlSumstatBundle = qtlSumstatBundle, gwasRunBundles = gwasRunBundles ) } +# The LD references a result records -- each distinct one the summary +# statistics were matched against, once -- and each summary-statistic +# outcome's key into them, read off the pairs that carry them. +# @noRd +.cbResultLdRefs <- function(pairs) { + dict <- .ldRefDict(map(unname(pairs), "ldReference")) + list(refs = dict$refs, keys = set_names(dict$keys, names(pairs))) +} + # The separate-GWAS run bundles, keyed by GWAS label. The runs are FOCAL: each # is one GWAS tested against the whole QTL side, so each needs its own bundle # of (every QTL pair + that one GWAS). Built through .cbMergeSumstatBundles @@ -1658,21 +1678,14 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { # Append the GWAS sumstat pairs to the QTL pairs, QC-gating gwasSumStats and # make.unique-ing colliding labels. (Sequential key resolution -- kept as a -# loop.) +# loop.) The GWAS side's LD comes from its own reference, which need not be +# the QTL side's: each pair carries the LD it was matched against. # @noRd -.cbAppendGwasPairs <- function( - qtlPairs, - gwasSumStats, - qtlLdReference, - cutoffs = NULL -) { +.cbAppendGwasPairs <- function(qtlPairs, gwasSumStats, cutoffs = NULL) { if (is.null(gwasSumStats)) { return(qtlPairs) } .cbRequireSumStatsQc(gwasSumStats, "gwasSumStats") - if (!is.null(qtlLdReference)) { - .cbRequireMatchingLdRefs(qtlLdReference, ldReference(gwasSumStats)) - } gwasPairs <- .cbGwasSumStatsBundle(gwasSumStats, cutoffs = cutoffs) if (length(gwasPairs) == 0L) { return(qtlPairs) @@ -1829,7 +1842,6 @@ setMethod( separateGwas = separateGwas, focalTrait = focalTrait, methodArgs = methodArgs, - qtlLdReference = ldReference(qtlData), alleleFlip = alleleFlip, cutoffs = cutoffs ) @@ -1934,7 +1946,6 @@ setMethod( separateGwas, focalTrait, methodArgs, - qtlLdReference = ss$qtlLdReference, alleleFlip = alleleFlip, cutoffs = cutoffs ) @@ -2075,7 +2086,7 @@ setMethod( } # Sumstat side of a MultiStudyQtlDataset: bundle any embedded QtlSumStats. -# Returns list(qtlPairs, qtlLdReference). +# Returns list(qtlPairs); each pair carries its own row's LD reference. # @noRd .cbMultiStudySumstats <- function( qtlData, @@ -2085,7 +2096,7 @@ setMethod( ) { embeddedSs <- sumStats(qtlData) if (is.null(embeddedSs)) { - return(list(qtlPairs = list(), qtlLdReference = NULL)) + return(list(qtlPairs = list())) } .cbRequireSumStatsQc(embeddedSs, "MultiStudyQtlDataset@sumStats") list( @@ -2094,8 +2105,7 @@ setMethod( contexts = contexts, traitId = traitId, cutoffs = cutoffs - ), - qtlLdReference = ldReference(embeddedSs) + ) ) } diff --git a/R/ctwasPipeline.R b/R/ctwasPipeline.R index aa02011a..f8fcceb4 100644 --- a/R/ctwasPipeline.R +++ b/R/ctwasPipeline.R @@ -201,9 +201,10 @@ BoundaryMergeParam <- function( #' log, give a step a log file through its options, e.g. #' \code{CtwasEstParamOptions(logfile = "est_param.log")}. #' -#' @section LD reference compatibility check: Per block: -#' \code{ldReference(twasWeights)} (when non-NULL) must be the same LD -#' reference as \code{ldReference(gwasSumStats)}. +#' @section LD reference compatibility check: Per block: the block's GWAS +#' rows must share one LD reference (a block's LD is one matrix), and every +#' weight row placed in the block that carries a reference must be the same +#' LD reference as theirs. Blocks may sit on different references. #' The two must be the same kind of reference. Two genotype panels must #' share their samples and allele orientation; two \code{LdMatrix} objects #' must agree on the LD they share; two \code{GenotypeMixture} objects must @@ -628,8 +629,8 @@ assembleCtwasInputs <- function( } # One single-element GwasSumStats per LD block, keyed by blockId -- the shape -# the two-pass assembly consumes. The collection's own ldReference rides along -# on each subset, so per-region LD lookups are unchanged. +# the two-pass assembly consumes. Each block keeps its own row's LD reference, +# so per-region LD lookups read the panel that block was harmonized against. # @noRd .ctwasGwasByBlock <- function(gwasSumStats) { set_names( @@ -638,23 +639,20 @@ assembleCtwasInputs <- function( ) } -# One block's slice of the collection. `[` carries the collection-level -# ldReference through verbatim, and combineGwasSumStats() deliberately UNIONS -# the per-piece panels, so without narrowing here every block references the -# whole chromosome and its LD panel would cover all of it (a -# chr19-wide panel runs to ~155 GB). Narrowed to the block's own variants -# the same way summaryStatsQc narrows the sketch it retains. +# One block's slice of the collection. A row's LD reference can cover far more +# than its block -- combineGwasSumStats() unions the per-piece panels of one +# source -- so without narrowing here a block would reference the whole +# chromosome and its LD panel would cover all of it (a chr19-wide panel runs +# to ~155 GB). Narrowed to the block's own variants the same way +# summaryStatsQc narrows the sketch it retains. # @noRd .ctwasPickBlock <- function(i, x) { block <- x[i] - sketch <- ldReference(block) - if (is.null(sketch)) { + refs <- ldReference(block) + if (length(refs) == 0L) { return(block) } - methods::initialize( - block, - ldReference = .subsetLdRefToIds(sketch, as.list(block)) - ) + .withRowLdRefs(block, .subsetLdRefToIds(refs[[1L]], as.list(block))) } # Resolve a flat weight source into per-region buckets (cTWAS's p0 start-of- @@ -739,32 +737,45 @@ assembleCtwasInputs <- function( # measured against this table rather than against any one block's panel. # # NULL when the collection carries no sketch -- .ctwasRegionGwasLd() reports -# that case with its own message, so this must not pre-empt it. +# that case with its own message, so this must not pre-empt it. Rows on +# different references contribute each panel's variants, each once. # @noRd .ctwasGlobalPanelInfo <- function(gwasSumStats) { - sketch <- ldReference(gwasSumStats) - if (is.null(sketch)) { + refs <- ldReference(gwasSumStats) + if (length(refs) == 0L) { return(NULL) } - .ctwasSnpInfoForBlock(sketch) + info <- list_rbind(map(unname(refs), .ctwasSnpInfoForBlock)) + filter(info, !duplicated(.data$id)) } -# One region's GWAS LD sketch, checked against the region's weights. +# One region's GWAS LD sketch, checked against the region's weights. A +# region's LD is one matrix, so its GWAS rows must share one reference, and +# every weight row in the region is combined with them. # @noRd .ctwasRegionGwasLd <- function(rid, gwasSumStats, twasWeights) { - gwasLd <- ldReference(gwasSumStats[[rid]]) - if (is.null(gwasLd)) { + gwas <- gwasSumStats[[rid]] + refs <- ldReference(gwas) + if (length(refs) == 0L) { msg <- glue( "ctwasPipeline: GwasSumStats for region '{rid}' carries no ", "ldReference (ldReference = NULL); cTWAS requires an LD reference." ) abort(msg) } + if (length(refs) > 1L) { + msg <- glue( + "ctwasPipeline: GwasSumStats for region '{rid}' has rows on ", + "{length(refs)} different LD references; a region's LD is one ", + "matrix." + ) + abort(msg) + } tw <- twasWeights[[rid]] if (!is.null(tw)) { - .ctwasRequireMatchingLdRefs(ldReference(tw), gwasLd) + .ctwasRequireMatchingLdRefs(tw, gwas) } - gwasLd + refs[[1L]] } # @noRd @@ -1427,10 +1438,20 @@ mergeCtwasBoundaryRegions <- function( # Internal helpers # ============================================================================= -# LD-sketch compatibility check. Thin wrapper over the shared -# `.requireMatchingLdRefs` helper (R/ld.R). -.ctwasRequireMatchingLdRefs <- function(twLd, gwasLd) { - .requireMatchingLdRefs(twLd, gwasLd, pipelineName = "ctwasPipeline") +# LD-sketch compatibility check for one region: every weight row in it is +# combined with every one of its GWAS rows. Thin wrapper over the shared +# `.requireMatchingRowLdRefs` helper (R/ld.R). +.ctwasRequireMatchingLdRefs <- function(tw, gwas) { + nTw <- length(tw) + nGwas <- length(gwas) + .requireMatchingRowLdRefs( + tw, + gwas, + qtlRows = rep(seq_len(nTw), each = nGwas), + gwasRows = rep(seq_len(nGwas), times = nTw), + pipelineName = "ctwasPipeline", + label = "twasWeights" + ) } # Resolve which TWAS method's weights to feed into ctwas given a @@ -1667,22 +1688,15 @@ mergeCtwasBoundaryRegions <- function( length(g) == 0L } -# The genes homed into region `rid`, carrying that region's LD sketch, or -# NULL when nothing landed there. `slot<-` applied as a function returns a -# copy rather than writing into the subset in place. -# @noRd -#' @importFrom methods slot<- +# The genes homed into region `rid`, every row on that region's LD sketch, or +# NULL when nothing landed there. # @noRd .ctwasBucketForRegion <- function(rid, combined, home, gwasSumStats) { idx <- which(home == rid) if (length(idx) == 0L) { return(NULL) } - `slot<-`( - combined[idx, ], - "ldReference", - value = ldReference(gwasSumStats[[rid]]) - ) + .withRowLdRefs(combined[idx, ], ldReference(gwasSumStats[[rid]])) } # Bucket a flat weight source into a per-region named list keyed to the block diff --git a/R/exampleData.R b/R/exampleData.R index 9c12051b..352dd2ec 100644 --- a/R/exampleData.R +++ b/R/exampleData.R @@ -264,8 +264,8 @@ NULL #' @description A pre-QC'd \code{\link{QtlSumStats}} collection covering the #' same (study, context, trait) tuple as \code{\link{qtlDatasetExample}}; #' the per-variant Z / BETA / SE / N values were computed from the synthetic -#' phenotype by per-variant linear regression. The \code{ldReference} slot -#' references the same toy PLINK1 panel. +#' phenotype by per-variant linear regression. Its LD reference is the same +#' toy PLINK1 panel. #' #' @format A \code{QtlSumStats} S4 collection with one row (study1, brain, #' ENSG_example) backed by a GRanges of 200 chr22 variants. @@ -319,8 +319,7 @@ NULL #' synthetic trait (\code{"trait1"}, N = 50,000). The signal pattern shares #' one causal variant with \code{\link{qtlSumStatsExample}} (for #' colocalization demos) and adds a second GWAS-only causal variant. -#' The \code{ldReference} slot references the same toy PLINK1 panel used -#' for the QTL example. +#' Its LD reference is the same toy PLINK1 panel the QTL example uses. #' #' @format A \code{GwasSumStats} S4 collection with one row (trait1) #' backed by a GRanges of 200 chr22 variants. diff --git a/R/fineMappingPipeline.R b/R/fineMappingPipeline.R index 34e15d51..debf0635 100644 --- a/R/fineMappingPipeline.R +++ b/R/fineMappingPipeline.R @@ -378,10 +378,10 @@ #' @return A \code{QtlFineMappingResult} keyed by \code{(study, context, #' trait, method)} -- for \code{GwasSumStats} input, a #' \code{GwasFineMappingResult} keyed by \code{(study, method)} and range. -#' The \code{ldReference} slot is set automatically: \code{NULL} -#' for individual-level (QtlDataset / all-individual-level -#' MultiStudyQtlDataset) fits, the input's \code{ldReference} for RSS-derived -#' fits. +#' Each row records the LD reference its fit used: none for +#' individual-level (QtlDataset / all-individual-level +#' MultiStudyQtlDataset) fits, the reference of the input row it was fitted +#' from for RSS-derived fits. #' @examples #' data(qtlDatasetExample) #' fineMappingPipeline(qtlDatasetExample, methods = "susie", cisWindow = 1e6) @@ -1210,6 +1210,7 @@ setGeneric("fineMappingPipeline", function(data, ...) { } return(list(rows = list(), skipped = TRUE)) } + cfg <- .fmRssRowCfg(cfg, i) zn <- .fmExtractZn( gr, glue("fineMappingPipeline(GwasSumStats): study='{st}'"), @@ -1235,13 +1236,28 @@ setGeneric("fineMappingPipeline", function(data, ...) { blockId = blockId ) toRun <- map_chr(keep(lookups, .fmNotCached), "tk") - if (length(toRun) == 0L) { - return(list(rows = cachedRows, skipped = FALSE)) + computed <- if (length(toRun) > 0L) { + .fmGwasFitRows(gr, zn, st, blockId, toRun, cfg) } - computed <- .fmGwasFitRows(gr, zn, st, blockId, toRun, cfg) - list(rows = c(cachedRows, computed), skipped = FALSE) + list( + rows = .recordsWithLdRef(c(cachedRows, computed), cfg$ldReference), + skipped = FALSE + ) +} + +# `cfg` for row `i`: its own LD reference, with the RSS settings resolved +# against that reference (the finite-reference size defaults to its panel's). +# @noRd +.fmRssRowCfg <- function(cfg, i) { + ldReference <- .rowLdRef(cfg$data, i) + list_assign( + cfg, + ldReference = ldReference, + susieRssParam = .fmRssArgsResolved(cfg$susieRssParam, ldReference) + ) } + # The fine-mapping settings shared by every summary-statistics path: the # QtlSumStats joint phase and the RSS / GWAS row builders all act on these. # Named once here so the records built from it cannot disagree about the same @@ -1269,14 +1285,14 @@ setGeneric("fineMappingPipeline", function(data, ...) { } # The per-run settings the RSS / GWAS row builders all need: the common -# summary-statistics record plus the LD and RSS-control fields only the row -# builders use. The chain threads one record instead of twenty arguments, and -# every field is named deliberately -- this is not a capture of the calling -# frame. +# summary-statistics record plus the RSS-control fields only the row builders +# use. Each row adds its own LD reference, and resolves `susieRssParam` +# against it, as it is fitted (.fmRssRowCfg()). The chain threads one record +# instead of twenty arguments, and every field is named deliberately -- this +# is not a capture of the calling frame. # @noRd .fmRssRunCfg <- function( common, - ldReference, initializeWithSusieInf, methodArgs, susieRssParam @@ -1284,7 +1300,6 @@ setGeneric("fineMappingPipeline", function(data, ...) { c( common, list( - ldReference = ldReference, initializeWithSusieInf = initializeWithSusieInf, methodArgs = methodArgs, susieRssParam = susieRssParam @@ -1394,6 +1409,7 @@ setGeneric("fineMappingPipeline", function(data, ...) { tr = tr ) toRun <- map_chr(keep(lookups, .fmNotCached), "tk") + cachedRows <- .recordsWithLdRef(cachedRows, .rowLdRef(cfg$data, i)) if (length(toRun) == 0L) { return(list(rows = cachedRows, skipped = FALSE)) } @@ -1409,8 +1425,12 @@ setGeneric("fineMappingPipeline", function(data, ...) { } return(list(rows = cachedRows, skipped = TRUE)) } + cfg <- .fmRssRowCfg(cfg, i) computed <- .fmRssFitRows(i, st, ctx, tr, toRun, cfg) - list(rows = c(cachedRows, computed), skipped = FALSE) + list( + rows = c(cachedRows, .recordsWithLdRef(computed, cfg$ldReference)), + skipped = FALSE + ) } # Concatenate two same-class fine-mapping result collections row-wise, @@ -1436,9 +1456,11 @@ setGeneric("fineMappingPipeline", function(data, ...) { #' #' @param ... Two or more \code{FineMappingResultBase} objects, or a single #' \code{list} of them. -#' @param ldReference Optional genotype panel (see -#' \code{\link{readGenotypes}}) to attach to the -#' combined collection. Default \code{NULL}. Applied when combining two or +#' @param ldReference Optional LD reference -- a genotype panel (see +#' \code{\link{readGenotypes}}), a \code{GenotypeMixture} or an +#' \code{LdMatrix} -- that every row of the combined collection uses instead +#' of its own. Default \code{NULL}: each row keeps the reference it had, +#' and views of one source are stored once. Applied when combining two or #' more inputs; a single input is returned unchanged. #' @return A single combined fine-mapping result of the shared concrete class. #' @seealso \code{\link{combineTwasWeights}} @@ -4067,17 +4089,17 @@ NULL # Assemble the QtlSumStats result: build the per-tuple QtlFineMappingResult # from the collected row-records (region = entry variant span, no cis-window) -# and combine with the joint result. An all-screened collection yields a valid -# empty result rather than an error. +# and combine with the joint result, every row keeping its own LD reference. +# An all-screened collection yields a valid empty result rather than an +# error. # @noRd .fmQssAssemble <- function( data, - ldReference, rows, nSkipped, jointResult ) { - perTupleResult <- .fmQssPerTupleResult(data, rows, ldReference) + perTupleResult <- .fmQssPerTupleResult(data, rows) if (is.null(jointResult)) { if (!is.null(perTupleResult)) { return(perTupleResult) @@ -4089,7 +4111,6 @@ NULL character(0), character(0), list(), - ldReference = ldReference, allowEmpty = TRUE )) } @@ -4100,18 +4121,14 @@ NULL if (is.null(perTupleResult)) { return(jointResult) } - .rbindFineMappingResult( - perTupleResult, - jointResult, - ldReference = ldReference - ) + .rbindFineMappingResult(perTupleResult, jointResult) } # The per-tuple QtlFineMappingResult from the collected row-records, or NULL # when there are none. Each row's region is its entry's variant span (no -# cis-window). +# cis-window), and its LD reference the one its entry was fitted against. # @noRd -.fmQssPerTupleResult <- function(data, rows, ldReference) { +.fmQssPerTupleResult <- function(data, rows) { if (length(rows) == 0L) { return(NULL) } @@ -4135,7 +4152,7 @@ NULL NULL, length(rows) ), - ldReference = ldReference + ldReference = map(rows, "ldReference") ) } @@ -4249,13 +4266,11 @@ NULL return(rt$result) } sel <- .fmQssSelectRows(data = data, contexts = contexts, traitId = traitId) - ldReference <- ldReference(data) cfg <- .fmRssRunCfg( cfgs$common, - ldReference = ldReference, initializeWithSusieInf = initializeWithSusieInf, methodArgs = rt$methodArgs, - susieRssParam = .fmRssArgsResolved(susieRssParam, ldReference) + susieRssParam = susieRssParam ) .fmQssRunRows( data, @@ -4263,7 +4278,6 @@ NULL split = .fmQssSplitTokens(rt$tokens, sel), cfg = cfg, jointCfg = cfgs$joint, - ldReference = ldReference, methodArgs = rt$methodArgs, jointResult = rt$result ) @@ -4280,7 +4294,6 @@ NULL split, cfg, jointCfg, - ldReference, methodArgs, jointResult ) { @@ -4299,7 +4312,6 @@ NULL } .fmQssAssemble( data = data, - ldReference = ldReference, rows = list_flatten(map(univOut, "rows")), nSkipped = sum(map_lgl(univOut, "skipped")), jointResult = .fmQssAutoJoint( @@ -4435,11 +4447,9 @@ setMethod( ) .fmCheckMethodCapabilities(norm$tokens, "GwasSumStats") .fmCheckMethodArgsForInput(norm$methodArgs, "GwasSumStats") - ldReference <- ldReference(data) # Derived values are ordinary locals now, not fields grafted onto a bundle. tokens <- norm$tokens methodArgs <- norm$methodArgs - susieRssParam <- .fmRssArgsResolved(susieRssParam, ldReference) studyCol <- as.character(data$study) commonCfg <- .fmSsCommonCfg( data = data, @@ -4454,7 +4464,6 @@ setMethod( studyCol = studyCol, tokens = tokens, commonCfg = commonCfg, - ldReference = ldReference, initializeWithSusieInf = initializeWithSusieInf, methodArgs = methodArgs, susieRssParam = susieRssParam @@ -4469,7 +4478,6 @@ setMethod( studyCol, tokens, commonCfg, - ldReference, initializeWithSusieInf, methodArgs, susieRssParam @@ -4481,7 +4489,6 @@ setMethod( tokens = tokens, cfg = .fmRssRunCfg( commonCfg, - ldReference = ldReference, initializeWithSusieInf = initializeWithSusieInf, methodArgs = methodArgs, susieRssParam = susieRssParam @@ -4500,7 +4507,7 @@ setMethod( # the same window .fmRssFitWindow() gives the per-row grange columns, # so the two cannot disagree. region = .fmGwasRowWindows(rows), - ldReference = ldReference, + ldReference = map(rows, "ldReference"), allowEmpty = (nSkipped > 0L || nrow(data) == 0L) ) } diff --git a/R/fineMappingWrappers.R b/R/fineMappingWrappers.R index 5898fa86..cf29ed66 100644 --- a/R/fineMappingWrappers.R +++ b/R/fineMappingWrappers.R @@ -1119,13 +1119,7 @@ setMethod( if (.csCountBelowTwo(fit)) { return(NULL) } - ldReference <- ldReference(ldSource) - if (is.null(ldReference)) { - abort(glue( - "computeCsCorrelation(): the summary-statistics ldSource ", - "carries no LD reference to derive the correlation from." - )) - } + ldReference <- .csSumstatsLdRef(ldSource) # onMissing = "error": every fit variant must be in the panel, else the # 1..p sets$cs indices would misalign with a shrunken LD matrix. ids <- .fmrPartsVariantIds(parts) @@ -1145,6 +1139,31 @@ setMethod( } } +# The one LD reference a summary-statistics ldSource offers. Its rows can sit +# on different references, and nothing in the fit says which of them it was +# computed against, so a collection with several is refused rather than read +# from whichever comes first. +# @noRd +.csSumstatsLdRef <- function(ldSource) { + refs <- ldReference(ldSource) + if (length(refs) == 0L) { + abort(glue( + "computeCsCorrelation(): the summary-statistics ldSource ", + "carries no LD reference to derive the correlation from." + )) + } + if (length(refs) > 1L) { + abort(c( + glue( + "computeCsCorrelation(): the summary-statistics ldSource's ", + "rows use {length(refs)} different LD references." + ), + i = "Pass the row the fit came from, e.g. `ldSource[i]`." + )) + } + refs[[1L]] +} + # Individual-level LD source: genotypes -> aligned X. susie fits derive the LD # via get_cs_correlation(X = ); fSuSiE fits (class "susiF") via cal_cor_cs(). #' @rdname computeCsCorrelation diff --git a/R/gwasSumStats.R b/R/gwasSumStats.R index 9e488c0c..dcaddd6a 100644 --- a/R/gwasSumStats.R +++ b/R/gwasSumStats.R @@ -4,8 +4,9 @@ # DFrame-subclass collection keyed by the identity tuple (study). Each # row holds a per-study GRanges of GWAS summary statistics covering a # single LD block; build a separate collection per block when sweeping -# the genome. Class-level slots ldReference + genome + qcInfo apply -# uniformly across rows. +# the genome. Class-level slots genome + qcInfo apply uniformly across +# rows; ldReference holds each distinct LD reference once, and the +# ldReference mcols column names the one every row uses. # ============================================================================= #' @include AllClasses.R tupleSelectors.R @@ -17,9 +18,10 @@ NULL #' \code{GRanges} covering a single LD block, so build one collection per #' block when sweeping the genome. #' @details Required column: \code{study}, unique across rows. The class-level -#' slots inherited from \code{\linkS4class{SumStatsBase}} -- -#' \code{ldReference}, \code{genome} and \code{qcInfo} -- apply uniformly to -#' every row. +#' slots inherited from \code{\linkS4class{SumStatsBase}} -- \code{genome} +#' and \code{qcInfo} -- apply uniformly to every row; \code{ldReference} +#' holds each distinct LD reference once, and the \code{ldReference} column +#' names the one each row uses. #' @seealso \code{\link{GwasSumStats}} for the constructor and #' \code{\linkS4class{QtlSumStats}} for the QTL counterpart. #' @importFrom checkmate makeAssertCollection assertNames assertList @@ -65,12 +67,7 @@ setMethod("show", "GwasSumStats", function(object) { "genome build {GenomeInfoDb::genome(object)}\n", .trim = FALSE )) - ld <- object@ldReference - ldSrc <- if (is.null(ld)) { - "none (LD-free)" - } else { - .ldRefLabel(ld) - } + ldSrc <- .ldRefsLabel(ldReference(object), "none (LD-free)") cat(glue(" LD reference: {ldSrc}\n", .trim = FALSE)) }) @@ -107,8 +104,8 @@ NULL #' @title Create a GwasSumStats Collection Object #' @description Construct a \code{GwasSumStats} S4 DFrame-subclass collection #' from per-study tuple vectors and a list of \code{GRanges} entries (one per -#' study), plus a single LD reference and a single genome build that apply -#' to the whole collection. +#' study), plus the LD reference(s) the rows were harmonized against and a +#' single genome build that applies to the whole collection. #' #' Each \code{GRanges} entry must carry per-variant statistics in its mcols (at #' minimum \code{SNP}, \code{A1}, \code{A2}, \code{Z}, \code{N}; optionally @@ -117,11 +114,12 @@ NULL #' @param entry A \code{SimpleList} or \code{list} of \code{GRanges}, one per #' study. #' @param genome Single character string giving the genome build (e.g., -#' \code{"hg19"}, \code{"hg38"}). Uniform across the collection because all -#' entries share the same LD reference. +#' \code{"hg19"}, \code{"hg38"}). One build per collection. #' @param ldReference The LD reference: a genotype panel (see #' \code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} or an -#' \code{\link{LdMatrix}}. +#' \code{\link{LdMatrix}}, used for every study, or a list with one per +#' study when they sit on different references. Each distinct reference is +#' stored once, and the \code{ldReference} column names each row's. #' @param varY Optional numeric vector of per-study phenotype variances #' (\code{NA_real_} entries allowed). Used by the sufficient-statistic #' interface; z-score RSS analyses should leave entries as NA. @@ -196,7 +194,8 @@ GwasSumStats <- function( ) |> .gwasAppendOptional(nCase, nControl, nSample, studyName) |> .gwasAppendExtras(extraCols) - dfArgs <- c(cols, list(check.names = FALSE)) + dict <- .ldRefDict(.ldRefPerTuple(ldReference, length(entry))) + dfArgs <- c(cols, list(ldReference = dict$keys, check.names = FALSE)) # The per-study GRanges become the collection's ELEMENTS; everything else # is per-study metadata and goes in mcols. There is no `entry` column. # mcols are attached to the GRangesList BEFORE new(), because new() @@ -217,13 +216,14 @@ GwasSumStats <- function( GenomicRanges::GRangesList(split$entry), value = md ) - .sumStatsNewValidated("GwasSumStats", grl, ldReference, genome, qcInfo) + .sumStatsNewValidated("GwasSumStats", grl, dict$refs, genome, qcInfo) } # Build and validate a SumStatsBase subclass from its GRangesList plus the # three collection-level slots GwasSumStats and QtlSumStats share. Shared # rather than duplicated so the two constructors cannot drift in how they -# coerce those slots. Used by qtlSumStats.R too. +# coerce those slots. Used by qtlSumStats.R too. `ldReference` is the named +# list of distinct references (.ldRefDict()), already keyed from the rows. # @noRd .sumStatsNewValidated <- function(Class, grl, ldReference, genome, qcInfo) { # The build goes into seqinfo, which is where a GRangesList keeps it and @@ -233,7 +233,7 @@ GwasSumStats <- function( obj <- methods::new( Class, built, - ldReference = .asLdRef(ldReference), + ldReference = ldReference, qcInfo = as.list(qcInfo) ) methods::validObject(obj) @@ -302,7 +302,7 @@ GwasSumStats <- function( if (length(genome) != 1L) { msg <- glue( "`genome` must be a single character string (one build per ", - "collection, because all entries share the LD reference)." + "collection)." ) abort(msg) } @@ -524,20 +524,21 @@ setMethod("varY", "GwasSumStats", function(x, studyName = NULL) { #' input: \code{genome} and the \code{\link{summaryStatsQc}} options must agree #' across the inputs (a mismatch is an error, not a silent first-wins), the #' per-element \code{qcInfo$entryAudit} concatenates in element order so -#' \code{\link{qcDiagnostics}} keeps addressing the right element, and the -#' LD references combine: genotype panels union into one panel over the shared -#' genotype handle. That last one matters: block-parallel pipelines narrow each -#' piece's panel to its own block, so keeping only the first would leave a -#' multi-block collection whose LD reference covers one block. An -#' \code{LdMatrix} or a \code{GenotypeMixture} cannot be unioned that way; -#' one of the inputs' references must already cover the others, or the -#' combined one is passed as \code{ldReference}. +#' \code{\link{qcDiagnostics}} keeps addressing the right element, and every +#' row keeps its own LD reference. References that are views of one source +#' are stored once: genotype panels read from the same files union into one +#' panel over the shared genotype handle (block-parallel pipelines narrow each +#' piece's panel to its own block, so a multi-block collection would otherwise +#' hold one panel per block), and an \code{LdMatrix} or +#' \code{GenotypeMixture} that another input's reference covers gives way to +#' that one. Inputs on unrelated references keep both. #' #' @param ... Two or more \code{GwasSumStats} objects, or a single \code{list} #' of them. -#' @param ldReference Optional genotype panel (see \code{\link{readGenotypes}}) -#' to attach to the combined collection, overriding the unioned one. Default -#' \code{NULL}. +#' @param ldReference Optional LD reference -- a genotype panel (see +#' \code{\link{readGenotypes}}), a \code{GenotypeMixture} or an +#' \code{LdMatrix} -- that every row of the combined collection uses +#' instead of its own. Default \code{NULL}. #' @return A single combined \code{GwasSumStats}. #' @seealso \code{\link{combineQtlSumStats}}, #' \code{\link{combineFineMappingResults}}, \code{\link{combineTwasWeights}} diff --git a/R/jointEngine.R b/R/jointEngine.R index 77a9f6a5..d22c51f1 100644 --- a/R/jointEngine.R +++ b/R/jointEngine.R @@ -1257,24 +1257,20 @@ setMethod( # padded, only when some row is joint). Every other field -- # study/context/trait/method, region, and any future column -- flows through # untouched. -.buildJointResult <- function(constructor, records, ldReference = NULL) { +.buildJointResult <- function(constructor, records) { if (length(records) == 0L) { return(NULL) } parts <- map(records, .jointBuildRecordPart, constructor = constructor) - .rbindCollections(parts, ldReference = ldReference) + .rbindCollections(parts) } setMethod("construct", "FmJointPipeline", function(pipeline, records) { - .buildJointResult( - QtlFineMappingResult, - records, - .jpConfig(pipeline)$ldReference - ) + .buildJointResult(QtlFineMappingResult, records) }) setMethod("construct", "TwasJointPipeline", function(pipeline, records) { - .buildJointResult(TwasWeights, records, .jpConfig(pipeline)$ldReference) + .buildJointResult(TwasWeights, records) }) # ---- enumerators (pattern x dataForm -> list) -------------------- @@ -1340,7 +1336,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { # cross-context / sumstats. .enumCrossContextSumstats <- function(data, scope, args = list()) { - ldReference <- ldReference(data) studyCol <- as.character(data$study) contextCol <- as.character(data$context) traitCol <- as.character(data$trait) @@ -1350,7 +1345,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { data = data, scope = scope, args = args, - ldReference = ldReference, studyCol = studyCol, contextCol = contextCol, traitCol = traitCol @@ -1366,6 +1360,35 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { list_c(pieces) } +# The one LD reference a summary-statistics joint group's rows share. A joint +# fit reads a single LD matrix for all its conditions, so rows on different +# references cannot be fit together; that is refused, naming them, rather +# than fitting some rows against LD they were never harmonized to. +# @noRd +.jointRowsLdRef <- function(data, rows, label) { + keys <- .ldRefKeys(data)[rows] + if (n_distinct(keys) > 1L) { + tuples <- str_c( + data$study[rows], + data$context[rows], + data$trait[rows], + sep = ":" + ) + abort(c( + glue( + "{label}: a joint fit uses one LD matrix, but its rows use ", + "different LD references." + ), + i = str_c( + "Rows and their references: ", + str_flatten(str_c(tuples, " -> ", keys), "; ") + ), + i = "Fit them separately, or give them one LD reference." + )) + } + .rowLdRef(data, rows[[1L]]) +} + # One study's cross-context groups (none when it has fewer than two contexts). # @noRd .enumCrossContextSumstatsForStudy <- function( @@ -1373,7 +1396,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { data, scope, args, - ldReference, studyCol, contextCol, traitCol @@ -1389,7 +1411,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { s = s, scopedContexts = scopedContexts, args = args, - ldReference = ldReference, studyCol = studyCol, contextCol = contextCol, traitCol = traitCol @@ -1405,7 +1426,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { s, scopedContexts, args, - ldReference, studyCol, contextCol, traitCol @@ -1416,12 +1436,14 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { if (length(tupleRows) < 2L) { return(NULL) } + label <- "jointCrossContext (QtlSumStats)" + ldReference <- .jointRowsLdRef(data, tupleRows, label) ctxNames <- contextCol[tupleRows] jz <- .buildJointSumstatZMatrix( data, tupleRows, ctxNames, - errorLabel = "jointCrossContext (QtlSumStats)", + errorLabel = label, ldReference = ldReference, cutoffs = args$cutoffs ) @@ -1501,7 +1523,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { # cross-trait / sumstats. .enumCrossTraitSumstats <- function(data, scope, args = list()) { - ldReference <- ldReference(data) studyCol <- as.character(data$study) contextCol <- as.character(data$context) traitCol <- as.character(data$trait) @@ -1511,7 +1532,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { data = data, scope = scope, args = args, - ldReference = ldReference, studyCol = studyCol, contextCol = contextCol, traitCol = traitCol @@ -1524,7 +1544,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { data, scope, args, - ldReference, studyCol, contextCol, traitCol @@ -1536,7 +1555,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { s = s, scopedTraits = scope$traits[[s]], args = args, - ldReference = ldReference, studyCol = studyCol, contextCol = contextCol, traitCol = traitCol @@ -1552,7 +1570,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { s, scopedTraits, args, - ldReference, studyCol, contextCol, traitCol @@ -1563,12 +1580,14 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { if (length(tupleRows) < 2L) { return(NULL) } + label <- "jointCrossTrait (QtlSumStats)" + ldReference <- .jointRowsLdRef(data, tupleRows, label) trNames <- traitCol[tupleRows] jz <- .buildJointSumstatZMatrix( data, tupleRows, trNames, - errorLabel = "jointCrossTrait (QtlSumStats)", + errorLabel = label, ldReference = ldReference, cutoffs = args$cutoffs ) @@ -1585,7 +1604,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { # disjoint samples). One group per (context, trait) present in >= 2 scoped # studies; the study axis varies -> "joint" + jointStudies. .enumCrossStudySumstats <- function(data, scope, args = list()) { - ldReference <- ldReference(data) cols <- list( study = as.character(data$study), context = as.character(data$context), @@ -1600,8 +1618,7 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { scope = scope, args = args, cols = cols, - allTrs = allTrs, - ldReference = ldReference + allTrs = allTrs )) } @@ -1613,8 +1630,7 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { scope, args, cols, - allTrs, - ldReference + allTrs ) { compact(map( allTrs, @@ -1623,38 +1639,21 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { scope = scope, args = args, cols = cols, - cx = cx, - ldReference = ldReference + cx = cx )) } # `map()` hands the trait first; .enumCrossStudyGroup takes it sixth. # @noRd -.enumCrossStudyGroupFor <- function( - tid, - data, - scope, - args, - cols, - cx, - ldReference -) { - .enumCrossStudyGroup(data, scope, args, cols, cx, tid, ldReference) +.enumCrossStudyGroupFor <- function(tid, data, scope, args, cols, cx) { + .enumCrossStudyGroup(data, scope, args, cols, cx, tid) } # One cross-study joint group for a (context, trait) cell, or NULL when fewer # than two studies survive the scope filter -- a "joint" fit over one study is # just that study, so the cell contributes nothing. # @noRd -.enumCrossStudyGroup <- function( - data, - scope, - args, - cols, - cx, - tid, - ldReference -) { +.enumCrossStudyGroup <- function(data, scope, args, cols, cx, tid) { candidates <- which( cols$context == cx & cols$trait == tid & @@ -1672,6 +1671,7 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { if (length(tupleRows) < 2L) { return(NULL) } + ldReference <- .jointRowsLdRef(data, tupleRows, "jointCrossStudy") stNames <- cols$study[tupleRows] jz <- .buildJointSumstatZMatrix( data, @@ -1823,7 +1823,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { # (fixed) axes form one group each. Reuses .enumerateComposedSumstatGroups. .enumComposedSumstats <- function(data, scope, args = list()) { axes <- args$axes %||% c("context", "trait") - ldReference <- ldReference(data) gi <- .enumerateComposedSumstatGroups(list(axes = axes), data, scope) if (is.null(gi)) { return(list()) @@ -1836,23 +1835,24 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { .enumComposedGroupFor, data = data, gi = gi, - args = args, - ldReference = ldReference + args = args ))) } # One composed cell's group, or NULL when it spans fewer than two tuples -- # a "joint" fit over one tuple is just that tuple. # @noRd -.enumComposedGroupFor <- function(gIdx, data, gi, args, ldReference) { +.enumComposedGroupFor <- function(gIdx, data, gi, args) { if (length(gIdx) < 2L) { return(NULL) } + label <- "composed (QtlSumStats)" + ldReference <- .jointRowsLdRef(data, gIdx, label) jz <- .buildJointSumstatZMatrix( data, gIdx, map_chr(gIdx, .jointGroupColLabel, gi = gi), - errorLabel = "composed (QtlSumStats)", + errorLabel = label, ldReference = ldReference, cutoffs = args$cutoffs ) @@ -2093,7 +2093,8 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { js = .jointAxisMembers(cond, "study"), jc = .jointAxisMembers(cond, "context"), jt = .jointAxisMembers(cond, "trait"), - region = .jointGroupWindow(data, cond, args) + region = .jointGroupWindow(data, cond, args), + ldReference = .jgLdRefOf(g) ) fitArgs <- .twasGroupArgs(g, pipeline, args) fitArgs$af <- .jointAfForGroup(data, g) @@ -2535,7 +2536,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { if (length(jointMethods) == 0L || length(parsedJointSpec) == 0L) { return(NULL) } - ldReference <- .jpConfig(pipeline)$ldReference isFm <- is(pipeline, "FmJointPipeline") results <- compact(map( parsedJointSpec, @@ -2551,13 +2551,8 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { if (length(results) == 0L) { return(NULL) } - rbindFn <- if (isFm) .rbindFineMappingResult else .rbindTwasWeights - reduce( - results, - .jointRbindWithLdRef, - rbindFn = rbindFn, - ldReference = ldReference - ) + # Every row keeps the LD reference its group was fitted against. + reduce(results, if (isFm) .rbindFineMappingResult else .rbindTwasWeights) } # `map()` hands the spec first, which is also where .runOneJointSpec wants it. @@ -2584,11 +2579,6 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { ) } -# @noRd -.jointRbindWithLdRef <- function(acc, res, rbindFn, ldReference) { - rbindFn(acc, res, ldReference = ldReference) -} - # Run all joint methods for ONE spec: resolve its scope (optionally # region-restricting the traits), pick the joint cell, and dispatch to # .runJointCell (one call with ALL methods so the twas ensemble layer can @@ -2765,7 +2755,10 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { jointContexts = grp$jc, jointTraits = grp$jt, traitPos = tpos, - region = grp$region + region = grp$region, + # The reference the group was fitted against, so each result row + # keeps it; NULL for an individual-level group. + ldReference = grp$ldReference ) } diff --git a/R/jointSpecification.R b/R/jointSpecification.R index 1d3e38f6..2cbc1075 100644 --- a/R/jointSpecification.R +++ b/R/jointSpecification.R @@ -1418,7 +1418,9 @@ parseTraitIds <- function(traitId, data) { entry = mergedEntries ), .jointCols(base), - list(ldReference = NULL) + # Merged entries sit on the rows they were keyed to, references and + # all. + list(ldReference = .rowLdRefs(base)) ) exec(QtlFineMappingResult, !!!qfmrArgs) } @@ -1473,7 +1475,8 @@ parseTraitIds <- function(traitId, data) { reduce(kept, .msRbindNoLd, rbindFn = rbindFn) } -# Accumulate per-study + sumstats results (tracking the embedded LD sketch). +# Accumulate per-study + sumstats results; every row keeps its own LD +# reference (none for an individual-level study's rows). # @noRd .msDriverAccumulate <- function( qtlDatasets, @@ -1489,21 +1492,17 @@ parseTraitIds <- function(traitId, data) { ) ssRes <- if (is.null(sumStats)) NULL else sumStatsFn(sumStats, cfg) if (is.null(ssRes)) { - return(list(out = fromStudies, embeddedLd = NULL)) + return(fromStudies) } - embeddedLd <- ldReference(ssRes) - out <- if (is.null(fromStudies)) { - ssRes - } else { - rbindFn(fromStudies, ssRes, ldReference = embeddedLd) + if (is.null(fromStudies)) { + return(ssRes) } - list(out = out, embeddedLd = embeddedLd) + rbindFn(fromStudies, ssRes) } -# Reconstruct the per-tuple result object from the accumulated rows. -.msDriverPerTuple <- function(out, resultCtor, embeddedLd) { - # ldReference: NULL if all studies were individual-level; the embedded - # sumStats's ldReference otherwise. +# Reconstruct the per-tuple result object from the accumulated rows, each on +# the LD reference it had. +.msDriverPerTuple <- function(out, resultCtor) { ctorArgs <- c( list( study = as.character(out$study), @@ -1513,7 +1512,7 @@ parseTraitIds <- function(traitId, data) { entry = .collectionEntries(out) ), .jointCols(out), - list(ldReference = embeddedLd) + list(ldReference = .rowLdRefs(out)) ) exec(resultCtor, !!!ctorArgs) } @@ -1538,7 +1537,7 @@ parseTraitIds <- function(traitId, data) { pipelineName, noun = "a result" ) { - acc <- .msDriverAccumulate( + out <- .msDriverAccumulate( qtlDatasets(data), sumStats(data), perStudyFn, @@ -1546,10 +1545,8 @@ parseTraitIds <- function(traitId, data) { cfg, rbindFn ) - out <- acc$out - embeddedLd <- acc$embeddedLd perTupleResult <- if (!is.null(out)) { - .msDriverPerTuple(out, resultCtor, embeddedLd) + .msDriverPerTuple(out, resultCtor) } else { NULL } @@ -1566,7 +1563,7 @@ parseTraitIds <- function(traitId, data) { if (is.null(perTupleResult)) { return(jointResult) } - rbindFn(perTupleResult, jointResult, ldReference = embeddedLd) + rbindFn(perTupleResult, jointResult) } # Synthesize a jointSpecification for the AUTO-DETECTION path (no explicit @@ -1635,7 +1632,7 @@ parseTraitIds <- function(traitId, data) { parsedJointSpec, cfg$data, dataForm = "individual", - pipeline = .fmJointPipeline(cfg, cfg$crossValidationParam, NULL), + pipeline = .fmJointPipeline(cfg, cfg$crossValidationParam), jointMethods = intersect(tokens, c("mvsusie", "fsusie")), contexts = cfg$contexts, traitIds = cfg$traitId, @@ -1645,10 +1642,11 @@ parseTraitIds <- function(traitId, data) { # The FmJointPipeline a joint run fits under: the settings the fitters read # off the pipeline. Summary statistics pass the no-CV record (there are no -# samples to hold out) and the collection's LD sketch; individual-level data -# pass the caller's resolved CV record and no sketch. +# samples to hold out); individual-level data pass the caller's resolved CV +# record. The LD a group is fitted against is the group's own +# (.jointRowsLdRef()), not a setting of the run. # @noRd -.fmJointPipeline <- function(cfg, crossValidationParam, ldReference) { +.fmJointPipeline <- function(cfg, crossValidationParam) { new( "FmJointPipeline", config = list( @@ -1657,8 +1655,7 @@ parseTraitIds <- function(traitId, data) { crossValidationParam = crossValidationParam, verbose = cfg$verbose, fitRetention = cfg$fitRetention, - seed = cfg$seed, - ldReference = ldReference + seed = cfg$seed ) ) } @@ -1695,11 +1692,7 @@ parseTraitIds <- function(traitId, data) { parsedJointSpec, cfg$data, dataForm = "sumstats", - pipeline = .fmJointPipeline( - cfg, - .cvResolve(CrossValidationParam()), - ldReference(cfg$data) - ), + pipeline = .fmJointPipeline(cfg, .cvResolve(CrossValidationParam())), jointMethods = intersect(tokens, c("mvsusie", "fsusie")), contexts = cfg$contexts, traitIds = cfg$traitId, @@ -1803,7 +1796,7 @@ parseTraitIds <- function(traitId, data) { if (is.null(out)) { return(ssRes) } - .rbindFineMappingResult(out, ssRes, ldReference = ldReference(ssRes)) + .rbindFineMappingResult(out, ssRes) } @@ -1937,8 +1930,7 @@ parseTraitIds <- function(traitId, data) { fitRetention = cfg$fitRetention, standardized = TRUE, verbose = cfg$verbose, - seed = cfg$seed, - ldReference = ldReference(cfg$data) + seed = cfg$seed ) ) .runJointSpecs( @@ -2052,7 +2044,7 @@ parseTraitIds <- function(traitId, data) { if (is.null(out)) { return(ssRes) } - .rbindTwasWeights(out, ssRes, ldReference = ldReference(ssRes)) + .rbindTwasWeights(out, ssRes) } diff --git a/R/ld.R b/R/ld.R index 6e90a446..ff679c74 100644 --- a/R/ld.R +++ b/R/ld.R @@ -412,6 +412,205 @@ resolveGenotypePathForRegion <- function(metaPath, region) { .ldIsGenotypeRef(x) || .ldIsMatrixRef(x) } +# ----------------------------------------------------------------------------- +# Per-row LD references +# ----------------------------------------------------------------------------- +# A collection whose rows can sit on different LD references -- summary +# statistics, the fine-mapping results and TWAS weights fit from them, coloc +# results -- keeps each distinct reference ONCE, in a named list in its +# `ldReference` slot, and names each row's entry in an `ldReference` mcols +# column (NA for an LD-free row). Fifty rows on one sketch hold one copy of +# it, in memory and in a saved object alike, and the per-row key travels with +# the rows on subsetting the way every per-row value in mcols does. + +# The per-tuple form of an `ldReference` argument: one reference for every +# tuple, or a list holding one per tuple. What ldReference() returns reads +# the same way -- an empty list is LD-free and a one-entry list is that +# reference for every tuple -- so a collection's references can be handed +# straight to the next one built from it. +# @noRd +.ldRefPerTuple <- function(ldReference, n) { + asList <- is.list(ldReference) && !is.object(ldReference) + if (asList && length(ldReference) <= 1L) { + ldReference <- if (length(ldReference) == 0L) { + NULL + } else { + ldReference[[1L]] + } + asList <- FALSE + } + if (!asList) { + return(rep(list(.asLdRef(ldReference)), n)) + } + if (length(ldReference) != n) { + abort(glue( + "`ldReference` must be one LD reference, or a list with one per ", + "tuple (got {length(ldReference)} for {n} tuple(s))." + )) + } + map(unname(ldReference), .asLdRef) +} + +# Each distinct reference among `perRow` once, named ld1, ld2, ... in order +# of first use, and every row's key into them (NA for an LD-free row). +# @noRd +.ldRefDict <- function(perRow) { + present <- which(!map_lgl(perRow, is.null)) + ids <- .ldRefIdentities(perRow[present]) + firstIdx <- which(!duplicated(ids)) + keys <- str_c("ld", seq_along(firstIdx)) + rowKeys <- replace( + rep(NA_character_, length(perRow)), + present, + keys[match(ids, ids[firstIdx])] + ) + refs <- if (length(firstIdx) == 0L) { + list() + } else { + set_names(perRow[present[firstIdx]], keys) + } + list(refs = refs, keys = rowKeys) +} + +# A content identity per reference, so equal references -- the same object +# handed to every row, or two equal copies -- collapse to one entry. Hashed +# once per distinct object rather than per row: a large LdMatrix shared by +# every row is read once, not once per row. +# @noRd +#' @importFrom rlang hash obj_address +.ldRefIdentities <- function(refs) { + if (length(refs) == 0L) { + return(character(0)) + } + addresses <- map_chr(refs, obj_address) + firstOfAddress <- !duplicated(addresses) + hashes <- map_chr(refs[firstOfAddress], hash) + hashes[match(addresses, addresses[firstOfAddress])] +} + +# Each row's key into its collection's LD references (NA for an LD-free row). +# @noRd +.ldRefKeys <- function(x) { + mcols(x, use.names = FALSE)$ldReference %||% rep(NA_character_, length(x)) +} + +# What a collection reports as its LD references: the entries some row names, +# so a subset does not report the ones its rows left behind. An object saved +# before the references became per-row holds one reference in the slot and no +# key column, and read as a list it would pass for LD-free; it is refused +# instead (one that held NULL was LD-free, and still reads that way). +# @noRd +.ldRefsInUse <- function(x) { + refs <- x@ldReference + if (is.null(refs)) { + return(list()) + } + if (!is.list(refs) || is.object(refs)) { + abort(c( + glue( + "This {class(x)[[1L]]} was saved before LD references became ", + "per-row, so its rows cannot be matched to its reference." + ), + i = "Bring it up to date with `x <- updateObject(x)`." + )) + } + .ldRefsUsed(refs, .ldRefKeys(x)) +} + +# The entries of `refs` some key in `keys` names. +# @noRd +.ldRefsUsed <- function(refs, keys) { + used <- refs[is_in(names(refs), keys)] + if (length(used) == 0L) list() else used +} + +# Every row's LD reference, NULL for an LD-free row. +# @noRd +.rowLdRefs <- function(x) { + refs <- ldReference(x) + map(.ldRefKeys(x), .ldRefForKey, refs = refs) +} + +# Result records tagged with the LD reference of the input row they came +# from, so the collection built from them keeps every row on its own +# reference. +# @noRd +.recordsWithLdRef <- function(records, ldReference) { + map(records, list_assign, ldReference = ldReference) +} + +# `x` with every row on `ldReference` -- one reference, or a list with one +# per row -- its references and its rows' keys rebuilt together. The slot is +# written first and the keys second, so the object is only validated once +# the two agree. +# @noRd +#' @importFrom methods slot<- +.withRowLdRefs <- function(x, ldReference) { + dict <- .ldRefDict(.ldRefPerTuple(ldReference, length(x))) + md <- mcols(x, use.names = FALSE) + md[["ldReference"]] <- dict$keys + S4Vectors::`mcols<-`( + `slot<-`(x, "ldReference", check = FALSE, value = dict$refs), + value = md + ) +} + +# `object` as saved before its references became per-row -- one reference, +# or NULL, in the slot and no row key -- brought up to date: that reference +# becomes the slot's one entry and every row is keyed to it (every row is +# LD-free when it held none). A current object is returned as it is. +# @noRd +.updateRowLdRefs <- function(object) { + old <- methods::slot(object, "ldReference") + if (is.list(old) && !is.object(old)) { + return(object) + } + .withRowLdRefs(object, .asLdRef(old)) +} + +# Row `i`'s LD reference, or NULL for an LD-free row. +# @noRd +.rowLdRef <- function(x, i) { + .ldRefForKey(.ldRefKeys(x)[[i]], ldReference(x)) +} + +# @noRd +.ldRefForKey <- function(key, refs) { + if (is.na(key)) NULL else refs[[key]] +} + +# What is wrong with an LD-reference list and the keys pointing into it, or +# NULL. An entry's name is what a key points at, so an unnamed, blank or +# repeated one leaves a row pointing at nothing, or at two references. +# @noRd +.ldRefDictProblems <- function(refs, keys) { + if (length(refs) > 0L) { + nms <- names(refs) + badNames <- is.null(nms) || + anyNA(nms) || + any(nms == "") || + anyDuplicated(nms) > 0L + if (badNames) { + return("ldReference entries must have unique, non-empty names") + } + bad <- nms[!map_lgl(refs, .ldIsReference)] + if (length(bad) > 0L) { + return(str_c( + "ldReference entries that are not LD references: ", + str_flatten(bad, ", ") + )) + } + } + unknown <- setdiff(keys[!is.na(keys)], names(refs)) + if (length(unknown) == 0L) { + return(NULL) + } + str_c( + "rows name LD reference(s) not in ldReference: ", + str_flatten(unknown, ", ") + ) +} + # The GenotypeHandle a panel reads through, or NULL when it reads through # none: an LdMatrix, a mixture, or a panel whose dosages come from another # backend (a VCF, GDS or PLINK1 seed, or a matrix held in memory). The handle @@ -667,6 +866,24 @@ resolveGenotypePathForRegion <- function(metaPath, region) { glue("{source$format} @ {source$path}") } +# The `show()` line for a collection's LD references: the one reference, or +# each by name when the rows use several; `none` when there are none. +# @noRd +.ldRefsLabel <- function(refs, none) { + if (length(refs) == 0L) { + return(none) + } + labels <- map_chr(refs, .ldRefLabel) + if (length(refs) == 1L) { + return(labels[[1L]]) + } + str_c( + length(refs), + " references -- ", + str_flatten(str_c(names(refs), ": ", labels), "; ") + ) +} + # TRUE for anything that can serve as an LD panel. A bare GenotypeHandle # still counts: that is what objects serialised before the slot became an RSE # carry. @@ -1652,14 +1869,15 @@ resolveGenotypePathForRegion <- function(metaPath, region) { # yields two differently trimmed sketches. Downstream LD lookups are all # id-matched, so a partial overlap is reported (once per session) rather than # refused; no overlap at all is an error. Shared by causalInferencePipeline, -# colocPipeline, qtlEnrichmentPipeline, ctwasPipeline, and colocboostPipeline. +# colocPipeline, qtlEnrichmentPipeline and ctwasPipeline, each over the rows +# it combines (.requireMatchingRowLdRefs()). # # NULL handling: # nullPolicy = "qtl-required" (default): a NULL qtlLd skips the check; a -# non-NULL qtlLd with a NULL gwasLd is an error. Used by cip / coloc / -# ctwas / enloc / qtlEnrichment. +# non-NULL qtlLd with a NULL gwasLd is an error. Used by cip / coloc +# (enloc included) / ctwas. # nullPolicy = "lenient": a NULL on either side skips the check. Used by -# colocboostPipeline. +# qtlEnrichmentPipeline. # # `label` is the human-readable name of the QTL-side input (e.g. # "twasWeights" or "fineMappingResult"); it is woven into the error @@ -1960,6 +2178,158 @@ resolveGenotypePathForRegion <- function(metaPath, region) { invisible(NULL) } +# .requireMatchingLdRefs() for the rows an analysis actually combines: QTL row +# qtlRows[k] with GWAS row gwasRows[k]. Rows on different references are fine +# as long as no combined pair puts two of them together. Each distinct pair of +# references is checked once, and an error names the first rows that combine +# them. +# @noRd +#' @importFrom purrr pwalk +.requireMatchingRowLdRefs <- function( + qtl, + gwas, + qtlRows, + gwasRows, + pipelineName, + label = NULL, + nullPolicy = c("qtl-required", "lenient") +) { + nullPolicy <- arg_match(nullPolicy) + pairs <- distinct( + tibble( + qtlKey = .ldRefKeys(qtl)[qtlRows], + gwasKey = .ldRefKeys(gwas)[gwasRows], + qtlRow = qtlRows, + gwasRow = gwasRows + ), + .data$qtlKey, + .data$gwasKey, + .keep_all = TRUE + ) + pwalk( + pairs, + .requireMatchingPairLdRefs, + qtlRefs = ldReference(qtl), + gwasRefs = ldReference(gwas), + pipelineName = pipelineName, + label = label %||% "qtl input", + nullPolicy = nullPolicy + ) + invisible(NULL) +} + +# @noRd +.requireMatchingPairLdRefs <- function( + qtlKey, + gwasKey, + qtlRow, + gwasRow, + qtlRefs, + gwasRefs, + pipelineName, + label, + nullPolicy +) { + .requireMatchingLdRefs( + .ldRefForKey(qtlKey, qtlRefs), + .ldRefForKey(gwasKey, gwasRefs), + pipelineName = pipelineName, + label = glue("{label} row {qtlRow} (with gwas row {gwasRow})"), + nullPolicy = nullPolicy + ) +} + +# .requireMatchingRowLdRefs() over the QTL / GWAS row pairs whose regions +# overlap: the pairs an analysis that brings the two sides together region by +# region combines. +# @noRd +.requireOverlapLdRefs <- function( + qtl, + gwas, + pipelineName, + label = NULL, + nullPolicy = c("qtl-required", "lenient") +) { + pairs <- .overlappingRowPairs(qtl, gwas) + .requireMatchingRowLdRefs( + qtl, + gwas, + pairs$qtlRows, + pairs$gwasRows, + pipelineName = pipelineName, + label = label, + nullPolicy = nullPolicy + ) +} + +# The (QTL row, GWAS row) pairs whose element spans overlap. Both sides are +# narrowed to the chromosomes they share first: GenomicRanges warns about +# sequence levels the two have no part of in common, which would be noise for +# collections on different chromosomes rather than a sign of anything wrong. +# @noRd +.overlappingRowPairs <- function(qtl, gwas) { + q <- .rowSpans(qtl) + g <- .rowSpans(gwas) + shared <- intersect( + as.character(GenomicRanges::seqnames(q$spans)), + as.character(GenomicRanges::seqnames(g$spans)) + ) + if (length(shared) == 0L) { + return(list(qtlRows = integer(0), gwasRows = integer(0))) + } + qOn <- is_in(as.character(GenomicRanges::seqnames(q$spans)), shared) + gOn <- is_in(as.character(GenomicRanges::seqnames(g$spans)), shared) + hits <- GenomicRanges::findOverlaps( + .onSeqlevels(q$spans[qOn], shared), + .onSeqlevels(g$spans[gOn], shared), + ignore.strand = TRUE + ) + list( + qtlRows = q$rows[qOn][S4Vectors::queryHits(hits)], + gwasRows = g$rows[gOn][S4Vectors::subjectHits(hits)] + ) +} + +# Which of `query`'s ranges overlap any of `subject`'s, compared on the +# chromosomes the two share -- GenomicRanges warns about sequence levels two +# objects have none of in common, which is noise for ranges that simply sit +# on different chromosomes. +# @noRd +.overlapsOnShared <- function(query, subject) { + qChr <- as.character(GenomicRanges::seqnames(query)) + sChr <- as.character(GenomicRanges::seqnames(subject)) + shared <- intersect(qChr, sChr) + hit <- rep(FALSE, length(query)) + if (length(shared) == 0L) { + return(hit) + } + qOn <- is_in(qChr, shared) + replace( + hit, + qOn, + IRanges::overlapsAny( + .onSeqlevels(query[qOn], shared), + .onSeqlevels(subject[is_in(sChr, shared)], shared) + ) + ) +} + +# Each non-empty row's span, with the row it belongs to. +# @noRd +.rowSpans <- function(x) { + rr <- range(x) + list( + spans = unlist(rr, use.names = FALSE), + rows = rep(seq_along(rr), lengths(rr)) + ) +} + +# `gr` with exactly the sequence levels `levels`. +# @noRd +.onSeqlevels <- function(gr, levels) { + GenomeInfoDb::keepSeqlevels(gr, levels, pruning.mode = "coarse") +} + # ---------- Variant lookups against an LD reference on disk ---------- #' Filter variants by LD Reference @@ -3131,7 +3501,7 @@ ldClumpByScore <- function( #' \code{dimnames} taken from the block where available. #' @examples #' data(qtlSumStatsExample) -#' panel <- ldReference(qtlSumStatsExample) +#' panel <- ldReference(qtlSumStatsExample)[[1L]] #' R <- computeLd(panel, snpIdx = 1:5) #' dim(R) #' # A dosage matrix already in memory is correlated directly. diff --git a/R/manifestLoaders.R b/R/manifestLoaders.R index a2f00902..ab6999b0 100644 --- a/R/manifestLoaders.R +++ b/R/manifestLoaders.R @@ -257,56 +257,119 @@ NULL .openGenotypeSource(x) } -# Resolve the LD sketch SPEC from the (argument, ldReferencePath column) pair, -# without reading any genotype metadata yet. Returns an already-open panel -# (when the caller passed one) as it is, or the reconciled spec -# (a path/prefix or a -# genoMeta path/named-vector) for later materialisation. Deferring the read to -# `.materializeLdRef` lets the loader first learn which chromosomes the -# summary statistics cover and skip the panel's other per-chromosome shards. -.resolveLdRefInput <- function(df, ldReference, base) { +# The LD sketch SPEC of every manifest row, without reading any genotype +# metadata yet: the `ldReference` argument for all of them, or each row's own +# `ldReferencePath` (resolved against the manifest's directory). Rows may name +# different references; where a row's path and the argument are both given +# they must agree. An already-open panel passed as the argument is returned as +# it is, for every row. Deferring the reads to .manifestRowLdRefs() lets the +# loader first learn which chromosomes each reference's rows cover and skip +# the panel's other per-chromosome shards. +# @noRd +.resolveLdRefSpecs <- function(df, ldReference, base) { + n <- nrow(df) open <- .openLdRef(ldReference) if (!is.null(open)) { - return(open) + return(rep(list(open), n)) } - # is_in guard, not `!is.null(df$ldReferencePath)`: on a tibble `$` for an - # absent column NULLs but WARNS ("Unknown or uninitialised column"), where a - # data.frame was silent. ldReferencePath is optional (LD may come via - # `ldReference`). - colSpec <- if (!is_in("ldReferencePath", names(df))) { - NULL - } else { - v <- unique(as.character(df$ldReferencePath[ - !is.na(df$ldReferencePath) & - str_length(as.character(df$ldReferencePath)) > 0L - ])) - if (length(v) > 1L) { - abort( - "`ldReferencePath` column must be constant across the manifest." + paths <- .manifestLdRefPaths(df, base) + given <- !is.na(paths) + if (!is.null(ldReference)) { + agrees <- map_lgl(paths, identical, as.character(ldReference)) + if (any(given & !agrees)) { + msg <- glue( + "`ldReference` argument disagrees with the manifest ", + "`ldReferencePath` column." ) + abort(msg) } - if (length(v) == 1L) .resolveRel(v, base) else NULL - } - spec <- ldReference %||% colSpec - if ( - !is.null(ldReference) && - !is.null(colSpec) && - !identical(as.character(ldReference), as.character(colSpec)) - ) { - msg <- glue( - "`ldReference` argument disagrees with the manifest ", - "`ldReferencePath` column." - ) - abort(msg) + return(rep(list(ldReference), n)) } - if (is.null(spec)) { + if (!any(given)) { msg <- glue( "`ldReference` must be provided as an argument or an ", "`ldReferencePath` column." ) abort(msg) } - spec + if (!all(given)) { + abort(glue( + "every manifest row needs an LD reference: row(s) ", + "{str_flatten(which(!given), ', ')} have no `ldReferencePath`, ", + "and no `ldReference` argument was given." + )) + } + as.list(paths) +} + +# Each manifest row's own `ldReferencePath`, resolved against the manifest's +# directory; NA where the column is absent or the cell blank. is_in guard, +# not `!is.null(df$ldReferencePath)`: on a tibble `$` for an absent column +# NULLs but WARNS ("Unknown or uninitialised column"). +# @noRd +.manifestLdRefPaths <- function(df, base) { + if (!is_in("ldReferencePath", names(df))) { + return(rep(NA_character_, nrow(df))) + } + raw <- as.character(df$ldReferencePath) + keep <- which(!is.na(raw) & str_length(raw) > 0L) + replace( + rep(NA_character_, length(raw)), + keep, + map_chr(raw[keep], .resolveRel, base = base) + ) +} + +# The LD reference of every manifest row. Each distinct spec is read once, +# only for the chromosomes its rows cover, checked for containment against +# its rows with `check` (.checkGwasLdContainment() or +# .qtlSumStatsCheckContainment()), and trimmed to their span; rows on one +# spec share that one reference, so the collection stores it once. +# @noRd +.manifestRowLdRefs <- function(specs, entries, df, minLdOverlapWarn, check) { + keys <- map_chr(specs, .ldSpecKey) + groups <- split(seq_along(specs), factor(keys, levels = unique(keys))) + refs <- map( + groups, + .manifestGroupLdRef, + specs = specs, + entries = entries, + df = df, + minLdOverlapWarn = minLdOverlapWarn, + check = check + ) + unname(refs[match(keys, names(groups))]) +} + +# One spec's reference for the manifest rows naming it. The containment +# checks sit between the read and the trim because containment is only +# answerable once the sketch is read, and trimming would hide a miss. +# @noRd +.manifestGroupLdRef <- function( + rows, + specs, + entries, + df, + minLdOverlapWarn, + check +) { + rowEntries <- entries[rows] + materialized <- .materializeLdRef( + specs[[rows[[1L]]]], + .entriesChroms(rowEntries) + ) + check(materialized, rowEntries, slice(df, rows), minLdOverlapWarn) + .subsetLdRefToRange(materialized, rowEntries) +} + +# A key telling LD reference specs apart: a path, or per-chromosome paths, by +# its text; an already-open reference by the object itself. +# @noRd +.ldSpecKey <- function(spec) { + if (!is.character(spec)) { + return(obj_address(spec)) + } + str_flatten(str_c(names(spec) %||% "", "=", spec), "|") } # Materialise a resolved ldReference spec into a genotype panel, reading only @@ -1741,25 +1804,6 @@ loadQtlDatasetFromManifest <- function( isTRUE(ccOk) || isTRUE(nOk) } -# Materialise the LD sketch reading only the chromosomes the sumstats -# cover, then run the deferred per-study containment checks and trim to -# range. The checks sit between the two steps because containment is only -# answerable once the sketch is read, and trimming would hide a miss. -# @noRd -.manifestGwasLdRef <- function( - ldReferenceSpec, - entries, - df, - minLdOverlapWarn -) { - materialized <- .materializeLdRef( - ldReferenceSpec, - .entriesChroms(entries) - ) - .checkGwasLdContainment(materialized, entries, df, minLdOverlapWarn) - .subsetLdRefToRange(materialized, entries) -} - #' @title Load a GwasSumStats collection from a manifest #' @description Build a \code{\link{GwasSumStats}} from a manifest with one row #' per study. No QC is run (the result carries \code{qcInfo = list()}). Each @@ -1769,16 +1813,19 @@ loadQtlDatasetFromManifest <- function( #' @param manifest A data.frame or path. Columns (snake_case aliases accepted): #' \code{study} (required, unique), \code{sumStatsPath} (required), #' \code{columnMapping} (optional), \code{nCase} / \code{nControl} (optional), -#' \code{nSample} (optional study-level total N), \code{varY} (optional), and -#' the single-valued \code{genome} / \code{ldReferencePath}. When a row +#' \code{nSample} (optional study-level total N), \code{varY} (optional), the +#' single-valued \code{genome}, and \code{ldReferencePath}, which may differ +#' between studies (each distinct reference is read once, for the +#' chromosomes its studies cover, and stored once). When a row #' supplies a study-level scalar (\code{nCase} + \code{nControl}, or #' \code{nSample}), its sumstats file need not carry a per-variant \code{N} #' column; #' \code{\link{summaryStatsQc}} fills \code{N} from the scalar. #' @param genome Genome build; reconciled with a \code{genome} column. #' @param ldReference A genotype panel (see \code{\link{readGenotypes}}) or a -#' spec (path/prefix/genoMeta); reconciled with an \code{ldReferencePath} -#' column. +#' spec (path/prefix/genoMeta), used for every study; where a row also names +#' an \code{ldReferencePath} the two must agree. Omit it to give each study +#' the reference its \code{ldReferencePath} names. #' @param region Optional \code{chr:start-end} string, GRanges, or one-row #' data.frame restricting the variants read (honoured only for tabix-indexed #' text and bgzipped+tabixed VCF; ignored with a warning otherwise). @@ -1817,17 +1864,9 @@ loadGwasSumStatsFromManifest <- function( ldBlocks = NULL ) { base <- .manifestBase(manifest) - df <- .canonManifestCols( - .readManifest(manifest), - .gwasSumStatsManifestAliases, - required = c("study", "sumStatsPath"), - label = "GwasSumStats" - ) - if (anyDuplicated(as.character(df$study))) { - abort("GwasSumStats manifest `study` values must be unique.") - } + df <- .gwasSumStatsManifest(manifest) genome <- .reconcileScalar(df[["genome"]], genome, "genome") - ldReferenceSpec <- .resolveLdRefInput(df, ldReference, base) + ldReferenceSpecs <- .resolveLdRefSpecs(df, ldReference, base) ns <- .gwasStudyScalars(df) entries <- map( seq_len(nrow(df)), @@ -1840,11 +1879,12 @@ loadGwasSumStatsFromManifest <- function( formatMapping = formatMapping, ns = ns ) - ldReference <- .manifestGwasLdRef( - ldReferenceSpec, + ldReference <- .manifestRowLdRefs( + ldReferenceSpecs, entries, df, - minLdOverlapWarn + minLdOverlapWarn, + check = .checkGwasLdContainment ) # Without a block manifest a genome-wide file splits by chromosome, which # is too coarse for cTWAS; with one, each study becomes one element per LD @@ -1856,6 +1896,22 @@ loadGwasSumStatsFromManifest <- function( exec(GwasSumStats, !!!gwasArgs) } +# A GwasSumStats manifest's rows, its columns under their canonical names, the +# required ones present and one row per study. +# @noRd +.gwasSumStatsManifest <- function(manifest) { + df <- .canonManifestCols( + .readManifest(manifest), + .gwasSumStatsManifestAliases, + required = c("study", "sumStatsPath"), + label = "GwasSumStats" + ) + if (anyDuplicated(as.character(df$study))) { + abort("GwasSumStats manifest `study` values must be unique.") + } + df +} + # Study-level sample-size scalars from the manifest (n_case + n_control, or # n_sample). When present a row need not carry a per-variant N. # @noRd @@ -1992,15 +2048,19 @@ loadGwasSumStatsFromManifest <- function( #' @param manifest A data.frame or path. Columns (snake_case aliases accepted): #' \code{study}, \code{context}, \code{trait} (required), \code{sumStatsPath} #' (required), \code{columnMapping} (optional), \code{nSample} (optional -#' tuple-level total N), \code{varY} (optional), and the single-valued -#' \code{genome} / \code{ldReferencePath}. When a row supplies \code{nSample}, +#' tuple-level total N), \code{varY} (optional), the single-valued +#' \code{genome}, and \code{ldReferencePath}, which may differ between rows +#' (each distinct reference is read once, for the chromosomes its rows +#' cover, and stored once). When a row supplies \code{nSample}, #' its sumstats file need not carry a per-variant \code{N} column; #' \code{\link{summaryStatsQc}} fills \code{N} from the scalar. (Unlike the #' GWAS loader, there are no \code{nCase}/\code{nControl} columns: molecular #' QTL traits are quantitative.) #' @param genome Genome build; reconciled with a \code{genome} column. #' @param ldReference A genotype panel (see \code{\link{readGenotypes}}) or -#' spec; reconciled with an \code{ldReferencePath} column. +#' spec, used for every row; where a row also names an +#' \code{ldReferencePath} the two must agree. Omit it to give each row the +#' reference its \code{ldReferencePath} names. #' @param region,minLdOverlapWarn,columnMapping,sampleSelect,formatMapping As #' for \code{\link{loadGwasSumStatsFromManifest}}. #' @param traitColumn Optional column of the sumstats file naming the trait of @@ -2046,7 +2106,7 @@ loadQtlSumStatsFromManifest <- function( base <- .manifestBase(manifest) df <- .qtlSumStatsManifest(manifest) genome <- .reconcileScalar(df[["genome"]], genome, "genome") - ldReferenceSpec <- .resolveLdRefInput(df, ldReference, base) + ldReferenceSpecs <- .resolveLdRefSpecs(df, ldReference, base) nSample <- .qtlManifestNSample(df) entries <- .loadQtlSumStatsEntries( df, @@ -2059,11 +2119,12 @@ loadQtlSumStatsFromManifest <- function( traitColumn = traitColumn, variantIdAlleles = variantIdAlleles ) - ldReference <- .manifestQtlLdRef( - ldReferenceSpec, + ldReference <- .manifestRowLdRefs( + ldReferenceSpecs, entries, df, - minLdOverlapWarn + minLdOverlapWarn, + check = .qtlSumStatsCheckContainment ) exec( QtlSumStats, @@ -2089,25 +2150,6 @@ loadQtlSumStatsFromManifest <- function( ) } -# Materialise the LD sketch reading only the chromosomes the summary stats -# cover (skipping the other shards of a chrom-sharded panel), check -# containment, then trim it to the summary stats' per-chromosome position -# span, as .manifestGwasLdRef() does for a GwasSumStats manifest. -# @noRd -.manifestQtlLdRef <- function( - ldReferenceSpec, - entries, - df, - minLdOverlapWarn -) { - materialized <- .materializeLdRef( - ldReferenceSpec, - .entriesChroms(entries) - ) - .qtlSumStatsCheckContainment(materialized, entries, df, minLdOverlapWarn) - .subsetLdRefToRange(materialized, entries) -} - # The tuple-level total-N scalar a manifest may carry, plus the per-row # "this tuple needs no per-variant N" flags derived from it: where a row has a # usable nSample, summaryStatsQc fills N from it, so the entry reader's N check diff --git a/R/qtlEnrichmentPipeline.R b/R/qtlEnrichmentPipeline.R index ff8a69d7..e5b30bb3 100644 --- a/R/qtlEnrichmentPipeline.R +++ b/R/qtlEnrichmentPipeline.R @@ -93,16 +93,18 @@ QtlEnrichmentParam <- function( #' collection, which has no context axis. #' } #' -#' @section LD reference compatibility check: A GWAS outcome collection -#' must have a non-NULL \code{ldReference} (it should be RSS-derived). Where -#' both sides carry one, the two must be the same LD reference. +#' @section LD reference compatibility check: Every row of a GWAS outcome +#' collection must have an \code{ldReference} (it should be RSS-derived). +#' For each QTL row and GWAS row whose regions overlap, where both carry +#' one, the two must be the same LD reference; rows that never overlap may +#' sit on different references. #' The two must be the same kind of reference. Two genotype panels must #' share their samples and allele orientation; two \code{LdMatrix} objects #' must agree on the LD they share; two \code{GenotypeMixture} objects must #' average the same panels with the same weights. They need NOT carry the #' same variants: QC-ing the two sides separately trims each reference to -#' its own surviving variants, and a partial overlap only warns. A -#' \code{NULL} on either side (an individual-level fit) skips the check. +#' its own surviving variants, and a partial overlap only warns. A row with +#' no reference on either side (an individual-level fit) skips the check. #' #' @param gwasFineMappingResult The outcome side; see above. #' @param qtlFineMappingResult The annotation side; see above. @@ -189,24 +191,27 @@ qtlEnrichmentPipeline <- function( fmrClasses <- c("GwasFineMappingResult", "QtlFineMappingResult") assertMultiClass(gwasFineMappingResult, fmrClasses) assertMultiClass(qtlFineMappingResult, fmrClasses) - outcomeLd <- ldReference(gwasFineMappingResult) + ldFree <- is.na(.ldRefKeys(gwasFineMappingResult)) if ( - is.null(outcomeLd) && + any(ldFree) && methods::is(gwasFineMappingResult, "GwasFineMappingResult") ) { msg <- glue( - "qtlEnrichmentPipeline: the GwasFineMappingResult must have a ", - "non-NULL ldReference (it should be RSS-derived)." + "qtlEnrichmentPipeline: every GwasFineMappingResult row must have ", + "an ldReference (it should be RSS-derived); {sum(ldFree)} of ", + "{length(ldFree)} have none." ) abort(msg) } - # Lenient rather than qtl-required: a QTL outcome side may be an - # individual-level fit carrying no panel, and the requirement above already - # covers the RSS-derived GWAS case. - .requireMatchingLdRefs( - ldReference(qtlFineMappingResult), - outcomeLd, + # Per row pair, over the QTL and GWAS rows whose regions overlap -- the + # ones the enrichment combines. Lenient rather than qtl-required: a QTL + # outcome side may be an individual-level fit carrying no panel, and the + # requirement above already covers the RSS-derived GWAS case. + .requireOverlapLdRefs( + qtlFineMappingResult, + gwasFineMappingResult, pipelineName = "qtlEnrichmentPipeline", + label = "qtlFineMappingResult", nullPolicy = "lenient" ) invisible(NULL) diff --git a/R/qtlSumStats.R b/R/qtlSumStats.R index ac68c7b9..097117be 100644 --- a/R/qtlSumStats.R +++ b/R/qtlSumStats.R @@ -3,10 +3,11 @@ # ----------------------------------------------------------------------------- # DFrame-subclass collection keyed by the identity tuple (study, context, # trait). Each row holds a per-tuple GRanges of summary statistics -# (variant_id + per-variant Z/N/MAF mcols). Class-level slots ldReference -# (a GenotypeHandle for the LD reference) + genome (the genome build) -# apply uniformly across rows. Built-in qcInfo slot tracks which -# summaryStatsQc() passes have been run. +# (variant_id + per-variant Z/N/MAF mcols). The genome build applies +# uniformly across rows; the ldReference slot holds each distinct LD +# reference once and the ldReference mcols column names the one every row +# uses. Built-in qcInfo slot tracks which summaryStatsQc() passes have been +# run. # ============================================================================= #' @include AllClasses.R tupleSelectors.R @@ -19,9 +20,11 @@ NULL #' Z / N / MAF mcols. #' @details Required columns: \code{study}, \code{context} and \code{trait}; #' the 3-tuple is unique. The class-level slots inherited from -#' \code{\linkS4class{SumStatsBase}} -- \code{ldReference}, \code{genome} and -#' \code{qcInfo} -- apply uniformly to every row, and \code{qcInfo} records -#' which \code{\link{summaryStatsQc}} passes have run. +#' \code{\linkS4class{SumStatsBase}} -- \code{genome} and \code{qcInfo} -- +#' apply uniformly to every row, and \code{qcInfo} records which +#' \code{\link{summaryStatsQc}} passes have run; \code{ldReference} holds +#' each distinct LD reference once, and the \code{ldReference} column names +#' the one each row uses. #' @seealso \code{\link{QtlSumStats}} for the constructor and #' \code{\linkS4class{GwasSumStats}} for the GWAS counterpart. #' @export @@ -97,8 +100,9 @@ NULL #' @title Create a QtlSumStats Collection Object #' @description Construct a \code{QtlSumStats} S4 DFrame-subclass collection #' from per-tuple vectors and a list of \code{GRanges} entries (one per -#' tuple), plus a single LD reference and a single genome build that apply -#' to the whole collection. Each \code{GRanges} entry must carry per-variant +#' tuple), plus the LD reference(s) the rows were harmonized against and a +#' single genome build that applies to the whole collection. Each +#' \code{GRanges} entry must carry per-variant #' statistics in its mcols (\code{SNP}, \code{A1}, \code{A2}, \code{Z}, #' \code{N}; plus optional \code{MAF}, \code{INFO}, \code{BETA}, \code{SE}, #' \code{P}). @@ -108,11 +112,12 @@ NULL #' @param entry A list / \code{SimpleList} of \code{GRanges}, one per tuple. #' Same length as \code{study}, \code{context}, and \code{trait}. #' @param genome Single character string giving the genome build (e.g., -#' \code{"hg19"}, \code{"hg38"}). Uniform across the collection because all -#' entries share the same LD reference. +#' \code{"hg19"}, \code{"hg38"}). One build per collection. #' @param ldReference The LD reference: a genotype panel (see #' \code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} or an -#' \code{\link{LdMatrix}}. +#' \code{\link{LdMatrix}}, used for every tuple, or a list with one per +#' tuple when they sit on different references. Each distinct reference is +#' stored once, and the \code{ldReference} column names each row's. #' @param varY Optional numeric vector of per-tuple phenotype variances #' (\code{NA_real_} entries allowed). #' @param nSample Optional per-tuple total sample size (numeric; default @@ -177,7 +182,8 @@ QtlSumStats <- function( .qssAppendNSample(nSample, n) |> .appendTraitPosCol(traitPos, n) |> .qssAppendExtras(extraCols) - dfArgs <- c(cols, list(check.names = FALSE)) + dict <- .ldRefDict(.ldRefPerTuple(ldReference, n)) + dfArgs <- c(cols, list(ldReference = dict$keys, check.names = FALSE)) # The per-tuple GRanges become the collection's ELEMENTS; the tuple keys # and per-tuple scalars go in mcols. There is no `entry` column. # mcols are attached to the GRangesList BEFORE new(), because new() @@ -191,7 +197,7 @@ QtlSumStats <- function( GenomicRanges::GRangesList(split$entry), value = md[split$fromIdx, , drop = FALSE] ) - .sumStatsNewValidated("QtlSumStats", grl, ldReference, genome, qcInfo) + .sumStatsNewValidated("QtlSumStats", grl, dict$refs, genome, qcInfo) } # Validate genome / entry / length consistency and recycle varY. Returns the @@ -201,7 +207,7 @@ QtlSumStats <- function( if (length(genome) != 1L) { msg <- glue( "`genome` must be a single character string (one build per ", - "collection, because all entries share the LD reference)." + "collection)." ) abort(msg) } @@ -524,12 +530,7 @@ setMethod("show", "QtlSumStats", function(object) { .trim = FALSE )) } - ld <- ldReference(object) - ldSrc <- if (is.null(ld)) { - "none (LD-free)" - } else { - .ldRefLabel(ld) - } + ldSrc <- .ldRefsLabel(ldReference(object), "none (LD-free)") cat(glue(" LD reference: {ldSrc}\n", .trim = FALSE)) }) @@ -580,15 +581,15 @@ setMethod("show", "QtlSumStats", function(object) { #' The three collection-level slots are merged rather than taken from the first #' input, on the same rules as \code{\link{combineGwasSumStats}}: \code{genome} #' and the \code{\link{summaryStatsQc}} options must agree, the per-element -#' \code{qcInfo$entryAudit} concatenates in element order, and the LD -#' references combine the same way (all-\code{NULL} stays \code{NULL}, which -#' is the usual case for individual-level QTL data). +#' \code{qcInfo$entryAudit} concatenates in element order, and the rows keep +#' their own LD references, stored the same way. #' #' @param ... Two or more \code{QtlSumStats} objects, or a single \code{list} #' of them. -#' @param ldReference Optional genotype panel (see \code{\link{readGenotypes}}) -#' to attach to the combined collection, overriding the unioned one. Default -#' \code{NULL}. +#' @param ldReference Optional LD reference -- a genotype panel (see +#' \code{\link{readGenotypes}}), a \code{GenotypeMixture} or an +#' \code{LdMatrix} -- that every row of the combined collection uses +#' instead of its own. Default \code{NULL}. #' @return A single combined \code{QtlSumStats}. #' @seealso \code{\link{combineGwasSumStats}}, #' \code{\link{combineFineMappingResults}}, \code{\link{combineTwasWeights}} diff --git a/R/resultWriters.R b/R/resultWriters.R index 0bb61c8f..fc838d7a 100644 --- a/R/resultWriters.R +++ b/R/resultWriters.R @@ -2282,13 +2282,19 @@ setMethod( ) } -# The collection-level fallback for `data_source`: an ldReference is the LD -# reference a fit was run against, so its absence means individual-level data. -# Only a fallback -- a row that recorded its own wins, because a combined -# collection can hold rows of both kinds and has only one ldReference. +# The fallback for `data_source`: a row's LD reference is the one its fit ran +# against, so a row with none is individual-level data. Only a fallback -- a +# row that recorded its own wins. Per row in .pubDataSourceOf(); for the +# collection as a whole it is NA when its rows are of both kinds. # @noRd .pubDataSource <- function(x) { - if (is.null(ldReference(x))) "individual" else "sumstat" + kinds <- unique(.pubDataSourceOf(x)) + if (length(kinds) == 1L) kinds else NA_character_ +} + +# @noRd +.pubDataSourceOf <- function(x) { + if_else(is.na(.ldRefKeys(x)), "individual", "sumstat") } # `EZ` only when the SOURCE supplied z. The spec defines the field as the z @@ -2441,7 +2447,7 @@ setMethod( method = .pubTupleColumn("method", x), standardized = .twbColumnOr(x, "standardized", as.logical, NA), dataType = .twbListColumn(x, "dataType"), - dataSource = .pubDataSource(x), + dataSource = .pubDataSourceOf(x), jointStudies = .twbColumnOr( x, "jointStudies", @@ -2614,21 +2620,20 @@ setMethod( start = start(regions)[[i]] - 1L, end = end(regions)[[i]] ), - af = .twbVariantAf(x, gr), + af = .twbVariantAf(.rowLdRef(x, i), gr), schema = schema, added = added )) } -# Per-variant allele frequency, from the collection's LD reference when it -# records one (an LdMatrix with an AF column, or a stochastic sketch, whose -# real frequencies are recorded from its sidecar). A TwasWeights element -# records only alleles and a weight, so otherwise there is no frequency to -# publish -- and `AF` is what the standardized-to-raw weight conversion needs, -# so its absence is worth seeing rather than faking. +# Per-variant allele frequency, from the row's LD reference when it records +# one (an LdMatrix with an AF column, or a stochastic sketch, whose real +# frequencies are recorded from its sidecar). A TwasWeights element records +# only alleles and a weight, so otherwise there is no frequency to publish -- +# and `AF` is what the standardized-to-raw weight conversion needs, so its +# absence is worth seeing rather than faking. # @noRd -.twbVariantAf <- function(x, gr) { - ref <- ldReference(x) +.twbVariantAf <- function(ref, gr) { af <- if (is.null(ref)) NULL else .ldRefAf(ref) if (is.null(af)) { return(NA_real_) diff --git a/R/sumstatsQc.R b/R/sumstatsQc.R index 48ea8998..07292576 100644 --- a/R/sumstatsQc.R +++ b/R/sumstatsQc.R @@ -5258,39 +5258,43 @@ effectiveN <- function(nCase, nControl) { # options; the per-entry fields are derived here rather than carried over from # the previous entry. # @noRd -.ssqcRunEntry <- function(i, sumstats, opts, ldReference, isQtl) { +.ssqcRunEntry <- function(i, sumstats, opts, refs, keys, isQtl) { .runEntrySummaryStatsQc( gr = .collectionEntry(sumstats, i), - ldReference = ldReference, + ldReference = .ldRefForKey(keys[[i]], refs), opts = .ssqcEntryOpts(opts, sumstats, i), entryLabel = .ssqcEntryLabel(sumstats, i, isQtl) ) } -# Run the per-entry QC pipeline across all entries. +# Run the per-entry QC pipeline across all entries, each against its own +# row's LD reference. .ssqcRunEntries <- function(sumstats, opts) { isQtl <- methods::is(sumstats, "QtlSumStats") - # Panel filter, once for the shared LD reference and BEFORE any entry is + # Panel filter, once per distinct LD reference and BEFORE any entry is # harmonized, so a variant the panel cannot support is gone from the LD # and from the summary statistics alike. - ldReference <- .ssqcPrunePanel( + pruned <- map( ldReference(sumstats), - .panelCutoffs(opts$panelFilterParam), - "summaryStatsQc" + .ssqcPrunePanel, + cutoffs = .panelCutoffs(opts$panelFilterParam), + label = "summaryStatsQc" ) - refGenome <- unique(unname(GenomeInfoDb::genome(sumstats))) + keys <- .ldRefKeys(sumstats) results <- map( seq_len(nrow(sumstats)), .ssqcRunEntry, sumstats = sumstats, opts = opts, - ldReference = ldReference, + refs = pruned, + keys = keys, isQtl = isQtl ) list( newEntries = map(results, "gr"), entryAudits = map(results, "audit"), - ldReference = ldReference + ldReferences = pruned, + keys = keys ) } @@ -5353,7 +5357,8 @@ effectiveN <- function(nCase, nControl) { ) } -# Rebuild the SumStats object with QC'd entries, trimmed sketch, and qcInfo. +# Rebuild the SumStats object with QC'd entries, trimmed sketches (one per +# row, as a list running parallel to `newEntries`), and qcInfo. .ssqcRebuild <- function(sumstats, newEntries, newLdReference, qcInfo) { cols <- .tupleColumnNames(sumstats) nSample <- if (is_in("nSample", cols)) { @@ -5639,10 +5644,23 @@ summaryStatsQc <- function( impute = opts$impute, sumstatsCleaningParam = opts$sumstatsCleaningParam ) - # From the PRUNED panel, not the input's: narrowing the original again - # would hand back a sketch the panel filter never reached. - newLdReference <- .subsetLdRefToIds(res$ldReference, res$newEntries) - .ssqcRebuild(sumstats, res$newEntries, newLdReference, qcInfo) + # From the PRUNED panels, not the input's: narrowing an original again + # would hand back a sketch the panel filter never reached. Each is cut to + # the variants of the rows that use it. + trimmed <- imap( + res$ldReferences, + .ssqcTrimToRows, + entries = res$newEntries, + keys = res$keys + ) + perRow <- map(res$keys, .ldRefForKey, refs = trimmed) + .ssqcRebuild(sumstats, res$newEntries, perRow, qcInfo) +} + +# One LD reference cut to exactly the variants of the rows keyed to it. +# @noRd +.ssqcTrimToRows <- function(ldReference, key, entries, keys) { + .subsetLdRefToIds(ldReference, entries[is_in(keys, key)]) } # ---- slidingWindowLoop callbacks (distance mode) ------------------------ diff --git a/R/tupleSelectors.R b/R/tupleSelectors.R index 70e71808..5ec79bd1 100644 --- a/R/tupleSelectors.R +++ b/R/tupleSelectors.R @@ -397,9 +397,6 @@ rep(gr, n) } -# Internal: append a validated `region` GRanges to a constructor's column list -# (no-op when NULL). Shared by the TwasWeights / FineMappingResultBase -# constructors so the provenance column is added identically everywhere. # Internal: an optional per-row provenance column. One helper for all three # (`dataType`, `dataSource`, `standardized`) since they differ only in name and # coercion. @@ -439,6 +436,10 @@ .appendProvenanceCol(cols, standardized, "standardized", n, as.logical) } +# Internal: append a validated `region` GRanges to a constructor's column list +# (no-op when NULL). Shared by the TwasWeights / FineMappingResultBase +# constructors so the provenance column is added identically everywhere. +# @noRd .appendRegionCol <- function(cols, region, n) { if (is.null(region)) { return(cols) @@ -553,10 +554,11 @@ # unioned, and a collection lacking an optional column (e.g. jointContexts or # region) is padded with `.naLikeColumn` -- so adding a column to a class flows # through combines automatically rather than being hand-listed at each site. -# Preserves the concrete class and sets the `ldReference` slot explicitly (rbind -# does not reliably carry it). Returns NULL when given no inputs. Every -# collection is a RangedTupleList now, so this only drops the NULL parts and -# hands off; the old DFrame path went with the rebase onto GRangesList. +# Preserves the concrete class and rebuilds the LD references: every row keeps +# its own (.ldRefCombine()), unless `ldReference` names one for all of them. +# Returns NULL when given no inputs. Every collection is a RangedTupleList now, +# so this only drops the NULL parts and hands off; the old DFrame path went +# with the rebase onto GRangesList. # # `slots` carries the collection-level state a concrete subclass adds beyond # `ldReference` (SumStatsBase's `genome` / `qcInfo`). It is passed in rather @@ -567,13 +569,15 @@ parts, ldReference = NULL, slots = list(), - genome = NULL + genome = NULL, + fn = ".rbindCollections" ) { parts <- compact(parts) if (length(parts) == 0L) { return(NULL) } - .rbindRangedCollections(parts, ldReference, slots, genome) + dict <- .ldRefCombine(parts, ldReference, fn) + .rbindRangedCollections(parts, dict, slots, genome) } # Internal: aggregate a per-entry accessor across every row of a @@ -742,13 +746,18 @@ # @noRd .rbindRangedCollections <- function( parts, - ldReference, + dict, slots = list(), genome = NULL ) { cls <- class(parts[[1L]])[[1L]] allCols <- reduce(map(parts, .tupleColumnNames), union) - combined <- set_names(map(allCols, .rbindColumn, parts = parts), allCols) + # Each part keyed its rows into its own references, so the bound rows take + # the keys the combined references were built with. + combined <- list_assign( + set_names(map(allCols, .rbindColumn, parts = parts), allCols), + ldReference = dict$keys + ) md <- exec( S4Vectors::DataFrame, !!!c(combined, list(check.names = FALSE)) @@ -768,7 +777,7 @@ methods::new, cls, grl, - !!!c(list(ldReference = ldReference), slots) + !!!c(list(ldReference = dict$refs), slots) ) validObject(out) out @@ -1185,9 +1194,13 @@ # @noRd .rtlExtraSlots <- function(parts, fn) { own <- setdiff(.rtlOwnSlots(parts[[1L]]), "ldReference") - out <- compact(list( - qcInfo = if (is_in("qcInfo", own)) .ssCombineQcInfo(parts, fn) - )) + # discard(is.null), not compact(): parts no QC has run on merge to an + # empty qcInfo, which is a merged value -- compact() would drop it and + # report the slot as having no merge rule. + out <- discard( + list(qcInfo = if (is_in("qcInfo", own)) .ssCombineQcInfo(parts, fn)), + is.null + ) unknown <- setdiff(own, names(out)) if (length(unknown) > 0L) { cls <- class(parts[[1L]])[[1L]] @@ -1202,7 +1215,8 @@ # Merge `parts` into one collection, reconciling every collection-level slot. # The single path behind `c()` / `append()` and the four combine*() wrappers. -# A non-NULL `ldReference` overrides the unioned panel. +# Every row keeps its own LD reference; a non-NULL `ldReference` is every +# row's instead. # @noRd .combineTupleCollections <- function(parts, ldReference, fn) { .rtlRequireSameClass(parts, fn) @@ -1212,9 +1226,10 @@ genome <- .rtlCombineGenome(parts, fn) .rbindCollections( parts, - ldReference = ldReference %||% .combineLdRef(parts, fn), + ldReference = ldReference, slots = .rtlExtraSlots(parts, fn), - genome = genome + genome = genome, + fn = fn ) } @@ -1321,35 +1336,118 @@ identical(qcInfo(x)$options, first) } -# The union of the parts' LD panels. All-NULL stays NULL (an individual-level -# collection has no panel); a mix is an error, because silently keeping the -# panels that exist would leave elements harmonized against nothing. +# The LD references of `parts`, row-bound: each row keeps the reference it +# had, and a reference that is a view of another is stored as that one +# (.ldRefMergeViews()). `override`, when given, is every row's reference +# instead. # @noRd -.combineLdRef <- function(parts, fn) { - sketches <- map(parts, ldReference) - present <- !map_lgl(sketches, is.null) - if (!any(present)) { - return(NULL) +.ldRefCombine <- function(parts, override, fn) { + if (!is.null(override)) { + n <- sum(map_int(parts, length)) + return(.ldRefDict(.ldRefPerTuple(override, n))) } - if (!all(present)) { - msg <- glue( - "{fn}: {sum(!present)} of {length(parts)} inputs carry no ", - "ldReference. Combine collections that all have an LD reference, ", - "or all have none." - ) - abort(msg) + perRow <- list_flatten(map(parts, .rowLdRefs)) + .ldRefMergeViews(.ldRefDict(perRow), fn) +} + +# `dict` with every entry that is a view of another stored as that one, and +# the rows re-keyed to it. Block-parallel pipelines narrow each piece's panel +# to its own block, so binding the pieces back together would otherwise hold +# one panel per block where there is one panel. +# +# Entries are taken widest first, and each joins the first group whose head +# (its widest entry) it is a view of, or heads a new one. An entry so meets +# the widest reference holding it before any narrower one, whatever order the +# rows came in. Groups are numbered by their first row, so `ld1` stays the +# first row's reference. +# @noRd +.ldRefMergeViews <- function(dict, fn) { + refs <- dict$refs + if (length(refs) <= 1L) { + return(dict) + } + grouped <- reduce( + order(map_int(refs, .ldRefNVariants), decreasing = TRUE), + .ldRefAssignGroup, + refs = refs, + .init = list(heads = integer(0), group = integer(length(refs))) + ) + seen <- unique(grouped$group) + group <- match(grouped$group, seen) + merged <- map( + seq_along(seen), + .ldRefGroupRef, + group = group, + heads = grouped$heads[seen], + refs = refs, + fn = fn + ) + keys <- str_c("ld", seq_along(merged)) + list( + refs = set_names(merged, keys), + keys = keys[group[match(dict$keys, names(refs))]] + ) +} + +# `grouped` extended by entry `i`: it joins the first group whose head it is +# a view of, or heads a new group. +# @noRd +#' @importFrom purrr detect_index +.ldRefAssignGroup <- function(grouped, i, refs) { + hit <- detect_index(grouped$heads, .ldRefHeadHolds, i = i, refs = refs) + if (hit == 0L) { + grouped$heads <- c(grouped$heads, i) + hit <- length(grouped$heads) } - if (any(map_lgl(sketches, .ldIsMatrixRef))) { - return(.combineLdMatrixRefs(sketches, fn)) + grouped$group[[i]] <- hit + grouped +} + +# @noRd +.ldRefHeadHolds <- function(h, i, refs) { + .ldRefIsViewOf(refs[[i]], refs[[h]]) +} + +# TRUE when reference `x` can be stored as `of`: panels reading the same files +# over the same samples, or an LdMatrix or mixture all of whose variants `of` +# holds, with the same LD. +# @noRd +.ldRefIsViewOf <- function(x, of) { + if (.ldIsPanel(x) && .ldIsPanel(of)) { + return(.ssSameGenotypeSource(x, of)) + } + if (.ldIsMatrixRef(x) && .ldIsMatrixRef(of)) { + return(.ldmCoveredBy(x, of)) } - if (any(map_lgl(sketches, .ldIsMixtureRef))) { - return(.combineMixtureRefs(sketches, fn)) + if (.ldIsMixtureRef(x) && .ldIsMixtureRef(of)) { + return(.ldRefVariantsCoveredBy(x, of) && .gmSameMixture(x, of)) + } + FALSE +} + +# The one reference group `g` is stored as. Panels from one source union. An +# LdMatrix or mixture cannot be widened -- the LD between variants that +# different members hold is in none of them -- so the group's head, which +# holds every other member, stands for it. +# @noRd +.ldRefGroupRef <- function(g, group, heads, refs, fn) { + members <- unname(refs[group == g]) + if (length(members) == 1L || !.ldIsPanel(members[[1L]])) { + return(refs[[heads[[g]]]]) } - .ssCheckSameSource(sketches, fn) - chromPaths <- .ssUnionChromPaths(sketches, fn) - handles <- map(sketches, .ldRefHandle) + .unionPanelRefs(members, fn) +} + +# One panel standing for `panels`, which read the same files over the same +# samples: a handle union keeps the first handle and widens its snpInfo, each +# row's `fileIdx` addressing a position in THAT file, and a panel union binds +# the parts over the first one's samples. +# @noRd +.unionPanelRefs <- function(panels, fn) { + chromPaths <- .ssUnionChromPaths(panels, fn) + handles <- map(panels, .ldRefHandle) if (any(map_lgl(handles, is.null))) { - return(.ssUnionPanels(sketches, chromPaths)) + return(.ssUnionPanels(panels, chromPaths)) } handle <- methods::initialize( handles[[1L]], @@ -1395,60 +1493,6 @@ S4Vectors::`metadata<-`(stacked[ord, ], value = md) } -# LdMatrix references, unlike panels, cannot be unioned: the LD between -# variants held by different parts is recorded in neither. They combine only -# when one of them already holds every other's variants with the same LD -- -# the same matrix, or one part that kept all of the others' variants. -# Otherwise the caller passes the matrix covering them all as `ldReference`. -# @noRd -.combineLdMatrixRefs <- function(refs, fn) { - if (!all(map_lgl(refs, .ldIsMatrixRef))) { - msg <- glue( - "{fn}: inputs mix genotype-panel and LdMatrix references; ", - "combine collections that share one LD reference." - ) - abort(msg) - } - widest <- refs[[which.max(map_int(refs, length))]] - if (all(map_lgl(refs, .ldmCoveredBy, by = widest))) { - return(widest) - } - abort(c( - glue( - "{fn}: the inputs' LdMatrix references cover different variants, ", - "and the LD between them is held by none." - ), - i = "Pass an LdMatrix covering all of their variants as `ldReference`." - )) -} - -# Mixture references combine like LdMatrix ones: when one of them already -# holds every other's variants and they average the same panels with the -# same weights. Their panels stay lazy, so the widest mixture loses nothing. -# @noRd -.combineMixtureRefs <- function(refs, fn) { - if (!all(map_lgl(refs, .ldIsMixtureRef))) { - msg <- glue( - "{fn}: inputs mix GenotypeMixture references with other kinds; ", - "combine collections that share one LD reference." - ) - abort(msg) - } - widest <- refs[[which.max(map_int(refs, .ldRefNVariants))]] - sameMix <- map_lgl(refs, .gmSameMixture, y = widest) - covered <- map_lgl(refs, .ldRefVariantsCoveredBy, by = widest) - if (all(sameMix & covered)) { - return(widest) - } - abort(c( - glue( - "{fn}: the inputs' GenotypeMixture references differ or cover ", - "different variants." - ), - i = "Pass the mixture covering all of their variants as `ldReference`." - )) -} - # TRUE when every variant of `x` is in `by`, coded the same way. # @noRd .ldRefVariantsCoveredBy <- function(x, by) { @@ -1512,24 +1556,6 @@ abort(msg) } -# Every panel must read from the same file(s) and samples: a handle union -# keeps the first handle and widens its snpInfo, each row's `fileIdx` -# addressing a position in THAT file, and a panel union binds the parts over -# the first one's samples. -# @noRd -.ssCheckSameSource <- function(sketches, fn) { - same <- map_lgl(sketches, .ssSameGenotypeSource, first = sketches[[1L]]) - if (all(same)) { - return(invisible(NULL)) - } - msg <- glue( - "{fn}: inputs reference different genotype panels (input ", - "{which(!same)[[1L]]} differs from the first). Their LD references ", - "cannot be unioned." - ) - abort(msg) -} - # @noRd .ssSameGenotypeSource <- function(x, first) { # chromPaths is deliberately NOT compared: two sketches trimmed from the diff --git a/R/twasWeights.R b/R/twasWeights.R index 6d05440b..a7249b61 100644 --- a/R/twasWeights.R +++ b/R/twasWeights.R @@ -52,16 +52,18 @@ NULL #' column lists the semicolon-joined members of the joined axis. For non-joint #' rows the joint columns are \code{NA_character_}. Tuple uniqueness is enforced #' jointly across the identity-tuple columns and any present joint columns. -#' @slot ldReference The LD reference the weights were derived against (a -#' genotype panel, a \code{GenotypeMixture} or an \code{LdMatrix}), or -#' \code{NULL} when the weights were learned from individual-level data. -#' Used downstream to check that pipelines combining results share one LD -#' reference. +#' @slot ldReference A named list of the LD references the weights were +#' derived against, each a genotype panel, a \code{GenotypeMixture} or an +#' \code{LdMatrix}, stored once apiece; the \code{ldReference} column of +#' \code{mcols} names the entry each row used (\code{NA} for weights +#' learned from individual-level data). Used downstream to check that the +#' rows a pipeline combines share an LD reference. #' @export setClass( "TwasWeights", contains = "RangedTupleList", - representation(ldReference = "LdReference_OR_NULL"), + representation(ldReference = "list"), + prototype(ldReference = list()), validity = function(object) .validateTwasWeights(object) ) @@ -100,7 +102,8 @@ setClass( .validateTraitPosColumn(object), .validateRegionColumn(object), .twasValidateJointCols(object, jointCols), - .twasValidateKeyUniqueness(object, jointCols) + .twasValidateKeyUniqueness(object, jointCols), + .ldRefDictProblems(object@ldReference, .ldRefKeys(object)) ) } @@ -171,8 +174,11 @@ setClass( #' shape as \code{jointStudies}. #' @param jointTraits Optional character vector for cross-trait joints. Same #' shape as \code{jointStudies}. -#' @param ldReference An optional genotype panel (see -#' \code{\link{readGenotypes}}), or \code{NULL} for individual-level fits. +#' @param ldReference The LD reference the weights were derived against -- +#' a genotype panel (see \code{\link{readGenotypes}}), a +#' \code{GenotypeMixture} or an \code{LdMatrix} -- used for every row, or +#' a list with one per row; \code{NULL} for individual-level fits. Each +#' distinct reference is stored once. #' @param traitPos Optional per-row trait genomic anchor (a \code{GRanges} or #' \code{NULL}), carried forward as provenance; not part of the identity key. #' \code{NULL} (default) omits the column. @@ -584,7 +590,9 @@ setMethod("studyName", "TwasWeights", function(x) unique(as.character(x$study))) #' @rdname ldReference #' @export -setMethod("ldReference", "TwasWeights", function(x) x@ldReference) +setMethod("ldReference", "TwasWeights", function(x) { + .ldRefsInUse(x) +}) #' @rdname contexts #' @export @@ -618,11 +626,10 @@ setMethod("show", "TwasWeights", function(object) { .trim = FALSE )) } - ldSrc <- if (is.null(object@ldReference)) { + ldSrc <- .ldRefsLabel( + ldReference(object), "NULL (individual-level fit)" - } else { - .ldRefLabel(object@ldReference) - } + ) cat(glue(" LD reference: {ldSrc}\n", .trim = FALSE)) }) diff --git a/R/twasWeightsPipeline.R b/R/twasWeightsPipeline.R index 7d0afb5a..cac12f46 100644 --- a/R/twasWeightsPipeline.R +++ b/R/twasWeightsPipeline.R @@ -49,9 +49,11 @@ #' #' @param ... Two or more \code{TwasWeights} objects, or a single \code{list} of #' them. -#' @param ldReference Optional genotype panel (see \code{\link{readGenotypes}}) -#' to attach to the -#' combined collection. Default \code{NULL}. Applied when combining two or +#' @param ldReference Optional LD reference -- a genotype panel (see +#' \code{\link{readGenotypes}}), a \code{GenotypeMixture} or an +#' \code{LdMatrix} -- that every row of the combined collection uses instead +#' of its own. Default \code{NULL}: each row keeps the reference it had, +#' and views of one source are stored once. Applied when combining two or #' more inputs; a single input is returned unchanged. #' @return A single combined \code{TwasWeights}. #' @seealso \code{\link{combineFineMappingResults}} @@ -1093,9 +1095,9 @@ combineTwasWeights <- function(..., ldReference = NULL) { #' \code{\link{summaryStatsQc}} first; otherwise an error is raised pointing #' at that function. #' -#' The returned \code{\link{TwasWeights}} collection's \code{ldReference} slot -#' is set automatically: \code{NULL} for individual-level fits, the input's -#' \code{ldReference} for RSS-derived fits. +#' Each row of the returned \code{\link{TwasWeights}} collection records the +#' LD reference its weights were learned against: none for individual-level +#' fits, the reference of the input row(s) for RSS-derived fits. #' #' Optionally a \code{QtlFineMappingResult} may be supplied as a source of #' pre-fit SuSiE / SuSiE-inf / SuSiE-ash objects; their stored fits are passed @@ -1308,9 +1310,8 @@ combineTwasWeights <- function(..., ldReference = NULL) { #' @param ... Reserved for method-specific arguments. #' #' @return A \code{\link{TwasWeights}} collection keyed by \code{(study, -#' context, trait, method)}. The \code{ldReference} slot is \code{NULL} for -#' individual-level fits and equals the input's \code{ldReference} for -#' RSS-derived fits. +#' context, trait, method)}. Each row's LD reference is none for +#' individual-level fits and that of the input row(s) for RSS-derived fits. #' @examples #' data(qtlDatasetExample) #' twasWeightsPipeline(qtlDatasetExample, methods = "lasso", cisWindow = 1e6) @@ -2105,7 +2106,6 @@ setMethod( studyCol = part$studyCol, contextCol = part$contextCol, traitCol = part$traitCol, - ldReference = part$ldReference, methodArgs = methodArgs ) c( @@ -2220,7 +2220,7 @@ setMethod( panelFilterParam = panelFilterParam ) ) - .twasQssAssemble(rows, joint$result, part$ldReference) + .twasQssAssemble(rows, joint$result) } # Normalize the methods argument into (tokens, methodArgs). The default set @@ -2341,8 +2341,7 @@ setMethod( traitCol = traitCol, selRows = selRows, multivariateTokens = multivariateTokens, - univariateTokens = univariateTokens, - ldReference = ldReference(data) + univariateTokens = univariateTokens ) } @@ -2404,9 +2403,10 @@ setMethod( ) } -# Assemble a TwasWeights collection from a flat list of row records. +# Assemble a TwasWeights collection from a flat list of row records, each row +# on the LD reference its record carries (none for an individual-level fit). # @noRd -.twasRowsToWeights <- function(rows, ldReference) { +.twasRowsToWeights <- function(rows) { if (length(rows) == 0L) { return(NULL) } @@ -2416,7 +2416,7 @@ setMethod( trait = map_chr(rows, "trait"), method = map_chr(rows, "method"), entry = map(rows, "entry"), - ldReference = ldReference + ldReference = map(rows, "ldReference") ) } @@ -2498,7 +2498,6 @@ setMethod( contextCol, traitCol, data, - ldReference, twasWeights, weightsDataType, fitRetention, @@ -2517,7 +2516,6 @@ setMethod( contextCol = contextCol, traitCol = traitCol, data = data, - ldReference = ldReference, twasWeights = twasWeights, weightsDataType = weightsDataType, fitRetention = fitRetention, @@ -2560,7 +2558,6 @@ setMethod( contextCol, traitCol, data, - ldReference, twasWeights, weightsDataType, fitRetention, @@ -2572,10 +2569,11 @@ setMethod( ctx <- contextCol[i] tr <- traitCol[i] cached <- .twasQssCacheSplit(twasWeights, st, ctx, tr, univariateTokens) - cachedRows <- cached$rows + ldReference <- .rowLdRef(data, i) + cachedRows <- .recordsWithLdRef(unname(cached$rows), ldReference) toFit <- cached$toFit if (length(toFit) == 0L) { - return(unname(cachedRows)) + return(cachedRows) } fitCtx <- .twasQssUnivariateFitCtx( data, @@ -2597,7 +2595,7 @@ setMethod( fineMappingResult = fineMappingResult, weightsDataType = weightsDataType )) - c(unname(cachedRows), fitted) + c(cachedRows, .recordsWithLdRef(fitted, ldReference)) } # Cache hits for ONE multivariate group: a named list of the group's rows, @@ -2833,7 +2831,6 @@ setMethod( contextCol, traitCol, data, - ldReference, methodArgs, fitRetention, fineMappingResult, @@ -2859,7 +2856,6 @@ setMethod( contextCol = contextCol, traitCol = traitCol, data = data, - ldReference = ldReference, methodArgs = methodArgs, fitRetention = fitRetention, fineMappingResult = fineMappingResult, @@ -2877,7 +2873,6 @@ setMethod( contextCol, traitCol, data, - ldReference, methodArgs, fitRetention, fineMappingResult, @@ -2888,37 +2883,70 @@ setMethod( if (length(gIdx) < 2L) { return(list()) } - st <- studyCol[gIdx[[1L]]] - tr <- traitCol[gIdx[[1L]]] - ctxNames <- contextCol[gIdx] - mvStat <- .twasQssMultivariateStat( + grp <- .twasQssMultivariateGroup( + gIdx, data, - st, - tr, - ctxNames, - ldReference = ldReference, - cutoffs = .panelCutoffs(panelFilterParam) - ) - # The group's block of the reference, read once and shared by every method. - blockReference <- .ldRefInMemory( - ldReference, - mvStat$variantIds, - label = "twasWeightsPipeline" + studyCol, + contextCol, + traitCol, + panelFilterParam ) - list_flatten(map( + rows <- list_flatten(map( multivariateTokens, .twasQssMultivariateFitOne, twasWeights = twasWeights, - st = st, - tr = tr, - ctxNames = ctxNames, - mvStat = mvStat, - blockReference = blockReference, + st = grp$st, + tr = grp$tr, + ctxNames = grp$ctxNames, + mvStat = grp$mvStat, + blockReference = grp$blockReference, methodArgs = methodArgs, fitRetention = fitRetention, fineMappingResult = fineMappingResult, weightsDataType = weightsDataType )) + .recordsWithLdRef(rows, grp$ldReference) +} + +# What every method fitted to one (study, trait) group shares: the study, +# trait and contexts, their LD reference, the stacked statistics, and the +# group's block of the reference, read once. The contexts are fitted together +# against one LD matrix, so they must share an LD reference. +# @noRd +.twasQssMultivariateGroup <- function( + gIdx, + data, + studyCol, + contextCol, + traitCol, + panelFilterParam +) { + ldReference <- .jointRowsLdRef( + data, + gIdx, + "twasWeightsPipeline (QtlSumStats, multivariate)" + ) + ctxNames <- contextCol[gIdx] + mvStat <- .twasQssMultivariateStat( + data, + studyCol[gIdx[[1L]]], + traitCol[gIdx[[1L]]], + ctxNames, + ldReference = ldReference, + cutoffs = .panelCutoffs(panelFilterParam) + ) + list( + st = studyCol[gIdx[[1L]]], + tr = traitCol[gIdx[[1L]]], + ctxNames = ctxNames, + ldReference = ldReference, + mvStat = mvStat, + blockReference = .ldRefInMemory( + ldReference, + mvStat$variantIds, + label = "twasWeightsPipeline" + ) + ) } # Build the (variants x contexts) Z matrix + per-context N for a group. All @@ -3218,12 +3246,8 @@ setMethod( # Combine the per-tuple result with any joint result (error if both empty). # @noRd -.twasQssAssemble <- function( - rows, - jointResult, - ldReference -) { - perTupleResult <- .twasRowsToWeights(rows, ldReference) +.twasQssAssemble <- function(rows, jointResult) { + perTupleResult <- .twasRowsToWeights(rows) if (is.null(jointResult)) { if (is.null(perTupleResult)) { msg <- glue( @@ -3237,7 +3261,7 @@ setMethod( if (is.null(perTupleResult)) { return(jointResult) } - .rbindTwasWeights(perTupleResult, jointResult, ldReference = ldReference) + .rbindTwasWeights(perTupleResult, jointResult) } # ============================================================================= diff --git a/_pkgdown.yml b/_pkgdown.yml index 7711362b..6d37ecd6 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -293,6 +293,7 @@ reference: - nestTupleRanges - RangedTupleList-methods - subsetRegion + - updateObject-methods - subtitle: "FineMappingResultBase" contents: diff --git a/data/colocboostResultExample.rda b/data/colocboostResultExample.rda index 4b8e837390159ba1a93d486892d515be547324d6..e99140d5f29393d27e0f25c1d92a010ebc21de0a 100644 GIT binary patch delta 2894 zcmV-U3$gT=7nm228UyqTTag`6f4kzu4e!j483z4SvHE>+Ieqq~yoEQ*`@~=MIp!eg z{f*8)hEZ4v=4YSgdl_M0@B}1ardnfW#0|qhYT9gWmo8hJdSvRTU0JNxKQZ!!83}e_5!faApM=R& zFUvESZg;6{c;Z&vfW?CKjeRUIqA=GXU$!nyzOe`^;;l!@*8VKe>=i}BcdAVOr}T}2 zEom)PEox?G&TU@cf6@<}iRULSh4Lr}dSLXw1~AZlJX|qZZ82QFx<|DghA`5_!k%sc z0mpIj{B~7^Shr<`vy1jSWA*hNwV@Qe8~bW(4yvY&aJ<1QE@sb#O3khdDEKX7y2Dsq zGhp~7IGRQzWDGzi{r>2Oc+Mjp8!3!MnRc0og{3e5HEgNAf4p9HK^fJMTT|Z&Eng%} zlgnbXBlgQpz@<7kY#Ns4W;{DDj#a(+M*fEJGI`_z{$AVt)Q2+p9+=vt;%FVsRH+RK z+Tg~1RK3By$;VVy%tnJaS-dUV#cXz@1*#yS-sgjI6}UtTzaT?x-@LIPD)HVsdZs2; zxwG}-eaUCYe+Sc1EeHVksC(TuHyx$8!~I3^O>N%{>W2!vsNp_6lu`FxNK#v5#a~@&L1I2 zOSu+Ki!k(9S4N-}>z5N>2sRBw@dsrw_8#+hkhGbxf7)L6fn*`*Hc5t>)>}Q?v(Nd| z`iE+(v$b2>8$>V+HX38n$`}4YGxfp|5vy&Bt9GAHQd4m>3?<%UDjV{Jaz|L zUEFoDlj%$gBiab|8QO&kI9PfCJSW0>*9>z!-B=G-s2C!}L~JYfSx@ju=n}L!>x#0ibzit!1d7S)>sAb@Ywj&ovD}+;*0+6zebd zCS0{+rP4p7RxfCTL9=1v!|OY`*E2**uT4In_y~tP;&7PiNgj!b(`LSq?4IqaK2m8A z{DF~!|2H`70+~wOnN%nC+)wbn ze;eg_?D!uh_-n_i&al7wqdc=R{#3vcrTek6!1htKt}^AqZ3q5#O>tt<%!uo?(YT(u zUa#dR5Z>WGoy=-V5YLhT2U#4i@!|zTB$yV8UrHb(w1)}_#`S}`F2r@y@6Sv^$R;jT zDikbgdhH!ApUM?@APP74q`C=vUXYo=fBd+J>#^-$X8ej}ryOk^CFz8OG^yz#%+Jfx zBsnX`Zcvbs0))IN)ep#AoK^PL?RkgglP}jZ*u3dl`4Hc?wHD~q#4KchzRGF-$yB4K zpUf2_ky>qx`A>EzF%|K!(ElClsuj$b&0Cba_U8MOjKpVT{Kj6e0#9BZPDUb(f71~u z2I%7jE`^bPhh(84-W8*j@DZ)qD=#P6@BfVK64scGhS(JOEk^cC#A^OZUCiMp4$_fI z^`4)}40T1~dU&Bltz(Z_PR%KRTGj~<*b{g2bUnmRrcIh%9=e2PYHJybew{-8)v4F$ zQJ8+jY*eeZ?<{?eX@hyXwm=%Ki2mlr}rT6r3Jq6NGk^sBwrSWF4gUe2ctfehXt| z?3XzBRCp!}Z#xbf^eKWyel6(pj0tQd}D1ItCO0Q`!6Yhr)4%Isy{%#RsL zxwDYuCf%d%OMqY$@euvkZjHl7zKqBv{I6E#qfrR&z3xj=H(vyGzXg0{Rb;s6*=g8N zO*39hZxR19*w!q8wR|Ljf9L4H{HE7{Q#w2a?9=Dmv$6F>Jy}s0DU%7%?q}1az9pHB zj9s>bv~l1Uv}ij#DyZ)b?NdgtZVe1bs%3XM5DxOUq-hQp{q9&7L9mH5>sJx0x%fXY zg@v#B(pqY_`H}Zv?^neEom&>Ll|d#T22Bc`G-)IhpiR$M@Zi8kf3(t8mfdPF`;vyK zUR>f~`f8%{k(=i2HNN zmM;s6{+Q=5mZ}OnMry=f1p(NpJVb!s^i$!vA)rEy@>kl84T5b~v*vRB<>WwABJJ}w zT`w!>TA0T@!pqyaePO)i zHuH(<+YI`@OQEE0#aTHy^lIOBn*%z7(I7@iCO!KUobddWYiZXf~uX+8@=j(C+B{@PY_9I46Ul9b1->CuvtPZO#=*fhzpzDq%=nn(>3imr_OHAu=T*TW8jU5`B%1jY>q;EsO$ zCaO4Y1R!S4=3fAJftjk8t6DpdFw$tu2Uev>-| z`n69XJ!$p=E$eBtw{Ny(!WHj}a8$u*c|D20SO8Nr(Tgl8L>UyCrHL7>$SyVsPt&|4 zXd$)u7@uPa`H&JcXX{*;AR&8Xr5J{T)PC?^hhE}&XcN43<3GH}82@&#Ca6mutiM!P zO2JV&f1^H_z1KU!W$h129B9uqK?}&E5*~cY=;L9e-eOAF(lkrk@ipI4Q9KI4vzhWY?K+^l#)H0 z#J%-*GVX#kcX=!Z3))d}`m!4)L-X;F6E0^iK&y#`Sj4@YT^P@z3r|K#XzW*V7;8j{ sjU=M&!>!`#hCBcO02j`$S^xp_7WIn(0R8?j`aUoXivj=u00045TC>oYI{*Lx delta 2894 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 diff --git a/data/ctwasWeightsExample.rda b/data/ctwasWeightsExample.rda index a1fe326a073d59798ea4e2ffafe294a804cb007e..9a847a381c386733ad46dcb9836d888c0bc4fb87 100644 GIT binary patch delta 6511 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 V1pt{D3FJO74T}N*00001Sz5yBu$lk> delta 6487 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ΞxI;UYG=G4<&aK8C<@k$@ov+ZfBk z@~w=b44T@?*j0JU8pn-v#}=2>)5_ELmwTN$`MXp>E6s01Gy!?sO-*FqhM@!JVYA4S zB#&gw6Z1VDe}nPtbFXR0zB!+s1#Nmaka0PfyId@tL}a=Wmc}5ymTpZ*L3l)dUiUcG zu1*#E(DbDF;hDWRGJxISrZ}53Ur;vSp;qn zid5*duS70kt^lZz0|#R;0ngLj!koDzJ59b*P}}J1<}*UckS&csU*3{u&@Ufamj!?g zU>8;$D?GEQZJZx?{&N23R}Bilvp_NFL-XyeXYOQhY>|jhF8udk1$+q+Zmd-+bk6{# z*Fb2Gf0LZI@8lFsGU+JFqN9MUxXZCx$QbufyAEyTjh|34C zkg<4eE0*T)P8W*6AHicw=n;rxxDn&>hA9hGImE2T|BqCHmCWrz{p|o|oHkIO#yvup%GE>f&kPQ)=%FzR@)z1UbOu-&{M*k3AEE=jd)WYcI{<1q zI2oqS8CR6XA9jFnDf1j$jSnk(4`jukaeFyn;a}%XpB3*uo9TX}*U`FJO&`*xGnY@o zwmLI3f5&1CB~SQc!F!|Xc4W|dVA|@_Nlc@*o=}J0=K{Qv)m;mX9qVl2ikF^eukZNF xF9PU;4As9d>*5>2xCH*)rwo1pwt@CKWy~4T}N*00001Sz6tRvwi>o diff --git a/data/fsusieFineMappingExample.rda b/data/fsusieFineMappingExample.rda index ed4d2e13c520ce082842493113d61c5e24683c1e..33c3e26094d8debc0a7c93bf8f2cc9ff580bcf9a 100644 GIT binary patch literal 22184 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 diff --git a/data/gwasFineMappingExample.rda b/data/gwasFineMappingExample.rda index 6eb1977f6987a1c53e8ec5f6eb25e1353d153a84..869d25406de9457775677bd2fed54ed79784d046 100644 GIT binary patch literal 650656 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%0DQofh?$6<;WuVu35sIXA4lN+2AnKVgxI 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ŵ(zq6 z0DfU#r7k%;ER5jx(3J9=oOZs@Y7fu-)qJ%QamLbdjW38hJ%UJvKVmkweCqSz^ z-REr-s|2>-BbQCJYML9teT+?D64bVZG1cUv!;Q@FK>H6xT-KkqMyd$lbEc9Qrm z5=%eT|3w}5o`w2;WB|I`sS&Y1ENk;4I9Dj9n&;@NoMP3fR;U}}sV@xP!ZSi8)W)RC z|9&V21i9rgS}o1tnAEPQ`BVOv&Lf)!$|5%mS4Vh&8Ez3x75hSwRc|FSCnF7Iv!erW z069R$zgCnyo}yDdM1Cq#6+49B|Bbr~74sgyIZZPa;|A(Iw>xV0EF^HLV2=g`eapQ- zlrf~E9K%21RyVA-Gz>n0n|=~g-Gqnh=7A+ge2M>F^cIxb3z~0l%=T=O9U1afF??sE zzh@o*pHFkEDwfQ7&{F5B_CMVGYBYmu{c5b($)5A9{klGkyV@Ad%f zj_QnE*lKN|cHSV?kWQa&^>A==1Bm&FcGYm;%5izmy z)R%)HPcrLg>>Oq#iNq&J-jPHDfVxF>f$4t<(409&chiNLcCTbtD48g?*ig@y&EKUV?!q z!y&zAw@J6Q{xUCHaCg9)=E;+0AedDA$ z=q~+A#L7KPM230*w?0i;BV?OU@DL~KYfSLULm^ui&g$6(gWaVNB}F|%ix!0a8EM|? zEaHaKH5LBm^xkDXg0CrPCM&F3N8ve6hCQ1?*K3tbGRlwx(Elzj<<9m@-fU|nA#`T! zIS${RCQ5sWmvXGJ!lyGwf!Mc}*&W?1&t_-vUJMhY)KT@7gtfHPK_lrNa1;$%IMT@hlGg*yJUcV(yNRcV zH*UiA40^g=&@}?QQF2|H!UJk(ENU6(I=`<_l^RArh>EPEu5e(I{XBpH@_~c+tG%sv z_%uExjLcG1WOnX2Op1MW-az6PzvH}MR6Wl!R;pz7c6AK8Vb7pu3ga zD%3}u2d}aSAwuZu*04y1Pie#~s2{BxD8~bTPa=4V3lC#OQLF1{W!yPC4|=5{`cO1t z?2^=@n&nNFZ1aVq5DZi?VGNoE%C4nV>eyzYMvN&P`m_}a<7Dq914h|o+$i-F5J4Jt z<_93OTRa%HJgtpOg0Wqn@yH-z$rSu6|LXCZ^fbtufY?z45#bGm49fc3fhx)^IU3U# z8M)pWAz0gv*0Kd>4t*b(E z#bsBk99>q2O$N}aZLB8SHmYN=K-BM3uMv9LhYM}djTeb+QVaKef5`IM_WRRDlz!dK z?aGM-|Elk3bj*3L8B~-|q(Ad1eA`%Pf#DpGxDLL#Bhb1vI6b~c4J&n#zb#)tTPpG2 zy|gnELiJ7FC;U4Y_hl!Et$p+$`nZ{pXk0Ew|15_UdNtouJ@LuBZry4j7OHv`etrLA zDSz3BsqVxBfXLNn#9C_Wfh>LhCBj1jTBU=mWL_8xoRQelg#B+Cj^WdXv+epLz$BA4 zsYh#*4c+@}0Q-_;%IP4 z^=u{e6ym;BzqBVALlwj&WPE=9_z&mfgJVIammvdST5nyy4u>|3j)jwxGslU->Bcdj zbAY=-0^`vA9h1@?05hyp&wpA~j*TbOT@^Vl7|XGAvLe-F%{=-tJ0H-a<|QmN zj%4Mr`uufH8{oC#hCp0Z``p0}106@Z#ySKOyxeR5m?UP5F_{B9g1RY{jeIpyntxSC`R>Zy~$vJ`vDAlDwFy zsR)DE4^8fDp9A8e43-GVBUi^(;0ly6$xJ zf>E3Wd~Fb>RgAcay~Zl4$A{#{~9 zX(Kck(x{l?4aNLPIl+B~+qW4i?`i3Ygox8*vgDjDF_NPvH7^X;mK6yEi!*|*aqI0x z_xKEUr!I~><|VY#%JEOQGHH;^h|Ca*;ACikgoNkP4@}Q~bV&T&9 z(fi%Ykbh=qgeRjA(G3>#`#o(4}#z2b^hd9$l2Zvi{vB=)C}U9u38G=0)k49o)1rGobYT4h#XYA~E=lGBbs9#jUZ*(WT^P zI3MKEWNgp-YP&}_XH4c~cA9xCkX8YxRYI~l58eO#s1aG| z(+xn8(I(Z*TZB&a_rNLM@Pyk|r`l*^5#4a4^nS({%FzvmP(v*CyHY4GoO19XIx|!p z`z>XdqVhFT<%{Lg+f~5l4gC{uY{hiKC5ftdK}K@^GP=D#2EOM;4AxM@jkrfTy__NZ z6hU34!Q*Qq>9MX^1Kq4L9D9t+rcV`Y#=FwJLi?DgB&x*97l2Nh4<{~10|dQK*(3}11x(SRs|7NfD_%WfB_T_xy$&u)*EQr#rPSRx7whz??>~&|yyr({ zJYGRgxJ)=-h@KQNM{E|(ZlK>F;&l5aT2F-%~ ztU_%^bjf9i$*(j3^_@ts7fLycdGKq#^%3&Q)CV8pczyO`JjP38Hs)pri7U@@!==Y4 zs_Lh@{?lBS+9J>%nWqH?N?=LThMIP2wP%6nu_a9-N!FtWsu_V!EM-D5G`pzZHW`iF zvyjx?=-eWX@2!TsE+mG-0g9<5(DWywIguhWHtA>0i^6$t1zl?a^=9EjK6kdTt(e%3 zDwk=a?`%yJV+L5rE{7vFDh)wQ0e_NS9V&%Ft?Q>o4vW9NZvTSmjnKD(AK!weyNSG~ z*wk}s3GTFovkP?ht|N%$Eu_!(f90)cTW_UI>YAsRv}O2Cd{xFl5$-ZtB%l zp}Zn4jto-kPR~+=)cE(ReQvfZH*Ok{>j@4(DxEnW=jwF&`uEsE9gEY4*bhc8f_{sG zCv{b)APLA1HUE^1Gce0f(9+FwnZLpR%VG*Mo#bne8@t`?0t4m$39v1?}{df zT};NZW4Eu{L-YC(ettqvvk)1FjdLkaQyWDuk-WAJ9+KoO`(>-n4U9&oeq%Rg4Snqq zYF4_U0~koIE%VxuDG>`Q--acScmywu!tckq432(8B>OAsW6@J5T5y?ZF!km$83EOL z^P^Qqb`-^dx_fyVY$sQ#1670H`y57xe8bzgQJzW_;6(34^-w zgS6WmVKbZ9t6`k;l3S06$MKL7lqFWqE+f>hT7EGNwNQGgM|GitvMkmOI%P8EGt%VE zJT|o=wQflVXMqPp*jfV*0|SD4j<9ijWi&~lH)S8I>(L5r?3$Gk#=D31(9MO1$w!o| z=9~4Ig<_V47M0`RSm*hj$^fnLPj~%NU3zy#{gRyW>;|4nLNnyx>}>#r3{B4P=rb~u zszM|7uLQ+Y6^`I-7+D62ToWWdFH;(Ta+~`*W_J|Y>Xvl?c;R=;F?jKzcw>5<1!j?~ z*?m3^b?r-xL!PcLE|tX`>4FJ+icphXk&4^4-bz^nh@6djrP0fOwL(u3ozxJn1sDP%Hn40`C#V zkrqk+)k&qI;?Im3&J;|*44O!al|0!xu|~{l6JGFQ^yoluc5WL}NH{kRtsZ9SZIlI3 z8)qmghs3ina5yg-^S?Q}Ricl?^c@yR0K@t+Tj!s3tV1wiRHLA#zuQ?^z~^@Ii^6~Q zjkf!fxfRA&CpD7v??Y_40d(2sVv|&qCU>!08oNrT1Op;Gqulf{2J{D` z@LA$tC4CMyPgFTn-K z(S*~Ko{08m-3jaC@ez=j|MPbc=~NTgbl@(7=sDYaY35~ig-5v!sUU@)VnsySY!Mw- zX5g+J?u64byc?;&ms>Bat5y#AEeVvNg>dT*InF4yc)X8!Kbshqmzaa8Qo0@b>A%nx zNyZU$-B5&k7)Sy&fAuVM%&4??>#vVcrMk9|UQ9}5l3YUuA&DAc5e$%L$dCt+=YE5y z({Hvc=`RhOQ7&r*4wnr{6b^2>-8XtJ5DaYmN!kT;bD%IN&0A`$nSk4x7c|4u1Wy@b zL|XAAebCW`weO*TS7PTKWsbb3r;u9FbBkQ^6yvSndje52)X*W?W|7$~Kj{s+sW}{m zN8KyY-~R$R&(vYZ@o#HJE~O0~^2g>Ka=V>&FCzPd2dMG|UIIMHOzmRtw32|7=+Z(M+dZ z3|m9LuY&eviZ=bw-7I&g#x5D0p!`56p>4>nqWt=MKvq~2DY>IL(S?DdGU*@D(`9%c zI)ra6CEHG)FTO}MnGJR_GinB_alEXiE8526{{uF}7?o~-FUNXAiCcU~Y)IF~>_vxQ z8pPd};8!k_(D5JZXFZd#$&PGHqq`)ZzHf{x?*d>`B_HCf!4F#_+4}i?bVSo<4emZN zsLknGj2&~sZj9B=Tgcx(w~c)>Ntk2tV&;nM_Q{Blfm=O)ztLjCJ39>|hkjW_k*a3! z`nG4&Ro^2%`$9YtmiER5X|O-|B<@hjVxJ&>ny7-{*b?C@_BCDaK@6@lQO=PsbgSw% zF^MD;aL&5Oc9ywksJK-P$PCB8ia| zQ^bw=|IN3z)BQd`jY?8w(H_4thWb^5$&B? zJF$DKb|Tjp%evNGSP^)J^FPC3+`GtbA<=Tx(-J0oP(qwB0>r%lSo!J}8xR&R`spQh{ zfe7=N$7aan39Sg+c4IQM^<1~1Tjas%+!nlhzdFrRfS32T%x}5 z(Gatp>N=jD&~|P3tDOyT+7!2<2nag#;O?k@6!`9D zZR^&R%H5YMt&urnR&RmqpPu6oq(Gs_fSR#-n(5_Rv+y{NHI6_MNfRQg2brG`%Qmw# z;Xd>%wBH3K*Bq~6NKNaU?wDqt@_a*6lnC4#Z@DKNBq4^56V?%RScL}WFAQ)-K?wrB z2*ICRp}@Ki1=6pEO|HT5qq|I3wg&j$@_v+Wu*TJs59IJ@%}{G$E-ns%EnuvcBrM=A zAFKr)AOKM(Dv9q8M zI3e$WM3FC9tl_!rnK3nZGh&u?V&DDcKku-g=@|;GRd@h=zIkkBZzKD#s#M`@8f)lr zZ5MFU2rg5G=U1)CQ!lubx$HI`i%)d3V^#xz36$BY!|y^H;4+D@$y}>_Hzd6~M=sV3 z_kQez9KsaXt?SFC;>F0CJc&n;{@7W|SguQ#;?9t|xX!C}kO8e1Tg4$9g(m?$gJZ1* z;T+l&^tP1}^RI7Z)8kdN?~a3-z9~^U=;KZxAa|iXB@Iga>Gb@IrJnz`cy>jO_$K?2 zu_MrewQF)apLNBznS?^EJ;B9K!oELJ(}^`&x#WwD zC7wkkLJ)>zdC&C&zuZY< z-32sNr7it)yk`=10gvOxBzrskF;vdfFm;LeMZ;4(JnU%DC#Ivv$IG6Xt;@vwj@V^z z#D!hhSVwz8AjvVezt?085^aF4;R9^=DMB4{&9cMWU|_c#6LoiduZ%cpGv&_>)3Ok& zzcTuzYtCIRawGUuZBtuq6u{T-N{x@@tx~gx>LnB>VNcFTd9H8B9GQanhQl!p`xLz} zu?wsAnK%7$iFYY)K4DAba+ZJ%a7sRd*|>xoNk`E|a4USyLf4yX-ru&o`&$3bI~YgQ z4Ve41D1}7ABfk{6(Hg2%ZVcS1d=-QXTburalQsXjH^mTEM>B>NSprE^NyH#33H_Is zJHYI%bFfB83QwrmABjr#k*pBn2WH%@kUe`r8$sW{xLf<5MMZX~J2EpY^;Pwlf1q*k zUnEnvZt^nuQkJBEA?wG!w-Km4>d4Xe)eH5eJpgNDkw_y;LljM#Yf@v6PXa}-(91g< zJympqrFnZ$y!yP%V32A#l7!Ii~<<%*qU=TJO`O@ zvd8@OU>eicni7b9tCM!5$^-9=aVkOvV?P*xpifwfT%$m$nHetmy-;Zkwn=qoBb0>? zG%=BcP0qNayuddoPUv`}f!srS()%05CVa${=GQA7-4}q4TB>tgfFam@Z7`HnZ-(7y z*t{`_$5m>7CpveQDv83#Ml*_;aN(5~d(pB=(oqlU+=s*M=`K-{HGzCFjP_2l>G4A_ z+fw&hrrqyw2mmeg{d?`VVH7O+M5D_or|*y0j`?+@VzF8=BZ73qjy}ip$^yoXpk5Xc zC&*@j9Qi9>VTdYQl}1*fvo^1W90kdNEsXuFqA|sqQyAmR$L*C-Wpr zuBy@^W?XJUvmkYDkC%t-44uG3(#M3+wJK6wj3q$(nEr1x!6fb>mJ$<~7`76D;KrZ5 z`{73@1p*&gII#QcT6{WDkAX-d-GVe}JRo?QeRQ4phyIfrN+CekzWX#E&!0CZk)+W} zbDox@<>e-4HZ1nWt;Y3AIkfzPjE=&&=Ox-}DL%h6YoDYvB$t@!kXNzoRWdV2H&P;b z)Ks<{gr!}#^w-<2vqKqQ?L8y}YSh>{sZ))7aS!3=EKJxE`XQ=Xi{;yWt70;5Ve2TPi=+0h~6;;t_Zq z)b|T$lPX&(Q74jS4wUIHGYv2(*5J#$H)gUalea=A){$y?(eYQ@vvNhz_@_6q)$tLm zdXUszC42*OUl=}VVd)*q>H?0>xfUeHk}8+n@{k6_$06Ow)wM@Tr401a6YDFZ zURqOg(VpY(rjqV2{X?OO*<55y)@7{S4|(v5IAM+cWjzCvjv;E1h__7*WNy^54)h)t zD@)z`x#$~cUL&D{j0d|eV}-)k`WMrQ{!PHCE?WJh(O+e=(J7aLAtijeQZPDqO$(b9 zzfNY+~%E-sadh(SNV(O3c zB6mcXM#*b6^YZTvqF&}uqbkJApV7@-%^-<18J-T4M(51$=qIhG1kRj<_X=#pT)424 zdDc7gXjuPg8d*QbJ`*L-EX%+0sYZvDG!ge)yYii7Xi5;z$p;5qW8(OWMKv9zcBYtqOlMrc~>OXnIJdza6#W6qxmHr#N42*vmHNj^zrTd%?)@l4IN{X z^~?lSk3(= zhk@!aA9k$VH=yjo(7&m&Me*+%t7Dvu4krzGT$#QgG+WVEPf^qu&+a7LpX9jgx5 z1mE2Js>Ry?*-3g;KYV+2llRwUR zxBTiz(IKlvrrkEJT#h#kHr%b#=s{|OX%1#?bvKIR+d13$Pqv{a7QLt9w&Vj!J05od z`JluTgc0|qN@dK32u_fi07uje4BSbmSQM*?@c78{vX6CeyLmBJ!Vj`F^TYi$0c|=M zviGt}07DgD4NEg`VM3_8)HN>vh@d4C^NdP!&ZKW=C(J!K6Q6jAunkXQ?HLK~IIU<} zSA_uyY*|5dXm2%O3w(VIG5_2`{GJAHya)~nht|kU8zB%2>GpGz-cH@9cDaOPxhb3g zNKs*8V^G6iD}JN~Ny+STHmsk9A8}W7za$V3J;S?vRW56~XoKNfD;jSD`F;N}-(FG*BU%66KHM-`AmR_Lbq&1b10UvJ5@o;XdH?CB! z45Yinjr;@A4H$knrWsY3d1kNB`P}u9#2unt%4hsLby$~+Ev22I!Vn^_6vHY+&9m6_ z=D(_*SAk{Ia;$P%+51FKbsdeY9H7jnn3h8c$(Q?R|C}A%q1?!O81vGA;H#(@Cns;*vQ_1LoQ^Kjmaq`eDKMQ~iRQxd& z-CS|cRaDg0dN~9LxEPSEDRKN1$&;=21$g(flst9!8gbL5$G^x@hLBWak|{Sllhwg% z5Oy4xmOKLJl2s0~pc7C^knny>uF!Kscv1@chKvxBR&B3xVH##Y2;XCoYK+4S>FdL> zVzIggezA3IMO{}10)AeI7{Yq!a}bIaf+I8xJpNDvz{dIjzUkOU&=L?KI|6)NHaoo4HT`cTwiM%{4Lu$2?8lK5cNpWk^d5udEnM{m!qMLwZ z>xH_(4MuVv;?=C#a)gXV)YG)DbR1!+?9S|TjTU*qtzBY&dHiYan6(RBUUEyqxXkD> ziS*$rr}t~g?Xhxd%w?$V%BrD+yRKfvbi)8Rxf9dj_VzDx!`ZS8{mg3fQ|zsz=9d={ z&vl!HVgl-7yG1Vr6if@f$#&Pz<~( z{6o+}w6dHVYGeFqu%(FtO&j75TriRnV^tJxh+T)xD0v|dD74+S4H5wOe#2?Kvqm6r z<#_eJ>5KV842P@`_v4w?6lw<00EpW)+gdM^O)wWbAlYV?k9Q@`2Z@Rh8uASx)-vpG z1*sWB&0Kf~Ab{vrUn|Zc*9m~jsN$^EU#t2PQTFn&wvkK3N*!rN4zSpA(YA+uv(2%XU&_u5{ShbxN+}@J zmjGVMj?sTazLwPkLGM-Ycj}NF;unm4gJh+#0iga#Yc0OpXJBnPwXK#I~ktH#j!pVAY};ckS=IbML3!^ zbK>vV`2(VEpjdAlBuh8#p1j19jzuu2v9r7kfYh(afh;~T=f;xKGF{|_W^mILE&jV$ zF$zi#DPy$e*%kz_1br*1G*9hw6OKflYvG{E< zG4ue>ZT3ObkZ+e30^TMt!^u46H8>?26#=zW#TB2KcKC3G3k0KHoj7}nYt6NcK(e+` z4`Zo@&6uU>!xk5YKWiR*iDV7;-Sf-`ErGp_G3|(!&DyuHbnli)C4E3bnxODc)o6uF zn<|YG+DsHvvJAY(9EJi`FXYp^(pcssbNw|h9kqH4JvPWE45u-P0`2PO6*1Pjl!K?0 z;IAZ|PvhO;;HTL*4*#%38iF}7;a7}w=u)wv zGE-YyyU2XSyYq%9(y0V)dfMnYtxzLDI{i11vPkgiV|`WLJkvb{N?{6yW;nADHhnzS zKE36nd)8*vBYJ?$9aF(TdOkM3888CBgKeuLpeD|Mitqku7OUaLj6n8J>VC)VKrusF z$jFVOlNU0ot*o4Qd>_Qd@ihx~@4WasLSpI?ICWjW=)e>7X}MlKoL75#la^Cuj7m5gmRJj{^J~mfNTnk}$?D}1o@HVUEPs(0 z`Z`mkMy}zLKSng7Z%z)&*qtvan~e50cSR~j8dBY*OJZIy=dm!^}&gGV46h#wlGu&Wp;)F+~hE37OV)o zJ1l-sofBeJaZ?PnY8ESh1T?Td+8Ja_NNk~;d#k)W;_*Bbf6Oov=4f^_3PUntI*8_c z<1lrV$?O^LS;CEewg-uPIIORwLACE62k_WN0c4o!hHpaq(p&+^H8^v6nM|fM(glH4 zw}#R*W@{r@44;^IlCrMTQdJn{jVm>ao{Q-+>-1rb@uyVIpz3thO$&I<_eOVMt$f8| zZTI5!grjC9+=WHB5ks3WFSnE``N{)U6t6mBWquCuF7G`f7X@Qe3(YwdtL6f2$nEt_ zv~>$f91I-D__GoM2xbd|XnIREH}BRn@&`NlwMvsDhVs>b$SyK@tb)vTI6IncXEck= zfmvPmdCX_3m+vuX#9 zpuME|1BcL89$5tFAC|4Zt8(uhC(IJQ8VuT*$w5F{jGCayu~HIm#0l-m+(FsuTS?+h zP4C`A0QWfd6zb=nd0Jw71Ednng1gUYt7@Je)LwC>*CWt;a9k>dnv3^Gk1+WmyboV+ zKx#g;z$X|qc`OtdQ?({C)*~HqA7)zk0PNW^eV!LnQmhYWC4g69p$t34D=-p zkXxZQ-Ak1tPXv}3Qf4!dHG>6rj{DvHpJn=4WwF}aFo>4GJ#SJ575+7pR@+wViiI7^ zC6c=;-lhNS%)eD7LEc3sPQ;r%L9(tquJph@%JM-IgR)h)&|Kb~iVrg7YnMhHa{F)d z(>1uXx1T$ovX<&VXcNV^8WlSlB#D#8h|wI5jtBf)zQDCX#4MJPH2E`MQXKFeEPf2g zm3|eJ3GM)|nF_ydetikQVM`*X2xoBPT*TdSb2iuYHZ7k~+p+&jAcaNz9#b?y{u#VVnj%maEqDT#X{s+dx zZ-D$7H4`DsJ(|jxav^oy$+d?io6(I3_|&h) zgKsLl`kEiOvv+aJZ-V5~W~xBn?0e2ZXSrak39FTfYNaCrc8C-GJ4+D>I2?TLT;$BD zP`F;bKN2lKTSZ7aoThz0=~#lu+3#oV9+eLmNCOnv{ljEz$!5ILncrl|W$Z1rb&m9m zL8na4>nB>ApVowUlwrB6x!;~XrAKuBi+Vp1Aq^Z!zir8P-4)mdpozZ_W2h1B5llF- zU(^J*X%ye%Y={^!Rd;{3Qh$dU+@@=n7(&WPO_5$J6VF-C=x8fX-Rj>Xf`RAF>)B^G zU!|vC6)?M$P4PQw)+fc3CPM@)Q-un-gJA*EyiQEyf=N>gJFV^%uoVyqDHvx(_~|jE znF5tX;`H%|jk$K5R~|M!Dmb>}_D56>t#!tcqE#K#iCe@H3mKOaw`L{IS|KLw=6Qu< z2vx(HsuMt8X$M}-wlw7NLnH7Bl{crMyG5xN=X$w;?)|7QCBhIL-Zo+S)fTH+#lss} zFn&&lbPoOU8;zawV7BLF;(hv1CX}D`Gcl918qGZoK`36Q1JdtYeY1EN*XPf9Wc(uN z^edh|N6|>#!S?pS7v3Mb>xQA+(qWC;Or9kBn~0vq%9yE36MIr?R%EY)I{aOG&HQq9 z>DNup{Y5cTds|%5%$fk3(zol7!>yr#R9QEVAP;%ROj}-qSY+{&d)tIVnan?N?k#pc zF=>AfpK!L+QtMLga0WiuFzYRKo+IRKP2k4jMj~RO{15*CAgwi1?2+f%ef@-a5exRQ zJleO^*brNOq>k9X@Z)30W&UbNZOq=1wNg=yM_V&{($??&8kx)A-N4KF`K>kNLqB2L zqxLtFP*8;@WZX^%vkncSI32T6Z<;BIRRKZ^2Xk=0l87SC0CbA%tWiO&!@qfW>jx<- zOTBMn(}+NsX?~_gGt@XW+z?;7;_nk^o4pJGt?)QDm`#BAsDX{s=`| zJ_LLk@Hh8cze(2TmFBi!9OTJPwzdPb5V3AhAZt#j{@$+jUDM&N>Vz-E)P3SWV_r)cgx^P(Vv%HM=`VTM^CMu(zor+{OvVkuoe;1CK)6xqVpHR$ zri}5Jh^K-knJWQsPrYPlWf1bwmU>CCOE4u^01HajTM;Z{UUY!LosSG-F~<}em!a`a z#bp@CRMEi_*K_C6OfA-ZTn41a-o(o(0 zE)%)7vE@k0{m*F_admiDB)5W?Bc@m^aK;#8CLdaaWZGzqzKA;UZEii7pLLHDP zrZcJKsuicxr$;^~bims8=z3Udb!pIjU5+GV;IIgDE?SlyB790*h~nXuIkhESwI9Nf z2&Wnjj$kN3JWFq4Vc=*2JJLH@%?6|Vx?EX#!zMR9Knk8=-oi0+o|T|sWiTn#B+Pvj z)Vr2J6Mk*}&X`S1oN%76Z}_wJIOVx*>2-a_9i}=Yk(OtVc7#|hCuBOW`JZld0U*BB zydor_u_Cd&w&Cxx7hZPBDW+Qcnv-`-M~~I~>rfjVeB|*@^fJQoP>XZiD8E}_o-9rJ zXy6Ei@PJ0QS&xUI`ereiv?g(cB$qE~cBeiB0~SEFR4@=3=}800{|}(iLF0z@#|Z^k za#;)@OIK)Np1W3vvR@`L+k03rKH<{ zuAtunzAnI~PwHuI_m4*1uh{h_#!4P{0zrVF^p@Ft*g9tozd5|8;9O|R&L`%tW{cNbr(dTMZQe+6oJ7 z&1gP~SASX<9H+~AE&*UsNQjTQ&fylJEQy^?_H^JACP@m1t_s}j-5gS@m`wtQ3vuiIT^X^Jr8$>^;0L;dEe!lPlM- z3Fwd{L-0D>YS;z4HE3h!6-* zWt5I>p_e-F_DLtZ+VD6n0X87dZkvoRotAgy2(=9V)%%#I%laxG8M7=U3paVOnWYTDAtvBgSeeOy z+%Vka$(xB1k8)9|s%C#&-{W?fPRQdWXfH|wMMqsK>6F%T8;{KRygWYa|IV~LI4z^s z9AfKR2-aB9gr|Frv;;!j{Ne|5LgiCKKS#@>E*BpQ;ev6#9#l-d3C-DTCElQ&0_4H+ zl+3UaD?`aeVoE=4i&9;fnnWISG{U9_qwIN|lgpBGOf{DG)&Vjfd}5${&h(B+J$3h* z61Qs|SsrxTUCwm|`*ueXU(KoBiX~e6@dat9a|ezAt0Af%70$_(+b!qcwQ474=i*Xk z15Z3kMnNk@>||c@GrrppQ~1|FF?m!o&)m4HJLmAzH=GVmp{F=81t8-;TBBig{+}Jx z(-ez;R^kNo%gSU2?X1?e^&vc9Z%8@=-Zq=%55`AjeUd3csPp9Lg+@xnfyMef16yWYvT@L3ZY`dnKqW(R zT&Pl%|Abi9<-PaTyIT-JbgHocy;k5V?A2^Xkumix7PM+&9wnXS`wNilB0k(j0JQ|i z*Pc4Ux4c-uPTa-M66i0t44+Qv-)-SQG4o7YL~gQE?TN$Qc6e=0Ur}(pl`3S&~O`r8)5jEqXGD9d!Q!1Vbge{ z=GqH#iJqBKaMcl6?fC6JK(k=14^sUp9?m5$s<%W%AAiJdO%8zwY`MT@N?5L4|fTwJ=Iu(smnUs>hejn(Y1B0zY%)1v8L;5&E~mV zfVnmW+eu=0rMMef(fvj`J}QxA(8;8U0<@R8e6Q)aB<@;`b3K z%t$rYa&P)?8O@BXo4Hrh59JcW-$rpj7gVjzefRb#)!2ACz5XKRM^|||8a^WJG{2L` z+@P3Cr3g2px1I?a$d^p-h=+5WCzu-XSWIV5(CQpsYm;NbxlR>oQC6H%y@nP|fBz*X zUR^jGvWO|6wFnoXB!{$&WoSb|@>#pE?!7Ca+uTczZ(1Ly17Do4Q2s8Yi63H*x#m65 zZOIkwPzO#m@qUGq*KQwiI7kiwgyaGKy zT@p2WKCyB-2}TyBsxT+BN{GcGT58&yB-z;Q8;O^&v6j+w6G_K@X1Td8pXHy z>uBa-q*5d2@5hHVxXL^V70T(Ua1U}r7~(9!Fk8&K2}cWUm?TZ?VF(OE{STsM;b!T^ zCbP!{@&-foNU)@m-1TWDi9aw$_@#aWXCPv~F2`kKKu!f!vB|~vxtmQ{@odmDVtUTR zjF+zl*>2HD>X8M(aq)gd0M(BuOV0L*Zz3?^ze`PJu_-;2bw|u0UMv&P99;Y8($ z;`CDBTXwL{Wv}6B+lOg6U+PYvMYT()vE?hZkU)6jfNTxKBA!DK?m_taTX!c)YYlPf zCa3GbPlMWhf1{|qZCih2;;EE%*l{W4us8yJbnR2%_*E~^1^}-t8|#L3Z`C5Eo(vnr zr{IUdaHC$9UpPQX7^v^3!^m$)mZHJf&3f5f9Z`!+N{JmY?cX_V1e@$J@(xD_wp02~ zu&Byia0;z)f_JmdEs;P83A2p9@OISq<~u#XL4DS zX3Pdg#IyfTA!tX6GR_lG{yN~Msz)!v=;t4{?GH>q701>}}J*@r*B~(-&&d_W+XW zcGNmQCSd=@@k+m+nkCn=TrT!VvqoQwZHOF}1d-;DaPUd%9^rt<6)B7OX`Jb11KjE> zlBV2uGt9@FHOSyEka!=Iv`tt9~k5pEb+-NNZo1HVD{B%%5DT!# zgVGAPLyIy2>Pt+p-^{fKX=bzKy742`c*ACQ<=c8S#H*@52wE!X8huK+<`a86uN6$m zvcfy6;wn-5L$@=97GJz#b!GbNy6Of+|6*vtW+b=5#gKUN)qpUTj`AFOx8hh@TVnPm zg@G%ZgdDP$*3Ip>7Vlb1E?DZ+zhq#hEf>;Z_9`MYs{>iqQ+HGgYp$p}6aM6lYZl|y zx^tgX+9HboZQmW9GJ3HV_{ulfWmV)}XI9u<;pdy9B8XQhW3n%#0FAsHe%JZQnY^>1 zhLKQV-HKoM>b!qcc-;~^Z*f$o8}g^wXE+%E71?GFnLgy8DLsSwgC;$FbH($6B&#{V z=w!F~r(F#B-5}~$k?ier5d=~Dz7r5xZ{y9F6kmM8^U;QawW|I0VUmJl{RM;aJn6mU zy|Cd2V!e*-QJKo2bz`!DOKi0;x|$-weSrq#^;qI)NswsrHnh0>4X9e11|OPzFNxU)51hto*# z)%>3P-Qq~98o+P=uK)AEB`xH9P?@O}>$)m&03}{dqCYS{mzM!QF@B+j_A+untxJpU z@*>viSvp#|Z9Dy2a(q$}rZ)ZuE?BYxil>*gaLY^%1m zkuIPK)S#6}sX?p8W}Wn6clve$q~uh!86jz(77bfE#lyu=@C$$IxP-Dd+GL(QBBPz^ z+a1EEp5=_I9iL`h4(=E;H)C1fV<1g(3f=j8v8Q#9{^%>Y;5Zb87&pd=8I9^5NQ7H( zWl&-n9F@$-`0h9rHg*vgH9xjL|@gpd5$JOSA%9x2C7Xlx=YCaih|w3DI~R0DNv?Z43WCoV1% zCQE&#b!>>UKl%BSlKs7exuthj5U-(YRIWyEqDAY3O2Fae8t;@^ho3{= zvit`b$}cs-&Wz+|%3igLzw^o0J=`6m@?9i-!6FzYn>4B<36*j)M)~^SsCLCC(=@;F zvF_1y^QRlH%U7cvzw=ZUdER?&l6@#-TDOdwp^W(4*RBIdU#b7BKH%xG4#J@gqiBIAO7{5+yeLf``H%xAvU?3u2 zb+nT}EsGWf3TprOlU1Z-xGe{=D+xAeAxBvBYp7^f)rF+-GY-Y{&O9+WVQ;dLZsWLe z`<~@bB+|jA?vekw;M=^Iy5W2mvViP4@$YIOQy8Mfgl$coHZeBBEfi>(S5m4jdg|I5 zHHT#LhPa!&we}V#-OP2b>aqzUvgP*y7U`ol>%q&daq*X)6e+H7`fNSv*^6+Mz&@n2y&23h9)z zmyrawVAlR`{7NMjb#L;Dlh?k-2YwDyOQyV{JNdLuzi1GQtz^2G+v&p2d-F&tMlwt+ z%s#>>JXxwSc&9sPcfN8M8NpaDwE&CpPH%|V6RVLi4N}N9%)OYI12vzHd8mb6Ab6WO zGvB(-Z^)9TxP$0bcdbYNU~AUk$o$y~O^41uWL_m%2&>vM%tm_0Ye`q9Br1}VVZGbF zRPeZG&^7WnR(7cf-?$hsd-o6(1oju9mp&ir849!R%r>nt)tXqs9J74E-$z4+Mv2uJ z;%#PF)usWGzcN0b8p8+G>7+4w+%9`Pe~s!~2{h4Z{cok`kekybT8MlE3oTu=;vCMP z%0my+ zIq8j81M=;p&0`Nr*PFMY#z`PI?$VD<|n z2T08vd}}@)(i<1GO?=ZNY`&d&55GD#0}ZT#J~76VZM&di{fJZHd^Gwk5NX(j{FOXb zZ$tQ-Kd+4Dp2U*H&{bE(Wt}~p1c!_sCaIQ75wsp*gWX%J+sd({I1=Nvfvau($OsCV z41;XDB^mG@yevlznG1v^e|p4(xVwV)2f?}vvHRvl6b0G`Yefho`$SFxmn#U}zrlz_ z(GsG&2zb@xbgT`QTx2TWC<-3We87;+AVh|hu0{O?jfcAu!Miy6%4p4X+q2nXtbJB0 z2!Hy%nptjaTr2x8EF$u-l@J>3eylS6b;7o*wsW(rJnBMd_^o(n`1uP2ou3do9g0pa z^2qi5tWGXma8M&5a(|xQ+>Z>b^v%A3^|ey`sNT0Tn56(Y3(Fb_;5_rkpY-uCf+^5T z{5zY@s^(?8|Fi1D;xEMx1TqipYie!4uZLGfa`MWIMeH{b1}NDzmmHMsrnv zAeWEIlA zX#}Kik*KQ15VTG?k{|FUWdE?Fuimw4Dv4>UP;iu^krhw=taYN?*jX}C;~j%ipQZ7dtj z1}3B@@o95WpDS@9xl;R?uh0KOd7^$n&5!968I3IYFlD_Rc<||WY3J5byS!L~B!UWH z$)6txA*$VbYw3o@vrVj3&$dI#x~3jeR5|WceSJ!qi~ocFshouvO=5s_`a;*6L^d+N z@x1Bk5`N)Tf`Hcswz?SYaZE;OEj})`(w~rJ!7*%AfndSHTN8hyVs3BS)Y978`7ulz z??q^lpZBvF9T0;mxM-Gl+RB4)ppMHwhISHTvVtr%r4T3;qE5jHJ;>^okaNoV(^_UjBCj#EeUyai z;#^-xt0h7xHOyDx-Zu4osQ>Ej?yX&eg_8enf$uJloSQV}(Dn(=p#+SRaVW4DH5xHh z>3=m3b_t%dr*q($oL-;cxF_UgD`!f@?&;S4@doFQ%tuTAldebS&;BS`aV8c84<_ue zEZn;olJ}^LBKiWNH`@sHjzZlhC;+(DyuuKPJ-UM+I@<*$`tp{etZF-;i?*Qek_xr( zU@`lB?f^5e$%cpf~ov64mRIR7}8S>hvvPV=Q9p?F9_altvW z1RjJ+(MPDsnnVw-!uiZwS5CpQ3xZpx+16Ok!w#b1tPqOFM};jmoK#r&MK!&QCWs~L z*i&KQu*j9Vy1*%4LSG_3?hw@bol-i)8Q`xY7tm+Q*xUr6*mf6sD&!&8KfI-1kZ=NH z0*}_vwO_CP^)2rt+kQG~?Qy?KM(Q2Iy)QO>eoM5Q^;O^sQjma`BjH(*rL zkX3(bJtDlS+KLkOv^hlK7a&*I{_eXi1yN0*#0|mSr7&B6vO4#SY)(>6pA>uD4^AVs z!MXMDKYHbiC_uc=K~+iZsCY4edLs{gs(NJmts}KCJ22a?VjNpf)U%5l?dx#uX+Dg& zO~Hv70gm;h(1hX~HUg+3>x7z|l?|D1-<;i#=`A)*L@J$quwI3CESy; z$KqG*4s|V$hJ`Is%I?2KB@x(|3H7G);)S5~m&)TJ%p<`H6C!o{WPpBi;V+odOhZ%k zc6?lfJ(h=U5|0eXyivlhYuIsRfV*F&3uY_)Tsa1sh6?6cC3(u6gdV-Ysws6rSz6PT9Q;kDT|f+%;;R9q|FkeUHR<>H@l=r*CVy5lTt(6}|rsoS$HoP69V-F5DQGE1a8=(t*2z6&iQx9MjyJCu*7 z+m{FZ11`cKfptV=+Gk+LX-1Hl=A*P1Cj{m9igC`4?Wje|MploMed=d)wh6I*{kxZ2 zY(~-$>_~L*(1^`gAcME28AH@ao~Gch;qrlCK{=GT*hX@w_tw)N(gh2AOEBz0Fv%Vx z2w($4w^*TOsv(KRdXg_&s0IK@4I|s8YSA}bwZ?U{ZECkhJ z9V~a!?SgSUZvN=#B0`@btN7TA&T16O+%j5Wrh(JK0FK|`4*M;1)XWnnrNYhnj1KD6 zt)0tuUK~8(1=WApk+y=&GrV04J9~y#Gt={6O0f6e6&K>Cm?M@+fO7BUYthJ6zEiSJ zt@xOcrc<_9Z8A!19C%prmZn)v^Kj=poC*QbW(8O?&i}K-O*8 z8dCG$ZKjmQ5C35U93Lgcp0vdbc znrExke;OYYcu~gz^*(DvG&p9!74K=ddx`LTd~qcA?h29zuD-akOX~`EirPx+-k5&u z2-Dz}DLe*^P5|gxIO9Zcuj1c3`ieK7ub3Thaf z&K6_qGEQ0W3D4gwzZ%>9bJ))i5~!QPGq-U{U;#m0_FqP%7H!T*`HgEvY-G)3(Kwns zNF!1iS?1cmNl9a>a&7@^9z@}2mkEiRO7G?>(Iv80t|DT!gsxrjr6-2^{WY0!^-S)- zhCxPwaHlyD!`(D7m+@3Uw9RwAFS^g2$b>8MSqNI*RiXz&d1^kxV5JJbNn@5VmM^Dy zSQr4-(2B+1jIsNu)`u}?&lb`8cIWCU1sl~pnn1Ht#ZC#`)C6;I%_W?=ch|HN!~mRk zzJY!MKP5SD_ey`BC+LNQ`SO~F9}%G?D}E}l;qp!LQ*~1gN{-+!S;i#B92rHTDOBei zFO_u^aF$fmt3Qr|x9M^hN01S|Y$k~J`juYj5-3%~*TAO|_lUTZ8I4eV4}ZnfN-%M@I{xeaYXSV9NcKW z@QVe0@DJDzQDO_>E(1bawkR-Omiu3vBaXBS9otH@9jt|~HhmTWxK9dpPXtWaBV{;2 zq?RlzPadiDZr1I1IE-bCKsa;ShewnvwjeG!{3^5ZgSHNYR|5#`iF$Xrh~1sMRX0hO|d;r%~dVf=QMbw5`^u7lNtj7_w@$C zIMku(N75VObJGnMXq-mfEFGA4xQ|-zh`<+Q%xe%mGJ9CZBrj`f~a~?3TZo_%sc`UYV-k(xa^NS z+Z(qwL~Ri+`|qf1^PD6!;!}!vWrcOfH0%dvJ*4%U%!+UDL0QHLA!E|vz}EF>Gil1e z9?*hGDy!6}p4zZK0`j}7f%OcOZ(tnJ`G+!o;&|ZllHsLe4?r(sKMYxpRG30fW+e`2 zh2nj_I=OZL1c=6jhl|4pu7dKEStIHubnAgiqTe3#9QUHw&L^bvtg#kceCNpds(Xv@ z&B%2onx|rF6DZHb*?U3^wa0CO`U85SC?;GzrJZWTa{CM;Sgi05GQfH4Q#+tkqh8^k zjCldGJ>is4NE0exsANk1Zw7l6b&-+=*nas#;yhqUPq0Bt0%jv#Ak~3@f$0t8x&~(G zjk-QuM<$!Wq^fl|@4NR$S4dvA<$r+tXWP&fC{IMpM&MN2B>dlO$;~wijNCKnQiql$ zg@Ce}1NIfY`{hRTU<-+s9Xpo~-ltbJoDPjTl@DgNui(N&ZJc%9C-!*MXxxs6PRD*V zi07PP^>;SO3_~xm%xWx{TIgr;`ASfbxmM_VU#WgjC&#rIutv2Sk~}+Y`{!`kwjTgT zA8}-M;U`_iL~KwRxBt2EC?ZgrB^{Py$VhpeK0_kwXGtNErbxSxYULCQ1x$BJ^sRMy z68ba?3hX0V7%A(8vha~Ps24j_hhyEg-Un1jsr7JlHIpf7HMPJ!mRGlCiD2Upr@X5AH}~t&b zCK$JlMoBtQDIR6Qj_{5-OH`R_%7y>3x@eVKg$~1z>0`(;ewNKXi;S)lI+->1<&?ji z?hz;qU=DQu_05EY3a?9ZuIY(Gmxod-&tMpeTpNdt0jcghC)F;0_9s!N&hZdcCvcSD z=x}y#PriDFC{-TbGb-l&}1Qp=U^1`6giiC zrkV911HN*xFL)i=%w{@yMTX0&R5Y*S2_;hXBDAoK#QzRat!pji^!OI@vd8LLjP`Dh z?)(^iUF)bAq)957Fa zTd1xN`9uhBO2?SlFD=yZhz?oE`9fA`8*`>F#2*!K_FMWr6v`j_WAZT=-hY8hcA|L` zue6UsD)2ybCrA194TDix<5J-r3-QkrvQ}^-(+gdqc|OaDiYLGOySrZDNjeh@?;%a*xf_(gH@on_+2;A48qE+<<``jaK!bYm5Oe!1!4b;% zg`U;qOjpoI$9cY9BaJ0NQU(=9V|^^}H8kARha!QjId7oiK_^Z zN9;My?OS?S5__HU0CYl_Y&yyCPz3FK3Hf`o;>Q0^dCAZ*0UxQ8F3owQW8y=}s_8oW zqu1wkTlx4B)#?7FhK|R`@hkAnq1B?Td~*S%T08sAZFv>R@Or39bo&g09s$H8@)S)x zFW`?JcKLi8{5({c1Y8kL58RYC`=S@UBc*CG}X{mYZ{Se&sbCy6S{YZc` zyZ&9tGL|dbSr>1mslE_%lAl0a38wS3uZ)Oj&xxtk{mkZn3De<8l?= z>HVTXU~hFh$4BK64SjNVq=q9^v|!71S{BYF7UywVlBXS{|Ay3auRz0CnjEF}0Pa@@ zD#JF`(X2F1AjEqh^q?n3I<=PuH$idxe^RC%L;sxVNF-|0o26lsB-FNnZ#q|RWK&L; z9KLJ@V(iu$s*0o?up$z6!x%!~FI19-mV2uqVr4vb)S`VGTd#tN>?ubG-aFK<4-D@a zq$eMQ&SO=R{fpGTUYaCO6w`r9=0EnwEULQpSA<__70U%Kd|MBn4R*-8)48pa>9KYVKlz_ACxWzUYs zh37e!VTiBG5+oE87R|EFhkj18N3x|J?Hsu&+$G7XMjQ=P0Z&85TJuN6LY%$>*Q{e*-<@Eicpb1FIe;ieE!(w*VPq zuhJ%#37XYg&Uk>DXMpP<^39E=!^@>Tr&dS=9w^&ARFHq)X_hu&O0xo>dQ(ZjQBcxo zF-ie9Ak98|wj=+n^9@%7^V%;|2)%uS@Se1_!mIulH@!j6CgA=xx^%P7%x`()DyDDN zC&jI&ap=j^QF`xh?JOVSNw5d4OE)*~baN!C{JB4}4TYbZhE3VezY%~RJ1yj-;W#MB z6I|@}Gn$_-eHRX`j^8lCQLPSIR$OilKt?d#g%rVvm&w=|Zyg691#;=m?H`+4X-_pwAK&W_`c zoSc*310ez(r=~mp>h4KOTs5N5tMgOW&27NVkhdium>+rSb&Na-g}10{g9E2s`NI+O zNNXJWK3A7yx}!D-S)p>^N_V(fwb619Ya#c#%$6|IF2vwT4P=Z#4G9$mUbzI9%;BDb zx1H?u9mY^7{oOe^udo)_brmQvcV@pU{K{NNJ=#*T&#P9cPB99FuBH}UDH>M(kbZ?X zz)lrC77Y8BA;Zb3>bk|=Eq30db*OL3(Wofh|2wObguQS-alHTJHsAS@bdC3MYYrqB zHo|WWl4EX6fBwfLaF3)yRL8ZNekx9^g!1*x$>NwQu45!V0jMy`Q`GH-h^&HF7#uq+ zVj1SK)lGs3qvVyLhH|rQ=-iMhp`+e@tH$G5C5!C_P=d!TU*VK169aX#DIwKiRc*DQQE zXJ+n$^`jD8t1}-%m9Z1=;;@y(p3OSotAgq&HFn30ZYzW!9}U2q4L{YU#KRev8{IV2!7|L1;G_E6FLnx! zbus{ROd!7@2q^9jXlUI=O_Ghbj+h71>eTX)Qq)Ab4~ViMfgRe2Ji@ z*sSR(fpWdB`D%|e4bm2Vm7_4msqu;UrvxXu=rZizEVc^dpnZ`z=(!Pj*SGN7FW)nQ z(Hl7=OqEoSlV@RXGI#)rANQLUzk>P~Ac8VS;}gRbFCL!7_zbIZ4F>%ww+#G!nV>na zLz2EqH+QJjzcr!90E>bA$5d7O2KIJ&fat(i${`ZX?3 zteIZ22*>ZNElI$&b!YEbk(%Jp8GaJ+2K_jW^89P&qsjCM4oao)R~_Rfao`s&$+{{z z{yvIzZFUFEL4JuQk7dj*l&xeO z5lxHZ;lD?&LM-o@PF`~~qII`x9==jNL zrD2g1OpD{>3;n4)aZty#V1%36<@;sDlfsJdxw;$2HWUL^qV6{4X1<)q8|s~v9pH!s zYV~RqFWnZ8odT9C{miV}3m4q%fX76aT4Ob>ZI|H2g#b-qD*XEQV39>ay+h{mv-2Df zA76L7&gZh|S%7$klrl?~bfRc0m_fl&Vr#?yvQvueC(tIV(_(m^?3)%Jd-|)MNr2!% zpV+x&?q^1swDZ<{OIexPa-4xymM#d4Oy1gmRzC^=#?gCURc_%gE%-ccKf#>l6{_)A74WGSfog9|7D@T`rKF%LWydvfrZbzYnzcO!L z9g=|=OOW-KRwoCm0nm|WW9U9_g%sUd&6yz@5%t{yXGXqIkHB#mY_|qMZQ^r4r;!mM zV(LwDCPiMPmJT)?{se=WA6Qwl3mWyir`F(Z#<|A3wP3tShr6iFrYGe;3{l^3vvS0z zB0^k}N~7%z%dfk4C`7|Ej}3!7L@{#KZ%qYXKFRER;Gp54)7YR<)-+uZyb8dzTm1)_ zWqQglxl6m1$gFQ8HSAHrDFexn9xQky$r`G=Ce(@|%-okh8WFlhFtLyvv#8Yl>kyS2K(GV65C+P&&^dCisl2=<=qyLr63IV1o<*43Tz+P5&G$E~1Kfu= z^!LYOIK^}gPkR7)))|}VyJz`3eMP_QL!^7Rbj+esbbcYoOwa~vj4-{)XJnJCct_g? zw94fE1KsvvA1YXcKlQ~MuaWXGNzoD;a+qYtxSDaX4l6e#VPQJGcigN~pwo;EsZSKi zRfYHTx-!jPe7PlzdqxpVV-^d9=;oEXlilxP*)CX({9T~iWB`TKIfcBi0=ddHiL56I z(=a|+j?-v)2pEMu)`geiuNFh`*>G2yU}l zDf>j`@s_|Wx6B9d+L+6kbnqZZT%tup$K^ zlb~Fo{O6NRl9j8Fe{vZ1-5klhTUcCcpv4@jQ{knR>=~K#B!+mHQW*0y+sq8>UJV!(v%n$T}bE z2GHYGN{Nn)$WH@g9sw}i1fx-m-`tIzl`3F&zoFl_+)7-YhnlKdSHiGj%Ygfh{}}l5 zC@c$&HcS#wQad#bJQN_CH^^#AkCTCC3Q}8byT^^i@plwRx1ZnI5$#8T<*Vy-Aw2U` zP&cShQ_d+Z&P;l2g zhQUWV!tIXZZ%j*kWvgwZ-VHhs_r6Rg{?26b(-io~MZ2^2CPp9~SwpF8Cv3?K8e?-}Ify`i)TstnUNTgy;7Mqq{xEj0v7BiTJHD4@AOl&cwNX{B)??X=p9lFQ42KKRJ+7nyX+G}976oTml1xWV{>?8ia-P2Y;~dDc zvuE3iT8^R=C%Wt|lJRB(M>oroE`s1~`Tf|G30F1~4tkYzrVxQ2UXRfcWIQJ0oDJ2r z|JON#+tb>ygV?nZA624_8+0&dru9q5l%jKYNiW2g8l~Ydr{+Wkvw$2vPcSV`BK&Y! zk7o$s)SWRVmxElyNFD=)%TgcY5fIS4 z4Yc$@GHsKOj&QmlY|r@;@j=tv?{6;!GnDRXb>7+2qmzE-ic2p?7wd8$oX;+|(60bz zUv%^@W}a5X{&!tF#`E=KDhvtRK>FtX*$%NbyM`Z9@dx`ozp{EOjflrCLl&}yl#v%3 ztgzD$pK{F=@I`Ls3iCWia=HZfxK?RdC>&E3{N z21&}|!dw2slUD;n6T#$3!j;o+)ZVG9hp<~WaFpw>n!DBJicgU0S@Hjnc#BSDGY_G- zMT^bx+~nnmuEBy=@*0?GI8R1RA8B7Hcf%+^Oxc84XM!2=xp4+5-|PQXhVyZ}k)_9^ zyXy_)CM(Rvx34*$eD;p07Mosj`4N9dq6!Q}CANBpG|HCCC`-uH0*TD$#`6NOyA7x( ze?LQGOiR)^*>Y2g9DG^IMD1vb7dNawcIuI$2(z=ALNAicTqL`}-+s@zN=p$TZsAoLc@CH{zUgod+WhORP#lZjX#4F$*&-_>b-%d+dxv7Cn#9~h&OxovX? zle+LPdX2M(y z{wzEd0YoFH4vB3sRo3*Hh`lqUPpfGqIuYED?;se}@`p<-qKdfouPY`1 z95!9VkyNPGQ{95##q5m5stRN=BBp4Fclb@19fnC(MmZLjlAcrd`I$a48(U*tI+66j z3J@NU%^s$e#yT1%2zJ$O2SDQ zW`UpL`hbCMrnPr}H%f4XDPio%Hzn~wiYj%3OsWW{VWsm_pKlB3z!T1zKEG}H3lJfSP-Iqn^TPj#dF^wnT6Te zgDyo3>UPCYSz;^89<{PNI4Ka@=*?H zQ--#9_k+V8kq=%KEtlv}zk zb8yOLTWtje8)h_B-Hg^BN?(qjX^>M!!wSME&O`D zxIH2q$$<#817%c0*I3C$#q|ayI$iHJ_yV!n!sn^ek0GKDB7fj+@P?tK)vu|maAL*m zo&A|TDoOLW*nV@!)3v!5k)GOtnvS>rR@}i(42k}7ca(O>5DZB{0oHavOd>Wp17@KF z66P(E-wD}NQ3x^>;1G|LB1gZtBdZ8`9VMe~pqs7QM%AU0(loOy6v z0ztf(t+|Jid@1@B*#s?l_BxOxS{;}o!q8}RPqP6ibUNJq%$GO7X_V=IHrncW_uYEZ zgVl*VEqHp=!6C+GWVT>NCTP-c_@rgw{)}es_(L)UhBf2RE4Ip~l_Y9E28H8hD&}v9 z&8SXa08CSIXtIt;zm5H;=Z3%+Byo2N0JBS{uubYkD#z_>r=z}qrm0Z+S*HpK^9)+n zRog3NxS_Kms*WTk^&zXNeh@6*`IsNz$KZW6l>^`{DroZDnGKo7=51;OpUwT@Y&=0i zcE3j5Tw*qiG20WEUluA-QpLh2Joa%siHq`_IG%p(*1r>2z2cY|PY^jCt!j{OZMAK| z?`SuVxCm<3IVymDZnL%m(H_xQEX94&j?B3V56megxq6`+dTg4;3352u(7$3*iARA3 z_L(Ak`Kf{i`?%pzYE8Dl{Sg45{{cK14B5J$#(OyxC0x25}9wPoZ(tQ_JkW zMA^Q(bApOnlFv`KOxCs3_fa5XO7xbT00gANxIA<#Jc9(Zq9izjW}qH{OPWm9B*U2; z^sAqhR-u@9^__u;Q(mS&23&B; z3uv~0J>C#a*vq3lx}C0OBjH(sm^uYE27gh9kP5m*TI1Cny1so^ioh1=GQZ}E11e@h z7|b;n=gW!rtZtRt%i@@KrKL2l@`pV$@cDp~l5n5bI$gg7_WWDjl; zkb_-h*zIBXzwQhDK|L$3d>oA4fC;PbHlh6u4GRafEtW_Y`=*P?f5E`SI=9b#@o7X; z_j=-!#YF(NpHRqhI zRFUWjSe(?j z!;vJ$m7S-F{E$Hb==Cxgxj9*bD+^%vk_o{MvI(Q}yqvMx{uAoB-W)MsTnaH@32L2N zv)akJBwM{fYBFJGO#Ikir-9_1I=Xjomzr)P=@W`?NsIKM#K$(SL6fIfYR)-xb}R?R zyy&bF7N0icL)LX`Xo7rJTaslsT1BRArLZ&(Szely4sI27xgd&$-o!2yl90Iku3qJ8W z4^{x=6o>|AO_A9R8k4BHJ@)dJ!sK-l8;o#SP|_y>0W#{P75*Lw41)gbyy;4OdOtbV zxCps7sb=L>GW2o&v;N({Zfmt zYzqvxx+VYQ5jf}4n%~mvoI|nb_{Qq@T@`yh}RwlW)3zc4Keq1e;IPj?3rxzTDOS2(~FYW5`A^^nc(M5tJrgr_y5 zbAX=|XgOJ^7lFMPv7F1!r3T#mfcBzSfrgje8Pv{I3939v<(U5q+8^XkLv>G6l<0#a z%iow8n`qMwVKV-hq-;A~D#*hnX!uKJj?$v3->KM$&>N`6e=d#uSxP> zBSRYI09@>OTJx}+QnP7i{J|v!0MrRyv$sp8&~^wQ4w!o=gcReUzCoc$wGNMVPI4ID{_8w5;@GTka&zimmb?KZiu3MIfMIIc zQ-dhxc0st8Ww6fa!bLaZV?hdG+TFS|+S$KJ9>_Ky{Re z$$Ln|DRK7x8*5Hl46g)g4!H2E(x<7uty^X0ItEy(L~~GDpn=+uMO+hV z4)4ZcAK9rlyQGBCFjn(S2uNT3aMQtG&ZjfLDw6BskAbQeOb1vjxyHKzh&|Z_p@B;k z<-FM#VEV&mD`-v@1D|f=SEdmXapYH$?$|Tm{y~#i$fUjp8HO}4uUSrSo}jW(4qX@* zn+!vL$>WU#^K#mRjj26pRkjT;i-$_If^)|(Vb0$C(j6M@wDq9*!q5m=_@d`N{BjA| z;ZV4W<2JeHtAU)Ug{PI~K-npXi)xUryp~62q>dOGQ1L<20PugUp4XC^7wVUlR~9&p zyTUWV|5B`yN)Rb%u_SPGE4K>Yo7rm4$}JL$Ad=&Z%872$#wwftA4hD;C^5zy|874` z2>&AtJE53K-)6n?u`_7jGS$gwopO&Y@M0zV%1rzbvxeUKnYgjPxM9~kuww8dZG#sl zfnUGAroE(XHJVq~o#|-EoxLbXPvJB5x`}<8Qef8GXP@hSPw96) zb{Ctn(s|L{u~!oy*+z8uwF|a@C|3!vg6f6}8+=?tI;?)y0i4S_UE*1Xrs?t%$BBRX z&4jjzlpe`tKm;qlhxx7$KR)`Ye@eA;_|rW*7HR~TL9B*9R63mLh)7I4a|U{pZ$T0a z?m47;DS;Mwo~3K96lO5I%N&rFYMfw5*{9xU23*h1qDe>h4)` z+o7rqpS}b6AF$xz5>Mw5vO~GUK^MtoAUCN8cKn^iOxY!eGu-q8iCpKqLPhB6^)X_D zjvUah053q$zg6OCETVjk1pv-NHGr*OP1nl7LLDqD{3e`j(GQJBVeT9il0$zPWe~5k zl3`21D)U5zI`wL?GE4U;OAMl2*WGAAw&s}F2CxP)0N3~O)~-P8I+&sb#HVh0KDLk`VF$WeeYs;~t_`Vo;zHqIrH^a zoHa*Wmab%D@Fc}d$5vc!U^W8;@p!|bVS4S_&0YnuW%~9M)Y&iuv3a~RSVX2jg4DvO z)-oWR&vyfF_LxAH%4+@>m+tfsHhiYtD7&po#GcY|GRUG%g^4o7@~wfQ=GuQ{>4k=6 zBu52UIM@`;3kb1bdymOr;wmTM4~wk^*i(!N)Bg^3l#1r`Q2uY<2^#$oaw0+4#`R@2 zyenH%cS(wg-eYn}R%4bBLzhoL{J%)iZ~{f zSF+gQ^}A!C5h-zi%G%t=%tr;z4Ql+I7v3eKGxmDO6t8oNz`WH5dn%W~8J-P!`TkG8C3hSeci;>b}|Ma!4{s`C-egSWe1(Mf%cW+ZA^j<|EyaqDi+MtpjvhF9o~=b;Y!XYnI16(xW^GGHO%eY1LX-h2DDFcv z!n}|b6SVRPfZpj4>Hk2gO71NqnGA)fldhTuIzbIBc9w3eC2wwsL{vLjYR4E^m4-1x zZc!F+oH=_6%i zJp76;OOOE2)#Pwh?t6hL^~G2KbeM8NtYbi8 zgBycP3$K%rwz7EE>-shRcqcz@o^Ur5^?Wy?4M^#bpRVN`d|Ms^*MJKXsvP86PXNEGwzz6`hP?t`ij4h(CI;DhS z8_pIRBSTl~6}j&GujEhAas0E>Wl?11@Yz*&Nv)T1{1|hS?P@P`DI5*e+-ZzhbBz#4 zeD%ua2|VyguN7`aOE*120V2V~*95a26t)LT=B9M&dF5}YFu+~cQkg^=yyqvLUc*rv z7^ZtwwWiBuZeRHy^5nIATCzt?Y>0`<#?~o0 nnwDXQ5O1r6&QEEW;npLLCNf-H7 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

< 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

nG?~$}b--d!}SQ`HC2}FZNKR;*n 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

  • j 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 literal 651664 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 z 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

    u6C!=eH;pQ( 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 z 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 diff --git a/data/gwasFineMappingLbfExample.rda b/data/gwasFineMappingLbfExample.rda index 19d08d1c10645e1d944b081f6dfeb7389a9ea5ca..c6d26042f6a3efcfd2e92c0faf9aa0a7913a987c 100644 GIT binary patch literal 41292 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 diff --git a/data/gwasSumStatsS4Example.rda b/data/gwasSumStatsS4Example.rda index 8a24d96346db558fa53a0a2bc397ae1b3922e7cd..746fb08926a09aac7493b7575ca1054504cdd7ba 100644 GIT binary patch delta 7311 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 delta 7306 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 diff --git a/data/mvsusieFineMappingExample.rda b/data/mvsusieFineMappingExample.rda index eeae7d4e632c43ef5cc4f0be170a0827a9bf44b8..bed0b42905d0e713f4882516de1504d2ee5ef7c0 100644 GIT binary patch literal 116924 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

    |3H6gxm>Iyz)Wip5L|lM$ms#fn(&{2Fr6le(i3 zIA`MHt6~sTpt}*Y#e>=p7V3&u@gT1Y^tz)Mkr}*?3ox7cpomYpqqvc<^$3 zYyIxN{L>9)YJ^>D_HmW^FPCx`7^;pPw4{FE5URv4GUsZV-V^A;p-z0dh z9H+N$D*1xj0$yyVAnjCCl6vl{Oo#)Llr25B)LGkRbd-f-%(?!v2TGU z?45)d*wBXMOOi2%gQ~DsykBYqu35kYqaLXU@gQXaE&mV}1wmMYOYW4vPd}Q_|D^rj z?j(3Wn$X+j$lLe*%_X5#3_UTAtv$Y&K_&lUmkJ(25X-`DR=xdEZVqCZEQ zNcR@J9@t9PnF&h|-IvkIsxBz@;-9*488zk@DS|@KIVYxR0atLx0CGXrV1m!h1BRh? zXEKAagW2mw#+^>JmTSU6z6HiO1yW=Omre$e{?Gj1hTi{4&D(xnR`-M zh$p}9ZJgri3nR<71_$W93mstG9PbGP@XN-Y{Q2V`y7%Y3t#okIyVX#z^`s++q>lkR zlh(@ZWLemxB@7+GOhqxQONk-nl3RnpG~tFVAcD~#I^LwlJSJCKEWFr-K{31OSSv8h zNuOu^77$pi<4y#WLSmH~yudF9$H=eE7P)y?R)o;~NoqMTPLt2ll-zh84Z;q=z->{xW>n?Hc;#QBzusq|!86eyum{osXOPHLY=*DzB3VEG z#>AxQe~3?jvjThsOxf7l++F#arMjnxAysxS%(K_QrE&p$zz_@of|Wp3-;zyAXQZ+k znMdLjZk>-!f){K9A1j5Bwp4^j--_G)B$7PziitP_|A7Uz=Zd(9yTQ*+1;^J&1E5s2 z@8FZ?PDh-QJ9JTGlg(-TX9lKyU@i&`ZS=G64<^Ot6x4{5xi9$|JT8bOdo@gY#{jH! zzFguqJjTTV#VilG+*`_XMYxbJs69&U^}usUmmU0#YWWpe9J&52R74!sv?HuBil)2) zwN8F~Qr9yv1?JmfMA(_i?-*BrX3!;JCEjRw=z}X?V9G09nMT}oF>N%Zu9TgAb4`dM zKz80#dmrw3E6Gz$=gKw-tLR0jx(AW7DsnQ;L?ojxOkj)?OWvrU$qLBVcN-1nt2*%A z@Uyx~4iXyFOwWOujy1w*0(b7rn3hk#pfHRYmQVxBqUD;nEkxxx0>cXb?NlVRRMSs# z%poD_o^v zs9Lt$AHjP%c#+{;2d`AjPfr!~7JQ}!M||Ypb&mkqoyocId3ncieo=MZdJp~;2mA~u zjF77D;bwpjhi~p3>fj%9;8i<9F0cZwJixGA39{Gbn6VI&t zH#QRsgNwF?)xH&Hdfg9m1L(?Z=7hE?H1USK9GugvE!#oymVb`8N-IQPr{g2TGyW6a z<9}ZvR-x4G!5DX$)P5vS|My%s#FXS3l~es_W$@(iHgd+fXSo~l$~USL4@ysA6%Q*X zL<)EUnR=@58iaHYm-H4L4x$pGjoP;HtL+pWEJ>NCy+>B#xg+ZkIzZ4870O|Z-h1X`LP8OZAwQvwYo_g zwH*9MSukST3>i_7?brTo`Ht5I%0q=Y7s}ekMw{82E|4oxv*Da- z;nhgbRZ(s|bL+&EP9%NG4Bf{|>h@n~fBV4qcNUc~f?~{HzM$xW{jW*4$Ubi^{h=n5 zJJLfa55Y_2#8E6oi~Wmf!|~$ nKODm;Q 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�Oy~?o8pdo(kH&mq z#F=oCdQ=S`sle@8AULzq6h-8)uh@a@kz+ugKuW~;$S=?f<1a)+3)>W`s^!-mHiXuq ze`Tq^OPxk!yA9=iHzZ?`vMh=DOZk4V^1eczD_C)dANk!)8{2n>m`HT{-hK0rdUTv&{^lohS4oh_Skb~N)*|;pO;18uY?&G8EL!H6* zu6yc2XG=-(xLNQel}^gTjR%JnveQ?QzRM;7bfk2fqSx80?KBuSoi7`ne<-l}F^&j{ zXM&~|QN?k$my_kkL?JpF;8uW+LUw*u)3$`zlt%vL56>P~+gh`8VLamEab3SX4O-lJ zZ2mj6r*6%TN=NVbpDR1$Asy`FCK?w!#Fclo8rz>bFLW({XI{^bgvaYTxLBGkb+>}3 z{go{B9~6`y1oRQ4-oRZey^-G3In4rg>L8Mc4)**1()I7qo-n7#oq^L_&a!sE_(ZSX z_RORMpkZc7_NxLx%`|1Iov&ymJP4N?SgA1y+skYV##;Hh&V_&jih9fmG`mImsEl53 zXomW$3Usy)_uy6HQkU(vtG*{^?4j?j!=Xm~ase5&CP%L`Q2~aI9j(%o`qo* z?aFHL@QUPDnG55-)BFh1SF&mOqMS0%yv;{mc6oI+K-b;l{U^h#R30|_0_+TY)%7!aiJGk zmTB7y$E<~Gt$>YdZEH%P$siq207N}P79>E^e$?|9Ir+>Vp%#{Ls(=o2zDyO~_*)ty7IA`f012+Kno{BfbLu$C!7HsjE*|VzD(%u8Io0-HkKUcZ|4_|-$ ze`5NF)T^R>YFBLSF}u+BQ5@Y3BO;#UrgQc*p6LEj9nhg+^M8&YulK^nRo2#jkM%pU z3X8a~6d*_3>GaFy%^<_$!9cIn9L>=wK8BNnpS!vGj+ZP|*-QxLZ~jKB^6K9S*8-+> z(gWL-PPl_#Na@jZ7O!nqPNUU4(Kl4cm{cKNM0%J}Z=BM$fNjo}Il7j79G~+mL+EBJ ztL%u!#D(#M13&o)SH)>FB^K*0PW`&zhMQ;+C&iQ0)EEUwrx1jpu}M)2h#|N_$RK>GVhv)p_Wb0E8OFPL z!rBlxspRleyNlJP0w(>o^C0n2h6oiSD>a;JDCAuVJ=ZPS+MPK>L3B+D#h0rNnFT6) z#4_0sFA9Lzb9`A#iai{3Kyi&@5O-{i*=z8zln3_~)cXI|_m*pN`%^z;QiB-f;_R@z zW7fUUSvZ(Zow%(m2Ku`As2b9;@wO3-1#nDR2&`5CCPyG6@l8DC zB;J`G27GDFiAW8^S)EHp+78_z%olJzRmQLEZk+>)Fmb}XZd1HqdHvlR%+U0%JQhQ6 zv{_Y8@i7I8&xF`L|6lgC_PYG^dN~#hSu9kfm?Uyeq50r=f)$qQ1;P+m5(lypuLXDw zeVcX|0JR1xr*9~<#{YCDJKyv}4FD*f3PIq5+Mj=1uU9HNuJ}{#JIRRT&T=q&!FRve z;l42r6k_34JxG~*a^y)5`sR7ycDj}7LrJM+_*kE-B&6)k#)>Vq;5RJzVn+VFyL|D- zxjmB*P>I`eXLapTn;`$*i5k1=;$9_Jsa-mMV{Eg$K5PBZxuMqH0`Ulcn|i@XTGo$z zL6R?=la^JKyV0P#QM6v@HQ&Ku9YW7z@iL5xZvSU+2p4wh$RFAnYJj$!VbhypHyNHoL)g$L)Nd5$*Ws`{qKhC zFI@vo7PLFYW6I4!(i=9=XkZaNg)cSKK*tI(wVPQ|fEX%I?O$Vq2Zud#WKty*JjDCD z<;6|xY-Kgw3=No@c9Bj@ts6GK?rDLpo6&>pWn2_K0%)a~>B~T$>yPk3h{)8C>G%)fg~5uXrNTl^u~PU}^L%xK1qbDH)mEiG6d zpSN1a!Xbj81f@$uCyVF7db zsUV$@O8vfUCqOBZq<0lBUO~9L6Boi9_NUw?{oB9((n!9|@^Ez#i#-o`GqHNJdp%3D zjgU~Anltu^2w;GPaE`5PG#WO+C`Dr!wxGvMT2*IbkYxT|o{s5ZldB_`OEWLbd8Nu7 zqnQ5{(X*&^F_e{nNtKl(2f@;l$9=F0r`1G!cB0xku+aE8G)b(nAKn`b+BgRObelc(G2^QBb;g{dSTv$pb;&(& zHU+%x9`3l*WYcCG7OD34t$`gN%I*vndgie@X_IEogn7Fh7^d!A5f6njmC~&EuRlvGRY&aJ@7QEOSL@PddwxP8%j`{JIB=5 zYll$a1A`T(+G2@fj8{HKdn7qW%!tiF9D#)W?yE58Wy1}xZ5HmN9l}G-*HXuk@>OnG zMOP6nKVpua)rjysu_zcj9F{2oowMW4ZGSED^QmK(pNGiH^;g>Sq`OS##;cTX=(a3G zLb4x-TK57<(XFXtq?9R>PMb1rbSo%DUBg^N=!RRnI5SC23}%=jkMw@gQdh%Yk5E*? zemBO_uTRXcdRVv1NZ&FN_3;Zdv_2zoaS{b8{hBL*in#Zwxog#*RpB>$ao71K*CNPS zKF>e&g}UegEs@1KO>JPX#H#cbl`muf6`6s;5fYdjib;hJfHPN>{mOwFfo;q;`+o(h zILbRfSlNw{#AZrY>3AG3*K9) z>DQ(Ojy5V@d2n;%_~3MK^Hu=i^9w`2a(ssX(W-TFV?i;uyA**jWKskdsYC_!PymM` z`u8lk_Y?8nr~7y$zVri(Pt*^DphY6Z-!NI^Z@b541oAk6yYQ~@?9}iO@;Pi7bLxia z3G1e>Eb0d4>RK!r81Yy#WX>$-cwm8(y(>+@Rc^gc@iDC^wS865`foaz1lwMzSOCgD zeY`92--~M^y;|dlz3hTd0F4VrlG&7G9WaKkH`3hzyyD>}^F zJI>xnw70Sk5?KJDG#G@Z^dK;kZp?dyq0N7x92-;O?6cw{AbbW-d!u<{Tll5-9YN2o4^@?7(VAjCIksI;q6PM^`a0K;^nu)u;W6WihD{SLI4g#^HK}K zL2U`2m^eHijI?l`>4#4oSr|ulTGnsA5GR%?r;!O?le0!*)d*u;8(reAC{G zb=b)MlV_CNKw1y2_c`8g>RI_a+psJjt?<67`zYvJAjl}oBzfdt4Y+kZ9%p+g#~p9O z36RhFk=dXF>bB;=XG}Ri1w1^}^^!cQW5(pKuC0le8G|YS2_DR z6LN}7EvQ9iiP!oYG}kciUHMbJGz$e<CWWNmuQ^x(oB|01mShZXD8crTi6F|9UYEOy&z2f{uGWVc-uoX@;}&UiIR zJAzH#N)gU8^Xl${#_S$>2`x-UW-tlg0f%(^Uj!FJcX~WoUo1l4rxZiPB%2*^jsYUs zb*2m{aKoWMCA`?E%d``M=D<+DMro(1osf+O{-UCAIw%4FH z<8WGPu9Z6~&ipLj)48zgY){=@Q;StAc_OU9m$f88oqcCBp|K*trIHN_kgPNMQd?*$ zz2OrgKg}LIpo5mK@5CC@;Rl#iWiRgC#F>*gQ$U4?KokSLlTRk{2K#FfW z8b(}S@477rY8kSC>?5DyQ}!{#r4x)g<8UwB?zB!OdagFZhcmGr#6^Jt095iLT4?+6 z?%<+o*dD&2GV3v^S9j_(aJis`N*|1>0z#_{!e+mv;s0+$Q+1$TjRKH8`k)T>zQy84%p8>Y!N}2@H{ovj+4uBN{ z>8wQPW)mNkNAR!ivO3*Ohg^~8^x9%JWKhli-7l~o6nUPIKaksO(@Sq8LH|^Ukjc2u zD@=rQQ?N$dH%=x`}oTnSm6Pb+Mb z_7a&#QeD5jl;NZd0LEr0YJ)#0D`4fRD<*wgDtKCqZu4{ODL@W*uz10hS? z34@DA2c8OI(5y}1CbV-w?1_8>{G}LGi8N?+#6{dDGIg6S(xnjO0zmC^((?_5uFgTrY%CV<^KS?NWs8Xn-=hp$spUek2+a{U zyRMY5SD-P-{);o%SO`ApBQ24Fv}?VFGo|Fe5Z&y=3Is`VZ4JRya^zqp8fdLxV$JzT zgN(1u1PEO$e2cTDZ+)`~GqS58Nyn}yzs?2nKu0X4==2?cThjIKELW_ZJ!*|ec-C%L5NU2)vY z+*mDTUzrMc??qFPsf_VZ|FEQ0&-P92)fPy);3Km%qos{`telkUC*ewhi!ksmsgFT5 zNMaF9t!TlkQ7H@mnYV)h#)N1ojL)S~9+D8p=A6&9!Q~BPw}%qVE~HxMOk?^Pskmdn zD*iJ7^Jd>DUe#YrayL%+u+97EXb?y9`-h5n$eFc_=*%(J?v5@)^A44r^-B~+uC=*p zyycbkSA5uiVm?~2H8(IDsY(YFSo|P7P%0aDf0p9(4~e^(c7`r+IL6Dk4UX=D9S|P+ z9`vP5ljbxBb)=buNIukK_3&R{?p}HB1TplWFqHy7OU+P6GhtSuTR@fhXr0YD&`a+3 zYtrxbT7``0OG60ECQBo+i3-Nce|XN_6EQ|B8d1<8n zK%zND5io-mRh;SH&!cId6SRfW+(NUU(c<0I*6h}}qz-{mYkWeuc`RWGmfig;6J`A` zyq;i-(@H5>Y8h*u+eb}vTLO|n?IkMjTciMfRZjEz($YPLS)Y$L2gjbMSvNs!a`dy% zXLo=Z_~g2)c2P_tahmRtnZfj>V-{JmJs2pi_VOd@LqukV*OAb~UHBRjefAR#LkYyf z#~M6=l`NYEM(UkW31@_8}YyiL%&g`?d5fF_O{XAqdeW2`H zf;80Nom2UxNmM=8t6I%~<4fb)rkkb1kg99veN>xjFL2Mq{m87xm_W$ciKqX7cNcLF ze5YE8axFG3en%NKPV%l;fqW1Wa6_6UVCXO|t)qe` zj&k|^Jh4!T06U`BSIiwk_ZAaIjB1j0zM(i>v8vqJ4&VuI4QIzlKPgYZ^r;DK?`%60 zcR=J{tKncQAxLeE4t}oAQGEc+27WCI6;#-oDY;t|JK}W@(lPuMLf_3BHhE(sv9W>(9662ywK)wZtGtO<4TDc`Un>urVZbzgJ6dwA^2jM3nogzB?u>cM?{NJBA zFHR}NkoFIwNgC|UqL}4E=BbBveBf6j?s~X|44K;)0L>+5Zpe2?pjxO;R^yKL$$yTEGDqNXALcP7oa$?@yO^7qm7%hBxOB zVkk1W^QKcCO%nf9P?S5aM=FK3a>J;OM6py1l7nw;krgJ0X1>*ouXGpF90~ddOI549 z-R59Rdg`0VZ21$YF2TtzdkxdU^1uv}$49!XT3^~nl76q^?fZh(QCg#5*{_C2_z_*| z_!3qQDlvjfRyqtm^Av)5J2DL|AXi-xU#&36KEhbp-~8JSNq{)~R^monaLZ2Q`XmtKL)!`C!1S)UVO0!fX#ZfEL%CS`w=^1}i>e-%3Hc1S z`jp${=SL!Gdwawr6hv-|_OzkFpN2OZ7jDjjpd}Vl0&30wDZ3F0(#vf2*CoQ%oY39k zsS-in!yl=%w9;IM^UotN_^=}HaU#qGoP1IGNO7{qsQQC@>+mGNPILO@KSyT zdU4u$B&Cf?3fFVHg-bJ`@k&fyezGK=9SStEh?K79FH7OwXXZ9xfx=x1|%R@fCl8bri$H~mFq zEo$W~upmm{)(_2`HF^QG1lzB&>{rAkQcQi*P2d;0k`vE4@c0H_Z4>-nc#XJ8jQwM2 z#F+T$uCVJ=xC%?TK{SY$rnTKciV=6a4ozS^47%QB(QQ$c!ImxyiZ=D#r_8RD-%c%i zp1sL%)vHx(hUv|AlHjjtzS3chIRL7amas{V3$!cJ1lgx zng-X@&%yzfCDOYWkjL0G*a8lRnF)VLLta`@>%wut>6&C@M(O%QpafaYSoIk6i5p_; zLhr#E*l;9{b6g&ss=wZ4lFDt^D_elz0;uN}(0ea~2(%tH;Gp@jdrN$f|NBj1pkc!B zK_V(UHC;{156+#!w3W9fs>Yw8%OFLY7YB~VI{y81-O_u{DjCSeT5jJIEfrU~iI40A zk=8X@w!p&=T&8Un6m+TE2&K#AU&Z;KTy8b^ewhL%dC``nudl}{zF6==4Alil!!&|A zCH(mEe{+V1>BX%`IhAu>QuTYZFsWpkpKn4pS>g08Nt4h2MYJ}PxNqPHa0Agesy`oYT@4E|L~jw@$e}9t z&FCsjw0@GFaf&f4d%>fKij_d;;}0%e5nioKNZifmqn5jhrw z`@19Da89Ll8jx_WnD}SRFbwm0090V7@B}*qr0h*j$$Phy;m<3;3)iUAwP*j;VhWHArQ4f(|5Er+K2@`8) zYvkcA;TRuJ=dDc<>SZJG@L;I!D1T_h&!*Zi$}J2t@N)r9{-M8f;kWzCrGH3F(`3eg z*0T7TX9kv|p@rGp+?Qo2F-Ag1l0`izi{L0U5yBxwZb@=%Qkp#fY zO|9+o=VGu$Ajs>KP*h{nBNpPF+_3r+bI;c5uBnsG2*1Pu{`pao*^LEFDP1_SY+ocH zc(p;mp?e^`f$V>u3~s;Gotr7&@8z(oR^fBCu$`p@zfI|F=jn*G*x;3U+#n|7w*yyh zQ;E&oMKS5$wv10~zDZRsfu8z1r#^Ee0NNG1sBef=2uXZkhcbmmRl6gwmL;+o&^PZ! zMD6;4PMWIF>u^k%ub~*evPiBI2;T38LjODGa(H8Pzh|zl?9bDThUUF zpT4GL0^2AKtu{u5-MuOp6rOnFs(cAju=-Vk5h^l@n3C1S@AQ9+AYzt&fQnCuyFsq> zByN8G5HT1ttkX3XR^8$WC7b>x_Y6`;^mZI{1Y-nAFjg83+O`}riZ4zdSXk=3uH#DX zEDNcgIuMg-ym9)KsaUzq;JLikfGz3t{uht#E7O1+XnaLy6LCsfr+%$l-Z{{IYDNJ( zfc2Wv&9lC~_-LPg#q*g0VqJ_>ub)`sT2F>CQV^^~4&p2THCNppAJSEkL%z>Ei>+Pw z$Rjx7Y=89+#4BCl+BLXzW^TZh>8}$5eQU^nYIShEvN zM#{c;^Zfhd9@r_2H93EfBR_$M-Eh(8=A9E7mh+yix%7MgIQZwg0fYlZL-QK2Z$g!BAPJ$g+@{^*TKyI9};WS-T0U;jqlNw~r zBAI}8kR)Dy;t_Ll$-lv{4OZtfxuV_rSEsl1)?AKVL5(u?QW|E&$OZCyBu-kZ2x4wk zqFXx-@-eq7+ub5rE>01^5hH$>TXPKD6O?*G6jTCyT@}nWQGCdwvs)v%vD~e|mD^?R2sj8+f9vllo3M=dNla|OKPb~vvr1}KW}$tkon-Ei zJ-f%*;iMpUhhpO;7yZU_o0#;xEt9RE{$nhXybcW9?Z_E; zc~w)Y7;W8VXH{lrZ#GM^yvjyXUTsd{)I6V@jBsH`lOp!k4bp53e_b`k2P9s&23(nVT^$}}h3E_yQ&1n8uaBPKmQsBev<8!(^_E6vZc3;Gt@ut*i{ zXEX3H-N%*hoi zpxkm~Im|^dEMrVZvf;vqD7@nuLWmyv<;p50hnBfzm&rDpnb+jyO|N+onbsEvAht20 zm;+bVL$e-k=$b*^KgXE*+;G<*+O`*<*;S42j^;uA<8jmYze#DGVMP204Dx1&_(qv- z{!l^x9$19xt(k5zoUguV1Z!j~GTr_i@Mwupqw?}UU2{K0QyX9hYrnq3yb5`sEd8IA z&%8MQPw_Qz9Ie#^eA*h`NXd9=oc7YY~a%RRf`{!743jdP(vbP47FZcfFxmM zd+j)JA;S193od25Wq3rz@^E>UVz`NVgj4uv&@;!c^J(cC^IJC+LLBOKRW-{GT|m_O zdMK}ShuV9GxC3(Po(EJ=l;=3n5St$0$48NfyqQ9PlxTvXKopE6Tc%mBGeCIh=9h>= zYBKgSFKAf&m(%6aig0#wWJ+m`+kMq9^JJeR)`ou{fS5o(Ra^qPQ0E{w=B|*~2b{K; zkIv?*6>)ubr07=3k=$z?mqipqT?%hg$f|00`ObXhGTzdp?Ql8j7X1TvT3L<}&W3(o zz{=A0qA8*1;#sH1pM;2-)$#jX;Mib~ECGyqNsxSqb2I(%Isn;0cz~*|RDz31t9559Sh!8n zEV39ei#A6zbj34bGM-0>!RIPwYPEWR-WP;|m;#Dxzoecob_S9J`*=ku0uQu`$m`iu z{dZ1g(DaIFvq+QqK(LiGOsKJ#IKb#@c{B9Bo6VoH&y?{Ivcx`;KyZ@E`?s*0$7>^g z%G*(XpAW6)PxnIASTaTe0V`5if4Kvl-%)b2{91J?PzOCW5u%;v-A7Qne6>tWFJah~ zwU$4Rc{Dv}a#UUKm*4=q3|bk&>|>HQh8H|cdWS(cwt^%4tmA>dkkZa5s%Z|3TJ=ECqHTo;CkmWM{H^GF7&i$sx! z$=Cwq6Kk1G1`1zBjqrP5vCdwQoFwj0-mn_r!S^FA$8GttCUx)}hU zJxqt8({pms?_rl>^QRttV|L}MmkK0uHtg?jeKA8DkDdc2BKEB31lk`fXyxGJB3@U)2- z+x%S73G}gT;im~Y+*)!#u%QZ)_80KVHY6ZbEz(^+7R^?o|9bg~H9-2}yN^f<4Msxk z8j<+h~0WtXIQgWtBh!=P)d*P z;d=cWCcO7e&+w^1xQ~F&ImV765TC)7aU^%#hzsi^nfsLPu}Y1kF~tNpWH|!mI}`B< znH%YI*YNO*Cq}}O$0)Nab~mM>>ah9Z2S3teeWo<#IwteQ^%s=!Jaf3_U6Z^y6ju){ z(vVB?@$Q;ZKp)IJie8IEvxi8-vtYs=9b}sKxHCy{zU@->D$kUG`(BKpO)_*c7%t2J za_rG08_uSi2j9P)U`~4Q?C(qnGb2R%w|#edKshqiY6@(73POD0%b5RkVScm$|D+wN z!(XY!qt>N$x2DX?rZh|;mkx<$3L_1JKPlA(n{U)d90-Csm9zCeDtzTvB9?OgG~l6+7F)Ik`tQQF8fr7`>1$^Wx4q&!SW zM?x}%I`jF%Lzy$XNL8jET%%!iUj>|&3j?V$gI5QUXzNj55R!0=SYgzqpNb!1e_U=r zJVnWm)7&(wO|^UC`XAR;cz2w=y{qP-b=FG>v`^nRYT;7$jkcxEZ4`39=ypRtZ2MUh zw7L=NhU)YIKhVp#ARxGHiCFAN5{%EI-yjDr0Mi5icW3-iE6DM^_eu#t1XK+}0Dm7} z<@rD_BgTyv5f9pcPPh6!so_+&)_MT7=ony4C44CP>dm%Kx+(by<@YFoSG~-tBgWwq zTO2#cd?R_p%Qjym_g{HRi1T}cH~HBu_MFK|v5RCO((jV0A%P5HAxOna*C#$08QK~D z$LYS6e6!H1qmYjI&E>eZJFOmb1BIq=lyu4i2Um*uiIba~T!d{jpKt7{ww{rtW-k^M8ojLn#9WapVLu~`c$ z=#Ux(q=8&zh?9V8=*_6U1fmT0=L(BoW2|<_m+CtB1m*eFSxAfS*6S z-SVVhN6F}owkhTW;!8kV2m{2&Rw5yRr^87_$W;|!1C$n<89#93;Io{UoVN=^VPqtb zw1cj;(^{)z76BPo*RuQI8PZcK$i;DvEDkc`ech~8NqHp|JyVY8q8g7fvKqK_D-id& zc?y9O7~pA;Ip^q$pY#6+qryMoe%e^tt_2Rw_z_u&P)!Mn9Dh9h5*lvkXa6hx*iyMm z!LpeW8D6PccqAA6?qy&ouM}^Ja|^N3BTEJlbO|lJ<*UN;A+&ptyew4?Cff=jgkbbW zC_%`cEM*fa=EhTB8)2-s)AvdBU~1nsWV22P=$6TO05M6|f5!+(-l3Nw`c;Q8RmLy+ z&U2GlorW2HTFcJzGt>^h@ImiS2}_dF`pjJ%KCuG!l|1N%o6Utvc3w^JRRg0EEhM7!VFm{W7l>6%gyUz=;d+SY@V5$b(pt8U^GP1*U+AVf)=w;WExxrqi?8*=J4qaK+yL=2_XD?w zWw|HLG#eN2u9xVJz;6bm3f7u9m9rJ1Y9L^~CNm^$l&c42&WVcsqfGKFE0E-9hi#>1ET zV!bbNi)NPd30mpheScJaP_UH=P5U;Aeyu^0U>&-rfK8ibZkQo9+uO(0}amr zP(J+Q5dL1ItMg1%5h}=ew+7$oHr~7$X)Y)H@RmVt4K$R|;Q<}GwWnCMC5b)kj(oN8 zApOKf<=jt#i734*?OuL04SpN568YI!@o(I&j<7ZQ$tPJN<%hcqbw0HsMVN57A68{o z>IwB5+c0mHR$78}Vw#k9bW)o4nnMVk#~UGs$Y&*t8oG=c=G@i@`tZ9ya?!I1n^!mCC{paS zdR|V%1+{O!uyAU4t2$ODSeHm7hf8(|7-l>qLk=y(iBS)%El(ZNxo_=~I>UkPi%Vuw z?Y{J43lS&SY?{Z4VO{O!N{}sRo9Pr6=Yv#;-!dv0v4&scvy`;sO~y(d@tV_DBIo+z zVEPWN#zfnyI)e|V2UYH{vz!*2m!Xd#1qs~)>j0YcZ~62zkbc*(-9*2|m|co$98Lrm zDv$l=&w3AJ^PMViL$a(QV4^_%C4H^5SE1!4)Xf&G{vQ>|NYS_!WHLmNib4|KD8%dQKTu2QdxO~{t!eT5Cuw_)Eb4JwMK$JER=soDBtc-FM#DJMgLxs)D>k0oE9;=d4%Sm{0Q06G!AdrOjJq-b^xL8PFZFjnts~RI&p%XGdFX z4W(NdXCgmo*4gRFyxR+>w=6@iq)pALPG@LZS&r)InN5P+<;qc}+lbzIp zB)F!60UVA-$a;jo+ErZ4paVLPR!5FnWpTyQOO z2Ditn&+*pDBi4vFM7+DciKk2qe7vV7ym4HpB8Wu$Siq?mGCrF=oA(b(C0r^kD`7uo z>;oBMg&x*gZzLFIJdfbsLBkE@3hJ@tSRipHZc}wgE3omUsVrNGn8D&f;npW7^TCkv zEK_p+FbLq|?InIwRhjN%p*wX_@-~h%3umA1vF9mBuXcZci|z6X5@KCfJrPwUgkj6| zVm(GV$O2|$DWSy;jcuTriyF)bc;MBOxA^j)Ho*aAb_Zq?c*3IgxR5$f=uv& z4@pNwPxq$Dak(6dD3k+QxW@13COXgkH_Z!_7Uq{reQKt-g)l}^%#E$UPcTkcEy+?h zBh(cs{BNw0qLy%E8Zg3R-59~ zc}%>xbOniLbJD`eIx2vL5KNH#6P@fS6uM{|7%0tWfv^|fucJJf$}H8yi%~om#v$Sj zkOZ_ec_Km)iTFgJYCa=K*iQ#DfDbWlXCJZ;8<+{0JZ!Jo#wI#!<$5>^ui+zv>-4J0 z44UppHL43kje=_?L@;V6DO3$T6`XJoatjK_H*5#^Z{c_NKRM4*W(Bw*9%LwPB^vy^ zDI7O$;R;0ky8fdmnZ~e}L8_ZXw;^@@iF=7{HZAaZ`kDb4cFF2nEgE5%3WA{w>sVGv zFxflAQY++Sd7GgUsX+!mT2eU|f+sjnX5kw1v^Ke*{iVwWFN%heoqDtuohX#<`nrQe zK_Oxqw678ym6XY)&oQ%L2$y>lGP=a}p*;j@Td4BxCw`g=UlaCM6>EVo3Y=@`Xe!wr z0LdlzuHMcFSjofs=WcDtQ@m`_IPHagQB%7Je4-j_Zk1*9XxW?`8*myUY@z-XGT#i5 zU&<>%pcCYJyv?yth#$mU>>v(Rm7^O&l3J)A9evzx>t0t-u_-V!hESYz#&4F@5s{w4 zkt8w~HcDfmZ3k^%v}+*zqIB>45qG5w>yH4%j*)I{+`=XIDdrhW~zHMA22u^pvw_xcdhOszo@GbOUj!8sHAZ=os~dlb{|gs^jQP0H;V z1Yq@7BzdlaGt$g|rx}W>bPHR-U-*LS^`DzX))=pQLi-V)H~prxpv$Dk-7cFaGgfnv ziD20gbBPuQuBfGLCnLt1rD`dF3kZ4-|3mKfo)`J5d%4PxXb5({Z2a+>eJ*B-xk_;4 zo;Qz^7R6u;4GO*JwYK;P5QYhe0#s0YwhQYg&7O5ToCRZ`)NcKp3hTIo3$8IN=3sQ1g~MF30~&o>d*>;{{k5QwvvU~(5h{(R8}qVcK}XH9oIyacE6X~)aT;bQ$O))&gm(1~`IF};lh zvlmuNERhV4;YU@&{~B0d>D1x$hDro!17D}d868Y?jDoWDV7495imNN?61z|;l$YBsvX=gQ) z%}8Q1k%rzYTzx?3(3aaisLP3wU1PFj%FMgTaT&hk*Y_h|n7P-kAJxCQKW4_mmSCf; zi&&xsqH%6WKe)gpjpuE(LjS_lq$o!gxMe+L#J$Ec?==52^|^Rp05bAj$i|SXqY6ju z(WIJ(qj)MgUZag^QBOcEQu8G{$AKPI&p_sA{xT=-!fF7xMy=kG!~eWkNkX|Mt!u52 zh9v-{o{GwR8Y$_Z*hEraV!VHwBgbCO_)59el4_jVT+6A+v#jK&LGmDwG(TtXa!$lv z4WC@c`xJSq#O?&f)ku8eeKPy`0P3^A8>$|Vr)=6WCz+ksPxBn+hbDHnqQ}gZ7+jvw zuDroT4bhp++fn7zmBL8^J?9@x*rpR1yXk!|Z0%RSz?-y2$cLGr>^wag)t-eaCjZNN zSr8^iVt8U)Rhi7Sg8+^Z8Oi{ai>;`|=OYU@*9akK{KytTy7Qxhy>_eL*3e|#4j+Zg z!}|}$3psOf{BF@OwhL`8b+l7aKFn74BgiJ0};b%usODf?_!q2`NDa2j@~RnX3};ch}Yt)rx;QGev}^@ zgj~O2|10Np`)S+5iq}u6WAf>>a`gLAKrx04@rM0WmnPqwIY2igdQGnm%Cov3gcl{N zF{o1fJc^3+|$t7}08G zt{rnVd_rk)>~P`WCAXT8ed))S4G|m%c-Y@EmF?~Kj;c+i5sVA7SVn`sc{+i1bd|ZF z4pnqDdX)IR0X*26SLR{V>5F{ah?|rpO2g|qhzS(MkK#9UlmMwnE$+v9QF=^-S9Z;Q zOVPL4&f=WSnGl3mj7C{e6)Scov{5r2;qR?)=L$9BxKvx6PPqKE_7NNdA+{l~>Ko3T zkdR(>aNM^J_K~0Hu^T#Wbu_+*RktTus01V--u@pHnn_y$Outi7@R*>PLj*Tp*p0^1 zxJij2u3Q8z+E<$4` zlpDkmN*J=Mh|57pjXI3b;i32QIZ4CZu?bSV9fFv+iY>}JU)fV~oxAU)?o6p;&$G2v z+Nah}2(sv1MeFN#tfN<3hYD2CeldD8hJvM5yX*Nt23ttg1S8v0gh8V<1x`Sh+M)51 zVzNB3Po1mrQhrZ<_ynWVgH4!&wl}*<2XJ*7OfiL>k^e;%rM*povu4CSiK-j#VerJ& z^+V=bS+SLK(+V#&Yq4;eGIA@%Ixm~egH0u_%i3MBP>eewfLpjqZ0g{l*&QJ}F+unG zA}ns~&CC0QA?C-EV{_hyPm9P_y1+d3xcmJWmMU}2!agna;Q_glhyE(?maK636m7H! zYY1vx9I|zp_Q?*EXppDCM`pDkuhx+r%h(16{vPS&YRdc&a3&ziKjPHR#r9}kz_j5+ zj~_vS2CE#9_zZOSs*4Ii^*;;J=VM~MUN(*rIP6Uc?Au_4ax6*Y&wCp{l{~`~+SV^n z7j<`Azi^F^rX$t3;0SVw)jzST!s(|CCxAK)9cR zt}aphe^Nt86~DUKpL~q){%>o6zq8?&4T9M zec=vx5C-a~xc5&5zk+!YznwOoGNWcg%18h&)TEB+sLtnz%jK*VMi6H6G9Y>QP4$;1 zI}c5rYRlA}_?IhdNdTs-6(U{Lh68)8xmtPzTOAf8(LJ{t*W^vRRjwxbwau!MYji9G zFL#ztEr0N$Kp8RcJ%3{v*k7!fFQr3B^;rAy1qq!_PkFTm6Lz(b9k}J6!;n38gnr;v z_2n~n{0yGBU0U36RPnsqfDE2qs-rJnDRe^Sw|g0wP%0_%kEnTqvL;-x*z8aS#p^Rp zod>a?X^Tj56zB`kPYgR47|Wt{S`>ND0*I1bpN;#CU`DU{eCYk0;#2KPTm_ESf4_Y! z{)nsDi!T$kM?@S!c1%R;VqyC_UE>OHU>D0*c+F{ORV|qz*Lmmt%eWeil~lMwG*lTe zpHJO5E_lO}=0%?3*|k1&Ibrz}l1AVM7gAF=N>Li9o7(kDVh=+(@2NHXfN~~z5x5J{ zX#lI}^YP=Z4yXV;I5(;8fED?4a;ABVb@NrffoN zR)6(h#eaF$Ri#=M7?)gz7r&1L@S2}M3elA*WQ4cjg*@4vQlkIBcjy!a>~%E zooRK621^qPzS&1Cn~KbvV$onU6R-bHhE)HwHpL2W^J3C;sAo^yCCkKi>=HV_*#4@# z9DSS;M|m6{=(e&SD)!R>NU7>7<#O8%EzLqeo_okP`|J$twhwl$u{;*kJV%`Shnga& za59dg(2)&iD_bMGaf8aZNtHHUx_faoVBHMU_s!RMoe2c(FYU7)uez473pV2dnk>ZR z&hRYQnAoGL(>9Q!IYeaq#+QwYs2=s&PcJ0heL9ro?0NO%QyHzz7Ut>wmsKcC>;Bsu zkQY9yCz6*AS^`r9=p)VOb7K|~kEUG}#Js=y8#4M;|Ahb>JV4-c!iq(e5NkMD^X8_t z)M^JuKUmc5?zjv1Yg-C1h;WB}(kG#hXBNDGpBFa&FgV3I=r0-&2%f2`n8PR?fg&bO zD36v94NTrBa!05(;g?+PkIYKUmTckk9<phKMC%{T*iJJS{nI&CR;k-j@hk`!H`!k(sl_)ie{F z4SlXlT2%q&OaKSmGjY-MnGv@cU&%2$Pfqy_P+k#6vK3rM|yDKrf)U=ON*qlW2c>JX;<`rAG1Z~X6zc};QYYO#ucur)bE(RPVy71E^8}GBx)q^ z@}+6Oe|%-&ZM<%7TN)3%T@CcxGgzAdulcc?xtrZ3WDZ;O>lwlcAIP+MT{VXGSlj`D zOH%YLNvXem1%kY1l0JbQqHS)Uat5W<2cvWrGT={+;>@?w$tbs3q|soGo+jX7iX6jP zXV@GihP%BqdxCyndzJ*O_jZ$h>>aCJ%le=ti|>=X z5{BAhHp+|R4{%XiPsRIW#3=XIuQR7y=zL82P|K1g;iA~D() z2!sN1ndlUk2+pxNmQ>iA3Qx;nIkD*67t4`%d=t?;IWS8xJs5m z3{C@H^oKb(o>lQ01+3A&M)a{x9S-Ip6uQS-XOnPR}^DBNme7FBIJt& z9^zM;Wu+&oi1RdMfuG+9C<-)|*wS4lz*-dduKhyB&!OEyvL8w zD?HTk|5a#0?0u)2M-`A7j+vx}9$z@vaQf|f>?o7%akt5jbgVoqWP77O*K`_S;?Z$Q zq}%x-=MvR=uW$e8U|12W+6*)LX=ThwWymQ@#>fxW_uR!-y^V9HNg?1s`3gWIc5QM% zhwpacMWrS;H8vLq;&jG96m@8Y_=e4a(ib+-ua*t{H$(U_W9IF|i4<+RB5FMEB6LwQ zh-9q)S#>>4FA>_GvKKe=GARd)D93ZNRVM$SP=2%olH^NbWpMKA;GY}#^?hSS-D}iT zdk3%^79%Ug-Fno2K2~w3U#^TcwB>)*=i%j!-VA7irM`D8uJ5(W64=xP_%NAK!n4u4 z5a=})h%(1SJi*5+Pl@t^_*TJp{#7{WhI%Giy1xtpIGvaeHLiOZdz<@}jv$Dh`3L;o zgj0b&WnYZp;lxfbl|w1I{mHxQeIgBnDiv>-;?1Y26glB|skCP=t#INVBKJ6ze1F#_ z;Qb?Tcx9aN1h|=Wm>vL@)9?Z#ku)AKxz+fGjF^2No$A9gl#$HR1Z4_K3)Saj3w**1 zho8@kK$?kVTz2pR8q%NvWID`vH#cXa@8PkJ!UmfB(m?_p(GXIm`*I?c5TgK%NBASV zY#|F?+l81V{I&exjisT`DMTQU!mkezE=`5e?&!2#dEwpGH%Alje9%3#Wd2K`(|E+< zvO(BU-Jo@PVe0$lHoPw#L=K@OVSY&5?j4TN{B|GhR*a7IFigQ#O>$qf@B^xir1fzzzIJfj$yUMHpOcD_BMrkI^nh}pfrU*dGj4uUrT(X zQFPW^S%4y?{#%5$C$cgtMr8m$1YCtGNe;Q`4hdli>Y%g`T-hhLta4JiRDaJ;BMB%@ z<>}a2G_dvfy!bXC=pFqmfk{}5#;6`fF{-NoPkPwNJ`>^2Xaf!*A%2q69gGIcgQuLk z82QObpbWZ@vS`ucPB;{pejic|HY;ZvF;hlb3ki}(ugS?lr*hLO+5c7hoqa|aoTvhM zS7|vv#y~gd8N9VOJeQpWzLUJyMZg0PK44(y$b2Yg?uKu(xh4JmCjC*VObkjVWGOY5 zaKQx)SvvYOz%eMTJ4e&1H_syQpkXPDsVhq9^xfU_IO%n-cfNC_WQaEH`0{A^h&;nK zx76X2v=cy6^Ao%hDJgAfS^7&A{U z_~lx8aa&o)0mBOZ0P2miF0?fEa8(;6sufTnvSmtFROlP2K`WsY`lcl2lLw&3%njnN zJ>XzHI}NA1*{k@TJx4J;L6^0pe0UUDuIs@ND(+mP0vc*eL?woXZf4N*H%nIDJj>fA z@;BsB+6E{l4tbQA!zQzKNiZhzlbMOeT=T@V21I6cplY=fG}F4bDe@<26iE26)KW>B zrjJRyi2-w7qYPhTa6cKaq)teL zPYBGXq|la+ReSe}7goA};Zs7uiWLS5Jxom|3DM>uTa;^L#1e~0Haf~A!6PS3AEaUt4m}|Xapp|{ z2Szc29Mkndt1>|Qc*j+IdI-5jwG1P~Y?%~WuqeT6`~JEE63MDjD+K5BffuuRbEPP? zyZ3urj4o`EugdQBn?A=p+D=0Hkht~!iJa3!SvoN8?KM}Xy*z5^tZ7^M9Pf`Yjo}om zm0%JLY4Q>iQ10~al$vllY#mWWm0pKEBKE6|wO;mY45g_)qkdW;UxxO$gKi5WYU{H9 z8S_t%-t~Xk1c>qOj#x1uZ&E6OTY4G%sREhy5a*X%(>; z*Wwc8gW_`?knhBG3wZ;^HDL3x{G7yj+LxNq^ zIr{>lZ+8!H6FzzyUvAj>PrYfdU5roUD>WlWHX|o}I5}f{0Cr{48d;&s-y}WE ziTZ`rwwU*QvudXCSktB?GtKl8#bF&r`BJr?=5ebe0Q6NA|fXQobo!vUzK%k z3Hf#o7A)kH0zdoTK&)30{lGOeFb$fLS!Q_v3K!A#gV3uv=Yu+0#Y?OOxkIbzNc#6! zAZpgu|2>l#xpRw<9==(lOsUh^msW3N#Dz06!q@#+FKwbToo(}rTq2BkWIgLwKwYf* ztVfZlvBfjy$q`NWYP${2^W?b&M1UuN%o4b9ci85_32g@Gp=t%K@}y7LqD@Fw#aS}F z^N&y5Y8jg}j>2WVk$|UdAFqP)#+Fy?m(OKk3lU0WX7?F_vlN*^(xr%-yaP2jWSJ`; zQ(P4$McO{Tdi9sn9rW#Po@mS*ML!#+ z3|C2sXe1hCL2N+b*@i)38d^^*m#Q1cSu}Nu7Mr%VYf7zwy)9~^3y0DWG2+Vc7hvp) z0x8;&s`FT2)|cKk0*bRdb#nQx1cc!@r+;>fZ5xnsopV(RT;sc`ktKLVOEv+YsTqsc zBZIHl8g^rd$yFMG1V9lOw-ZmHa*Gk00T{DP_b2k>Ir^EIoY*pWR?%~zE!L!;2~5)y z;FyRcD|vkvGop!DPzz6c%qmduQ1tO~;c2ZJpf9 zerNHLg>#grblW3HRuC9j>5+ajXB1;K!@Tr6Mz}}QFa4opi}LbhY4qyZDJ|NKO7M{ad)EPvgRuJkI?=%n%$4f$>j<^Vg z6LOQa`vO<}jD0S~E2oY>?em#+n91-B?4! zS4pcY*qcV3;fP6$6=)&A%sz>FW&o6-xu7;?c+A7BS&-9<$W{o#gSLVm=6O~H`~ZAJ z$b_1&;c=Rd%DMUWiC>EecEh*Vh+1qC#^X&a2yHEaDE5r8Cw7_%AKBnTwS~ltD94@* z_j-DAR2O2)UNtA}{A6ZIs?JFZ9mzI~_gtmLTJwmeh3ndXthuX|?xR70rmKB)&%E@t zw%&T`KkDJ;v(IE{E;JEZJbWlfZY>Lg^1+(@%?@u1Bd1DBn&g+dbdLWB@2U7_-}OWg zelu^D4u*B7^OZ*NocS{k_F9Ar(upZBy=;W#{Vnx8lyOv8dv3z|@ep#2RZn+^vp+y` z@Ml&OFH$Q7ez8_pH+K5+FtjisOL&?Y%WRK9Z&_kVrvCJ%?_Av+D8BZ^4t&snhGN>W z#(6Uxm%h~Zq|I5<-K_{&lB#ogOnCFeeK$}G_mwk(XwLZEUVj#yWwpgN>3R`R(MG_b z4{wonLz-YQ9h7s-h0__V%2lkePY8I9d-~)MeT+OoIf=s&ed%oR+~4*)U&gDXm(x0D zegwKxC?a6=mO06aQC~q+-XrJoPgOm=_PHpB61ewOCtfEcLejBmF~ z2~vg~b$)>9OW_x{)U3%&gr^FWM}jnOg+Au@NL;{71PpXWZhpUVR`&m z)RQWNB6k+!;DK`bYyO!@MVU7iEARShb!uHZ4qR=&@%=8x^80hU{z`mEb}~|H-1|)Z z0s5DrN;Gcctr!|wgr#OG2!X}AIXyPqNT|IsP6-IiRY6pJqIP=eIBxF*HPm}n_1D(eBL?UtM7x2%wW{196{%l6l~Q-u!~g{kG=RA00O0{ z_Mc29rry}5{2EF5LjF;uIEcL8U=l%3r@T-q?+S|mD&m!>{wz6Nz^%;DJJP0Qe3CKLC&lfgmeI5{oF8w zzScgDk5_eX4{Vd)_<3})#4Uw)zBDSfHw@N9+D&BEkcxlKsJ?@UKA$6P?gECSG$rqT zn8H`QfQ9E6!Phimsit&v%Nz%#rP?cZ^0yEYqlVH;$+eFuu)j|wfg`w`j%oT4T$q}z*$uV`igs(?&cnxDldI$AU@J}$ z6#?#Cl;HlJ$Zc&Ne*y^q#g8MzOo9{%dW2m8S^K?NGxbh)VrSkscf-SPQlOOk;U}vn zIJ<2T;umrZ=MnK=Uy+j5gU4uw6-cZ;c`2jx&+ut^L4+z|1GrfN28l>mZ!Xe*qPoiy zl6v0tXm_82lTx5W+gwupxl-Y*_RmL-Iq-w&cuP{Ro0nM|tS*$4xZ9t01j|TZqFQ#Q z9l$~4dkOp|(rdDLw|5Wx@}}b|MEwaJ!fq6OBkaM-?eo7DFRI^=5X#LZH|DWud{1cPj5jf zD$eq-U|0zlD*-GJWW(ZS>$8|M_ix|n%s7a@;^4-MSUI{ZxfPsEhbqDV#dr*Oz~cqT zlimwM8BL(M{&LdzS(#IPv*z8(Twzz<%n+3(ss|k({G%(Tpr}C}AwU=X}VrZMl* zZJ5Xcjjl&qaHJ}N|7Fpt`T$)j+)nvj&V#Zovyxb{9N)#s(;FnSiyvUl{;rc^4WXI= zq6+G{dhYbh6nepU65pigg#)z`4pd6lVCDv;w)M*b**yCrkE$|Sm-Qy6j@{rb(cEJK z8)AYsit?n@r@xgUZL~u=JOxE$(Gs}B?iUix7Hxvz%h|aBWKv8VgXISS2TH>!!n3%=%eCGk{|-dUPjp0&T`)wx{Z0bYvlR*CUM!A?N<7Fu;|#+^D4($eSla z@-Pr1#vnB+-#($yZhEj&6l1*l%i<|a;{Xxy`hA4+uPA6D0x!TB08?!+ywx~2`2S;# z{e~oUj+J8UztfCHw$pqPri`IoB?ygrgo&!eBT1Ryo&;Y5>~U4@!g#6!dZ9_~#tS#zacqKn#lwFXSlE=zddyy$zJ1m8+e89+Q~%Y84& zQ6A9X`jdkF0DT70bF`};>5q5HZFQk zLT5!7IjFa!l71l49=dJA`}XQ>h=y5#`OYNJrERA2CP&Oh(<74$0oMJwsCZH?>5D9Ln9M)kK?@-{9tQGV%-S0*h1N%4-{xx`aBiuL8R|OEC2v7c1V?+Chu%Y z!84lzcN^ciiD9)Xy-)L)@uQmU!$KnC%V*b}YQQ(~}W%IFE zKE8z_4GifaQS3_2up}=1v(mzc2p)8=p?fc61%pCnz(aV<14*3bY39S3k58Ex=|QoM z>D5eWv7~PD8U8Oioyx1-Y74M<``gzTMAomcfZwJj_2!}fssb*U^5nv!LYEi@;8EFE z6k2##-|%F$?^5I>P^h}wMMlhNCDU9}-0V*uRTZ@uByrz)mNgIKy~V&FJ)Rv7`r&t_ zwuAIjU_U|v?S)4nDc2&Yb9!>d#*%&72%9E7XfDkySv>8>=TS`_o;0@KtamF z$-hO`TX_BIDN3RxC=Z`oK3KeoW?s(X&t{my=fwZCB- zBpIyfYUXTxv{xq`I8|8}<=)EhSX-l4hf_Bw*kF`i`=boD|2W$n>%$S>3bIemH*j+e zWxdTYW^4}9UbCj9wLe80mzfgR6aH(G6qCn=RSu-gis$Wq-7{Q0Rsf(%U4{UII=i+B z>)v&%FH_Cq12XF;vD80S4$+(;kS%_B`)1JLM#HsEr_gB!H&Y2WP~9u8cKm<&c>&0s zJQzX%d)jON5--41*nz6A}q@mlzwsKhJ!EO-m^}3ySo9^m#HS zSyV2#?5i&_n#*cSA%6gLX;i?x{e@l9kYIEdlxMRgufqtKk5x5VDcmk+sEYy|?D z6slYfct_JB{9*g7R4~)ALO&-}M@wwbw}qz|XdvPs4Rbv9`z{|L<6Bybg1!>27glEy z|6N2P!<%v*#C9iJ0v=TL++=@4=w@ih*{(xh;Pufd5>E%q3^#>5#2LNtkw2oNl!TrL zQ$?+32ph8sU(KfSrsF3<_sKmhU4|A7-$z==TXV|-;~hcx*Fk}PMNj99uoYL=d@F>? zdy~{z76@{TwGj_-s<@u844=6m? zrcH}6>CX3wJ&3}uoKqNap(@gnQ-e7atjrA;Gjj~xVutg8bAsFq*PB09vqZv&YVfX} zT=t+mh(RQWcWE^9bQU*h+ue%;Y8LZ53Gn8JZQ+T*%A(Zt$mKKfetOX8z!5AkR(2zSpfJwCFZx?_Sar4eMFG*7KsinyhLqo z{ywzU*g8WnQ+me{1;PXA)$a4ZB03j)U3vlvh*9+4;m>z*n8+uvnGPQ{=Pwm)-5mHI z8$!I7id%LF%OO7UN%2>d*FUw8Ixa-9ef_B>b(u>a6Oo};{)kitc2;&0hU`trn#7CAP%CVBNhNuZLV)jT%Wrf;_q96YV+SGSY;?kPj3cZ8* zN*O+u*iUS?dd+mIhV+w?i{qw>3XNX=$ve?Um!ISoBp z%6382z5Q8W!#1sHeU;vR14XuT&4U7v*+bfF{QUu08l>l)Hjx2cs2r7X{UMWJ;M0c# zVl6o?tT%(h8(ghzyie}mJmh>3buiz!6!9D9MjHnpsVW%p)$1_~3|8Z?=}%U8sn5+2 zohOY7X~_PTw@N}%v!agp?0qk6RE(zXaNikW$=rD>(Hk&(9j_N(&NA(Is%Mg2tn$qA z5tSNK-{C~Rs0S6O<=KcNQ8nw(v{hhSjLtRB`M9*&m3tgZ;i3b!Ah58!J?_l2F7sl{ zH*Uc*m#%V)3jN~B*fSZJf&zMR2Rnzdiwn_m#hxlGq8eZRExl^S<%JAeC=_||>yW$l zqN4+!ED--m+s~pH{=Veg%Qm3=aq9=FU=8trxW9DGVsSTZ^OovHCVF98kFd*0fv1f9 zLxI~(%|YXRAo$#a>yK75jqRu-cesE1RU*3HlFoSsXw&~@qpVE8WYyBo4~>6mH~%i` z7>JiMNkja#<{iv50YD5BS=%pi67X<;|EpWqDXIJyMDHOX(BadBA&Q{VF%A08nW9;} zIwgMtTmWt{g_NGkIu;xXkW(9|AM#M36us%D9L}Gy7i`6`)f2Df*nFtskeJUG>&5 zPdNRPLX{T;EP)S4dkx?RI>R@8^O}g4J)T8h3D74&>mP(FYpjibQ!76hP6L`?T@gj5 zWpc`mC*fjMS>#$8CyW5O{Z@(sS;OG(Z%!p9ECk4p`ex?DyAEiRl~S#FJMpWr)>t`j z+Lyn5w5?!KZI(R~o2t5@4smQCuOAXDP=Vd(K{kT1$=~hefv&f6V}lNMr;`$KcPW-{ zJNxXfZkhWWr26A0xu7tCNODh8PdD8wP=U^tQ4HZB|Ni3{D4^G8y6t12iiH)nv*R2V zQFH$7N(h$98^oCpfzLJKiZ>?@$?De;8n-^c*hGCdp-gL%XB{IS5jv(p6Nn;T68l1g zCNJ*G62_(^LZ`=PlJ*Xoob~+!By_h^P;W|5+?DzbW9k1J#S-H2LxH9Fs^pJbY(Nshw1s3ePn2 zM5C}=NIiq0G9o<3RR~AHM1a<%{JXbfetbgLMWo>;H<@tm2lz}#5JEn`R$vSjH{U$^ zxZCVCxkRUBs;kJ*S{X3$$s}dbU+aEG(2cLHleikJkUMKxB9HXh~=yVjsmRy%Kfy7(=|c3+bXDFNM@3L zq-*An_KeOfX_Z)LL5Q5V)w1QS<%8=-?RrjM`1=Tgcx-&Msz9Q~PIJj$eUgVCI>wRE0(ReR)JP{$tat3)rK zP%J{9T`h3y(4o>5C7vY2jtIY9s30Nsiym<&%f4&3nDnf?S%hktvr`*YKlz`; zHaAaXVDwXXm`?Svc+|?2hlcdaT_Y!sxm+G29)*iV3l*#k3HI#iSWq*7jPjhGMA10V zYW#eMBRV!RljROGicLUVt7=U|o;LSuFk0r{VP0rAPdE(nF z)^84E=6qqRT7oN3H@8{Z%~z|7LtE+I$CdU@o@tED93$ih0W4|5D(bxemCF=*DTsAk z={JQ?+#@mbM%%dh%v@Ed@0M0sis`$|t=tHhva8KDB%?y`<((Y{>s5{-wl?P_{e~6I z?Gi7;n%Qj3dN?^`Q6!hccS^vu36*>&?+{STe{BA*0-U_pfL+#SG|pqQu_Nxr%a7lH z9&@M*GNg8cOKGI)%DmD#`lljRh+J%zOhT@z$|`e6UQ+Ts$!1SoDvJw)a}??Te<^yS zhIGxO$Y*4Qn;uYx`dIQ5c-eyN96e@$lYO;(a%zcji?MdekFgs2iHzDv+U(v3u?^l? zh>{&jVjks5*G=iU9Szm_-Pa`Z)A@sNTm&BhOZc?@@&7wuK@jXvs_Hg+?r9u7YVR&s znMvZ)0qyF;bH1SdC!8J@f4vzvxUOR-&5kRF6@ExJC^VyR&m8txrVn1Z@Nu(0<2Ee| zIEDPNDv*nbP(D%Ww~!1re7o`WCIK=i`-tj7MEg1qClhTu_(T`1DCL0LNr8{d^z!Nx z|B`%whY+~4_ybj+!~+p5b-@{{nG@$hXKJXk;#*cG^A`|bOwuB2!|yYV*T>fql!kC@ z3e|d|Y*ghdpcp6}1idi5E24VCR2uttKrn(osWV2#E&E-lLW|6=PXW*44;~(2L*5bk z|KNe2lvfxi*G)vHA%Mo87iTZN9tW_@^ko7_dh(CBXn8CV5SbVS8y+ME9zPV0CsbGT z&W5Y>3fC(qfaoD^9me8VsUW>U-iQtPZ^ryz!@fGw4x+FTl+v&~CaIv719sa2GYH;` zLb!C&$J!||D~$}UaWDxtrO+tTcRL+Fb)Ms9o7$&S5^%4}9azy4JLfR-ariF9k#?Q< z_yeUwg6JZ%>#5`vDnI7e8q1Fyf${U;!CO|0=6hdvpVb)pN-Fe^n;Mcsx}*vd0m4n& z27~kI6aHrb_bn3{JAH88(n5=h@ezN2S+Z7GFovl(-q}vIXUZCi?_4;$Zh1#u`E02C zAnIx&w8tCNmKJDNq#b$5MeOun5n!nTR8XGyM+z{SJp!a+55;9js4*T!>YL_DDZcWi zOKQLDY@+XG5%L&3_$l)z7=+I@2HDjlt_%q1ZPbvr-u&Sx#O=Sb)%qJ^>;-7_nK}Gc z?dLiIYZp1DEa;|;hfAx(rLSKXP;bRfv9Vbe5n|* z3k01|(lr1;IZiAYcrw4=pC^1juV|2ZsHy%oq?#&jg9~U`eiCH4wQ(uh4W+yT$iS(G zAtf6iYv>{ZLncs9)RzApA0-VF*XV_c4rJ4}uyUy?MXl9x>!Z?2$%~d{-5wl?I|kaG zUetw@8m%e5^0%h6X~q4lJ;ubV{FT^e1T5RM4QbG&c0m2jVjvZp!1giM=L!yaoD@Tx@KNS>ou$8e3ise@%|Z*= zd28soM62At3~(jq%SoIX5?v%-D3w;aw&|=Y;S}i!E(U4DI$WTMHmOTEoFKg?Q89Q$ zV^>!wn!!dA6nbv+lVzI2@B_A@J17@E*a^?BuNIea{63nK0jD(1Jj>?WA4G6~voZAC zgHp{hjF^41<+0?;-jqANOeWhuGnoCdgO&P+Jc>?RaP3dLxE0);qt+Fg{Yd|-bw*(V z8f8(Z@us@SE+x?kNRSr8cuP!F(9kI>`bWI+M5f1iB&&4?#6FR~TYt{L6FniUTJ~LC zI@PwF;odsOjF3LM*ysa}4)n#6R*Y6uCee49+x1*>S7~54g=>u;)Q44zYWVDel>W+F zF+W5#sP2o5NGlf4HgxZ5kM>;%T(Y17*%t{khNLce#BI0zxA*@xA`vZ~o$`zeAKL(X zb*h;-yWl(!L2bcQ(%lgf8uag|U*3$;m4#xgx0ZsrsOpAB38umiP2p?zXPHEB1UZj& z6$_^xeSjd)HH;qGYulrSIupdt2K8u7RZB+21!VnuFz3a9MeOFbE}xzS{=@$EI*WnJ z9{!nFGpsndWQS~=6&B0P;<+Hd;1lgW%oV^oKo5TaX7q$IYm|NEf6SRWU_3`ITv*3r&~u;CE;bK4{&RUtNGy zGRBo>waN5O3M1DW+h|M|5@A#mo4GOzr`Y0Hv`uG5YO&#gR54@yknc%`kbi71QKzD$_i%w@G?Hz@ywXh8^;vEj~qI{Nb))Hs0dLyF&A1uLGY*hl;u z!tlY%8SNgQb?R~-hb+p97qFvQ`v1JJd|-sQ=;uF~`tXY!cv0s99pive-IhmKp|E~% zIOiOl>AS;taAwy&>A0paQkS{Bq#a;5Ip-``m4w9q5GqCguUJ)%XNy3zk_k&M61}0b zJT*W)Apy1OQ6NwuADFNCLGuGnY3u;=!(sNK$-=}|Qn8JD0F12#_nY(g28Bii}Um@F`sU}cw7Dsm z9_C<7)fIiV+9_rnkQx2<{X~2UrQuj+%XiEOY*pOsNoAer6%ZVGdmnqPlG)>I%e80! zmFw(t7Q$4>*op>tGZJ=~l_Jh_rU2%tY)E^xd*pbSo;r5XIZW}EyvCI)b3@5SBx8*9 zTfD@n(1ZZn**+*=!!K8^4Q{vD7%}el8OkK>Bp(Dl%v3)d^bmmC*m792iSut(a+YS4n%3qXr$C z)S8-fM##YO#&w=?zh4gxoMeE^JXnM|53d^-UG)CkBNZZGDg^C7K()+m8wV!5wrrOU z65nD$5wGCUA9N%t4hspHkH+~X%!DRGu5;6Y+JSis$q9^H+|!o9)1tk=c_U~ zb}t|Ybl+NOVExciTm@asJMM~$Ya7SEc{!z=_q#yprc8fETa#RN%XdW28}y_cTkl9#!WLG{9-j~5{sitx(;fiK9)<_cqCEKcTZeDsPKEwv9a0};3YN7F z?<`uP!sVWUft7wF;2K?DBM&oFoJ6Qk1FJN`I~o4^;rNpoi>{GKE@I5c#7=W@bDaYN zx`bSvk(b*xiUo!I0blPRZ2$jPi&wG-UIB1ww_575fK>us%BMy+j!iB*l2z{WV(}!Z z>J7d9bePKnAe7~?EkU;p7}6BM9;E8y*LP1GHmwiOh2RO&k!!$YSZ@WSPCOp3mcxe6 z>HDb2bQf&S=9w(`5nf#t4>?x|q&@tc=p7h>5jY$kTPkK>{rLjl3Bp&J%pYq#N5DZp ziRnkx#L9>mO%l%|8w(@fraX+$R%g$^QxR zp6*MEmAdL9ASk*RI(<|w*xU;KwNHoc%Of4ReBD{-?CiTFLv`d9sohhw^0)VrCFtp1 zuLZ6xOT>WjW;hVIp|uC?6S$ zP&EndfOZfMQK2uc*UZX9Ak(0@6w$E~PEkgEI~Ez=w3CzHkRbkM#FM^jc$&@=peE~Y zxcEeOPm3l8hJtx`!KgJ{X9;IZ&x~yMpdtlUe@u}wxdW})*fNXAA2D!Ef4PfL8I(7d zOy5~&;`6e`E!>iX@({#BY0)K(daqQ-+8(VTmR0r!S)Y1QOyn+IaOXV3WI}q`Txj$6 zx^%fTJ#~C@k&gMZ#|wVNq^NF9G|SZwMzrDj_mtQu#MZ0ks;yP(_?4i|DIdh5G%UNK z%xG~6IOT4FoFPBbi^x?(u|2BV`&rC+@ju1QT~2U7M&s@GELU=mt%X9+Wjj6WH26uo zN(IKIH&av3%X(Ye@=(lh-q`rH{AS_@p2I|43={7es_TVfGK&<)y^@P5Y}qT{Hv!pQ zDXh{lptSMwR^mqgTzLn!+0xkcqe6^ETBnf&DOgXK;{4|V@$|JK9V3Tcr&9#?MgD$xr|6K4STGIJrFGsC%mP~{5Y_G zix@UL`o-yfytSCYrW31{UOPNPn#sYm{}~BMt+0Uh(07@wCCLRw8dCn8%v&N}_G05Z{Nq81XZgx7X&EFee`b=igTRU; z$)hB-16ZBl>HnJWlwoGvMKlxReCL1tU>wub> z&BH1oRJ(Ih6QE{X6YQreldQq5sgHfhyP2B}jV3zgh7t`OxhxG8i1{33zwc zE2CY-Wf{gl2N^O@KVet)6(~8J;A$w8%qwyX_{0P$Vq=k1bfLX>s#tGbVne+_kHW7Z zDa#k}B7{-U?fTLRMZW-H%YBlq-7o-GMt?m$qOForQ2jZ+RxyyXG2t}E@&$Qa&d%fG z_s3)B3}Cm#2o)3aL@7(Iuwy9x07I|W9KAucLYD*&y;Xb7v(`DX4kTS(;_6gHjB~X) z9D8yElmDkwBvnvJ=zRHIVH%dMjdzPRFNd6PJ&>^y8e+2wOih&g=A(?hBX#s0@fb+u z`P~g%E<2TmV2X22yL&4345D*S4AKW$V&0NJ#tcl)>mYoXbfzX#)itcC;J!Otl7Ij> zRuMOc*+<34_8D#QAH-RS8FIHFz4n5ohb2(8zpNt`5{lWCeb5mshU4u@L-p#5f-+sW zsI{dDS`W9*k`{fa3kkv5XRnXzzR{o>Ted(8fPj5HIG%MP`zs=Ef!_6Cx9uaOrZ}@2 z!{*Bz-%r;6IXp#t)h!5&WZiV^&&uG?a0m$tL-*SWWqz$*3 zV&Ir(=MhGOX1QFWfcVt4X}e*?F`1p<4-feQ#{-Clk_BDjv3x@hhNu}8>6*Xsg!1P+ z@8;lz7Kz4p2>r4)y$e&XkPtMbe=kmY*r@<>EvWnBGMgttT2vJP*2hrd&WTijM#*(7 zqfyhKIb-4TB% zOeW45+KU_tmF76KK6eTOR{lhBaZr_Q_545mS9j6zj987WcApXVe|N`69P7kTVWc+^ zjhD>=P$A?-f#4&N69mukk)R%mH0~QyPt`M7WlbD^L)k3&6}B#IiyiRQAaK z^5cK-`>fa(SuXdSRQ52}HxRHKMXq!Kj~l_w))U1xAjoe%RLN2yIeg)3Z%@3hqb#|z zJDaj2TfVQV9n>TGkf+E_#l2;%$>87H6ywC5H>PSjU6^O-Fn{Cid8UCnOCip z6sATKzlLY%U*f7|?+$Gj!tpE*Q?iSpK7wZfO%#VPngvKLSaMIJ3+$CYz*K5W zS3T3txSA?r^lWdKBUEc|d+J!djg7j-jTt+0i_VFT^^{(EfEi_jg}mA<)pqnyt1hkd zwk|M9=5mN5r_@WqmIcCjZ>`R$KRH|~C{}QuFYWZs=QX}H|HIg|mbY7ZA{~JUtv`u!cS4aylv`;hiVa$M&(P#s3Y9q)&Tjl>XI#5QSGBm(nmiTaha)aru|9 zSNZSOcpm$&sEsh$daDq#r6tIn7}b5WMI{UrD7LC@f%&?gP62)5{J=Z8CuL|wMoB(-nd!|U*TVn6Rhb-GOGSvuois7xeZ|tv=^;v0 z^TdbMN8Mg~ipfei&NwBrVV;4&9J^dm^$@>u<>;PNDD8{zy)zry7k}xLdk}0f8^EtQ zF3)8BOIwZ6dlt5eG@K2CQLWGwl<|%-I6!D0N=&l$5!X}li(?4L3C&i(Sy^;SExu4p z7rDq`??}+??S)_|qZ&MxyTYtop}Wx!A2!R}c%#o!V_T7zgw4dFGVS)TgX5Jx9-c__ zgdV=vzW~}LojPn;5IltidEivb%OB`0vHSCZ+@`j8N6rTY0CLR%3TALHtFTO>jClXws96Wk`(S9)0>8}*LvefUC1z@8nMb;#DDDRCHZS4R#jK<~0t zIgHyJvRr7H*c3E{OWD4|C_|rTm|Cw*>8{vjp&OY#4E3w-)z~qBRQjoQ-v!oeYyfv< zGPHUS;@5{Z$I7dbJ97k8Q!7b5WY0V1wHtI`knalK{8b~i57ppq`47Vpgr@2=rTT|* z4iV z&(y5klh7!2QEnJAy)+T|2Z15*I{h(Rf(e1_TeviHz|w(5N<>t;AT@(r^4m`=XM-5^ zANMTQ|HAw*;h}X93sbuiL;@h-n!4B-q}|9F%1xpg z8#JEt$Jp2skKqfdpcl3vjez{x{;(4~+Kl&`t}ecrKc}@F2cT*iGp*G%q(1VO!B$rKt0TmXG9PcnqtjNab*MTNrWJ5QVrMHb$xchZ<~YX zWF9aYjGv>mz~A}(rn83dU(fH@){&_O{CoynAFVE-U~F_q(}Vy5&fx^=3ZREX^A{uc z4$~3T18JhJ9Rwy>yRx#g9_{Z&V5ZaFq|m6O!|aXtA*kIC5j(~V6(II;d}rkYFc9sM zPvucl3~a6z6CoYr6wbk5pUq7^MoHGv^W9DF zSl;G&QEP$M63l&L?y}lDi8ybd+8X4j*Rz>@9A>hsU|l(%48Yyu^qaY~Q{#_U3qn3xAyu+0Xx4t?X_ z_S8orP0LP!D9%vLHR@%{PWF#S&2;UgSi%cEax^J4BF$$*v*CF09oAjbYhy-T&2l^~)EiRxWb3*egJaB8nqo(3KSgLrwk!A!t z4DOaqSb8WLqt2g+InMwHa|^NSR3--{P3=Ke4=S9BsJ$~GM+rdX*dxs5Wh%{}4M^no z{e)hoKQ|KizJKu-Jx7Jjocc0xaBKCW_FqA%p&No?7+aM8pPy{!R%kx(<2_)!>#WkSZ_PA9z^%q1NLm~7HCavuiqnsiw z3ON+K%8-G>A`R$vVcg7*%D1<%UwCQTk>!a?gUepxbiQfhLzqP>@eh41Y1T~=5Hg}U z;&&6EJY*MYPF=5xlRHKRCm`>+0Uv9b|Gd_B3yYEzL*A%8^`-H=r zHFLf8QdL$8-v%TyDCVbAti-~7h6Bb?bn(Rqs&zmUZPX}Qw~aipYPA1kOA-9nhu&AC zCqML0syTI z%9xx>Sbf#me(BrUP)ZG7=99WHdC>1a|IGrWPGF*%*cWwY%zczlOzQfQXO}Y6?iQEJ z)LcV$dw)Ko*j_J;{-*}(Bf1I1SZSxK1x}q-zWnF>IW?vtOK|f4*I+P*o}f5 zvX<{ROT}ky1MhKyZ7BBqB@yT!y&?>UE57+NmroivKoFKQ+8X%R}+QuLzrFqj58p$!( zc!AP-b%ZMs0xm#o6~<}g}65s;O7k>t;Ff<^3HiH zQB>ZXEVb^an}jE}w_SC!+6x$d z_y<7#cL|ePraO2G^6bn(Ghl~tK;+A$=}cED8357StOXcy4=#(oQro(|GWNtRO;ML< ztUG}=(txa{WG~fOpMVJHime@N9PdPKnTWgvnSLyVLV$efPZLZ+e~%%{w7b?#sZjX8dl1cSvJzjyFEqUG~C zFQNh23II)H3Du1fXm_|x`E5}_>Ba76Y&P1=ayBf5Udo9v<<#=BYEY%0%ljiX_TwN6 zm@_+p7xvd&prVN@ggCDGJbB~yZhb_d42lcxC?oHYJbact0Asqtbx9oEt(i$ko6jZw zO}vz<2ce~^x+`2p1}(T|-DW?|GoXZU$%AkPj89FR#tqrq_((ffZbd)D3kICYwE}#O zV@63QiV62R<7Fc|Q*FR%+IrNVW*cYzS0@RHYS$!*W%3uez!oa0NGUo8L^(z)Uy+6E zrJwV>hRt*JfMb0ri$-cl)7;)|=o2EyCCfd0m5~MK= zL6|XRibykYW<$D9)iw-r+4{*?dMfRGZ2$e~))s1T)shcg@-SwJUOtE$aL;K;1(o4d zf~5SAS$}&z_eEjlsi9W3nnD}9Bux6l+JEv--8AqLVMu4`O)}$dzw6}dG*SL)t0W23 zA%16kP%#aI<_z%~i9yt^1>25dd{aUdv_t2V@W0(LbM_E_&xt#kJacxhla z6i2amM`8TVM^)kUH<>_+gFtG2KbRMF+BfWna1;}8+|l1#ed26@Bv@4lcA8*c`ws6# zmtIL_#06SUhX_z-a(=riZ%yLdYe-KI@RPl;{D3Wbd&0v6Btx6JwgZ6rMi?nE&YKqe z%H4eG;Vq+D+^yr(U@2LT_iXJk8awnF2S+KwY9;(3Y{H=|S=UNiGX)XGtViZH_6Z=W59KL|T-#OJWWc>JvL zYWJsaa*C3#zE-#@^wTl5dumxeo!?=~&Q@VX=EI#0T@VGTcJ&Bfiid^By+2;i*1}^K zb#gS!`^_?EZbOuebOS-g`nh50ikSZrGUpg=C~H4EOTt(mlFQ$?0OiZ)G~bfE{i2!x0rJWE_#ydEoFSQvz#VL zS`X~xh$jZ+74*V8q)hfSeDK_TH7bY8$Z)#Uzg&84dpdI14GdGb3}V;*5;k^zk!fC~ zLY0(qTbeTq(vb5C!9AvMJ=}&C$uQ;q>KqY_>a|E1%|g9aVqU_03=`e)qHm0-#5}O| z%QS5m_8!04AaLmdjFs}f&BU_L+hAuZf7_&GJa)!z!dgli6$zKWD#U|+&WwM#XPfKo z0TK>&3J;$8N6bjr*3?2RX=4@0iZkS42Sq|zyX*l(Nq5v*;WZxn><$$B_eOH=_ONm>bJ={Lr}4W z%nr_+0i22;ju8Lv2~rp#l;@Dfa-#p;OM3XJl!3`AJac1$soobrr6z_=NLQ`(HQmkXr7d)*pkeQ&7OFs{xqxmBTig{{|H&@J)Hy z2F0AhHZXM%p6!C0ZOYpqG^+9hBw;VmD>*{jx0D>RJqJ=1HhJxO=;3Bb%&kLOWi!)f zWd825gpIVw8{vM^1B0*1XfgEc)Noni#)kLNM#wbD&Jkap?bz~oU@~Pl4l?|x%PJ%z zeYeM%L=E)*TpGG9CbicR2OF#RW?RU2!oH7e4$*^_nI&{hvAL)gDUI8h%}9TsZ)_YH zh#n7w1J5rSAR@Q6tt!*B49A=+RMQSz3Gs>tfV9+4G4(RDWD2WJL~%GR)fclc!7{Sq zb7({<<__zCn55~h=jQfT11Kq+&&tMNgshDp^PmimzGAKAhq0nLWHs<#pqV!PkmOkA zw*F5V1XZ284kF!S3RZnqwD`rS!;baz_bqq&MeL=WNg`_s=26lNamX;;_oS3lokFVH zc6DhzcLL}=^5_j-L}+gv$5WXmE$hCBjo6jU&aOX4 z;t6vkIEl8%>hvpH2(gupvO{$CE_Ucc+km2kd{2feDxilyUgdw(qs|Hmg$5f)MI8h7 zSm_b2BCr>sjgUY5P1gT~17LY`S?TwEr$#`O`+<<+V-w@KrZP->csq9@EVT9!5`4e; zylq4xL%XCxV-TzTugW(N7CE#nHXT9S{KWlCM3-OJ*&&48qjg%g(HpC8d~95f2s=MV zCO$aKD55i^-?O7E?2lSRDND=ApXoDt`U!H!+m27rF*bBZ+HU_Ix zt_q)ySA`~MTLp#MNLgBQse1+{v?QxDiHr|i)+Z^@lB3ypPZTTm*`0Q{ueIPBBf)I? z23eS~91&(t?or}`&-9$gSu4L}{cK!ryooEwG|j3}e@ ztR1C!mwo@6I=ZvBvKwB@s15OP-hM%67nS3g;fSAC%@pNWH-<@yU%8msEfS_Ih@4a? z+OU>?N~(`qkgK5b6v>EEB|2?na?2ztS$Cu+#*p?TBHI4~fI|XdwH**hvEc-4SenL8 z=9n?JK2KR4=*=EUo_U^{wL_JxM}zsC093o>oc&7X2 ziJ2aoT%XPv2-Mg9LQIq$MHn8&gv_^yXWb72eDh0E+N2FrG0ltAd}ya#I2D2gxR20{ z7fLPhKs61K343j}?eXwkpg)haGhO=ZBxS}}K_9?aodzfccJAytGZZuErf9s=aY@nM#D zCBQC-cJtUJcDq%lubcp3XwT?Q<6vft zmgu&Ia7ce}3RyK1sWbqXRy_OC70NQwD19Ooy%U`tzb(!ro&e=*78GPG`gZ?{=yiRO z;2AVru}dr&Ir!#n36SU!$0EzSd5lgQz#Uu;O48MXQ_aGmPg!5_M^O0U^hK|43<@0W zoKiEgN`6#k1;S+&F}tXV<9z?So|}`-{}|cDDicjiIkJFfWlf)LQ@L6P9K&~Z(WU_~ zpWUq8h=WGXF-f_Dtw9ye=Gl40dl}JdCx~psaZ%>*3M%Oa2`Jg{39K)`A&IK&N{`(%3eO47aLmTi5q`I0Z1D^mUJFo03>`-B6hf<7X#2SLIDZ$9!+!8jOrJb?t;7UFBW*|#{v)g_+5Ox&_?KFi^(H&G8r(9bQM^ufFp%u_i>f(NXj)vOVst0^dgafw|CSH;(l5 z%LIzsvP8!FLS?auTL!iROO$3j`G_F0>?&E9#L@+g`JDX2^hKgNz%(!+3iwF9_?(4k zA}Y@Nr@_#9s90@V+0%%Vcd#rJsj?CKL@=-`r9!)J*AC0C`0K*cq>Wp>ya!GNt|eA^ zejEMJoLZ4jHfsf+sKUhe)m@oH{Boh*And7s`;(!5fwD`Thd}D@NxEP@Xf#Jqxrj zk=_+sNXT z#Bs9Hagu|_3grM`BZ@kwoZizSjLA=LuKzjtdF4)Cjy?@WEIB^ zFrQH8vk+~#7_@1Dv4@Z_f-+~NHY6&55%sg^Yb>Xjpzd0q^o7pz;2h%cK_3JWTUac@ zrs8>0QIV1ee!Ou0#T9iH2xW#RMCUC>^Jk*p+49_RRbc&dKhg#COkp}znCWf=e7fu) z3iPiEiDnOoVX#Fk7!c4xc!nQcVQrMl^abuljM7m9s3Uk|y@N~u{lGdv)8t)Lqac$a z$I#wl?`7C*6#g-TW*NL*t-Nb?p=Hf*`JM_HA3mb~ZWmK^p+V9n;A}uVe%TsPp~B)Rg1+|g;ylM#iWn| zt`tZFJi;{vq7cvj=I?;_P&d@cRbgRT0&;p}<|`EhA;vXy5%`P1QXz9>%&$9=PM&8; zB;FE4HZ)BkL%eN#d>rxkF7vxLlf>G5ng-$c0g9+QEZzdXE%0%mm9wwpm+9BQ`&oY1 z_GocM_2xgDj{!NHW2&w04eC~p_f;2TTzgc0wo!KEdYI+%8d|eeDl%r#^l!aWpqDhB zgsp8GzSOOBSXxKv!?%$78H+E2o?5(Q_H;VdEX(l0^0LT5-MBWBMiKm1WQ*bvf0xV1#YIn>pHjH~z z;_|E^V_k6nGZ&g4%!f0TfR+D?<7k7u6#zeR>3X>H9M;wIOlB5aO#~f~{Kf$WLNNcd z(xzf8satOZIV-V2{QYT}YmBGA^TY*)u^}YLCs93XE{t<)ShyYIH(GNEh|b4#jE+RoZe!6ID0I zRi!c-4v;)=q{}?K^k=!Ww?9k^HNlP0;deb3;YE#AP9E=;EGjj2T8h@3RpfVmo-n^t ze@xim_7hgKQgT?llS+(@-5gp~!cd{Eg9l^T2X;KzcbiRMGMq7K*mPo-I+jkzc)a=0 zsQ2hiYGd6B4qfi*Z~f8-l=uuYQGkGd>t*}{dZ=-xCP+RWUYjRgpsGh;nkjn=vQd!{ zNM1~;wsDzThtwZ}ARWY?*lRHtcWFdr%emn}Kp*f2%{!uXfXAE={I8Pfett^jx_v54?}PL+P9Q5w~D{r%K#J3;pK)bP^P3c z?$DYd#%&&dr3&%Hzvei!E8w*>_*IyU4iT%eYxUqI>Sz{Bw0&X?RLP9hx}AB`OSP^I zF#9d_dB$MpJ3El1OTapMwz`mPDeJq*H^{`f5TH_4dyxp)2CDkB0uIk-%>M%LzeLo4X+Y2~8IC4Pkq=*}$}!8h zv-oeP1PoWO_m1{DMsw%=a6i%dj%JwC|JB7F*HcodrLat&o@Zg|QGlsuhM=>|3ys$D zw0WJuSiBBNev05rss+v7PP16@pH4^DxE9v>VE*DC3`bQS<5WE%0E%pH9Zu|v{@~0o zaGD_Kezru>59@+W-4_To$p*Hp@OkNWLzLp8?WSO~0PPon%5rsT` z88L?qWOBqoNPT4w{vC=hYMP?pUS`1F5At#dh8v#h#7wnCzdT_Cn}}1q4O9fbU>JmU z?@wc%aqAudaM%>y5f9aMKkkPXB%@l`=%4(tnP;Qz`48t&q1o}z&B3`J#|a29CI&i!WY*4rg*x1^8+U`&0_^9xFWBw;zOWOr-t$A@ z6L{v4ouuejaeWQaAF9VuilCYv7G4cUn)$S%-pZF1!8U zay7$aJju#jw51&vQXl2PQ|I^uGr3P9N}3)Apgimnk*B3d%cXbl_70u%0KjkEsm>Ma z_7iUZ$qS5c=r(+4vWvI)C7ccx*K-%e4F=%<;V5r%a@O9#bOHSl$luBv>eZE;#U6y{ zP{$(df2==&3i;~SvD@*4z-4IX555Y^LFrUvO4-69npwIPa_^Cc8wVxgKI~@TaE^!h zSz}w@%(FR@GY4ON*{@#uc0&da)G-uF6k;WQ{v_2UUez2B&yx!wGgV^q`z;bFsR`JarS4F8@9%*Y zmI_fmMk+nun65F|7BcuWJEqI1H5fu9;Q@zQDto11IB{vJnJC?h<6W`$IaaXhP|&e> zS?!DoIueR^IjzrSqXgq;9>c!Eb&wPbmLF4~wZl9ln(pm0`2HU*N7DDrQM5v>_r&KF zS8hdn+!2QUr&sjMtVfL_H)WG^_uXA#;M++Xdj$iYaPQJvYh2!6iKx6TGe|~|bJo3~ ztf`4NEUu4Ygec^UfSWHyVzmV$g2eam+&N)$GzQjEhPn7wb+Cz_;Hdv z9pUV=hUXs%pAM?!NmsGn>^LU@gO7~3pER0w(D*2skenEG9tvo zk(O5UO=a#En^4715nEG~XwXZ=_wtZx!N5tED4_n>=hZ8w`*<@u&30RYEMx`v!_17Ff6g+3U$5W&;UKgqZJ{L>lhkBnnI` z{j*K3*U?fNX&N}%yErjDrj%GzVQ?CQnf?H#C$Zey`;P-Gpn7Evwzrg~FL8^VZVMAE z$;&;~896|ODZ=A+5r&py;Qt+P9E1dF;BE#$1ahem?hPh=lkpF5+(0tMGiVroL+c6; z$Jp?Qfb_}5PrV}oZ;%{Sx7kF5uEq1ieu-RN83Z%tA>$4p{=ggYD+&oM{dBVSMwB>F*MU(@YI=N8WnY!T|JPD7!W!IW`c0I7UVwKnoA-i zxwsAvYh4c=H=Y5qkc_jXOeNnU)E}r5JaasqOowTmkK{9B_AJ`Rh>X~%7_=+c8^>@! zR9U1rbHq@;3qlvl`*X#w6)Ec|(S@{;f6pawuOA0m1j& z>>^{Tv;M{P$}uxdvsR#TNvv}W^rRj{b1?*;vzNFOSonAumcR@p(Z=8WV18P(UN4)5 zU2(rA*O+@k7wd+$Cyh;j!69S?3R2Q_uopGx_4BDQcqAG+eaLCh^Z$rG5?H z^hjbXRbl5FM!SF@<10wrI6MYcEoN|FcOnRm;+SHJjf&xRy8hdIm2#1q8|#?IU!;)! zhuVit%*#qbs(nCwY^fY~_|*@&Y=(Pvrff%n~fvv;WE@`a#N`54hBPY(PdhFHoa_2I~p>HU^I5kxq;eSN4jGh$4$4lb5K9 z%ETf&AmHWQ+*LI8%;SJ)YkS3vDh{dEZ#X$}V-*?{tndU=#@|j2g6?7r0OP~&Fjsc; za1S#scY@3aK0Iv!KWzS`mCbb|seZC7)PnV7a0^$AbhDL0%)fgZ>VJ8?`Hl@oWkjE$8ksug=?QD%uE#d#PwI1iqhcTqay%6xaK>=P- zHPi-LTR6J4Ss&3ULMWFCdqln7u-JOviVOW;Hi{MSf2F<9!n+Sl^1Re4&v*ZC@Mc;RwJ9nL)B@%R) zYUjlP-&uyECJQ$93ji!?z)mZ9zT3~stHS9gjr0BW=6SR#J_HfQc5l$#{xC$lHKcq> zPKsC5xtG%7QbQvhcYl|E?ZZesr4f}G4pfrMw{FF&`aMx<^@ol;Nz?TZoY(BpC|nZWm+_fGVM^4^-R?%Ox)Cww2RQ*q9O4u3xIiOaXX$-78-92E zYpHbGm)1_tK09;-cg(#&+2mnb*>^Zq3on84yGo5atW-i)=Sz))lcqZ2e9-6;g3E|g z>*kgCU`!tYETaqG3kF{4Tn)H#oNB%r*Z`i%=K0PB7dk+Jn7*Oqx*ZHVWi4((q^S|j zbFc3;YYRH~^F~(elAry#=;{-Ae;$6Zy7pbRZF4KlY}6^<>|4QOXO>D< zu{E6XO>6sQsk2LnE%Jz&JifUlgmiU#$(^Q0-Ybh=1p5a7%ofks$#4j zKs^%9cSS|xl+cuZHm+6u9Z&amyC3g}4kgPpNFE+4IM}>g^Ogt1tw>buIxrg50H>Dg z%`s8mbA7Yti&`@`Ji4q#glwzsd&Gzo_t2YGk|WR5H2(3C1h!r~G0&u|~%wXIs)6p*!Hn-7cZr9js z`(1N!I1Q#BJ|4^2-FGFXgbYDmWn>P0X+xt(?>Wm#UjZGxu)A8QvZp&VB&T8ySdpi? z6fuxVjH!x)C7>pZov30cBO2}LjC^6`2#n=9+Q=mnAyr!`G&+$Wv%owdXs2QR;eY;3 zOlDGCM<9FK&YUyk*1l-K`)!*W^?=RM$-PZwpw(B3piT_$tlPrt3~9>z->#3~amtB;I`DBB!@Yzi*KnAqQ(X9R~&oPIhwR`MVV1-453&;!mpmn0R`L z5t(21hZl$aaz91`5q_!DddQP7u0#jS{LbPRvj||g4ML$}kztfcX_U2py;u@P3?ahoBSn%k@tfa<h?$YK<*V;Z2NqbDOYaBdP!rsuhvX!1b6 z_tOb=R!S>Qr64T;9|RV{!!mAqz+%3N2}}*gWH_>YWWbIIoaEo>qujjPccy=BJfx35 z$cvK$Nm#YtLN*-nXt-h+1dwVYs7Px?WkY9m0lZJ6jn3HjLGzvj* z(g9okNBHidjRUAik2_`CDY>QPd`kq6=#cM9Fv~;gZJsH(?KcB@JH;OmC7>|i!F#zD zaMB;$|FEf=I~W%%nZAubof;vKasJ2bzjDBOBKzxuY#a*e&olexcdg=V`bfiEfCkkau0bIMt`|)Op*gc8NR+c z8AU#QNGqt7d<47{i6O_{EMCUDrv~yW7&#(sL#Yk*Crwg|9Y1;h`QU9Lyq8&GAbEXJH}q7CRNEy{Dx(!CwY;bzBO$89{9}moQe>d zBX4CikA;^~@fKwSh^2iR*+oV_aZO>BrsbK*a2d=8dw8{DuKW z8H@61qEYyD?CVe?zb+YQYm%AHbSk-d#O-m7zaA>s%c?=y82+zz@0)vB_rssK3xNn5 zp-9K^ks`|+QFnsYU?VU;om8L>KSJp<#myh~Z65rDKyP_`yRBGID~h);XRFlVqBt$|Ww7Lp4o8ga zbKr z2e*mN&^4xla&$@L%oxvVjzc+0cLMhp&0400df_}$DiLD_p|PTN&c}xf?R>EC6=n7b z&tc641{rmf#haI0DBz8{ITlT#g)`yWeIN>YN+Tg~?aMFzIY~SOmIF`kVL+0n$nygh zQ%8V}p$GzeOLkq{u=K%9Ja z=bdC1KCafn`H=r+ckRR*T0@DQo(k6M)=wMI`boP# zauhsCE|qovz@ExiGZ>L+`pmQM#^bu}gVy??)y;SdY>cD?Z0`t0!LL?9%;39E0u#2X z{9*=im0gcZAGs{dJ-7y>xTx&_7J7ikk4ub4#+hy@+6D2oF?ed`xDb5g!%u6uH zz*54HI;QXN$)KOSzh-J)&!y4cZHQu=&&>o|G?v9TMSWX~oWFN`7+pdMQt z4tM@sGQR^jwUp3_LA?P+%QIyU@xtSm081*xDxYv;>g-6nIm2r$z=X-!gx}Z0V@^t3 zI1LjTH3pea3fH~~d)L56JR0p@y7eMHi-ug7^%lkW9dg>W`9SFC!4#t#x6&v1{LcXRb;iYTyWq4s{e-x^S^$cK2la4NF%kL4`2ga-w$Y zhVW)^`b5NJdY{4cZHH3@=D<{S}z=4JELOEKR6L(+nGqCkNuSOlry;rIqBr$wf=u2=O;3m zJ)tSh$_u-a3a>LSC^RLtWxR%&W!;ULUUPt*ySJVTfuLvdpeIEEbEp-!`_5ZzATkF7 zn2x=a+ahs;r1_D>R!P}-ZfgP?@Qs*Xk?rfn=LOzcv2Fy(?pV29a~ZJyxwAC>V?)ZQ zJh&HhN1DFt)UNs{R@01LQ~|hz6^!A&{|t2m&{-6R6HbMV6Ab>v3gLpH{d6a~Ehm{t zX5{1^e+~XIU12dj=h_`jXyoyga-~($b>#u^whBTg44`YPlXimjnbcN?C*Yc(D}ZR3 zqoG>>bl<&Yc`p7c#s=u4&B(N#IBAA-9;}TG9@qD2;Kq;s;tqUJS;fX<#yM+qHDxMM z$jrMB9dHJ@`PUI%(>G2*i48OPNX0TuESA?PnP4EcG1V32e&SM?CC10Nh?&QPT?$X8 zMaKI-B{=(mWQDpR;Mu64Naq%{#0#423$a)>ck~i+z4}~H<9t{D^Y9w$bDnmYJF}Bu zqD&-r*FG*g*ek(YY)+KtzhX%PeNm{5&Ie!sxn_v$SfdmymUnB5ZEE>4#g;@=KyX_D z0Ojt*YiU#wj6TW#QZ1B2IXisYH#0yUfd-nnwEyQw`Df_qr;ay2t{rmPb(=!kYZ28) z*e~}mnK~y8_gljwSepAQ zz5x}Y$}R$zMQ}{4rpu^1<&0+=+HldYb0*T>4)uQ?-*^eD?Q)$8 zghA9xTOgk)jH`}c7p|~)hH4Sf*R}TDsDzpqydErfBNyzj({Kq+o7%}m9$O6*jyw9@ z02}||+DLss0gzAJZ7)^Dn@5zZZuCR==)>4mama9&CZ&@l#Dpsz$=N@I_w(C5;@>RM z@n<#sSD2NThtyR<+AK!{)M)qTy{~k!U(A(cO6K-bm1M;Iuk?JsU8*v(G_u%LT)kFC zkO>+^i`3}|U-qT=oLxpwe{!!E1K6Zd40QzIJ-@U^hv~ajbMhhL2^MbeZJ57>@6R-+ zM-@YL5u_;@Zg$xJuDlx0oJG~gAC;ISxtQoarw!J})k8Y5(kT@8>`LWpCoq##s~jXJ z2l!>HRaK9_efqZ|*TyTsuo)z_K4ti>ZTHCXqXQX1u1O>V8BaHr&0{UO6CTHB$Qt zQ*lc%Dc^f-LkK>qk=yQGXSy%UQerJ`abL zHchDl_I1`N2r;?P)4C(=3_LTA?*9)d{%8h1yPQOKyEYrQreSRe{z(orV1p|bs4+Gm zATW0mEZQTg%r^hqc8lGSwQx^t1jo6HAtFklT}q0l$+UI;Nuav<9Fs|N5>>x;K1av| zz0&>cpUIS^U(SY61c42Dpm7IR`%V~z4Qyhg`;MO3o?V-uyVTT04MLdxM~LAJK|AbX z&0vmXnW78kseN_ezr9JAElezuQfKb))YIZmDCy*ULFjSWR>b%UCJsyU4f-rQud=19 zAg{?daLw7n-0d8b<9hIisYG+pv#Yj=@?cz97;Dn96wEAOr*kH*?r$t@5q)mcT5}fM&P3eU!6x^X z#3uvDjqGg`2l}yPd2LzkZDV&V*@sm6yJgazKCvZG4})Qqw2b)SzWx5F*fOkY`VQ#^ zc!RBdf0NL3>-KGiQQS?gS$hf+VBtv)%oJY~?lr9xo7OSjjDDcXZR7%L5-d7MpKcs!fx zk;l1oGQ(G&nKP_I!^nVnGIRkc8}<+P_|J80lmKpBOITLL-$M-kv82@GHI@fSD|Krg zgth&NAcEq1Xr1i#dbg||TnY%FNHf6)wk2BWS+1iniIfoH9IO@HhN$`=+%H5OhCw<$ z1DdCe8f#N$Zl0RC=)e_v5uyMNGPhRkpmqE0skrM)hvZUBI^FxfLNL{KPLbotyh-jF z6;*LC0(m+B&2EtKod;~HritaUA%qt9wuT#%g_I1((AcHL%{?fv1fT?8h{`ZnIM6jl zJtIhRQBH9yArY$zUI};BO^5ZZKVBE8+vxk%j{ii0)t^haAZ!+4G^I^UXMpt;S}3l) zDiqaz4}?FtZH#1Txn!?EQ8Uu{)YQ4Kl zItqe$i_z#-Z{Xx$@p4{2vI-Q5lrQ#&_qESH5l|79mh&Ax&KyIBiE0%@2N=t5-*Aq2 z87$Dd)vE^ELYB@xg$JH-_+zZ9S#jyTvWXr zANCIobdg&hv{U0)GnedH`L{H9brXXH$?Q zwiQL?nAGCYcSi*0n^5sK@Wm`|M^0uea^zE*Y3Dm}50rG<2~itc*374#`JD>9;qYKM zHrN51yW9b!&)&&sVi4x``Tb13qtKzM2f9aW>?;s@oXJn_xed?xXvub$a=VOFBW|Ik zbP`wzq6XB14*9vdIr{%R7?=^#J*DU%4|Ydb%Ka{V`184KC>tYd0Rh;8Kw`qA{rupi zfVxo>wXc{E&6vzke3d$6b!k*@=Dw2b1p@QW0V-DCmc@5>E&a@{M+O(ZOlTyS4+yz* zPrGI)Jm-^8bP`F_XbHJ`9 zM)d&^$3UFI?!{l4T)50nsn_qzz#7ye_Tzq=&+>^&9f>#plCWOwJ1+uFCxhjZANA2( zI!Q6?G`zM6n0D;>(bvE+sb;yz`9=!{;lg!WvF0Dl2s+mTvJrtU503Ki(VdK(3$cf@ zx1-XHhFyXZr_T4oAesTb4ZZQ6?7sU`LsZ8iCK0iR8bGD@uLi$$3OQ0zS>*(2) z3A2c>piZT@kvA?P9CFuaQ*XeJcVxeGnIj}TBS+NlULk;+!7-pQ!TPCs@S4-&*E)X?X!6IF=ei{%XU)4)4ii)O_nNZZV80a z;Q%0&%}TZkpY9jxG=WZ)q2fwfk&H#a?TTdS3wp{i*a)5zfu-Bxr>qZJSfegIQlmgq)8F>`5;o;VrwSMwu6r#TFv`^U>GRzb_1#t8`W4tZPej z+3MclJY_ZzhA-B%?@)u?E>F!GXw<-?S$P@@<)Eki9O}X?wivJiN6+IUk4iJ#b6)f; z!UJw%l!UWw@>=OMdp7@m$$v^tuhKm-G3sZ{W(F?Wk#C;4$`eaS3}dx({Mz?3^Cr`y zVH1oHz-&*TN}wfAt<%2YWl3ff3iInr1%8)Uxw5U-qfB$h;keyke#83~L|CQ9S}h#; z{LpI>NW2JF>_%DOO<+in^4=d&3hRW0*sxrLJk{D57*(AKPT5HWvG}Qw3CN69CTcps zFV&{eJX?+64mJgV`taF>D`(mzkYOx)QYo>a#0iw) zWxZ+^UxUu%Tz7r66UAK^{tbmh{jAX;1w=<(E#vnKT8q)XOhvBh5XX2k$+juSGpqkL z|69O;5iL+?JJ{A8NWC*sowctUqND@g71auCmkglqh>w4dqadBNc67ucFD7rcqZV;% z1(|+DAwrSr%5oOKeqFfAbmmkpS4c%G zr!tou7z%+0DMM+WE7K)9FIHWJABWWp(UL)z8acW~qz#A1Dah7`^oC|XuM|8={V4T+ zVX6bekFjMqF@Q@)1D((AY`QNqf+kf)DQpfXi)3pYos0fM>uUN8mk=<%WIDuCWe0+! zqwYQ)3^$hD9rr=O>i10Y)55uubA*~w#&%Qd-y5t|pyX+nrsAw7yXJ z+aXU^M93^s!mJgcwAHLa?@YnQ-n%vQA+|kpzLo<+0B|L5ZWvZ!?X+JO;j2Zb`%5O@ z@Cc<|ya~-X(TtX<dh@jw#_5(nDBwp&yu)? z(a;9Vuz|Ka3;Zlg-Jec?zgGJHr#G3}5(_j{X&E1_VfYx00ROg1L`b)@WUNWPlMg1C z^YMVG>E1-+$>k{mVG$z^wT%9Hlbtguv_2bLZCUlY2ry-a5fixE(5P*fd-0C74Vdb^ zAI;F7wn9ILM~ryKbo-mR(^2?X3nZPDXCs!LYZU(y2*RQc3eyJNKpGr5Ks#(-JFkWN zvSS&8T*m|iKz+)^q!|cq1(TnaQDHjPZA^V#ds-iyI;Qm4IbcK9Ibk#8_8g;4JKm_2BzaCt+Ryo~ zZF)72Z9``7+fyLj%5a88Fkql`jrlJBYSzlF+wNAch-^KYBB2?5b@44d2x$0`Lagxj zSBu?=5WnAenlY7O@a&!86&~~iBN&_UtQGP@o&RO9Gt#<#rGqt%`dca0B!~qBJtwz> z)#A-bV`@E7!Ms%_u3o@#6eqe3+*ornP|6^DSxZwfu4dq>fSram?hqK(k)nBeQv@|F zez`XOA{R!^*{*U?fC2v?6L#0*Q)zpzSmm|0%uP@3C zQXl9uOS#^&w}GS)UvO15ji1~)PcYHsDB2($=O1rxs0 zM#cF8Y!0oE8xgo72oO9flj9XRr6oDuB7WTl&*S*-YV51Wt0hR?0F4#!0j0ve#Q+ig z?q!a#s;EIx1&bw%;zK|&;a95cD2v1$W6Lqq1ct8!X9@5k3yT1Q#oET62L)BHD;=~Y z^j7qDX;&o9u)0-fjW@^MN-*;G*5*F*2z2SwU386;W8s}SBtOrZPH4;w9&di)#c%@l zC+B!69RQ|rFE%&ZF4-n;^r*_)&b)7_MGGGt0o;N?yWsWLp{>78x%PqVTl`90+%1;* zmviBxR&T?W2w?vlFhQNhK=ajxF$T`W0Ctb#XOnwWng{=*fSygh_s(^;pw1Qba3ndJ zgU8IpErAEuS?kii%M95a%5M?%er|=cNe>@Z`Y(lohCd7u5eJkhy6~l=O(vdi`Uzg~ zJ}UCRzp2|Q7x3uWk~)$KDPw{#`5_O3Y$8(0+RZ6IppHE;4F_02~J=p+OZZ4aHz&&x2#O z(XY7{+8A%mN58(~*!7c17f<(^Hv@6y%@flG#mz(&&v%7GOCLm8uN}c5iB{V4^qWE7 zqwV;)N$;0D*ZIp=7hCUmxT}7}cMc=MHYxN>CRCoJ3&{)9k6mz#v0R2+!d4&D-$fdk zb^cKz6rz1MT|=pl{)LTh9ME6OLa#Yp_UYrD^an&dJ@D!7Z)#DmCZrjQca*b15!ye5 zGK@;zaQLmdyU#aT;}EybL1Hv9Uz`RgORI3EeppmYJ)y$h=xAiH%G>P&Ok*=kLXI8S z`;o>qTPwvlMG8kC+j<3I{Xip({z+QG=O06y4oy1ka*<66fp&!;5rgWRnhZ3<9khqN z){?M0*Y)#L__}s!diN~{3E8#GlemhE5-1U6@SbS!Ojh`qLY^k;BAdW2e;a=)M6p%+ zVE$8OwjkmEum*{Fi`_0bJWq4zKhziICADOpPBj zonoUu{dePHft#d*#`5918>_xc8Sk=Rkk!cQB2-F6m0*nHh1B>7}U-5AqK0i7rWD2mq$Z`q~d?N`&LE_d8$ASO|QIi%bAS z6siDJg=>s)2U#S2gW*AV+ew&Rl}QCRwH}ZUJC|hOVC^x?^a(#gNDJ+EO^QBmtXcIA z@P{DRDI6)U??5_jL#JM?1Y9UuW>UrDSkIb#=$tnna}jE9N;V)G3yBx2 z36uhRX;7K$Q|Qa!MY%|XsunX5x#B-|y9Fte+?BZtS87)brLVNUr?Sj2FoT_3D<&Xt z^+2}~Isj1xcMZO@pQD4*5;;ifNkN-e~IP@IWC8I7)fiij|`pmSRQ~!dFr{*AEz+!`lY|79cq~ zZWXm%&FLd;@K=-gas~;Dq7D2V)~5F(Vs++R=A)W`fKpWkG(dGxgq)QU00f`FIwk%= z#3t1=lh({98C(s{7av%jl5Vj4j|#0bJE7~-$U;sG1!8O}HEO6p{34*}$b6+SZ-&-k zh1BVPeU{>3i3{mtJnp5wOlWgnTLhBXN-)1GX21>6I9~N(U7pND_uP6;t`%XbrG}Gz6W2|Lo>p5&C++Wr=dRB zkq)2GV^yX@GR^Pis)>U+ETGcgf4x-U(x9| zAns!8ELB44z_h#dwTu__MeJ;L3$h~~$<_3O{zOV)krDtLzfz3LZN4PgWlP$?0zbE; zB-M=#7Wou`eDY#A!onomRA`m8*%H0X&eqK{6M?*^TI$+trA^EjU8E zJg8V7O|aW3QR@*mA=7IxrGJBeMG*mR=-3+9TZmPfdi8T5{@!70k0`Vso8o~b7TgwL zLyl7_sF60AVGM@@HC1Tf3MoFWL5Y93+ltk3c_5nuyd2clME82v3bW#|QL7RNDihnD z+6gop1lpBsnPf=6s0)ivgL2?!oV&c(^K0CF!}m3__G-_O$3j3Tgpvj^fH2_WA0AZB z>dd-{{<7z^u+KW*6fmde8E2xjdrUTBAGcnRctierqy`+eRoD;?>F^0DGA84{)^0ZL zv2RAFUq*-UJq|*V?I*sIg<{0u2SyK!bhLT&;chNPFStb!K;al(Zr3##5-ja><7Q|9rJy(hA>d1BGCwLSCD zYU%O4l*#aGzerSFJtif|G708;e~}%Fiv6FF#Ph{wUdeJUA^R)u`n&cwlIE&W{C}y1 zg?2YE7TOxcaBNO~9K_EZ$Xsoe6TcUlu8_TzRIQLah{Qt!ZS}1TL7wBOfl@Rw%q-)1 z%qu!~4t-0D79h^9G%Mk9+zIg@olo-OMubW$xtlaClJ7%+@YqkCwJM0&Xn$JbB5jr% zM&s;DnY5n_^~z4FvFO+9ol5k3J%n;}*5cj#go!J*-9}FlZK-+0QRFS|HhRv;lZ>J` z*e=j3wTU~q>16JgZsVe(B???-JRAbsU#o-$>xXLmjEz<%Zq#S)(2>y21vji@egMR(UKU+LB?>Z+(lvB{^sAX<$oP18BnZP!K6P`F+Ypx);ugs16b3bLNVT=W?Jkaa0# zY_84hZ@5SMcdT8+?$ThEOK>}u+ zDC&InO3Gv#f;sb!>l=3x{?yx~@`!I$SusX=sGoG!V#1Ni*?(!<(mI(F^8r+9%d>$h zH=V8x-wX64pUDM`^w-}gw)>ykyk32Yhr%CH5&j3JShU(gHITs|&nQ(oYX{ZX1T%NH zi6q1~#Fvo!BokHSB%oC*QQU4A_@`~ewcKS0cB=XQu)k%>#pzL+24&;SjS3OxK!G*I z&)n4^ht>N327a=g9f~AX?dPgL8QTY$*;lLFHA|&Pc=8Q$+z3%%#fTp!KQ#0FkaZN$ z$KO-$yi!MxfF{$@p&4;pKs`*#!ujqMHnR}N9UC>UdsS~JHCO@jeloy+{tCW(8m7t% zyLsMv+Bi_~kwy&!o3?PgId}n_s9Q#a)Zg?+ItIljaAhtTanqA;>GiYR-D)ZY`ih1G z9u+lL1BGTs29qK8&(eclyd!WT>rrWfa~~ofA!2>wP61pJDu^WJ=z5g(RCjbkmVmExnTy zSh4Q|;MHhR5-*5TkW4WPa(yvBi-Jn7SttB=ciq1m=(1m;JqcnpEie&SK~VlSY@4|} z`;dm#WAACorrLx8Xn_c8Sfsuv)+uQGx+C#xu;rtL$_d7~8PR=18k)6}%oO{s`&*!U&H|3?>?e z=H}BG1XWiRj)5f_1**n1FyJ0%LUaHO z?0`S6>Dl}KeJacF=1&4^X2{d%<{Rukloq0y$Lw3%hrpcP2 zY=1mQB*aV=*4xu{fW}EcTnE+9)kE3Y1#l`S0CTwNcUh_(;C1yrW?Q{fDW9@0fhUsc z>BaQlIbcF~R*E-v08eJVC&_ET7Ph#5qA?=!yk5xd5~1}lAz$#qHl|AXm}r+fG++08 zr8n?0Dox$!ncO2M%fDWN8{(fC^xY2L`uW9hBulOjgs`zdW7cX<63x*h-#uGl+oA^q zx`kbQ=MwW><7`c`ep}bVoKfy;$DCD|lNmf|v0>A(z z7@~WjYDLoopz>WtLQX3ifxKSN51tZ_f@>e}(e!Mq_!*ANs+9``!k3Ea4K+&6_>TcRu9uLG#d&tEfpB zfs=Pyo_3|bTqXFLAFV@~tRo-MIK^Q06L7d?Z6$pv)>t%ueJRiUU%`?_i zrke8t`>u=Ai#@3j+j(}LtUO)&8y#Q9|Jvh=smezR=cA_h`CO{b%*q*1unpUoEXjtc zD#SMRz_5m0-s~U2)A`l}-ST85`eAB|y_8}pDNZfzZ+%KoP1o+j4(yS|93?2|RNPZu z8F51CEn?O?%P$no(u7$*PWCv%Bp4iy!z~FjugnZLWvVU_GAz}a2$kHk17zsf+RYaQvYTv#OK3>>>(qy=SV0PB9es7s3L&i)QEm7{*>EFdrVbm}I*rd5G}#W_L%KTk@G* zcg1!FG99~|rO0d4$)BW;?fk&zf0`o>nb!_{3G)TsPQ~VOSDQ8JluA7~`Uc|?4bRwK z%EI-Ycn5A`Bo|-zWczpq#emGx24rNv=mVq#v0Tv7zBL4P0-&v>?eUKWf2qAQAQvB{ zWEL8H7Wj)g^QW#6hozJ!dhX2j*ic)CA27-_Dn#=;Eiu+LlXYYEL@$Q<=Qe`edH)&( z0J^5I85GQo#spgO1IbsG;<^NcXn^NK(Ec8Ds`uB$?x+}$o-!K<@mYDau@7~fk`}<> zbWgE2X2SGzk=D0Ia!kzc)+Vz$&Neem$n_UCeYM+^uIL=&C7^3BLP~WoWsCiDwGWn_ zsI3$1Dx>imBI8q;nfNN@DZys{!Jk6^oL0eGaH9=&8$wd)3jz@jB7L-x=nNo@Eg_+G zYufSi3OT`R5GUqOXNnM6uvM)SV@Os#-TSx!sa8`ib~;Rm=r3Y@bU`4%%B2D_3r)l! zpv}Kr2Ys761GQ4=J~;xZ7$RzpY+3n~mN*y3>E==%3jcrr=cNWh!et#w-?Lo$&T+8o zxxv@weH{$srdlwXGbEDDK-Fs2OeqZqm&1p{Lxl7C1_G@iFagqzHdkUW8yHT){p!e11(f6PvRYZ7=#Y} zsBxBi=e)gq-bI}caiL%ihX8ZfQZH(;8PhNew%tb)S-oqZ?^&P9%-Eo4{odgZk45Axp z89N|h5h;$f+sqd4x}-$fOBKlLgmlVbviDk#FJlg!SQ|KBJb6=%j@-j{e3iFGow9v5 z;Ck~6P-Se-9kpC&aJqRoI?Gw)50HC%{UYMKNLxqGOpPr>e{Fb`<%F^-wcMt?2@?uD zu71c+t!d+TOoZ;B96G{k@URiOd}r*GQ(csl36P^eNP0%QVaz$1 z$G@P#5d~W$I%+^e|4ZJW!nKA_n$&u!;{ZHo=jvViD4C>*Id^TzNCw+DPnz<~`^#}O z?3K(OEA-e9KJwfZG)?aU_mhxX;uiq7*5}3+BVQ<_3)XOGdi2fqm{1HN1mwc5s+#Dq z9EmF!Fhglg*$uSNJ)wRcVCyyll!N$d+pQ>I8>&h9SH0+`jda~_L&u~pdPU<+HO6! zys8-NZ&!GV-r^|ybMayjR)-%}bR26q4C17Gf8Fnhi-Iyv>@VcDi`#M>M>FInQt>)n zV;#4SVS0Irnm@pUw#<|8Hy5b+!~N2LT||YqI8uUBr>C#|&MmBkFslDgRW8XhwI%MZ z&|z7>5ZD)hR~CWP@3WX=fCCmmznTVWY>v$nik?!d-wt_m6$nFyUarR$ z$`82FUs^|E96{Olq^ZYfBc1TW_0n}Lx}+f+bS8HH?-=CI7$E>GAJ)B}shz90=0NWs zNUv79X(|9xAt$W#UO|`;XenPamEhasPS!aj(7|ZM14q*P?2T=UHJ`$ z#<{gvxI~F>O&(W%{9HW&4G`P$g&J>r{&rlp`o~IVcRKDSmn3xTSFoBv5f6Pp z0V)mcCKV4HaoNszfmKe7W5HB!P>m7?SD}%*T0Tm#qwz56s8*_dsw)IDDE^JPP5LRQ z_BvPDac2LdQ?8*;I|ifhy~vFXcfBsT9& z*3;-#MyA`CWGS{3mDq6wpRG5ojnB#4f9+d&#YdywU;)VFu9pZ#R{agr!C>&N0^iFlKJ+XdFRs6gXKMi zQ91r(^5eu5VsCvJ@%w<#_@|1gaA~)FlKRcgz+A0ZBX_d!RV4lOSHP*R>){&&PqYq6 zNXkhhy9bR+mBDKI^Lb9BkbU=i+QpmvmBH%tw827J8}+v7-I=;WGEuha;i9~LmUztn zMF56oHm!%abj@3-(Bl`yF{tov&U7gD^rx&G2GGrALe*ihK;!JD77K&1-vcj=F zbn79rB^^}k(KODuA@b!{+uZ8|JPrSxflI_>5F_RGP{7niM8Z$@NljS*-Dd3HJKBItiqd=jFZ1V64|6BY7Sv_H? z58IBP-TkrPE>&NN%~RtGd@F72hvu8l5}4lLd(inT&66!sfiFM) zBjnHly%EK3G1uL4`UeGn%e0Eh80<3_a0G3ffC_BqzFdGvKkLO>BzM!#hm8JJu4%IF_N=KEqRD{yxOsg}{{= za)zJ}n?7XZS2;ET#&rpsxcEmZ(16hQ2P4T!|6SA^VF1M~)3^3Cd!GN|od~YtX(?z_ zzWMW-4ZBmwWOg<(5W^KfxHlYxn;YHE73;hnzbLY-b%Yv^lqxg8zZ(zXVWo>4>aW=={0B=CN?$e7)K4WKqf9-BBY=L_*DqyT~hy?zoR`GnLpkb%x zHuJ5iSpfR8rh~@DXuHf$=@$BI^33E4OC+nd^8faHPqVAt!2xu%6)Wt>+yqdbRa>E8 zLK}xtK~6~;PWg{QW9N7^Iuw_uf0!(moxbB#MSZf1H67smfW6neuaUp83~Ggr$bcfM zy&4TkiKguYTMZt+kmv^$1hEimh;W?m-lo~&EWN%qKZtZ}g?)tidS*Bq7D#9_GaU}>eGK{m zBvlm!tB8Mo#?t`;m#yP%3N8iw(sc+OITq2nLRl*z(+T+t6!VL5{({-ewqaJ0AxI`BB918%2} z$(8;hrS_s+I@;_{1lDHYCfW)!p|VYN@1Fq4AIR zC*YPISby9(c6hHLMP`o5s(Fj2RFBLL>eK_cW|Ag$Q`{XKup8fB>k`My@HQlP2de{{ zM2vXZ@I8G-npjsuWF(OEW^)y{I5^}phdoILT4cUbGp5FCutu72o<2s3@DBZiy+nR3 z&2-9!_bavs3z~8YlAZPG>ff6+ut7By1E5oDd&?Q(?I+=60p*@C+WbYcBJc_&;K~gb zK5VmD!RMZ7HWP%AiTLJ7=K@i0!bEgb%D&?lZgXjIvcr|!X2JhgQpc9%8IR0?*fu~x04(4@4ng7Aq zH9JrV+-N~i^l(ldk-3r8u=+j zZF3tb_f@|#N_&MBh+Z242!n60{JDh;B;HEd@oFuGT(zd>qP{KFKmsEJd!FBP1dm0- zRkZuMx0G`P9AE-zt>{7k!OQO?MgAuip9;I8HQ8NC40KS_cTIi{HU;%P7< zWcAXqd`oF;LBaJ99)rJ^DswcQI7kunSn5uG+plu<$@$pE@-gHnTF3FBw6;gB`Ot&IP+26`NN%Nr#dC3k=_0~1c zE38dR7ZhL{*`(M43+fU~>2e}6af@aqpUo5>%KOA|&GS~xwTQn1K)}#CTrWY)Lf}Ee1 zM?{h!Rcq6FtWQF^s8FH@=?-@Xl|GGlO~3ur_%qeU6fmA+iRU(Ks0RGHj6 zX96PyVR+796Ap_s$7y#5H*9EO3efvQ!Q`^2a+S1=ErU6bB*DAJJ>q3%6b!j?CdWdu z2y|U)ImQZH+7Fb#+$e0W7ZK{4`;=}DWa5@H8(mN?-3+BJ8Q9J+{b^5aiY?1?703J^ zzNs@I0uK|Z`o~Uu|1T^DVq-(NxSZcn4Cy%DAnILPkfB5arrVKEN~Wt_DnL|!K*wG< z4?`!pj@o8$yC#--o1o<|MBJ9~0#PqCK6E;6Al8+Y-|g5M`$awVYFx>c>I%j)OWKJ( z5kj3g&9Q87C7fZrq|rbZ1o-D#8+pS3-M&sA5ykOiDUK^4Poy8+p^ONCK?yN!*TtWL z?>?-C;Mw^|7=pVVAKgOSwup(0%XqZ77Z{U@4*XSzHlNJvq-G*L@q!UkxJ`7R+i=9; z_GAS|h&q{UhyLM~xUhGn1M|s-El#9HikHXu%aYv$|Ib=UdQI_l`H${flKKwd^6XX0 z@4(9gClk-m-y>3+Jm5C68AtKt3EbVz?-Gu7z0@>j@+*a9-50_sKf+3yja`f=x~*4$ zMwM&GCzu1(pbzw3Y|;`X1Qo%qBiC N4T}N*00001Sy}+vQ&2UKVgRpfklJ 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

    %yb4SidoWM71pl?0W$I+ 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 z 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�rg+KlCFEyyOTS^xECZGaWHkiMk|db?osD*zV;d$p#W z99&<^D*P#@-qyPS2jTW7IQG#u`m>y;DUe*d&#$w;TXJSk5GMaaZfD$m(*Y+VE_KMX zL3oziQaTw;b#-AiVT(0pjXHj1-vC!wlG|Z83^45;{y1w{qb5TJy#N%r%7a&OE7`Np zMO4e{_QKygYIOU*wZ_s@I&kpr3jkQLp+8rbTS3i6WR=B{%?kkC)m+MBaoAu?zeI-dwEu5@HY8=GTf#4| z;!I}H;|~35f7iyqR%#4@O6@A!3$UcXwhI%Q0vc!KZnxUJHys$B2x!Nq?7)SvLtVky|0Y5E(4ih0ei&KiTe3C9QWlYLa1a4mCSsQW%lj z&bm|+Rj`Mv@dYRl43axf-nHh$B~F;kGtqNAQdO>hir(0fBHUY}?GR)dmA12W-@F*6 zhjWJO>EV4{>nsi1+iPudV{2&aDF9(+r=xpJ{^u-4u64b*0;1O;rBLC#Fj z=t@Thf=^w4kB{@Rf12jFisBkK;o`$MQ5-x9YwQwX%fH`Y3*yeTrBYK_3~FEtt5kBO zZjF443Qaw!ZLsVTmw$l(jO#TsBf>94|?o#FRmva+r=Yd7_3)rlCj#aVJjI z#L>t4jOCDCIN02J%b^(iVsn{d56z}5nmfHM;#Bi1MgIb-=Z(MU`VF0lNp$=)kYD8I z>s@1L9^5;GeX^!_tnk;CmC#iZY9>WgokJ#%24KOUhptwrEvavepq#UoUG7UrnIsCS zby`18$sguJbnLcB>df?9@kaOT&|3cD6|hOWlLQf zmrvnKO2uq|Q>ILw)`Dz3E&dpbw~sfik(BonkLbmeZLQe6exbDk#yi@K1`&>Z^w20G z0|oukv5eFf*P;Vy#>fO{`A}HbUCAupC{qA4K+M0FJvZHbkMM?p;`=!ZqB?67%%^U< zooUqrhGAdLJ1>DHyY2fkb8)sF^W9~E7;eb?q0ZCDIqj;sJNmv~UzE=uv3p$pq^WuM z|5}5&fj+qH;03l1PZUwIGX4&)tUO-vO1fxdrhj$282T+e-fw}r5O>@ ze6~X)v(!ja6~5sg4jFwUnzo}<{ABpKdJ>kJYsf0BPTyO;tRBkop`Qk*l)(#RgI@=B zn(W~Q>r=pZ*hpU_xj%O^sdvi5)oD#<^q@hImfrkP{o3M=*j(BH(Cx5VX0X$2BtZvC z;=-cC{-_TdBf))U(IsKbl@=i1vTu7S(`;x)kRg%aGVR(yVoRfeLZ#CO5N;&8*)e?2 zWph5+LYRDEW=8Q-L$}nz-+cCBMtuyP zfHz95gj`!z-k%eN_-Y#Ys#+;oPWA#_Wt%M+vvqhm4n;6Z(;LH~>=G0Z8qaouL2@V; zm=~(Z_UBe{{^RQ9lhjHED)QcvH3{mmNy_5%noEa@RbcR2L>9Wm?CiRVb}xHXZ(DPF z%jINheWq!j-aidaWrJ#cLfVadT}MA%6bJB|z2?5HFJ&Uzmsuc9USc{71M}9Bv%?&C zV00S>h5tKD4R;=FfEs_qk5r2U3Kf-Pd%hX-)+MSW2wD`_u5HIpPQTz@-3S6@r{=qKBQi$frQx68JB|A0d>?Vo^b7*u)^cNTf$4Mh|_Eh}P3iQ*yDs$A+@{~`Zj-NF=n;8M5; z`nf|B=B#Q`!l=)v?fpBW3T6$y{a$!f52>pOO9F3J}fXDJqikxdsL>MbbRvPvE4ke3bDS= zN->X@3^sPP>e_3%tL!NqKHOX3{@NPueGMM$+5@jk7Z%k8vVYeU6iJI3*D72|x9s=A%dn*h~kRI$&6;V9Ajy&^qXz*v!(}1L2aBd2eJU zG^A;kTHFtKb&1aOl9g&E`T?iyl#=cv3hg>D97G(KohH*1!ThzccpNaIew_-&&;G3> z=zj2^kGzEBFf9=BJI@xW*T7D#{Ohkv8lKnrJlLPZ^1O5GYXFtNr(~V1D0~M*0xCi7 z={wVWXTF}fY@OV-Shc{I&B4>{5|A!!5dV^O+96o(rVmAeDt`>%Z3sJgfL8KqxmH{F z-$ljI&&Uq(axL~QeuB6`?c@|NqPMX~bG0D0)ds4lpH|=|Xk`xY*_so-PQYGln{^@v zQ;9dM?0S3SgOC6bf!MfA5if_&t2*fFSG+%C0U@RuDW+xHMQ0=Q zs5nX01+!?)+BCBBKz_(3DCbeOC6fg8R&)1o?{1QC;~|azQr?*$e=OV<-Y-HB;0!ER zKiGi0Fp)0PQbqDSgR|G0$#wb7g;OhXh@gF%*B7Fqrb+WPr$;@o@uX8olzaL3$+Mhv z;%b08!U7wHtLd=FYQ-qozhAmI%nTk*M}Fc$`h_e%U;IEv`77Ro$uv09$L~L`JH6F| zL1`bA?w#;@NL7kgn)B6$7R;q5g{AD>fcAoWGkB7Yl+jzH>O-hT@^;dAEpYmBxy2I1 zFz|DR9%kTuw5MHSp{ELv*3Dp`8{N}-+^k~rB;oJ97=IP#0A`>0T`(w_8HTC!^i)yW{e}Qyi~9O>>z+SNfdebr!EOK*Z?JG zECr7-?f#_Pu2SbiqBeqwlE-|caM>dFU7xp(W{pm5yGWTr2EFFkDU`SXY+4GDWWv^< zMFzFj77ZF7Bk5nQB?<`5+6J?3o?t+d9rA3)7PPy%W~%!mF_UL~Pv#+tZrdlfg(ect z+VzO*%iPzbG-Rh*==G3wzH@Whkq#KfDIj2;=fxy{^PRt$AbTcfo?wXP1z`_^n69&7 z+zLIa^%W>%MRCt6mG!_b$J2vrvv+h(|L~bRaZ1>GhFv=B5(!2QqBwl{vk9uKfRkM1 zUQWs2!&Bp;4(?JQsT!<%!DypuCdqY}4}-E0f?}4^B?>s-;!~!==6DRAxN)vy6+Vt? zY-_HsD__F_6dZPwlFKPnVj^tk1)d1zrXYFUS85(9+KY{~aliEk_~rpg=`nj1p~4`AE&1{kd;HO3IOO=Vi#qvW6P!e+RR>(_LZr4P&iD8+fc1DYEOr>5?!Oaq4&EA2MVod z*n|i|8~Ivu5X+^bKRn4rnkHTf`9DLf9gtG9 z@+gK>f}}LIhLuM6={J@49f3}I9Q+H%q=J=}L0IKgAOc|I+xw%%C`zs|Dc%(M4J5t? z`6TC5s&sgEvQR_Yu>5O=FVKQkRbg`>26{b~(pz2AR3OT0OFME2-(O2ov zWJfkldArlb=|xMv5F;@G*}8}LkM@;K4V9$VP`xC13@BASl6_gP6HedxW?4e`c6CRu znYe@(v3YY{W!QQ7nAGS(w^nLfXFp4ilkY*gZTasO=krxw=7cwY#fQONha2DfHjqZd zkJS&vyRGX!VY;CjvhLE3v6_dW8!UVJ7wb9|A_)0G&hOJF%DgzVc{gasS^{9ZuAXAb z?u))Yd4FafH?vJ-)5$-3pem2{L(=>Z)+aZTh-u~0V~hSz_!bwYCQTOBAYJJ9fjN$~ zp#k4vknwe-YK5uAT&PR-7Kd=Z@^Quj*`34P7Ucg-sPb~evavA3Br<+B?YIJ0@4Yr? zxTI{#ql8$OkqDG3}dW)J!}1m-Xh9j4hB6o{ggxa6(KBm^{gn^j(Hdi z?BvN6kgFM~IQA;jH!rKl#}IJZBl#ywT>nn{Be-F>ej=%!5!P(vPAK?|#;vSMvHc9U zLE1(J4;nMhfIlHY=HG-9X_(x$(2IwG>Q3d;Aw>{_B{J6C2FPLA@a;^JnVwI1Rxdlq zMegOdS6Y_@F2JXhHgdoX zkjg1StCVkIK&$VBnxmND#noq->|ikwQwA6`Rm-k2JU7wd+4lZYBH$H;wJt-!^GE-1 zR&rG5s~MGi>m%&*^$PX(6FFIWdx-Po>fJ!JyGQHZrjml*f%1tS4WK=so_B*SMvz_Wpo_; z7ryK3{38j0&cdRWii^d#X&AURuKao9>3R$O#yOLek)X?qr%74m^E(=St;yoc`ViP; zLRHygpZ5MKXLa_7O%*fywmvih5o`Icmo)1J?_FZBxKc#j(x2{2N{I0`S8tzqI@n|c zxi8T7?4^FBNZM>!PMMDub3F24o9QD$+{vX%j6Y_Dg-qXT7L2+%+V%qY+bd#!U)Ar2Qr-KXnGoDR7oE<@-a| zSgNqjdXBIo0(HHOF^x-3hnu;6 zI!MgLF6W-&*DUC(3;9{GTumg;E1fMbf zrrJ}r1}Z)yUYi8N@QpW2->e^ba1-HuFqEOVx^1Yo5y7GZBKetVRJkiheY&>$HUYas zCS*o=!EZFEm}GlC>|jHn{Cr_A|LV>uW(H+~$0q?}O{SCqg9z0EnD_ZSx(;I8nkAtB zL`ayZ(9Bv3BHdBWgEKqiUhSV5*alG(wR?JEzHAlErnlr*k=vU1_fg5+Z%!!iw_tN( z8H=5fy%zDUK+_WzT;+L)3XSgbYa$aWrzEjw2?Wo{0@CNh?Jj3+%bQP#shH81&WUmE zyd!~ZN$7t|!?cBD_@O`5k6_N4goHnTDT5RIm(`jYbOmKFl>7tbOmq_}B6p_*>X$`n z!^Yv>)n5*B_qPI8;D|Zh3N&P4^AT7kCWNg>DN1;*MyumuYbdV2DFYs3p@2?| z`L!!R`29(>s2h0{vEUNQcVo&e|26ChSQ+p&G$k<=r?L6tw_%g4VB$MEox>d$6loM_ z>M;+wwaaWiZimc(JX}WoIGQ~*Mk1j%$Qj9Oze3}Z3Ep;iBm-*56(BB48^oH*OUX}6 z^(qDDF6`E}3%R*R@0Fdc)SnsCV-9lHBT5)cac*n7GE`X7P?=(gXlBt<=MXdAp9Pi5 zXUJB-m+%N}S55CwMy{{IyBrkWKd!7Qd-b*n0XQl?w^v|IuWrFwz!(1|(w&o7#w$kd zHB}%eDGRR?Hj4VNSc2-y{8WulDZjvtG+|rq(Y(k9fBAdv!_jSYp_2;XbziAjFg2L> zuO1grLnz=5R5hq2L!x?5yb#eh?X5SdR-4x0z}|*j!7v`U@)7DJQE?Q+uw+Q!{qIir zPFqS6%jo!}lw}UL((ZRQ;}vaull8A$^2kf`LT2U--3;CJiyU%E`iPars$5zt^sJ`r zig;kcpUSfdaVzlXyTp?caBkE$o5v}oN?tE0RrZBA{Y8;w4)_79(D#CFnTi?5de$Ci zS@QKyytKzhLQ-Uj$Yh{=c@-EigAxBpmB9sKk0ulPxQ}Tk(k^7&eI7sxX^3Ewjo50J zTEz+GcUin{@2?d;j6qg&pD~}FjHlq#pkT(x;k)$Qht9ICc0a% z-OlR?bk^I5UAkh!1WZfy!6*cF{CwHB%Q6*tT#v5#tg6T5kgSz7^)Cbu=qz=*V zX+{PB6z8(Gzd6aLv11kLd#tle&*wraOJSlVFLm3Q@Y^w9^;8&NDyh%#pS?_U$s#`e z<#54Ktk93BPdNT`+Tg2xN>V;qt5#GgeIv6R@lv$$>vn&jr)F$Um&;aVv_hndq}dwF zbvpg;fVv|I6;-cbS}FP~X}tr)!V|Z4wdDuM7qTrj8D!h*oKJi_J1c0_#pGfS3Xgu6 zt1$-21Wwp0-qnGW)j>q{^EL#qgHcI+!@~3R!iYoBZnI8{1o0$!k|Ek$oWm(mv+h43 zFj5HqX*{|8T~rFd*S~PvgzdEUn|xu8XJ;?dQ$pSu*2BH3wp3 zvYTi&@Ggl-k3ngZ7K9KK@<>^>**{O4H6pDG5SkRRBXWm}i=wdsUba1?^iD#WF|MyQ zzoVQfNS1oE+c{Bvcl$WMk@DxC~IbvDdc$ zR6<`lQ(p)S?W;1s=*L`d(6x7%zSlMU8Cb>%L1!r)hTw1JC;qiLeJo-5Hs>}X)olij zqNr(5qELJPo*q4z-?!V^U!ng@0f2a)qH*g6*~qTh6+ zzuE`pj*jaLts-+0_xYN3rF!E;K?&jmb?K&08Gc14S-M+9iUAKBF&M9Kg>?)yIc{?Z z0X4pbf(eWqJn8WDQ5?|7rUno~P1C<0Not}ZtZ>8^7K!zxYJBtf9A(t)hbo5IQs2nT zhE6KcKfde$*sRqMoK;`K2?-0(@q*fQ)IRY-H7>J@vC^ICpZI+y?oAJM(rj%RmNpOS zeV=I^6nflM6G?(KL{I_J<+uZ&WYxgw9{HR%brQygVVK8hLbFF#lpSZjv2>~Lo-5E~ zv{y-A-N8j3mF^YfA0}7K$m16AR;DL7u@ENqq`Y@|I^%F~#UyW&?EpK_@t8iKt>{T5 zv;8V%6p8+n#U__N$|ls4Yqsd0(0rHC81DN;Ko&K)eMK)N#es06w%dr zLozc&X2_kPX6V6WpO5mG@GS^^2ZCH2Pt5V}gnFMCt$I~CmE(ei_VDUe1$Sv?Tvqu7 z`DZoCj4D5Sh;YDbm_W_+`WT)q{(J_h>AY#!=W1H#%8-yUd{C7nJdHbl@??NmW{vAo zy*z~SRhlHmueI%Hfn~t7>io=0DBUwAtDF#HnEjn zDkWg7G7`msrEIFS2_I#{Zzy$uPmDA)M@RXZ&?hOI<}Pifb$q7YA|#T}muXamNNva; zkmtZZCANpiwDH|q*pU*$$(GjKi^T|dmwcphaw*;LGk{IBpnY#zy_pJ`PlqPw-n_ig z#FSdIVB#8RWX)=ZXwUeeaJtMNnOC}M*WE{~WIm7dX%{ zeo!JUvb)JI(q#=2XB$#5sx-g|6pxU?8J@#|D5rhp^iau3X1x%`e>^vQ9$ZngB8;wo zjEVha*522QpKJ76jTG5bx<9h{LM|d`!_mQGBVZ3W<|gow-n`lUZ-Y39`dnn`RKnID zx|N@LbN2ud44HRUup4#e^Eqz!Bxw7@JZILD%fmVl7BqpZfsv4=y#dpE+sMwc$(jaP zwGuS?g<{alJ8}9zlC^kY+4VmYe3}U{&Ps37wkW%w=6>%@;S>rYUQ)`Z%7RTEz}xCG zVyJwALo_X%buD@rE^_|hwIYQU5B5q(Q2L{nj6^>;AhdU3L#EhmBxPA{x;Ch+VZnyv z=yi!u0!5%&aA!eK7f((x0X3T1+(#gBJgH0YaV3dL9JH_h%xRIJ4=+axaX`vvuv{6C z3T|1w9D^Et{#qoZebE0iG2Oqo#@HpjBmY)123hgrtvi3Tz^ zl>or6lCxuBWqN3lFAYl#@E3w?q)fLjYQ%=1r&-8R2Hp3%7R!d4hgsO`GTPUlh%*`SSoOwFH=hgmGGZ|a=+8gt)+XL zuEQIc$nDfYP_AnAU;8fcfVDGhX3kvzE1Png62~|!mji|_%sx{|x^DJ~e-oCgZfvT& zh*0iUu39SZ{lTSYytIJ(80oC1$P0!F?mK8mRk@+|DxaAF3EhY8c6rM46!iqaEW3uc zBd<7Gd-2_bt3AWQNR!=E33aStKXWe%Zf%D~FyVH}NRbv+9_egU`2z%5+#g((uN;$~ zV$I7_X#r3NEQUL+PcU$J3$^E_?holYuJN9I!O`-h8^YlL}NxTZ*7GlwawnvC(z1CN|_JmKOUX9K$XsqF_S zWK7fE{e&z%O|%7}36XFEbni=OwgRP_Me0JG04oGJMZ+3v1Eu6u zuQ)YqIdtoh-RUMO+JaK>rrjqPm$Uaih}#S<4TH^zJ@S9xBH^wLC;EAfvKr?e?W790 zz;PbFMsD(fj5PPs^i$sqfoa;)h_O@RE#;`XoI;lwAef1s!Uoh+4Y~1XJ{LU+07;Yk zVhqR$%#^aBR-5Xk?T2<4DVGTux3wjq7?L+GlHdTAOzzq#mW%zo^69oglDKR6#)EH? z1+JC5RTb^l#NVyIS+v?W$KBhWyd%6;P|hiini3%nUaz(xT8k0vDc;eA{1qbRjl*lk z8J@28gv?8%%U8elBb%x*zG}S`ZiGt9ULFDfzj4R}ysD~$l9tfo!m(q_k^K%F2brXV z{LT)99s;ex+iRbr{bFdtDj8;R7lbA8^Q%1Ep^}BaScMu_Zq|p}P_9c`kS2GhcR*I~ zzL_fxhdBk~{=*q?+1b%`-u+BA_iTO*6fPeO$2wPad5En(fXJ@!xwb0E@MKOQk)MS1 ziv-0Di`i*?pyh~oDtJyjyzHL>neC`RH<+*)g^?f?D>sEv?CJIFwfjz}u8+~6kDy@f z065L6hMmIlw;>^@)AY=vA8yBx?C7)_ZnTG)2tk*95gAj6XwfnXyV=3LC^-MJQJPY# zM|Ur(4g;mxuCnf4#FyE6IPi>i0#l%R(wQ(u^Qx*N=Mg`Z8y9y4i=#53yLl+1W}Xv% zv?hKx*-7FycMLR^%*TO4g#hO!Vu=1>rxnUA-ZPN)7d8R-sPwtdKmdMlhVN_KG*oB` zxEA77{eo&2s`eV*rO%tB(wkTaEK|#c;x<6;lNtnb!ozktG|c&EoMuUqLKru$J51MR zt&a*s195;SDoc}L8ruM{HpR+B?fr7Zj~fTo#G|TL%37m?P|4_D6Nu)K3L_ZYw=uhQ z4~iS22vqA<%q22_jW&6f2bRf7vrz?j8c}MRuA)+nF9dEv#6r|q(ILHeeKKv#HAaE8=-AUC%!z3 z>Lz0&rNPJM9hbgA*YX-@Gc8)~6!{jy?#bsCOR(js@^s4BDk2MIRCH?180oCHf-`L{VxwPkg0P4P;1C*On3i2&P zffG>QXF_=WbBElD+!B`P6b>QMeZuPnpkfDGgpDK|6JU$SZOiG~rXaK$le6@N0b-M& ztv?w2)oT9D)QDO`O_Ap{cIJg;3%O)GGP9fUM}!@x1NAJJ%onuc3W_(Nv@x`G>lKV> z6^2Xba51w$7_RKy?>T;7(u$8uC!mpFTR85pu5394?!Gf;#0L4y4VAN`iyh&k1QS9hV>F1~&g4UVv-7wq!hXohDOL zZ#BhqcP=b{F60paBQ9r@NhueEmHl?8|8l&~GE%q)E|d2;cj`K(MzaddNGIeU0M0h1 zy$R71>C9O(R`^j4>!&xc74=YxI|Ri5)QN_nag8x>f3ywRjOI~P}7C8T3GirlBVm6p5VR}tWYme|Qr?RW=mvbW$VnfiVq1WE-thEVdwk}tI z<93~ahJkm01xcoph#YQ~4vCy&j%jNsOskPW5fzz+GhhlPoP+e++h%aAIWa zWW&NwBtwjNVA+3#NE74EfoT4d(-rpvOz%}m_@alNXO9DfromC@_8>f$bb*Aj z0V5EhDFO4veA&7gDlY?`CY zY%#>ZTAxCY5zHK~cMnIGv?UOo^S%tc0jPBMv;4jR8H1J12-s8224RCF2)XvHPgwaP zhFN2-N&6=u1?ZvE%$5+h*A0L;A3<5mqoSg)-(Ab$Qxn;WR8IrS!?yuz%O+NW`^XgD z1Hx|=5+&%K&~>!3s?fu{h)kN#)DGoNlT(LG0mYYe`PglGapr;RsL5c=+A=-g0K1Y~ zAuqVY6#d0gatXC9C~k1ZifuYAA1WnIYS>9xD8Jm6fMeM?$+$8z4i~+f)*1@uje&46 z8>(>hgyf+x!2j_8OjK~qO)QIMr9S8jwafm3jLet#X zHKyy3NVyj~&MX~joZZ`}rHBKNYA#)jv2S6kGwK7R5CkT-axy=PX*ix#$HjrS-(uqA zSw{c;IwgU0dFgi)Vm_O!RXbiq*p^?j+B&c&u|=rze%?fHz&am4Z=54d?DCEuP}eH= z)N+L4|5inU3s6*REG}Z`p@ep{Y3jbPAfQgY*x-}gNHLvfXBv>2I?+{60?m=b&F}Uz zY$M91nmR|=?p;&4^Kh8KvA-<$@J=H_iv4Sadw3f86+o5P4_ zA8Tu@plxd_f5o7{Z+Ilnh2;IW3^qLxVAjo=@FKxsOORjkYEK!oh)C!?DZ;t%DwC9@ zBswi>Xn(^~CaX=tn$vgS`dldQEG6>BvN)RWKmh#$=N3tYD6z7_6%U6DupwZ*MJ}Ly zi=L#Rlm<{-?+Loq`4&7r!*k@>vV}h$ai)k0Wh6Qaw0V_-%jKKQ6LPb4oeI9Sn~~A4 z)4c2xVyKnTs5E6Km0;%Il;y`XD$!rF-Jc&x6v5`{PmO-qwzfX47bIQ2+ZCY5?~6|Y?%wvi^o%R)Im&xt`LPm(34 zDC0GH_V-wP+RdS(T?DW)3Ni7xqLc-Ab8*(6_33sQDf)t@t&*D4n6s_xe>W9Y!1K%~ znjTMOzooW@qI~Q)sU>avOR)zvYPirumZ!5r=*>A`sUzpH_9xdQ?7uOKoO(P`CC!msl_B;x+H2Fvpp2Z4uCB1>w7Dy1`1N}}_foF~sqH~_g z&c8m+2HCVTo$s1puzZXQE_>8HsyKHQ%=b%(Xp$yvEyQO#c`s9qb-q=BPf)1OYLXr* z{cWf(<$*aM4J08qhE9jpdh+j@95HJk8ay*Zw|Cpp4~~*}NU00acibBuXWBrHQc< za0DX#sg&#ABn3|0qbeABZPlR92jr913IB9#(}H#Tc?M1!`FAed$)C@k`;l32Os}cL zq`L(!Km}jiUb8+@BUJHgY0Ob<;g&01@|;`NDg0p~x-5HOy^^9&SCjTgvJCF*VZ^NV z70*y>yR+nNr`9D~?Ln$?8M}L^(>-~^@4XxjFRBivm8*ZoZXfFghq;foLPrasmfQx7R{M2gw2 zY?gDa&xmUk9a}}T|4Ue``V|rj3X1hbcSo1wFFgdf;(Yd+T*bFk|Nn`uHs87io$gUykpL45nkzk9g^utL@qNAzxc+~Dj z^t{8m>PTKmK-9)llj~)n+(9RHaejkYYe4SBEiiH7vpbU*-hPb}lZr%^3m)aPSKe*u z;SE$@@Uf+!Uhqn@{z6eQjM$%F+cY2k@YR&o2=TBc)rsxN9CvCRPj%t9D+zgWS)XF0 zh&s=;C=o0Uwb zTgbg#;#zWD^~cifQ;^6fL*~e8y#<7{UB4vY zxxTz-+H&K|%;vT0DUL3*nPTI{ryVs6pHsItxH2x|#pc$Ugu3F{6X>p@O(kxe^_53K z5q{hYtd3e~{7o72Ec7SZC$TQGO~~Um76fV`da@HEkTcz%n+y-fZiR5E_*xFYIEkHm zw}{?0mp(5$cY+6z59fKea#zX!Wjv#^P>c5&euF>^eush{F1cq)c|PLBoV+>XsgLzq z*UjAp#F1KJWOMy$l5j*@yN<8!*eZUony4485Y`0_XQs0m#VE>kj%@<l#8t1s6u4*FFehHOPFbIm@Bz+74Pc7h(8ZDDG{5}hv;`+*&H+T4+Cu@c&d~neUG*Jt#`fN{4+7Tgx3X(Fo z%Mh^bRkosiMK%y6GW{ z>asj+FdzxHjx8D0F|_b)j+Ya54RbE;f0aO89^g@@#WVmqQVtw<>_x~dq5;PFwHT_< zKlLg5aWs_=5(_0~a3r+btBI@2oY4}R0N^luipm5`$475M%?o;oJe4K6w;s;;V2=Aq zJPrYT5wj7ix{fUjtY3a|KGN$VHGwEZ8DJjT;Jbj$|BuA;*OBk^S9AT^QOE$u6w^B+ z_r51pLWFSIh!{;R08%;)oWDTeQO!NzU?Ct7FW zEeU-5&9a86h$MVprkfzxWD2$SGkG@2S+@IIu>qRnC9d04<2?>2h{lLNF|&v1;K;Yg z{Lbi(bV0{qYKfzp_GUIFP!=jJnxS{~+UHp-^F+^!{ zXF8>SZ+DOt_6~TiypU`Hd8P`;Bm?`50tOcZ35c#1uR5XvjT_3f{|pO*sPsVP1?{u_ zST`C@fAWvp5IyPJ7k97l6%-=HVe~dDqlk@{=vZ@<&|`eK*j7@kvG-1e-PcPHDj}s{ zC5xBa4D&2Zhip-M<3M>fpMM?<3(Dx9?*A0mNg-!*9$%KN;6hwEp4wu=KgN&@Tpv}v za{9R%02p~0r^VFrfzo?PUtC=y7|2Y-`^V0ZDGZTG;@cWTGstF41Q+l36OF7otI({m zT>dh;S!rmW=knK%X`4NJ!J3SjnwH-Tpm;?dh}N`Ui~F=vzy_3W#?#9dO zCdjiJG6@n)tvuTU7IJ3FSuKULGJN8Ie@LaLdPQs)w3l@W+vHl|ziVEn(XD&B#wU2! z=%0iDmFCDZNkuuOCtDz(~kXNO?W}c|l#n2QVZ`Y|*+-CPccmTeb;m2WC#1Kb%~=8%M( zg--HvgnF4nC+Rg3sg^98wkPeoP#dE_Kk$Tt%L{gC2A5o_93Nh_qmgkWy?KFt-J<@0>AtRf zX9p;`p{@HE535c@?)n@@j+o6n>SX|(sJoM+dF!LKywK+bB=&gVr^Nv?VPT3zDj!X{ z0SjP)L;!aR`5MhjfOu#<21e+q)9*!$MpBYStwq|y9oPt2#b^lD2IxluhY~4 z!^H-{=T)XiqQQeGub~Z&&K6Hf^{^YCQN#67*e@wZ8Lf1P_i>RqL?Nali$Js~uEy=V z(I@|p`*d9Z3#7iLYe=mPzm5-^#`iIb4$Wq^wRxVlW58=oPv16FE;B`=f{~ETmKDvf zAwmGzb1Ed$TdWAON&m>Kh1Bp5%b!-Y(xD*uI( zHE|IsM9sK0uh#ox7;^2sL52)QU(T{Jda(SCavDB~c^EVG(z!fc-~{W0sM7SqT# zG2mWPwm6TEDwL=lzZ?~FH1KGNxXip8#_Vkklp%4mGXA^neXM=BS!@NuDvk$!5zJG% z`#Mk4jnOR{1;_i@Ot;1eDV1-pht|1f9TCQxlKF=1KhKOvbxj={<(BiYr{s)pF)ybrn9N=`!^p5MfgZ}dTWqho9Q$~5)`=4Am93#HQ@ zPn^9KrL)6u^wdH%#=%LvuSpJ;(o%7A8}9^jWd#HVm-Wr)(Rz{t1Xrk@0(5ER@5Kkf zx43zl&R`A^k2e9WTWv_u%D00EIjS6|?+$**h$c;bKviVaf|b$v9J(b~*}(?7rLt zRFTYoZ-;tLDJKz*au-Io0(W_HkuBP&B0Z@rT|1JR)*%{$ z9+xF^QT02pg9HI0UY7FV>yNl&xbNIZebI7rxU__)$xEx+uqc{=qaPBEce>`(^hY5cBi~<`d!@Onh7v z7ndz-G+9|hELx`LxgyEsR&P5w5V84E2=;)ZlDaKya_*KSt{`=uXqb;=YQWy7`VTf^ z#TT_DqY)w)>#B@xH~Tu}!#^)j`CvkJ%NQO=yq6@NNshlrU~cC>Gr+4ST~P2v+)sv| zdK7+k=?6DKxCSMHDEp4>!_nQf*mYFo`E>Sdp*eg;%>IJYAaM_?4Lja~=9Q>*TH4B~(9118Q|B5Dic5=u661Y2rcWZQq53Ddt>+DL2C@&50P zcyVO}hAsQ2J7^GQAiyRM?Aq3!r2eqna@Wm0i_0-Rpr_j*Rey`oRG50BG|vCT4*$a3 zJMLIY7x6B1k{0^VC?1F`|F=L_jOs#U9QG2co5(^*ps1uV zg=$SP()ID*m-Wul+Cy~uIo{kc_jqByl|MExADEJ4@9^l0%K))2eOcY%27p32`&*QW z9Cy4TU<9gfNS^Mw|MUG@Qw>8H6&r#i+{1swQ>dj3v;g`z^&t*okj3>9-8@bBsbKDQ z@vt~}Ky)sQRve3G(^wG5>ZF?3@j!fBM7HJpzLw*msO1vm{l-BgM7$wY;b%p##PE=^ ztVq-wuOWe|;Dr(baGQQo0yM z$V(Twt@S>7fiN{t>;l$rnw0e4$l4WJ)4p8|S%?Z-;RyR_l-F9wb>5&lHhtrnElg#d zGgjouQIHfoPFZU|uzX_NKNsw99$$b`(~E!k`B^J@|p+-I+sgOf=nR^JAT{QIkn&toD#SK~^V9n~RyJWre0x z`c74+fI_pasbz>#IP z<&-g;L6CRTe$+uDj#73IuZ2t5k&WK57hDDOVD7xOD+=&Uo2PUB{N7VbpbJm`X$h&J zN8YvUX?Hkwd9zR^PQc+1J7p|G4+J?p&b16?R>0-X^(4wR0b{B+&%=tCK+c~Zc?C0& z=H8L&(c!lEK6F^w6!71+DKFm=mkOM`0@y zmki4vD^4a~AOZy~X=6Yp*m;OMyXDz~Cwm4j14t9wL^ZYqk)rbyQ6TAb_uK{ooXbfv z1JqjJD&A~waKbDFcekyT$j~!w@=>YjR51u8ZlWj~t0k8#4hSOv4svILxa@;5DD4Ow zziw)U?>3st`rcR^3ZYkPbo~#Ftiz=#%j@({&}xoI$gQaSs>7DqK6q~~8sdqStcq>3 zW}%X|0m!OzX5ZjT16Oq+#CGLan!?0ip1(OsUWyL_PCISQw#QCtF`pc%=_#euHg>(f zo!^K!_AqIqn3>JnTF_YJy`N_ct5-7!lLIp*E&)DAJriv;5N~O>Ns;~l;dXMV^|_)< zUKZkiB+gI`VglH}7;S^*mxobcUVUa0unlSX)e?M4Lm?qZmGB%l3_eLbT>6eMOs53E zo02}ol;MDC#dN{LkjAghQ)KZwf3kh9hIH2p);p9`td)w3CQ^CtANu=ooYTO>%~pxQ zU+884?#18J{|iWzVF_n{>bl(UVJUZ09Xqct%&T(3Y;e zo24^neB*}HcfR3I&b2M#e9q_EOs*UF?X-RTJvC<7(rQAKor6UJGwb25lw($xDD2Wy z!8o$GR*8lTh5O1d1dP0?q0qY6)#!BOhKv^3_=ukCa3x^P4V-9SNTNrmNFDMP@ns6<;6rq?L0#SvyU`9a*z^=;F+_zQm<^JQhq z{4CO%$Rafrny`S+91~UR!vA`6G?D;0WiEsq(WyDuL2@v?0uDtobmvYO0MRhAHbLW*hTR z6w@#dRyJ4o&&Dk5K`T?CYCqk8b#_iFYCt;NhV!8xU`o@8D0~_c|FlG-=_g0vgBu}} z2?+T<(t2v2B{u$G$ryskcRzyvcAupq7iF0!%^LuBp_<%8easbG(-RCx*dr{9A(XQA z8vx3B8=o@}U=%ELwur0nL3-J**clnj=m{4ze@84^AOgzDP zpOx>F;DFG}YEyB+WR7Ub{yu#?^5G7u3SLPOEETt+Lheg9_fr04$9^gCUHU#`NCWvg z5&tcMzlJ1flf-%vO&5vXp|rn zi^e@yVe#{ zw9d3y*+q_P+sC`N!e_{AwHwzBs`M8!hA!el z;_$a34bvsZ8+O2!al_5lAPfGR^>{y*dRhDDg0m_rH%<5ivkxc>RS}rC?1$g9pLHpN zt~_)ita6gbRMyvnRvr#-?q1_C;LRPsP{LIXNv(XIS$h_5*v_?21b4Hve5z9E1j@pA zC>j96?{(dp#>vcR3&RE~rU;NZ1ve$BC9FKs6<6quAe39a&#{JZgn*Dw z1~Uc@mL)s%pfVUp^Q<+a=x4}TEWDsn_~@MOC6silc7mL<%Z&#_k^+9%QQ;N?POy((~7)H{q z!lI1LM_4#C?+p`uHF4e16SsHs7gkZ8*hV@=CX)p!wvpsb)s`m%@Y$rpTUr|+uP63V ziTzO0$Ys~zf@$?7*MiDItst*t1(;=z6o)0Qby!iNZN7ut(Qqwolv6@jqq_T#YSs&O zt0NT33u3_J6}hP{?G@Qa(W5>0+d9s(iFpHf`de`8sxjD^q<>b3sf@Dz7V7&am(&sW zLg5-2?Ci1k&v9MNr7PZ6S&~L)fvGek4(6!wc;E5=x-w)4hvbK9cIs070DH)j#*=;n>LFW+Qi`-0KP~LpsqN-9E=@ke*~PXc7Ny`^gp@O@A?MM)E?W0jbOWN03E6L z@WPRiTqS%$#2IPFvQVPUS&Yy z6!BWYj!-?pio(b$pKyVQe!jm*R}wzS1l|b~b&nN9Bi7gN)b-a>0({~jc;TFU;!Ney zYYhi;p&F`ck^a40Y~D0$Z_wRivk8s_9JLbB0KQCqvssYwqW_ZLa1qjhhF^HXnq<;I$+=s)jRQzT+26P}4amJ2QvGF+pNu#Ml-HB2HBpVI6V zF=cRZZw(i8jjGT^>a3CxtIO6OZyDb0C?2-%0m{SUH<2ozBi{)jP`ECN3IE?H1{9lTs}T&@?74VG4oxv+;s zyUKdbpfv4#4Zhd{h;Ag)Izl{5B|meeiz5Ppg-U+G0nfJi>$M$1t)!l+_(x%mMOE84 z7P6$yH|zvI-?}#wEg$9aq*CGV*gdOSgMMbw9+1W<$89nS%~xtSyDM+~biQt6Zi2#C zdG{7fr+xsNVRZF(S$%CZ(eG;oba}+WO+H7k;)W*rKH&9Z$k| zk=%QBZ~s7bIemnbZEDmo!72iPSO|C}-g|w*-Rc+NuIVqTfF#h>G@Sy20foNtX`}zS z{vvq5W`RHxJKNKRFTes#Ei1)u^;CSJR*AP~F|pwqoV_ z$LO&>T^0&_;cj_VE`imfa^|2bx_;kM^du&{vpYu}aR|&ZP!wlP`96JQ;&5wAg4QUU z4z*@H{l8#~^!lDPLof8Qv+f0ciR=B2fL9JedVD#lz=`_$zv1KRB~vaO8QQlT@PeK+ zCSGv*GReSZ%I_@+{}V$BPVFh&=Hcdu`Tir-mf;-Bcax>>TATQJFWXkTt9av_hTUU{aMukBcQI|3$0BjzbQeuX=mRENLQQFP3?+@|s$$slu zp+VJY0R6mLl-+VdLuqT;6~ly&erj#V8Wd%Bkpcm)@#bx)B5eXwVv&E`wn>Ka4!@E4 zL0L@the|Fc&niCAAm9K-Zs{c1k{+lpoZR%N)GNohN#>mvKQu0JacBYY=gf$R6#_t@ z304WLtPN(4m?_%^XTA;A7yOrzX`=Ef>n;#5<-Eie&}q#*E15CKs8Tn^YrxEy zu`^gQpK*-}zrV_asarVnnlj}t1;6rxJ)a=~6 zsIB$rk(TA$u;Az&{NOP*!=~mS#h9|n8-V(U{@hETxyE5e+f$P>8**BP=p>kA1*N(1 zk+*%F!jfgcq{KR3dl)yfbMk|`aDp^G@SB*scXDWLOiLVIw8w9}e_qHkW9VKb!%7xX zFt=9jCnpuC($uPnF1jZsLTyV0xCX*MGa6(nV6+r48FyL6KF}ku$S=v?+O~>5PREs~ zBsI!j!p2^;m+>Lwlr`Drb>nl&TJIrXv&~y+g40fl4~|>o-b~o*y!aaE;Z|%^_=EY1 z&r@v}BQlnZ7(ZX&Wk{O=h!|?XI?wE}?Bw3`W+a5=&FeLEo7VJ*@(7+@o<9D9V|@X> z6djE^vHu5EKluEiVen^36uvNoE7;&ush3}FApO>)@olI*r%}XlU``*@0fveIcy6^01yea+RE>lsnJQ5c?jKgmYtKipJ&mAISVmI)gIM zfN#b6bS`{92hSOS>&nLTE#7kOW5Mw%Bt)*{O2c2BX_@ zffg0Y*STZe9LD_ej3w2eL#OetN+cdBQ+8{EKBv^vkB7lf8Rb*ly6ZSmeqQ+E0%yVo z_U88laax@;dxys+d^1E@!u=m^`g+sOaklM0^9wqgXbX{){2!KLNTL z-=rRJ4da54I|sLLelhP;WE7l?;d3{-8Wq z)=ORuePGz@`D3Y<>dCoFQluj+$;e8%ZFL_=KGHk0U=cF z4*x5jZp0WBF=?hNqx_4*hz~9J08a7K%e(QCen}mUZo4emXzk|n!x`;T8e=QD@IoNx zaIUmf=( z{0bdGPxbuBpmuKIm3J>9R@1UK%|EaS5T}Sv|J~K;rXuZXCp+x2E7Shdiu-@t$#HFQ zE8LEkVjnj-z?Xuf4gP|{lDVV{&d{(+R0hvrNVr9#R>VkJg}c|fIoc;d@R1PGOX~x ztK0W@%VnA_>vFIq`=RdEj7ZRM+=g*th25O!X)M9~)NnhWCr3v`XsCBTC2@=6)mG$%}vRZB!lO|@5z ziGPfM$6?H>&P`BH0$#S)KtG#2I6q7^b{eB_z+0fdCOVC3*;NSxoP z?DCbas_WSxIf?mJnRD{!^a}sdqnHtuvxdJiUVz4<`aSy(`6}vNpZ747i1{Dfi1Mwo zGw0xeAH^03i2g(uQ5$z-4ZtkToi2L??iJ@6Ebj#sE;8T15eBNqP8lkh!~?c=%V-NR zu{hR1Qf&$OI5Znqxg*A_Xtbv61Y`}vF0^_>Pa8kqH1JwhtWOAG9};}NjQivagnsp} z+~BS@O4o4fp4#_BKR6V{bpMa?133^Y72iU$xj?WdS&AUNO zbbr(a#beTAS`-27;z~&Xd=HW>6)L*>G2&kkX@5np$7^f>q6#jm0kqll*s|1dY)6u* z>LxwroH-coIaf>Gv9r$J3snd#?Jp?f9k!(7j)ebv725U^0HcLZ*=kY!ARbKsi;*{mBT5gX zl-dH8zYW#n-!Ua^g_F8Svt?n%JbWW0tI&#WMHL1a{w=|HeWYjLVwJi=Tq|2=CKQ7{(}k!G zzoQSkCBK`g=L+ zp}_U?r@_S@?oApGkAk8%_U$RJ*1lmr@T6j!#+k2Msa|ZZemoP1gc>aU%_XHsl5e#y zFltjc7Z)5KM3*soHGt~vSg3Q)Z?X!?zRLOgVK+$McoRY@y~4G!ya?jM1re1>48sRg{`K@$)l;Ro_29w=^IgiN5+&|VKOpl;=)3EX-z(Ege)~^G= z38s)Ue-Shahv?3l3)aZF1rL!M-lqZ%YJ2R2#DX8$uNV628~jD&7GHl%v{y_$P~66Dpd#oo`Ht5Zse*UDx=c$h zGGdx=`nNX3&Bj6u#`sad(P2*!kYJaO@C9kjEk)$CX%`gTyHbu4BZlyU97RE9wg-&w zgMu47e34Iplqz!a&4JCn1tlkcxc*x|^}LxXbEJoR0>YdnkqI}U&{{BVT#Ywd+DACC zY^JXTU_$X2Z19ugG5#7IWN&PbwXz-dLb?!;CCySx;PcPQV-HqgKmxy`C|Ih>VH)2z zJr}toUe)Xh-O<9fZndWrtBr2aj6QrfSh7bSe{U$H#gPp1o8Is$I}^ocM^jm zqSKZSaxvEl{8lR+bG5t!tBsfvjm1-pQ&MCUUrqNEi3Rczb22#ZcbB_aan@hI7rVz` zgSuHkz!JdMZ>k(DIb7QgG&n{pzN7Te7*WvnqJ1BVQk5TNJ#-=Aj#&0rR)QX;ztN^! zpC=mTlHSsC=%iG+^FRjp(kC4d=#i_u#~11ppw_3ODKb$ve^MLwsvG8zSC(BA%A1n5 z0BHpdH`@3CfzH~0(T(27-4yjTRy4q>kXdYY@vCtl3vf90!r_z_my%_xMPy19S0qIN z3?+B1DC~qK#$pJ^aA3zyc%isq z!}}iA&2_t!d&)*Qhd~Skm^`44j~0legf_VeAXQ~$<-e9jd=49=%8%%f+RJOP0^4u*Js*=~#5Pf{hglho zv3p)SkWL93(ApI^WQbkD?KYbZBT356{6ga_KvTw)2LbBA{!#I-x+ZQyv1hEYN1gL@ zaFU&FT?>>fmQ?YkucI{OBp2in zI}E)f>BHX%WAV2Rpc=ks>;L*d!Wy7Qorvs|0+l>*P@G`_X5ZIIYW4GeXX0-&{I6!c zn0bBE!t**+B%6@;3uv<cjuawA7Q<^Sz~C!Rv~ zF9U3`6HPMkbC!#1YTdCli2NOt4AS_Ie>d5GARnYdNxLFRL+&X_^zvr};W-zu5L#qL zhDOtyMth;bwm%{E$qp+HR%<6Rqm9e|_mU_m1mA%!?F+;E&>!Bw*Fy2d18+Q)#$$}( zQbMzOiZoOpdU|Ifh5^h^O~;$A%C)GbV$wlRnqUrMcmO3*myWB;ITFZ#rKYNHX{mhY?v z7I&LekTDF1x~@lQmB$`X{5Oj4d{Mw;$HvwaAE&px%6S z>6IQdx&Q%|hjeYV74aKOl)Blec-UY#vP3N#XYB`>=x{Qhmnua@GJ{#F)P`G+&Eg{U z67?2+dy&!4;l6uk@kDb$tY3}BbVV)ub(zQ8s%&9XM0P7J50E30m$0g-`ywkJxZ#Kt zwM6o>6t7a#%pw7C3IJtkC)x$_MTbYmVB8`mBsxKQBEX2q#;`J7`k5MH7PQLqA_)Hh=3sSRTKXdWsI~=`n!j?#SXa6X~Jmjd>(;w($UH*?mi^53+4hV zAC+Q2VXFYkm{(O5xQPTaTf>VS4jN~{M5#2vf&GYiO=cIs%9bf# zRCZ?4C;aa|M{U^_$N1Yl^L+j%^us=x{gpxz6R4-gG?cYvIoNA!2K=lRJgX5rVIa1O z08VIeby2j9UI>GGfmpU^2IB)5tulNLR@w&+<08$aQKmwS5>;;_Qh%Hs5{;~6?MVc_ z0r??XM>Aj2pD=oUb(^Ub+-OQHTKg0P-f3%TyTXXnPG?2Zmmbas$ZLP1I@?hu8hr)J71A6 zb6#evhbC?WIZSv(t-{Js;&GBSG)ai8M)a(i&=Y$Mh`t=cGs(c!{(A5t#UKfi&L>Vp z7NvPHhE6uwFWm8Gtz(+51h;|fM@`s38kM0sd79F+`sBD`1Wcx~zK!KChpd z(<#~HKJABdW4$1Nm~l-g(c2ZdT-2(6!Vys;w5GtTetkfywakyNq&;<~&Va^HfmLV_ z45NPQ|IlUy-U-()o|xU+tD-iupXX6P;e}s5jW+)5M4znZ+=yuwLa4VY2v`3hA24HX z_m|{aq8fz_Up<8WfRg2I>Gx{lp=J{jinDg(O0)&RfEhGSMU&64eenfrLqZEcnNnw6 zrBb|%X;=UaJC^<2RUWB#r?k;)s7ZHum^*x$t!kWpEMDhfABc0em zi(z$ZMYP2-A@WcK=}-y?6N-!s&eeA$Ce19i{3Xiy96fjP&65s0(r^VD>lE!x)=0F2 zYebxa8JFv{vTn1U(on z(qeNXMXQN4D4ygfd#9BP}tkMg&m3*%!`A?Qe-|{seXJt|kEy zig5%@kYY~T+1!mSt2shgAlWEUv>-s8?w%j#-L>wNcQk~fAO9ef<-t9ltejd6S#<+0 z_`eR5gyZiOsZxUZVBLw2TSxxSrP1_GC+{7K2{!fzG>Qv#*nr>&0~qzU6_8KOFb+tE!!hDT_LAx@25^0Dh+T)0r?d}QJP5cT-|yW z4A)?ZSQ5S4GDt|PDNhIzk?r>;FWw5!C@haA3|yuNpaBJJoUfyiOQ}tpDk4ahNC7xf zJCli$4#+Jc+vL0GNO8?h0X^gRuSo&r z_L%4Q9B7gy zkTz~#7IAbbP6S?X!%r)bQzA4ozAK}?1zRf}#~3v?6U#-s>HpATXGKA!5X8H_K$?AP zAB0;z`@3IbuDE5_7{icZeYN!;t%Jo?`f>_;X@DuKGQJ2{u1mG>?rx5z4be=eK0_4bS7FF0xfb9O>ltZC_Ts^=5f#Jn ziKKpb?P8ftNjWviJj?tO(P}exWL1fsH($~zq7ZVYne2ZN9NkH+qyoZW?^b+t_+m^m!V0JL`|82hWm)LdGz0+N9U`CN?RB6FT zvGwNQ1 z>}r*z0aQM14fHk$yLlo#siDUFBPIcq)U9jSTNAc|I`#Tve3a$*Ydi5>h&_aHJbpg?GXh0&l#{;fAuWRiS&!vYk z#*IZ&|0>G}GWj4ycNvI<;+kj}OfiuCVPUUo?&ve%B26BmPrT2KglO48T8@M5KTfl3 z#0^9o&94G(?(DB}ja;rt{!?QGnN~6SW`^Jc)TPB4amE<*rXF8hm*~Wl-OAH-=!Pp& z&B>iB1@kmK7vDX;3R6f{Rm7q{ChN!<=EDG1-nF}&g~4J{EkeQYos7UBp15Zm;Z&pnZcWVe@Ip4-ocCka4bl0HZJhHeO*w1`kM^oV{}A!(1J45 zId6MZVYv{x;clgt%2LO}=%ua=R2+$EM%WytH?Tr0m^T(|*0an}dP&2xAXvAP%=i@@ z3u)Xg7ft> z*(Y6&Go{s@xl2Md^g>e|yoZLAhvx2m^9w}$G(9g`CsO27MO(d%>=rO<*(8k19mo~q zOT91lfzK5AdInExR)AcimPWq#HFVBRzLos$w)3r`kb8gCpmF` zQt%dShzF>|&>)GD9$^g=TU~v`2u-aPQ=pV71^s|4@;`T2i){qfn5^*Gga}{_dHXqG zz6_asSCnTf_njn-pa1cgTqA>;thXU;SSJGd$z8B$go$VDsRzpn z`^PoT)}NGTc_@XY+C#eba4O_mjHjr0bLEW71^$v?bJ?>*8s5hp#u(^Kojd|GRPBOOX=-drfF~iJj#nZ&rwv7(@ir=T>_mhLie*#09DFf;XaM z^YH0@2KWpoXvx#bv<@6PX1h^*4jNSQ%_J7YzI=N^5*8|<$DHmb3Vh8?1MvcKflq=84LzHrTjwp;$d|hqqy?K- z5+MXh@#;GP3PAO-+|Nl$wj1}6M?lgXLJ@i5JbH`>?^EC=bmM07Uliqi9ig4diLwO@ zr$tAAE``%I>c{0%JAHUUS*4}6#=b%4z&`34DY&-^+;pDJG2j!l)>>)IbTFICQ3~{z zC$^;eZG<)cz{E2D#Y||J?HwFrjO3;*-b6pHX3tUE2Y@sO)nIVfW?#mJQz;|W7(v^+ z`JFRgvmt;!4bipx8p3e(-DxWO2TB|kNwpl?UPn%7nt${$xmMI?%{T7~6RQ@A?VGLj zagtwZlt0&Zma_F}c}9OULbO1pw9pw+(BH*F||w)TsYT%}+B$nNM+ z*T^8fXN*k$m1SN_FG}1%Zw=yEoEczI@iE?dI|ny=c0j-Uy)?HtzamfjExIVsULGh+ zV4Ot`b=|+BG+Kqs{aNS{D<5Mw3`Dp+B^2}5M5~y-L@^vmE!jqtVpsgY9S#7Xwf{Ai z4XpK|)VGg;0D#`TB^>YzW@E=#;jCRl=@>S9>wkpQ=~E4|lbWxaaDoyax0q1)*4M{kF|VdVW=$JpwJSvDM2 zoGxIIVB`;%T!pU@KRJTY(m$Dp$rAqbGdTH~*}4UMgiPGs z{4kxqZ^T`|dsh30{Z^x6IX8I>!?^UsnKs%M?7i_mtpj=UVSAs4#nE^g#dZ$D;UPeV zMufbmT%+E>JgVJ$>CSZp;`K;Y3tvN#4{KevF*4nOfCHT%9Y7_>Pm`_6KssW z4mdN206XJBNsuow*gnB^r-{oto!&r;a_X9(V#ODTQ{^va|LbHa3s*T>DevmPOS`q1 z;NWorA2n!G|Ku{)UJ&O1kBPMDKMUVYh+~ehN@@q%Ad*wK8Ij6YBkscr8%q|OpUL=) zlJ4(`3f#%^4UU{;(q;r|K_L?wNO|^t%Ek}yv0yBzE5A*2N~P}Y1us`61T~FT%+|fE zxP!}t_{dOJT2KV}WTnD&W{9BVcqk9z7#h=-X&bK0%7L;Xfp+SqgPQ!or-eo=Z!R;> zFU?MzL||@@@6=wqMvo)PXcAI7e@!~ixMb>GG?D@ZR*R0itoFCHuC%r*i}$H_%e_}K zTITEzRuyS-%d7$mOSbI-G=#~d-oP6TfMP}r_Z6xbSb4oMwTDSJ*7gim;g(OJr-JBz>b`0VmoolIuOt)F4_%nP_W?79b#)FtVXrlQ-vD#d6DkY!5xw1<%-(7Hitzjy-P$2C za&m_y!*LHWD<-L3HJJH69MuEBB9MXt!aZUP9SS1#+=Vk3xhUr{^NPSF;((*@5~}!p z`%SQiycYTSsqlKVE#R>U?oD&bm6M_^?s&9{|83U znRqmu+(e=vm=m(Jbh1B9N@-kj{$*03;1}8*&W)?TJnm~)@}2D<~!1)Y*PuvB5{g%u0`v4fdnWWlu8gX<l; zyL8*ZS%&zvOq4j$&GEu~V|NUxFBbg>ELiu_MN-9(shkWrFf*-f5(|+-;^2f z&grB__3kFxTY3$*(_A|zO3OGwz*aB+ZqF#_s(P>eMIh~0O<2ggBC{Yk)FjDSiI-bm zB|RK8AZdx0~4-F&Y{ro!_<3%M(4m}c~a zB(b)WyR*=yjq+wNK!okPCo&Vc)bJlzH^s57zjukmGN zBoy*XD5}#RX1vaGxfcUyH`R0nOcIEEILekPK&tC+jtIjeHzRL$+P%#;e#99mqA2r# zUOQ-D0C_syRHdN82QSmOLwX~GTpR&%4NPq`!XS`UAhN$0FL3(ywPUwDL#xc5;k4<{ zP*%${LwW&IHV+Af3BEE#eUsBZYwI({Z8jY5 z>@7>LUYDNk4e$gH-dlfh9lI`7FJ!_LKrjSIij;#4sX}0b1~At$vD>O054|cvK4mcWs*YX99G3)dkWnp=(aa-!F`SbAxkzyU<}1B)X*0;ElI zh;Lj^gm?$+rIZNVDAx85_sW>Efaj{ALE%-Nw`g^?R}%kusN_Z|Rh`o(>Vfx3fB^#a z4rjuo_`rpxNWDCOu5jnqf)yH*ksvSoQ2ZuGaJpP7m+dWn8-BH1VtVR~eWmHLt~{C@ zPEK9!64Ds>CHPe4ccN}LnY`H4y8MKY0iO6_rT3B53YdKBa0Ver#dxEYvk&;sbZ#;D zk;avxtD;FXcq5-+(gJ!aE3~vd_Dlejs^laPgCwN7o__)&eo(dC%$yo;Egl)Ydd|xx z-g?u#Cx@ZC-qsj=BaNh>Beah%Z3PP9kP|r#E8)OaCI2=ek_m5A!92e~#kK})dLc_R z*;&PWRy^TMp16|abzV}PSAxCQYc>W?!#3|$rBrVH`6c93WHfB9ab&$}-c)mmhdbbC zodukl_%3>o&_ZPDiRN|puhjk$9bL=-$F&{&1XLu{)PZjnWYl|@a_F`Woz=&p!X|>@ zn%axjV1mv1ejFFnU*bSOUjQP|0t(e(0Uxjjuw~|7xlMR!uzEGrBxX2y;AoN;P1d;A zc=^w4;-xmve~R<6S{DA%3)n|EZnMAPxWjk?03F*XK4lJFoUbQ$d2V8s`W!r)$KF7EiSi z8efS-_i2vd3ans&dDE(v-@u2VB7nWFlKPMvaC@`Z{t}%GGOhc*)ZPI5R&)@Lr~~ac zT`wjL9`KVE2&}H}luUVKfd;ER&ABB;oGy4O-69lm2s+2U>Y%lv9=d>#0nrG~Cy9O2 zGmer7)K;VF(4PY9RlIogRoWI-k_JmH*m-Y412RTu6cmb7Y5Nx};gPx@RqU!MY`2UC zr`q+x(RDWZv$6Nz?;i3u+M(i>dInwFWY=vHSp${aGBXiIj)>tx1P|7ZXL_wWU(yWl5mz#&$AtT+>)rd zBXdl#z`L^B*?_Y*1blGsdzqDY!n`JyTpBT5D=iRHK_Z9N_uKHU?K$LOh6uQQsZ$8J zEz<=We0I^FNnbM4#DZF~j|h`Bwc#xet*DMd;zBjlXnM^uk+r@M!R$ zwnKHNE2_2f=Z33EarUDnb-`6{f{K@x=~A5~r+diJMR)SJbsnb`Y!9|udIrSkk!%_} zl{@x<#nWc=X_aCg>jjdx8)ZI!+wv1uI_CP5^F>NWeQe$e?6zql*T2xozc#+DY07>;QGi_dr%yr{W1_a{H;+}FTc=Q@6PmYV@5%Q7WXk*L^5(Iib zrPyLr+*Jl5)8fBw%P%0qUsXZneq9_X8dy79p(TwM?BJAj(a|GM)DzQcb+{^~ zJQ>VD4q`tSQDt-tkE>82SZlASn3j-c9h4Uhy(oAzbnWSyQq{-x^=Xtff+)&iYx=&Z z#1JV&*4#G=&{O%ZQd7P3UXZ_nfBB6I=uXp9Qf^N=1;$kCzH!HQh!#1sX;~>_;8?#FUKcH z|Ja+j$A4!pYo~)q=Rs z9l&j@Ykk2#9wPE8?63Z?QS}XSaT)e_*nwdDz@9I-i-|m+l z&F2Tr3m6UBC6)L&r3iJE)D?2}xdT4VO(O_%F)C{J$X2>jtIDYuo#cwrFdp3zjOZ}? z07XE$ztw|C@dZozMTm+B%s>Tqo<_m5xVlo+;KeixDZHp2nZ zfPQ{}pgk}{`h7chb~AGH#BlA36%Q=@r!SSEDLYyTDUy&$AYnXbq z;M0NW%QKV*B32g^bTKFD2j?EyjJZariCbk}1b;_Z^zQj!Cw40Kzt$!PG^_5GA|Te5 z3`PRMrM_L2LO#JCJEeiwy9W6cv4k#^@chRO?SNa138954}qGT+W7uBc?|M8!p9eURZu%7wC@?^7FD!j-2+%q z$19S&9UtB|ZxDWZkNRZ{Hv@Z~dmrugbfv_)dqt{v$>C@%2J1m;20LErZyn&aD^lIL z`}%>i3!##$&#NETC)L%4Jwlms?uJZ}2!!|q8y68yKe{0A+nfEa1aoCqwpB9jChZUo1q^wWJzFL7G*^Kd@Mc2X z5pGd-J2nzOO(X=w-2FAmXK-j;(j;ab$7n|+HQ^Bl)m{h!0De5;()U942vG?qJ8byc zMhNka+^v;UT(oWA3W}YM1?0U~y<4o^r@WH!qQaBM{_b_N4q{BDEyGgDknicHLghjD z=?@N1-f(>QeSTK>6v0>6=_x~q;9Rk_buNuwu%;UJIfv&HC008%;-{d29l0PJU!h!z zd3Ie0>DsL0IE3HM3dxS4Cc*6A863tL#Uc#gM8vtKe_(g^BL&u~nx!YT;1h3Cw)lYg zZ$UChoG+q20OQ^RYeI3%eC?(p#Ewlg{w zBwu3K_w+vVZ`~krC7__Jrj-G?c0pMxJmp-bZTV~lH*r0rdd&vyxb z^`CfrOblhw!;dS~aZ)Nm-<&OM(#@Gohk#Nkj^FWUZxkkhqWHO^6P_Qkf^hxBj_h8o zB?TLOJ*-jNdvRe_U_u6=PO6G3f#9?8hmyprgh7!{0B~EHOc`5nQ(*D0LcJlT4h2ec zkle7Tn#TNtt5#+wQz=q!P31jHWZRhNTB#jABl%q!@e7~hMEIBV!}7FWtf3s^W1K#T z&CHW@OS$xI?`s|W7^sF7bz3HmY6uItOWF z%h#eL9cgrfo*WbH2U3-ITZ+*RPJ=l-^j&w5$q14n@jmfrA$H_?&L!1y^DsEa9<~fk zS^XkS8%>_bv_-pM#Of7K7uCN zlGjh@KB*QrZ>fK=2QkYs^m%_84J{lCuy(p)^#hi_N|kwDAp;_KxW+OpqwaO>`rTgb z6U3+XxTEWvjz9{3wyt|ibGWyGn2Fp5eXW%e%pE`m#cem+!?-hfI^`OQ;uG0;w>WYP`neYL%m$(fFUN#^zQz4^|{10>y)9KR5pL=}!=7;hBzD zB9k*FlPxu~$W^E#SX@y@jPz0OyRADWDcAV$XH{pqtDALb#7X4{{QzDwqqcxP*j-JH zKZgt(s&^E|q!oIOu4IoAz(P=s$EhwWD*`;bdE#W6m0F~UqX&+KtxPP;eXkF8c%Ujw z$z1Lq{z66ci9nk7qi#f1x^D1d%Jp_n6UL!AQKgj!A2T4?tgT?-+cISdFe?Htn{}JX5B2P%kV$zW}7UsknDv<@bctrsq?jU>x2`$?vCJk}=% zoZkZPuYmD6DgUPy-hFRZDrLCor;ir&Ofy=&ISOV-|iO>r<(XHk|^E1E6=C_dd z_ny&zdCfd(lW2{o1JoI>_`O(9OgUoSMP@)Kf2J_|;vk>plJNnubo6JLQR60aY+E^z zySt$2_u>ZxlnkF3f5WGY7HB{dM=Yms5?BOt(VT!T8vxCCs4#DE9hSXcKQQtSgzGBF zn8^wPSTJ_5QpEi?NN*}XZ41B2lvRFyI?eV-lg1lm81D;Y;IsCAkULq00JJ*9UshsG z;+%Fd==+f-?0n7Tw1!kje+Ug|>PK>UrHA%5)>)y;|zQL^z*_|!(YWKn2t z3hWJ4;dKd3<^RYhm(d-A{`{+Ai{1M^rN&|RHUKIy4$z7CP6q+M0ZVKp1%mj{fc=Ar zyZd^2u>D(pkEe1=3Nb7+P_TsDyHyAn&E+K|v)g#E>`UT z{Df6;qhjCnS(A*cYH*d7DM-vcpWlK5JE+x@hbUX3xrFaX2Be#|(l~M)!|#>S!I5NbkVytoX#B;*55j;%#;|*-Q1|1eA`?mtF1TngrpVJ0@X$>(o(J znHkJ1R~u!fkx1rBdV5FIXA*hVtc`Y}aBqNbJhYFP`38sRVqmpu#C`AW?MvA8Sjoy1 z&HIvnkYzB%5G}If#DyPB50@O6h_c_8cH{=G$s)TrQ;iqR%b(YZ`Eu91MIZ=8Du)LSv#HTJ)UGd5)-MBu+ewoOF&n553cZ)mlFKZf|^7Iu*-$;{wabUlc+)+bQQ;=vUue zC&K{&9Ah6v@3nwbO2SDMu&{$?fn_$3&X^d#j^D-!=qH}7YYtQanw?Th7Izd4yK#yW zuSI$<6oN#ECASXF2O#?)pDm(R;Mfu1FLr6gM!JHPclyKm7D7qK*k;X(HC6Xt{hQQ4 zuln-9DqM|H5({u@QMZRpHzj}+2s7T-;OiEcRqCLz_z5ZI91|JEmQtvp;@yA=4Q6vk z-*qnpzGEU<_PYLDxTMp}H(R#JiSHid<&qXrh>T3e<`({5jKPGRoq7u6U8k;PzR<=M zhr;n(wVy?IVe&Q1&!J%`zI=N306j+ch-sbuQTxx(AcmxlZteGl1QynaOyz9V!I zs$M=@o3f&y9oo6skzP4jqcg%t(XHAkTDJQ?!|od!5$(R^Y)n5yTB!V4tP&x>1kZ60}1$gxcD$;0*ka zw3@w#u4p;+7>*9~4EEKe`tDve5V{hwN-kSo5}^%epoloUi9dIegiihdIjn=5STgJL}_3R~%%-8u6QEp|FJ=ulE)MCiAWbobz z#kOwoMvF4|Id?6oyYY z12yv@W&c(dJKZ;rkBRqwW>T*Tk|CPq7AIu5Wj4d}ULNvPt<0-VDcf&d zW8$YtX?Za5K{2$3OqqI^B9PFcJ83f@I*;@cksX)AqcRL?{X{%#Of<>Yk4I^_Gl}Zo za&FitBa`5Z&1RrDn-0E&XS%jcA+kor0yL-{QLbtU489hWFHPb^5(Nluy$j~q+H*v6 zc+L)>FA^`lA@3kuqhZpsY)WDY^*Q&vp|k92rrNTX%_4jKH?-A<{TT5^%oc7{7)Xw*GmP2}NBfFqcW1Mk&vlvs?e#{J6o+>nf#RX}^F@E*!p-~0k$ z362ld`#LU2uPs%C*CH=GLfaf4F|Lw8HUvPYvoACZ5~>ByP<-CIqGqQhnr!Cr2p=2W zxf39^sUeZMpc{x_Yox}NLo$7e$o2XX@!bARbwQqe2x@q5yu#>j?1X|RH1!Ax&IExPaPr|P zD4I$i)|j^nVY5ekmv}2x#kR$xAh6Pc4fivAv}*5!E2^+4{nsl!)MUbS0SUJo7icJY zpA^zt8B-5q_5Z_lcIclYeJcUZ2OKejp02%wlUS=bid{(8d~7HqM(w)D4YIPY?Jxg} z(bc9mmF3bC$PQE%%>1p}{=yp-BeUUY1ce%TgqgymyEZ`Z_nvy9(`O8xkS!7glf-Q` zZe$Ys*hx+@SFOiD)i#H+SJhwQwZA&~YRNVx@=g&=D|suMp_^ZqO~(|#520-a@3Wik z-XZ%@WIajrp!aeWI6Hnx$8y(b;&^Y&+H;&W~xjIY!`KL^@RQ{k-$i zTQYQPTDY4vm|hwI=l!7CQ*gc1Z2Td*N~s4Vo}nygTum82L57@DeSMNP!^;w`_1}bG z%4Qw^5xknD!ACm(AZ27~-y~AW%NE#f$Rt$o{~)`@TF4>H)bsM8krO28WOY)MZ$=47 zg>p2jncC52eV}%%hMxfAT2J5MBI%VvfhdfJ5uS??b>dDS4aP+eo#dOG`hw$nJK-C9 z;97BB=>AVum?JSf`$WmUHKXs}CWI86_mM(JcVo0daW#o(X>P3nN;k$2RvXf z0@+_8Pq*7Hf2!+161pE*uCxtC7vy0~XyHARq29+0jW%F$*)obI24L;KShRL5B zY49Ap1l~ZtsKj5_30$cNJ!m}|`<7CaKTN!R`?V?!i1au}Q&v2$QrTR`1-l@_M^0RA z_KF&q4~teE97FGi%trXf*%kTclnBTk(-26U0s=sSNcd{o)Xq!B|NAJ)ROR{7CSvnU ztN#!FSuM4pdu^AoCHxhu$?PufaF3ndyL7n`@1>p;v?# zQwFEYuRi)J_fFaj$?kdy99Bt%$TLDPtA{7uOvRgXv>_3&5nTsE)#pn&2fMs$dICm%2)n+jTWo^SNqX)gH8N=0(En<-62vahY#Kj+E6KT66G%hUd0jJc2#B%&^vmNIVuzmGVS(T*1sKEY9}=nCHvjdhCCSP^49RZS6@vxwtiI>6G3-7%s2Ls7 zu%))X#@Y1r7m{8~EGzYy%E8PN(661yiD^)N0~m#04E{j@L2mmja7B!2#3sdF?njaz zKt`{jLW&1DR!;4PJtDJFlOotfTUJ!Vf|;zDJ6sENb}xHHyt6HV^#PK6 z_>kj81*%%oS@SW(jnJ+hTE*aVGW0LGXej94`l12Q%0SZs6T9_AxVe1r5YAgkj$&3F z?~5|@bYa<&Nd$&*L$D9{fXJI`?I=c5KccY4OL5ut|H|QZMa%l1sT9$2KN%BB6+#Cd z9R5Af3W5syeIWtqpjDsZ9g!N=OWAn`iL)6zzuI{ zwPS@;#^R+x8pNvWBnsEiy`0h8pP!2jOwO(#(y zTiSGgHS`O|bC8mygUSO;L&AlxUzP`Oe}eR(HG2+V*~uEH_?r4FPKLxars z6{QLd@5sWotFL3mWV;zjJfBtV&0Nx*s;c4uuG43XCHBFD^CBKEq zn`UgCOJe#NQW4AEK)F}i5BEg%JC(Mbtg>nN3Au!wodZZwC&crfT@@MtpM<2{gV1T> z$*(Jty3#k7RZqL3(*{cO1is2sbYU1qqC5x#6XhOyZZ89}+czm3-U)K4l|7i}!i2>b z*r?33(<})Xq$ZZyM2|MQYQqzm7oA+JL_s^odDo@qfNnjoYhKWCTX{y_W)QxPwmakPKbUW%K?1$S3y0!BIBeilrP!Bh00ikwa)EFKd2dn&LoqDPyPp5i z-&F`Vk&(BVps(IYM?vvQ71emxVsq%iB__CLkFd~7bes4?nK>d76GA@*a^aO*z2f<1 zzs^51n0(MOsQ#wZJRC)9-=riSZe-K zWZ@&SoxGkng$x?3R7MCDXj8YWQ{RO2&-yJmmg<`#0#1Q4d$5oyCtZ_n5-H0_-_PE( zo>=!C-%>Sq5urI} z>)(^CDe0pmmvgrT$*>B`)HxADhPgbNYHem7A+x?@QOjzIqs@PMtBdjl2ha%j;y1Na z_pkafdv^f0VKbm~p~M(_Mg6)`9{JTcvRI31{W!sBf1?AoZ-& z3~{gSTGXtSP6OAKDYT20b$|^efa5GhaV-OttG6B>iAcb{VDEmI@i!Hp8JFip;@d^w z7|@B(uquY%4fqhaB6-~M3OC)c@5C8)hY)$7BOItecwL{unW*}1Y| zR6$eIcxoM}B%s}&Qs?Q`w~b155kkNhSkb5kCOK3N1D!7L{}qY<3Ui zCC&g>I?jr&zmmC`ry+4G)2hJ`FC6GhFHpivSp)FETy(bKcrD39KIgVp?Li{-$MU;(H z81^9bX&0$P+{Y9E66}_y{CtV#SBiU3Z3>vjPUde6u;~RiZCQT{N`WrCy z1Ui1~#Vh$PSu-{=7$VFj6n-k<>hPVeq2Riqi`WA-4~HJbS2>xc$GU3|yv~C@>#Rgz zI-h%u7xk^D6TmZvj!^KAJWi{GZP(l~+JkE;iZdYD+xf=yPZxHibHtw<$Be(+eRA|p1ucV;elIE9XabRs^(oO?9?jUUY5 z;pUOk|Ee-LtbK~E<#KBNed~@8`m1FXfDApe5RooVDv7PUXdQSE71y$O2-9}^sV<0T zcQYqMkyw*rTR^XSP?MHBdH>v~P+tbOKz zH6=$KOUsNvV&V`gKObi_T*YZ@ds;AA2=EXgSMDY^!(-1{0qa1EXQ^L1vgLJC z?_EyHCR$LqK?o$C;%EnG1wtKCk12!euWr1OC9s*2mt9WfBuZDIg zrtYo5hHJMNrUM5JH?kKdEqc-Zw1EN=nZJ_YNbyN&5sNwK#siw8wyo{$K)ykVXYYc;BuzL&tTT!7cuKkND%0sl@PTWO+u-wiM|Fp+RDqUEk$$4 zJxoa)VETl3S61hc=k61OXxl!nQw0Njf<*|X-)S+1@sC0T<_b4xwQvN66g-T7qIFtu zv?2ne3REQ5_&)$4ckvm1wCY;-sWg3thtS6I!2JSxlM1P5uwcPJG?y!qaX7%(yzJD` z!UHNi+*urh`fS7N)8fOzkjRv1E9QU`N5YZrip-)K*xy=dnDkXHnp3qC>AM54vQ!@4 zf0TIrw5w!#|A@@;)53Qrn!UTr+;ltxI!0oGx?yiNh`-h+!CoHEuG!sa>Xo-8sSIeWaPh+ETaPxd z*CAyY5?Qacdz{}f5J}q+*)wm!J}mFYoBA7n+&oXutE9`uOiq>w0dTNwN4h#MyW}MI zD1N*A=bHWbi)>14a2H>&LYgSMbZWW&cB3GqT{s`18?}|Rm?{r>p0j317aPOXp;Mb% zzQXI~O-Sc^u{{YS)EK;7$*VgnxfGYwoJO2EnU?50$lE6O(k+wK&r zH=wME52)#T6JmDJ!P<+YVgLQ3t2}3PfG*ghZ*rQf;(HE~yI&v^HL;x8Xzx89f`0j2 z)m%dk>*--0R|CuW_EC|>ESg?SoW18EP8wCy^h6KLMqf}&QStFibg{>@Ea6k%Xp+16 zCP$6P%N^9JyhZmstOPRmsq!DY-90&NC(fJk1vbBFU{?hjCzl;otG7SOxWJm~%_+N& zsTl(n*1KPAF2b_V!Gtmrx~1ZvN3oYC0rObMorY##IYC1a)3UgHsg^d%GviFV!986+ zh~4wr*#iv5RoP2CP%FzqnIt=dO{#S$-d#I?X~Je5XKk zN|&#U!aYTDr2Dz~&e zXrmGPq%B-{7idEdAu~F)?~phg0q_x0PSeg)Hx0fFij)a%eK1x=H2^?s>NwDQ&Z@I- zR;&jl_^D4~hOEb?Xa*#_au)vEla)iIj61OmsEEmeMlE9Eoj5u7eieoib*Ce*l|%p+ z8CG!(Z*g1A{rOCtaI>xGA~Ouin#Qi8x4y+aT~YqPJ9p8==dx|qZB_f=6bd$}!HD<; z5Xe|w#W9sB8)r_ZuRws6BU|?<_l$N+QDneJ398FHl1rEYG_?@688(?U z(Gd9%_|ts1TD4%<7rV-=pkn@#E76C3*}#UwpG0r*W)X$KL?lo6!Q-naub{PG>QzP& zvu;}!e7c(ly3^_+%oxYkRxBe_QY2F{V%m`sPR=epX@njGs8>P^jW(oew|f)wF!%fQ z{h;zQruJYV(T*_#-5Iy)h>D#5YwcjNXG5}Ka+NO-i}$&yo8EiZ(8=?orOs;AS{q6= zrTS@9#;YH;X#t_4+kR+82PS)NC?OR6TQJvXbln}7gAUDDwRR3@_zRe+?6I&W9o!2d z0Em}}=T@zaghr%Y%T9)WjJ9#(;E?rgMRI^R}S+Ro~Fn4rz4R-HCW5#U5r38?$B zUJK#nsvmF$|W-+gBmLvQl5d;4zlSZRn^Ns_Za+viX1sfqt_4GWOSf=JGv#+>=01 z;8XFV;eHuNiA4t>9{PH^_ES+@uElM?r0%0I%NLVsbw%LYPMJ{&bOJ?JicS5EILSkx zBpqb^YbNwN7#Oi%Dd^|%RW)TF?I0(}BB2m}92LO^997>@v3RN~p6FQ`S5|zpZcPl2 z%*Lm!-@`>rjPxiQ$|71}V&70;Fh&ca%m38qqV7Gu2z8*XRAKe~vd z#WUCIGxS98rLmk0{-H7x5m)SN5BiypGznAdVJ=2X=)E<%u3crp`L-cKNPRUYzKH^{ zVz~-If4HaCVsWk`Z&SLB4m1)Hyv%3j3+h#XKbs$kOG$h@SU$TQ5{DV@stZdw|Kj|s zC+69Ga!J2k_l+7KC8>plwOF@ky*=vI`Q!HJbz-6ZEs> zw29gdr-C^c!9OvXIQbC2NhSS5TZS{yxFFqLNMnd!mD=wwSYyEKrCWE2Ks1l#0VnuN zzU$%h$ILv<@yqa08F3grLa&e7`cD9)Y*>-&%-K^c?^4A_0xQpxS{&!R(lLJ~ zig8T34M;6OgYs+(LwYL`43>5<4Qu1NN1mB|HJ(|I(c;8CfJ=SCZ%So9`d^jnaAeI{ z9!IsO2=mX*P67Z-6v*5JOiw!5EvPErN89L97>0v3fQ2Sv>pdK!=?2jFt$?!h zlWSUMq5BiwpEw+7gOu@NqGp;i6bS7;7`LFZlb-!Pf|ti4E%y;f2suS5zh)KRUt~cp z*CM&i4-qZV_~)#2Ko6a8rVUu4ZUu}E2~z_>{3La4U=q6JFd0A{)p;Ien$K+-gOL;I zveF=_oh#|}vTECA6L|E!vhq70y(|bk#f;C-I=|`uiNBm6uD6oE34if$aK17}RPF1@ zolf~1(-FFYzMTarp{_3%Y+7kEpW79R$Ax?3jkZC7Xp)xHFzLi!0 zE~eFSb|%u%EnA}I`;oE6E3crOWT!=v<_>0F{Tn;JKQrRqx7OeYF z;aDuf#mF>mS{_*LtpWGZ89|w=r!sXX6|N`XAD6E;NN&E-aAGoxG@$u#^YC4BE8r=TXK;B z0)THfS|Qa@Fjys7X7{tuTjm`~Ln2%TEwv@ZO7MQ51aqJi(_bZFpOt;q%gN2#Q@2a3 zhi+B9>a!Q4i4xf2z&*~G4S=jqzCNNQ%6F)#skYrloo6_Nm_yLoO1iyFSwO`)U(X6E zI=AOoVwiPR`f-BsL__EAXboHn++tHru+}`y=!?jmgn-OGy2cmhd1QpkUhCX=6y~;v z`(Bhu=*cgY@px2P+#&$%@3}iLR*b(H$PzS*n6Ig26T7P!p=gD3OnHJz-ZUt-s+fT1*D&ulvy{{EF^jnbNt(qS) z)O+W!X*PS9YWW&$p37*~xR*cddmlc-1NdWo>YJ>*UIzysj*TSTwN~J}RhVTj!Y&M*>Nr@s&WX( z;@gt2erRi7w5dZ&(;^IJzC@Vw3t268xv^6L<*?1UE>@c=5CR0^ zmFmQ#2)EZdP7p6G#gxCF|8l5NqOK^P&6m-JF>?gqw0kWJ8n8%3`;In!_SoMWL<$yL z0)!AGZ3=Tyz7|5EA4U*?P!Wh{CS;D<2Vk zw0dX#^n4P^hfdu%kqP?z+60xKNscD+dYV%h_n6e z=$_5j(=PgSH976hjycqWg~>or*)~g(CCh)Ds8jLNvK&8=0A{uC6G%hB{(g45H3D7u zl~*?v7FQpr#EQOaPHP?~_?E)*eD4oiD!jh6cswM1_aw)lLhg5fuX-kT%-Scr%KSh*pVM_ZS^Glow_WsS-dg}7hFzIpxrlb%H3Vf zTZbu1;1x4Ljl<#is5r%pUm8oe!t=m?dk zy)27wK8@2FBS3|t`q{O~;#io|y?@ghg-2N$i#%|UNTf^zaT=X^vP3koD1xkJTql7z z?z)nor*X!{;-m{gS$Bby+n>?EvJ>OP_@-^CnA5GH`VvVt+nZoBnSQ=U#`SS~Bq&_6%L9|4Y!;t z_*cO%RHG(AVr0)y=~Z5SJ)?YK+jCkSbPr?Uw<}&bvg}Q>!PoLN)uPRPirG>Tz|*qI z%df0t_liHDn+T=y;CS!aT=JCxmTlj^+Q@(?mWrmW&t$y~i~`&4MNaxE9#c-1?{|a- zdL9#;WIdq7(@?+6K%4ENg#Ho?KqoAX9Z#9eQyaQTkP^UCRR7OnmV4Y0675Y%0ThAg znOCqiAT95aR)i!C*Q?HD&`XBL8;nFUtMQN07B+;>hR3U|8#m2$O-|c8K*O}JD*X8s zW`TX;=NTR|r0uDZGk~a{1#yem*i}%B4~jl)WZqH2>MR%cFVWojl=3 zWGmIo@j&2T;HzJ}%PdVeejQU=~F*2afdjAbCztYM@zLh#Q0MkUxv~*Yt|IvWy_MaA`VPHDMVN-`C4 zr}IcB)@4J&wzzO-uxe)WZfzhfmKx6KAN{uUW^!>?Bt<)Cl@7<<0F5a{??W-^e^Ysy zuhT^?qAh!(LQ<)53N8|{7fbzhWWUZ_!kn3YFLqaIcw@FOxZ5(|pXn4GCZ4)G=23gp zivYY|DJu`nkQx+ukD$KndY!azSO-q}qjc4ReJF=*yQ|~5Is2&2y~99;9ftt zgjRdeu}E}IKz9teLd3n;1h#LFfk}U&EwFnSn3euF!%s`mj)nP;K&sLqZD@62>j)kN zzv|MqU9rIPBnYI&Rl~}!|>g#7JeEv10 z-Y=ANCNmhHwRQP?_bav)zqM;Eg+V5p%M&BoT@9cri3d@7CYMb{riSPdh5^n;ywp8@ zy>0)_pQ~jkP9gpLacHF|(c+`kS0)-pHJT6?$|$(2j{CAFcQehM95r|=id5=qFFCiS zOML-SRWS-L>bLcl4C4e$_&`^S(@%zs2|0yl@;~4FLdjI2Mox}CzZBG8@WaS?;@c+W zl9m?biM>SASg!rHM)8ASf!l>~&E7RKSN921wX*a>3hvPL6 zZx4n~KuZU=fo4nSX$r_;uqM)pSlfg!IDo5Ppy#AD2T)rAMEzf|?EXx-U<7K&yzCrwjYIpM7n8zWXE5MQI;T+uqf-2m)0n(~vonl8DfI?1$ zo3F8rg4sTOhkBIP1?qG0b;o(7;r%J6JJ{|IuJ24PU)K5#iCY7&U=c4j|SfH zY>vNXdsN=e5M2rue(AL~ML|#%xp~qep4jKpaJ9I*394K3d6kOvvx*=^1U##EBY!NU z4A0k3v%y^lw-q?Gw$uwOM^4o^MB0eBwMKwA8#TfirggPh?W%fRioF|G2}_=s>hvrk zi4~W(!xGonWX9tYrlEZx%v%2!nr#5`1-$oHW>rWk9SsGjNpgMe3a4ce{{7c`n+p!Io@KhnMEW}z@2UdVx-A*Z)YwIB~ zhqwMuYl8}72}~J?Y%fV03jga)0QQ+t^9-RN^KtpwM2Z0^-~{7UVP}NUegz7WyBON^j<1=km|jF%KDt^Wvj7gg9OS zE*|%ws&&FHvFV+6K)(ZPTi7ogW4(PPhnlQ~z^WLZGzFXIB+OfGj1)p>sxRp|#h4Q1 zHV8ORtkXdb&NzYP(1G17$OLInlqQ9#7@BEHMa6^o#Owz^DK0UIBiJ?6QSvOsaF}c0 zAs1UQAkJkiaoax|1E#gIYjpTETJR~bkB&64YPe#1qr7&*8Kp* zW75aVx@BGh4_GM@iki{o`_)~5Y&coG>>TVAej&|z>3_~Dw9V>FG2Z>@A^u-~K%FDv z=ta&;E1H@-3~keKEmUuP7Hban6owIpeF~3u!Oc@5VcW3*zgfJJ;P?)Gc99U?RdFAd zL%$mHwx+sTCJg}jY>)m~s-WP{+bz)uAuMz!JJxyr3L$6PACFvVR}4PN(!G*Rb+woIWv) zcB@&ewnv#Sgn$7{XzSj0KM8`r`b>^Y;hjpB&2s2P)qglpZ|0GylZT42{kdJH$h6xF zO#>O-kdXgx-ubh^BuzVf`F;EsB$2_O!f@`s;HrR81<;cvPc?dTz^A~VB(=>Q_n5@A zx4eU{G!Op;rZ7xgL5#FlZE>if`Bx;BM87G1DYX*0r}74~lp}DN%nRHS$Ob;`;a?x1 z7BiqbOj62H5II#M;i+&upAE!?9_g~~rivt%#;7?JV3n@Fej<&GgO+CE4%cd7gWHnK&mOkRIVO39Y{P&hz8~*`*{>UNVV4XR$UJ{b!J4p zdSE=``y5^S0fRR3iWVjJEW1@>J_hO8zF&plX@VU_N}~dWhK9!_6nxM0usU_)^SdzL zf-n9v@K#ZNwTwJgrt1EtS9frhdNWH)K{{8$eHm;Jwu)DymlSG+62L3Nd^d`tF zN2q`YO9LN0g4}fFnf>RMriUab8_- zNcT;8H1T1lwZOoP?nJ95Cq6?*`U#0kf%3L!%vU6N)M&?ph-gdgh`ItI;8(aQ7a^Y6 zXkj0W&yJY^nYU|Yf6a_4X`c;XN+XTxJaGX!Ms(@vyW_9}$e zMTX!;*tnrUX9V+@C{C2FXHCGA14VJ=5`)@0lF&a-n)Yy3toE+c>E_@nl_pVgT5NOxxCLS3j!$Oc;D2 zAoda>v;Rks`(A=@Qcbd|B1xk|PW}|lF=#87&A^BnWfbu*y=|Z}Jguo3p)3n>y4}6A z8s}})GLuzATh5uF_Q%c{2?k6stJ}7^lM>Js-byKCP{~}=nkQ$C$~j?n_i2ggX%)^f zg;%S{wLg+Tzm}LOD&K@WuG{v*>bBJ7ZOyA}y{*#B7zV#s zN4H%^vh;Ck6nuxH5$sc8+2P~x+4zR_&^Dp6dt`9Jfd|4gTtIxFxCVa5@ z7DrJy%PjK33i8Ya7RAEH<`jaCFf1m2F@|YB@XxN65q1SlxY1V=)ElzlX>AJ>VP=M4 zBit1_U*&<5C*Ww`YX;?fT~hVulFZE{w_+AhV<;0v1*)^}tflV(L#As!|KzVpS=LB& zQ{{T&|9u+pRu!g`g4OotnaKklq5T3#;Ex4Mtt#mH)&_0Ok<`^iJ5Z99Vv(Uw6T>fB zE_GwX!A?m#n(F{VK)k=*mZsR=aI~V-Sdgv+2@IUK=Vo!a&V{?LI63*vv10&YLKa|VHiAZX^8Z?gaUrMEs)O#o~h9NT4%X{H1RBlSm z4kIVWn&sW}gDm8DFQt&Z!P5w$h>f*KZ=VJJ#*iFKyPdm)#iiJ=S^#sa%$iUWE($!$ zwFZdk^n4Jt(_nXNw_qJ!mMad`nIO>hdK3rB^9Vdop_H1RRQv7?5x6&->oa;pj|7!@ zspq=JFnQ0aea=THoR&k!KdrD40Hcpb=kIIZ3Up!dm{sB)ddKTdl8$7DD;)tJGp(w^ z=t(Jd`vfN7Ejock?MOcUR#4vs3xKoG-ea@&B7qaSJbaFOzzW*YM+LTvfz%7x2gx?T zP#X3K0BO{+r@s9`VHoJ^Ef7UCNl^Sa3tzSB& zTzx?tv@!wNH`R7|XVjO3nBz+2p}oLUFmYU*L-1e|eTvoD_N?K03yWEVTfx$lDs7&O zlZ3u6{NnirarQ<^?|`G}~eC;pK+=Y~1)XYpVxbDVwHR0T^r`X#QK5i0#~IWcX*f7p{wqR~74r=tn}ku*y!0;+y32na&Dz(2)RD>5nJ7&g0tKb0Gv_T@pO{=tzLi z25~-1SKCret*_Vq_oP@Nl`xzJ;qH1ki~jXp zh~AvF9%HoWS^?>-UH3{VW5u?U=MjteCqfaeAZo%&y4KR;nvuqzF%yd^Nsr~fQFlIr z1`=4$^L-k@nL;t;V-i;w+zh5D+AwQ9z2Cj~r@}-{83Zr{ z=en-mc`~=T5^%22tbqP##j4ADNJ*P9|)Kb04jd>>01+K(xRc3 z{=JJag`!V(ZXOtb`d0`$)cWWR#I1(Q3=2N4piJ1b94h)_H%=sV4w3?j!CDU zGYV@+tXjB2mr%6~l1>px0mw9cG1rF#e@&+1fqOj5tjymmriuVYwW*a;g#1_#L8rYQ z{;}}YlEw7qjhU+kA+C5LxM=su@Snf6*hetA6lQ|hh7wCvMLCB1my6&4t;@2DM^3g6 z*{45~F)ka?`=LI)oAVX}e^z_19;43^#R^nLqd80f?BB^JC~%gvYi&0mn`0aL70l4K zb6Uu%uA{mBnAmqSUD47ulK0wufDXsHlHgeze8;=1klN7`NLU%O^b9?B5!DQ{6{%fM zGJL#Q+d=!!OOMXIp--Rt<)LSFG%Gn}`xtcnRAWBs1)+Qk?Gs+rLjGk;Y72G!!u170 z2yc?2z&^Z!TlrO|XthAOUOZwr_u*haN%qrKnw1qgqOC#UqY~{wF~>R)oOK3YKK?Oy ztWEtq%Xg27hkD+b*@H|!r*o%Qcy=&_YpqH5FM7wnq0V;bu|Z3zSsqf0kle_~c>ahS zQw^0x4i=QGm<4oZb?)VrgRL18VH^4XLZJ+HA=EwF(>i$$n(k>u@a24?_Y-aCTEQ6u zKn2}uQtj9r`PdB;4!bOyCb6>(wV)#y0M)-*{)<_Ay*6)My=JkN{U{|#0GiCk8S%;7 zAk^o^Me|1fTrr?c4(K}`!dmV33sSSk_))X;De~?#wPdjk=)Q0u=%hsozCTCC$>5F% zTfGcK3ffwG%BxLE#N~ptcA>{K`OFzBgc=&-sM+FY!S8aCkth)C7STpOr~hS$ zl2@qIg$s=SW^*a)`eHv~dX!0*69F7Cr%%u&+sSIugR~9V8vCx%zbAYYZLSpm9*H{2 z_)ZxlKfpEmkaf{kfjx(uYDQSl*Ys2G(Nn-gjmthxHZ2rah{!&JFiYnk=|Y3CzdYg# z{e0tWCQ+bg4Y8I4HgmI$Z{1MB)|Usfy&@Rn>s$AtQ;sJnCv^U6i-je@d#VX(_z;E#CsY=&G zTxfCF*UGRst5JJVVudeXSn2%?`9ha0zNEq!PbjBUzHuhCagAY?yic(PRD!bOcR}jJ zC+kz5RW7B#D|Z_zq1&+tGjCVdX?k7jbNr3@6<&%lw!t@6ft42r-o}l?!UW6Gc_DOH z8M)zr=A3TPEuy5h2&3Db{;Dz; z5NAp0W9%N0My-o4Kx{vk=reO*{jQ_)aqP#N_(Tj4-@_%kSFt_F+Klu%B3gfsmf+E8 ziQrIeGBnc{$r&qa&y*7(R-Z+*(dHwl%lH$w7!;4FD?%lv?p;j@2WD=}s~NndA+cE$ zZhoX)E4wccc~YOdVt><4+5c+N%NU!rpv04Nu>G)#`)mfN7zcLrW|5vJx;B@7w9UBU zcF0AiPbvk+g=c#(HnmHsM-^#`{ADo{}w`OqH!EurZ7B9;bmNz)5NU#D-*p{3t?x zc&AZgj@?KDxTQxcPAJhj;l{@0v5vRxdjeIPCjjqBz)W4snkUJPqR&lJwX|DcPMlqM7G+)!`}@t+#j`BV8EzHkL%Hrq&&SwC@P#X~D2LANp`QC-z2L zQ=kIVn#pk!8iv1WGQzLL9w}=5oF1Iu6z`R*O^OwbErt`YC?6Ho{Lc`9?tGhUOvO<3 z#o<-|d1cDC-@!V~^)2*ncKt(Xn=w9cshw=c3fqA%KHl&h$+i~kThMx0qRP|yN3yrWdT0dJ*KmuL9ajg9&w zf`Q&K`kHwcu?bmnOu(@0OKnTe)qsZEDG=~9kC%a{RP~=YWLiG=TzGTYzh5HuE26gb zo=N1~4K%Z?ac;|OH?WZ;W`%Wmj{Idh``YwC-NH$jaoBG}u2(P$n~Ha~rB7q;|NYt+ zbn}n=sS~v?i;v6ajvxxW!@bFhc$ZycLPF`KQZ``5Mo4@&4SH2>aFw~rN#ywrnWO_h zqD|}q(_gFFpj{&JuopqC*BR}k&D5m_+Nb+xL<5`wZjUE%M3(V5U}_edD-0`@3&}+v z!4p--XWn9KHVO3~N{UqT5-_1k;0M|H7y)U)8KDU&88uU)7_Z*bxl$d0!{si#>hevV zVqwX8g47s0(nI@(t|>Mq4MDyhHksXAI~la z35W?a!&B^+yGs=k{oJ$iX`X;+_|23%Syd1gx|sPWa|L@as=tj~fNjzUO2OYl7ynsF9I z5kup@4&Z5{t|VH7Sq{grP7SIS1R{VmP^1p7e9ufew#4}$5DOzz4y2JoMnSzI`FsnD zogl9cMGGgk?sJ{Z8}Sqhv=##GQ6Wg|173V;WS_-e(jN3s)Tcu=)D=~x+0h8GU9O`e*+r=6#wM9P?a$0L(kfg+ z8r9yj#$O89lannQlDKK4#dQI0qF*a65SgUpFzQ@TB%HeMe9F3V>_JIYUCz!;0Dq?M z2fwFl>CGT4Eflh4KkCxOp`ca>=Gr0-fa2mxfFxtcN*TW#MQ}bTgx4_VIAbS1YGd5U zE^Bk(N>-hIowtSv`8)fU$;1MEG#2je?%!ICDk3SqGl(JMI-?q_2O4KQfehxCp10cuQyI+VqDG5_#DTr-_AA=gs{ zvW;F)^#%U*L3zePl2kyu@r&$lvgip@8uH+T{X#Xos-?(vipIpKP6Yd#BzzT|CxY*u zJ6(jJg%9%>Oad1j*zN051jf!uOj&f~}Ef zMRHh=xfN>xNdyt1~M?SWwnmmDa90;QXpV-m5zp z)&Ss_+lj4VzXdzqCm@&U!itBPg@OZy<`S_CjlOU=Q|~B|%zoZvcpYv7(5TcqmNYd> zOC`#ct_mr6-qy0J*cAkI&iB0Ov7(Xv2qhriA+MBlb~ADFS9#cCEHO?ONbE+H@^FtmGOO;{8-cuPlfGiozH#>2)gLi9>Z} zGVL7^ksG9j%%H+$S>bau)7Au?y&Iql$@A6eR)^6LkzODWVecZ6{XB6Y*Ei21PnWjJZ1EU3wXdz>LP4}ib;kx8&S0tPHc$a!Gd)ZO%h z{ZjMDNtXtJ%-svlsS|};U=~#$hM`)aU^l_EgDXvqpaeVxAJIlXQuJGlczT;;j8|Bk zpKb`jlEjmYD=@lUAyXTJ1@8Zh9J9NzL2&&5`}nY+3CIi{f0)YU?SbC1u1?1ra$KvS z&be$fH~!HvP*buGTIlF{brTR+6Jme*{$j~ym8uSfZt5NDloO4SFHLT7cri82M$KLI zutW~r_dR1z>w$s}Q-Ny*zrVLab) zIZEPtQgiXaMkQ12!!hp@<~}5J9km%-ANf{AUv(%ofTyu|T&R^y`YGqi%{MQ)@<7=a zXv5A z09)keW_It`jJLS|fdp*TGIo1rFR~db`j$uJ9{U{UsPt_==q`KLdg5cZXjpglhSkz8 zZ_V}iuDS%j?Bs1Ns$+oKk;mI|=H}V-flmGm*xalOea6StGbintc^DA0SuyLY)dO{U ziAt>FWq)~EY>@|x@bM1Y8PQMmGy>rCp&nKK+m!nC5&pJgDmCxWBJTGjDNg8#S}WRrB?k!3zy#4e&N`4 zeouA*WX!4!`1%R!M4266~r*tOjt1NVpfg#oBAaFM9*5echB|3Uq+AkUd&Wn z^qoBKrN@B|@+{yw?D+_S_xg~)YT7jy%nuUQ^VAULSO5$e@l(3l$%NW9izsIE&8m(F z{UkDZ`Ol;_5z$aV1Z4WDEcM`Px%_j;tTMb*ezxDVzrQla8@SWdT--WRky`jLnqQ0H zj3M*{QBkr6`&)-!ba5xam~QPP0E$UW#u^b~2acz@xyGbqCzaI&0<4#Sr--}Z^kVI( z_aJHuo;+*Qi+-E}{i5H658^gSC=tu81Dg;h^-B#(ayep*uAWXs*le94xQ8{O{r5IIl+8DV_(#ULLdR)6?Gjw_i)Rs z8e8Q4GGD+RzMjl`XkB&+ttKkb_X`}wq|aODL}8`l)4qgU}Yt$w@XBWIC_RBZnJ6E-`*YDHl!Djm=uaWI-#WqyC(w-e~{W-AG%9UGUa{dE#TLM4SFOUZqo% zj!G!CPsmur8{!uBwc9CF$aFa;@a?n{H}I!Ra?k=>R;V9?Uq-`;Qz=gcyaw*C#?lMu zKqu8nfjw(D1o2HP6hmE$h=qUowzDLHjx}@>!5p!?ICd)%UditzJcWc3+Md>*|Gor-TfYez z#+C;uws3ieS5?}-=I~fL_I?B{dY>5$LQRt0_vMSqcdW5vAsqrw@mZZ+!J}2def_cG z=6rWAyfh&It&Wc_+Z^aA7YxJZi}Bce@#bkU^p2`GQp0H{jc4{QDlqnQT8{mPN#wIdbhEP z51Gn#L&b<7rlx7gB*Z9bi#qy`_9~1Q;6PNL6T?U;TxiEvvu=^hnQTuO;GE} z_3vN=wY4H~EExe!<;az;vtVU@o+%8n3EglCfn?cbyYW^e-PFk^1C}Ov+Fv6KS{f?` zt@=Ai_9?Dg*vh>Hh?uDT(#290aCu8|wYLj1q3_4VAUvAckc|1~1CcB!-fi6BW^|I- zFb`Y*XP@GCvh^ZQwE6FRSq6O`w!N-%0C!n;5NO^ogiwHK(g)#C0wS!cu`14^(9&Pa znDGw(;j;nTOUTQ3v1{w!D@IkICV@)LkaLLVK{_Qjg9g~dewjWkOkgJ$Rj z;1N6C=~0!Wsw9hbqq+VAXz~(#l>BUMh_C>r;hN)HyXm2kxK2}x34HV(a1)D>UN~Jd zQ~E-NHfRUQYOLiw@;u!>Prr!Mdb!DLurlLxSE7m0e1SuD5J$gI>=6TQoD?uyR11F& zdF%P1A{$(_8hE%#C{1BgWkXymHP>h~O|73WNhL;y@-gyET#;WLNf27lpGl6yK*I{Z z9;f5gZS<5c^H4&raI)3C&@JX%(6e48SyAwuZzvF){F;TBJi#;ML>5`;kdx*Y6a)PnjUV8=6n-Owpzd!0&%nwoWLpaP+lFy&Za8?T@SJ&d4FE;s}Pj-XaYS zYy$*xYD>qy6U8L4*%5#TFqD^6GCUI){9pg7eN2EkWw4KGwgFhCi81-X&Ts^@Xb7>t zii>s;Pe@z`N|<7C(uElHefW?^3dP(J!4mb8tcOLEUeD(kom4P=81VtSiR;9f@bd;~ z2MOW>S_)bUGMi6j0Ehi^!5C};^B}(`6~q|u4Od&mh7%VC{$m1Joe!V}35wUKF$NC| zEyR$Ug0S{;XjEtHxrkOs(jLAO$7uE$^SqRx4I-c9l@{FTgeyjdSOZCIi_bP3NY7L2 z94Hb}T{)jW*D{^*_uzz~Ne^JQV!B5Y-UL7H_GV)-aMsN_dj_U3NsH~pvRPFkL7X%O zjay%HmhN|BY%7Walz*`|?i~WV@!=D8z=@UIi(y>NK2FtzL#s6&BnpoFz0LeI5nV~+ zY!&$U?4I|jn)c~bNd#_`x^vi@fP5fId;bg>L0T^yaa-2irtG2R?8)G{$U&sE**x2c z_DVPY9j3YC4ck6QV^NhiwnE>wD*4uPX8>#(6f{M5XUb)Qm)rl)GMetSb1hy-lzvs} zL!Xu5L~B(J4{fALTjxb^70l6B2g!cOu9`y8B@O$xfIAv_FTYkdGnb5c>h%1OXf?%2 zYffm!PJl%@{3s}B!+jUaLaFwNxv8=P@j)lD^SiQ+-&_A`|NO_jV&TNwVVdGAQVpdj zj;Tt<;0F(bCBEI6TUlILI%W{Zo8Tazb0jZH7CL>uF+ujqG;SF* zlM_=6%4LiN`tFb9g&jf%;E*7?sgKry^K2t!aB%jS-b%32{i>iPO?Xs4qU9MH z_KgLcWScDZUipR(@Zg)=?9|I#|CGhjqmr+qzdJITiY%$4$Co9Go5O~33>FH4?|^vrZGZ)4Y8(%@3qabVMQK>u z&{Hz1(X5!s9sx=sVQ`V6biE^H473DZ&scSgbG~Y|=YhSilr!X=_?k{(Fv;6siP=UC@i8m5SNfaE ze*0OwShJ%7pzq;{DTj3(ZPR_@n-;&e%VMzqn@F+aF-EGE44H=Gi$B(dJJpFbjk34P z66j*WSWwpDwjo})dHtGo_Tg*KOL7ot^oLVSb9P?JF-H*Z zQHz%P2>iW-&~hk?0_;KXCu!z}GzmY+o`!o*#pp;gm!4hx6#!7l+9Xm^C7rX^3f-K- z)IAMbEmzbo;vP-Q``ca794dpawMuoVqM-=jpbgZNZJuhpymS!P1N;LohM7sNsU$&g zlD4#bDoin>eF;NkwV^tJzD>pip4A}k3-GDmp!I_{bgc8oi%EWdIQ1&9T|1M9RqRdP z`8Mg*+d)9*#0tD+H2a24LzMOYMz8?xR2FF?o}tU=HA$ed&SfZH0LrJgQ_wh&;Sv`>ks3GvQW;INHjlj`RY49+Lx))jyHr zoAgoqGO!$fcAJ<7Me^V1mBkDa%e3V;BD4`T# zb%?O;+#0;axtxr3jM#%bWjbm(6t+MjUWOgq*2F)!u?#cPH5J+P0Xrc6{59p4-*118 zuCu<-<8+;x=?SD-vOC&lv|x-U7^n8p{+Zzy9Sq;lZYm=o0`~Q=g<0*&8_a_ z&)7XRKo8p6rt(&!LAZ>vbL1--88953Htd2RCYRJ!1fF}J^9fKl>l<~A8bhQQ^g7>o z6*#-J<&pXk&xs%*XS?WYeUmM1-n4Dt?Pb@)wgBcXEMzV>%Zp9L00rl!N4-4tb21%5 zuk2}N6*Q$To)}3K-A!r>3TimJX-7rVcSLHql`K%-)K zqp^-oV;AKJszKt9;(tW^KsabpMW^8!a5*jlNB-Kub&{~hg3HfC@~}F^(#UtE*^1#% z;(6g?%grDpauMd<(vSDlW*hdd?8^r{gCB}X%~hc*IyuA-2i58|*+9~T!s3v!f^vaT zc9M#X03gj=+|n8uEC96S_?M&gzi0nlHgW|&3_nWdKX#bA0i6|e$~Dn{LrOpFXP%BV zwg%H3Vrgy&j0#+5m{@iWIotGsC0ts9j)!i|{sG&%9VAdnn|6W(qDhWxbF4yuV(wW% zdkb1@Q-es&z8C00izaaEfAxus zl<^coNBaXCeBz4#8?;~^PjBvV}_|TPNnuGADAcpVWZG zsF)LfNh38+P6p*QK5QJEILyn8fwef6Az(WC`OwC1hrh$)LuW3rMcRtv;hoKnm4R3F z!ZuC>jID(Idgi^vsMe|RZ>~ScJluk_*Hdjg8sqrsA%MYJ3p;Hgb5qJKJfA;q%TD z5&2I*(9-Ap6%b;V%EwX2`)!RO5`zw^U_!)=5X-PLzgF7Z8-`% z6R7MnB2d6}>hsaC;~#gMHc3O`E4rqcc5VxKVPoq5zI1c#8|w#$&gq3Dm*PE^tvUwX z-CY@|aBW-@A?E>w%vJv%y-}68dYy3v?Vi}+x6?5qLp&_VbJl)@w5e_Ixu5bmX(FLj z`l$|H`nZv>sTKZDYbM&@?om0fJ*`M{7|q5LOr;%^OIf2vXz&*`?1n)U3Q1l5O+ zIeBh!iiW{AdIsmv51UnpY%EkKDjBV2@?DT;%=XdoO7FkY{1a!Zg6x9O-*3J?*8@9P zTx{;A^Jc32BlHWQ3 zm##>@)KG9Y#+aF4l+0$GAK%bTR%O-E%ifrH*I+BS1O8`Nc_AFRtX$$K2ADdfmA~CE zl)nJBREHowewdpaT0cOqp73_06-Ie@o|(9IH@X*IKtVQB zZ+oCbj$DPMJYlRk#j95#SgT2hv2RZ5=2&E{T)M~&HKS587r1X!VAwniG!bLypyYe8 zRYf2U05yNimL<}du`&PN=#?&#T%=styk^lddc~Lk04A{URLt;9%vw3$#N;8?b@fG@ zk*bTieqQww(w6DjR)3u2!&Oo5Qd@P+mfskB=Nu@~Pw|ysT%+9b0d%gxEWGbK@;#)b z_QWRh`j*T{Y)JnfGPWB7Y~o9*M+FYUwCNdnp}&sHD75CFo(qbyvZZb7HE&$dO+!zB zn(0`aH?#MIssR-2c0C~C2#HhyHUlyiand*q&JQ)RL&!)P8$0P@aC|kh4#%T!((4pH zi*Waobp^3a3&}gO?o1vID5Dws$74yR0 zc!>}K+GY-Bzu40Ita=S_@t;G>IrxrAziO!Fuef}oj&hU@4CEoDtwWmrHO#6e&G3$a zi4Xy3U$EpfV}pYoRu=FCq2;WC_C#Yk&YsKJYmSGVe&3G6D%!q8t5O2RN>&BVUcX$d zLRWCUe}P+OEb!@^gnBPRs=xpWuVlnem{-cO1dx74d3+1JsbLmhZ2XZGGXKjCQP5)| zo*huga0+{3j!;hCM|(DjdEDM5M@B5N%rz%tx-7m@nmZ+*OGGn*n;CU(D2L&bkui1_ z=bNlbs-k9Wg@QA-i*%1{>)PF7(ht( z1riHN^bx!Ybu?kF%h9UyNNOa&I1g;LS8T38_0q__H+fef3va~9K+YtbFd#Wd*G)<| zeam7bC%k!z{dv}MzZceAxNh4@)gIe0G38?@DS>rh+knWm&xx=tudS6EPUi+&AAto9wKf*-DNOe9hJCKH8Hx5#$n?* zqFhk8G;-0~e73DYfbz$wXX`(eeneyPIdT4{j}b)NoV(_5e6M&}-~!r!+u@EP2m2NU z+0m3Y_X~DXJt2spV#i8hPBa^Zj874&!>2Eyy2xEfTxTVp)37Bcw1Aw(mH zkq~Xw+}8BGG<-0bPy-~%k1yeV(w>p_jEZyaY5@W`>VBNXSi7Kq!X1=Fx&ib+Y4@w~ zkqXGzG~tw`$STUJ{r!kq_j7pUoI@`T@JYqim3nxf5)luYshm_YqaFbo+1tS=tOz!A zg$P9NY9`x>(5Eo@40xbHSR{t#<~&iPne@1GkL^C$w#A5Uj|UDA9GIDC9MQbRDXRI# z6|y1`>_rsEHS|f}01l*?`jpkn@cx4m6<n~WX?uCF;W$7~d@>}hqDwR%au)!s8E}h)FA+#(3*Q=Fn7m%U2qjw6K%&o#RNJ3p^WvGk3K3q9g?2Zw^Z=yIZO_mr~7x%&f6rCiS0dPq5HONA|ta;7ZNVCWPmY z8q$tOl99#W#^b`C66)uBYu|9%dBo;Lp{q~7(zm6Vg^KR4tcS?L^Eb$~8jcjKsPTN; z%7jnjCFMF2r;T7#`KioXF}0^x<}Ju;xi+HS_0kk`syGio+`PsABYb*SXwX`xj;VrSjL>bL#c`OIYe0=oND;n+(BQnOH$ zQV{HNxD=Oen9dv80A^x!XFik19Il4KMuRgTt|NK1t0*`<4E2Qrcjwci7%;t*2$lp`dr&e$~7=U?fC|=iXk!4H2 z*kS)o)?yg%4FW4?6zCCG%xc!>*^eH2?*aa#XO)swZ`g`jG!rG;RQOtbiq65MsNv)HK9oeT_QeeaMMf`D}N# zob@TBjHCi9;>bPZy{JSAW%k+S0Hv@g$vr5LYCCotS>nYtlX#NPDH$=Os5AfSI3w6C zvGlNTMVBI?E(<-ABYqi~ZtO_A(LiI4O4sijzsbLWg`vP}p&ZnT38)HC#OS_*rWqn) zAwiWErAp1s_(l|P=Sk$Vh2 zRp`QzdzW#B8E8FXzCp}q8I>S1vWKT-b1Y)V~PgVQ1G|Nr7g;lDMfb!z!cJ>lzk>;YSVg z{%Qvg8vj}*?b0(QPdMY;g^y)V0 zGUVCy)u9aV|9MFk$86Z^RgT|B%q@@xJzR2q7xFge>0RSM*l_Z7=`faLBmm2Xf5jo6 z*2zR}VER-^j4(;LE~|5>Fo4X#+C0(erBv#(B`)Wo^w3<%4{M3gaZ;wlFJ7Uy)5gOJ zgQ~ckHk3IH40CRa-~)_1PI-&SgWR!+D=MErQPF}RE#ovseq z@0Sa-Wc|V!C>%ow_k!HkG8oTjQPp%$H?p;i-LnyfDXCf}ty)oo`&5mv3)~%TK|PT3 ziO9&le(VF}B?n)+$Eoy0zeV`Tc8zJE8KgG4MJPebg5bc>?csYgd|H?Zc3U5QwA9i#Ezyn2Eq zC$H_6^jO8GR>vA62jLyZXDrJ2;SzaI(T-%p`*myg-sWB+p0RG%StQ3m_t_r*Ns;6R zbC#Vf(#_$NRdiWGK!W^@eWy!D;T(4&w{|kX2{DZrEkDk;1pDH`2^jf^- zKJglk4v=RHh0o_ynA@%f(TqmA5FK`i+(WgKw$WXE59$r8ZpqKyg&hPz3(vhKQV^izfk5UfxQD2CNo4C?M^D#Zo79snAW-K@6h^A*@wJuE z2>p3Y<=8Sg5x*M)8K}8+!fEAbFBYyzpiLY7OR_bo(|~_1NM_4hHiOZ61H?GH-RoVT zgo}^bb`71AacK|xU-mK;{G*9_8JaGKPa8TX6p4>was!vNaXzEJXiZQfPahThcBIm2 zvlRDWZ;byY@Ki3O2F*U)!VZh_KYn4+$CG{RC`j3VF0OWL-E~)t%Gd_>nSJwNE4+Nu z9*e`dwlBXj(L5T6r_rUpa3SaZehM~7PDAY2a|@eX%)>rr)CLq1u0;crrt( zG7bSdVtjD=oX39z1T9+7j1#Lz*$?RWyaSy~cLPj-JDmM(-8={F-F;Iu3BpEnT8Q~> zK;qvBG@EQn6j188urr|?3>0FSlW}t0)G1UzfMZL@BkHj-U1~iY7ShI9J3uNUxIc&- zey1#JuGn@@Xk+aB)OBWKMD$BZZKWzfbWo^@QiPgxjT3!&XZL=+JQKNI0YF8MUl~}% zvXBD9XPgrKISr5zjXE~D@{^%=8~gd+^l4|$%z$@oevRFWPMUWLRj{v%0`96_6zhX~ zb&}t=si`nAw=b&ccbbHOY@XS7VlA%9t%e8*f!BbcT;*a77*0nlAd-4XN36>(Td7^z ziPE@}eML(*?1OlUv)Cz)B_U*A8{83f9yK|oP5S? zBo{^WkSFk6Udu+^R_qesHsO%AF!3mJ67}9a#@yO&2`f2!VndW-bL(6{7R1*G6?)kx zp9^7S7*5bI*Su`hhtuyYa#`&3x|-rrdH~9_dPi{bdoEY;>oa&Gm zEr-TWIRt~hy6iAGgZsDxgKCh=GN?sp4LH9QIHE_;BKU+dEQsdu-K6v(&nzRVXt;qJ z=<6gY)s?@al&Mr#f=AUM3S}V4xcRJPb7!83*@ytkMq08g+L(kJeOk|_4z!-vZ%R#Iy zy%KKyA0QR=--Og%NG4S0=N_Qdr4u>R1SvE*Oseq4zUE z-8IddDRm_zL;KpZ;7AopJH1OzY~0;13eWL!cb8tPwp8*7Wi&_}{W_43V~CY4SWFnU zGVxId=|u*#F$o6&%E@%<Cci_HGP zBQ}Y*J1m!u;~9LxB>IS8BBA5^10y|;7jPbg#JUmK2zb=gK6K#S@UO;AVVe5G29aX- zA)D_WxfDxzW|PI)MDz2CH}S%is*zRhj=eQf@pOS`&{pAec;Labou&cE#}f+pLZO=s z$Nj;hQYYayE`Ut*#+4=~pD<(%D=xEm6g+Q=%I$!YtP5(kD6kyhz?C&$mMCt!ZmV$- z)>lIjsPS=~MsK3OU65!}vvdayTn9w2505{!vV!!0I zI+#=q*>l?k(6LGgnB4!t>Q8vjz5;|N0tQJzRXuc2HMWUe2mh}S9L@W*Gg3K<)%(9> zrfw*o>lXf5Vb*cz8KUIj`V`T__(6xc!MVI#NL|J(9gw8(yG@HH%x08`2jsH+xrVIP z(*hsxZtr%TSc5}z4h|q+=D6=w06>~l4aBNEWX!yCY;8(r^A;%)%L)Q$H7A3DODXpL zfW%(^ZqPTKQu8DajC)Go`*Zp(^U$JEcQ7^hYYEi-S%P}%!BXm4o+st;^W!6)g$y!i zFQLcS98M;|DS#4d-OXX;lcO#4A_^~!05R`)u90Y+x)z#i}pZq zhaU>I-|4wC_WrUK5WE($mb$jZO(j`>7Ho#90v1S>ZDjHZ)M^)1c0=#upL7{JRx&DI ztgj{^k(Ti9GicrthJ};jp4GL^u8-K~iNXo@UjOC3cZl|09j&T@4hzOp7Z7zMKaNNcRh}jLOS@Jnn()GQ~Qp z{lk3;=O>)!LI7>1Fi)CPiVlKX$Bc12O4-3Lc~L}t z5DS;RswBBu542s-LNm8%WHfUU71v{KYyWlTB)Nf_rn}CtN~{I!1*?TXgnrLX-nGzIAbtZe;KcmLIhb8Ze6{H3DZ0$Yj2&r zS>eQfZM>(2lv)U}>6JCoOCigyOQnPZOO^Cjk3ka%ZkdAP3ini**6Ao)7}cH?=UZWO zRU>W6^@ZFa1J=|sQw2|38Rs8T*%}osAxIDzqLx|O7DE!Cp$&t%S&3J3FK#bbicC+Q z2U*0AI33vu@j@Ew;V0=m;20C9Irz})L7B3P-nE84qF>oJ!t*CP<{W14X)Z_*|9eY7 z9X%PHwqvp;8n#BEAgqFZyt}{~mj!Z7VR^Ss1c_PifLdZI6u@4o)n;H! z(sqWdl9_lvePgPkgM%n|weu+p4WoQa%m|KzL&qql$@K`HX}7sHZ!rbf&KL}6vHY=4 z>&S6(jRYXZ#(Z%Pq81F(M@Yi@Nrh~{oSDSumpg>VIXv3zfxyO$+j`y1Iax$S~FjU185B>hdwl%0^8So%%=ps3%>!lor6D@>?a zw$`*;bVd6aOa|CIbrvIJ5r)d4aVUU=RQsER8T%v0vhg@-T>REfhXvgQG*eik)t!DI zl4101TXc!W%P!B@Y$A<$4M&9s8ZxMKFc4H z2sSXVBwGG`Fm?_q_uE5^2QFe#bd;NQ3R77?xHo>IAD5mkIhpYSNIGGz08WXT%~vIW zJX)S3=C!mz;tJIiH2w4?`>;E5ISk9Pb^cvJkGk_c_(N4s*qChsqVl`XR6BblnC<%MegWj}9GmED1SY-& zD!&$V?KUv z%m|&Z?5lM&%n@rUhL6nG7Rt?;0^C1H$##BxJVk4Gs$gXmc~C#av@o1EuvMoI3!rtF z#i77FLjE%dSHVYOyVhAl>&n}&b zg>p*p>Q1r09s7Uqr@+f^5-<3}?m?dR^H! z^V0htwqYiH?@fKa2tehV;M6#BW4{9USuAr43V z2c6Hj(xw-+wj+yXqWXkR8JGbJ*1b!aj<<5Um0=g+1{hWI=hpF5%XM+Or|}zm<`9h| zBUx|Vg6B{@9e0b@Sa336_!Gx1`OT(5Yc-7BE2HCe>$5@)5f{{Cc~ZsY-LB)Rri2nUHQ!fqd;l2 zIo<1->Q}2x*)f4tcUs+ z**Do|!vUEKObPD(nO)CCHEtfev60BqMKY-@S}Ba00JOE!lAk$P&lcr^Xz&n;cAlcp zDb^r}4q(5xkQ$4M9Q}bl2UN2mgOgXe2d$`fUo-fwr-y!QJN4C%h!AAO(khQZBALho zg{kZBoAe{_I#^>1GpqN{Hi$Q5r;KP_#P(vjPM zx*kV2;$euf(PKbGnHE2KQ>w60sF1+%{0? z4?cVXriR5;vXra&o_aEsc^~YY<(2G%-e-F43-)=9WLh!R25QA`UM=Jks#ttu$qJKc zj2k_6BiH+lNxilyPrU024D0yLH#yPeI^A>S&h>7ot9NSUVijz?w)nsCSucgz)_Ir) zl;gsr;==OtPGSI3U^>PZGT(_@JEYQE6sP!15*+ zTwkERkXDph*}4>Nz@gCI0xL0kFp3fU1g}4eBr5%48m?b!2?ay%eHta}GU>L7t0^>u zh-;P?bkN|8=}BIle(@#kXmB_5%;pwV^Xna2FD@!|U?;Fhs`G-KDO>Rtj|e0r*Oni( zfw`$inBnVlm?a5p%A2O=m79Wk28#8lXbmA zHPM>=cyyxAQ)$aDdqty-0XBi8J5)6t@SE2udzx9YRVqLK`oN+i@popl)-yZ#ru96EK-pOf zlqdu?dR;5Bx^b28z2fL-OdX=I9N%F!sANvoB0ViAv?R=~7i16uE)J*hXL1D~*IeF% zC$%175tWt^s3`JuuLJW!b%&HXk4dlIuOgVO1^kaU^4mAg>Pd12a!K8bRc@1JJlLCTCxQ5M=7pQa{ zo5^iqsmM^XG{sA7y`RX~+&+RoWB$My&C1uaDm6;h3~PK!t4{|B>+dJ_)#x#zZDSl; z(M*lX10(_5B6U3+6)kaoWE+NW#O>m}i2Bqvs9&f6jk}hCTHAEA~uId{bKcx6w<`^tpjF!T)C414CVUJh6r@ zIcA%>OQV}?9@BzoJUU_7jJv8=>Jx;DtDMY_UJ7iCIo_{=l4LLhn%V}fVT4~(bqE0x zEBec9TS*PCvd8QTB!ERX$}O4~Vm`mnnZc)T;^sgSyei0>blEs;fdi$x8LnGCTEaF$ z+4+_h5N+2xF~`$x;|QP^LCR+X^ND<*{yw-qj~@KUSR$g#iX zsck5A^Ku|POHcF6THOx2EK94UqNa<)*N{@5-VS9$^U6*{xiNGj=FT2~75b4@mEvC| z!i!*6OvK+S?(qFDHbDB)6w5ttiytO`qiexNb3PO3F3Okq(ZuwOJnZ1nHIsdCQAPm; zjFK_SG8}&n&m$wgT^Lwv%+a*g)c3f}E@5JFp5(hBUT0#f>uoJyE=0XQG1SF&%g$a3l zIo2P|hkX+-+H#t;4&rg176?sGYsDy;@L#9v=}*9kwRWe~#gl|2B4@%w`5s(3-^`P6FM8kXFJW`r#vcxI6}x55DFh2R zN3eO~&zV|DC78qzQL{A%Y>ig@`kC{y^E=suE;_Un*oM_m3OUXdehx=6!SYSW>y>#j zolvdw{yiKSY!D%SbR^QN;CNq!bFs1Z>fL+NT!3l3>7wG^koc}WW*&PSoYEkPV(bB+ z-*fHG_@}Iw3XhbsIqqK762ie~mArS@Zy7byg2Dk*bVbFaq{(UGJTxepegIXy1Q5hM z9VnSAa}yUET5 zqznQQxPQy=Y1gaaIdFWfT}@0&+?^u6z0!*0tp+KOSa`^*2k1w)moHLgHviA7avuuMaN@YtGC8Rg;yzAYz2y$Tss!~nif+l4 z4@$FH%2Oc-h<5amS}js0&BPTmQl@&2p#*#C)*>eK0Nd+m)Gu2f{<4V2K?pM&?}7`< z`^-ee2Ju4?W(l`?hH{B@NN$`&fpjK#TU}3~Bytj3Q93$XO2@w@mE-BCsq@}zrv_9M zl^hnarF}_zC?ZpYjF5vD%!qNaUV4~{Ermrcl2Vh6^3eEuG0FNii)AvVbo+5ToOF*m zaSHspGrM&;FfuRq49`{PfqjilN%!_RxQia07H|CjTyl(iLNFSs82@$rNtFrd-V=qF zjzSrLG-CqUw&gwKk64;K*tgyyHUS)YN6XKRR%mNh1jV-{_cX8%aIavQ1G8E%bqd$U z#&aNSO{BCy0MkiPo3C4Sm$bPV!Z?1Rjo26m$_T<&i`>D-@bBb%M(!$kIS z&p*mh+xjWM8w5ttpM?@NLbF&Z3t90p!Edw9b=1Zq1P$_GfQJN3f8Kjy z8$2orYx7m&>;d#7%!pCHP7aPh9W3?BXQt-?pR$jTbdgkN(xltUA_?Vz^Wey(V8<9O zFoxh2mJ!l(zVh-Y!B}eZJkj)^D3WS9;QRpkRMhFh1(~(qJmiYaHO2O=nI+r)yMN9i ztGsta^lnf)fehff7b?jbNn1wDqng;V~f})iF zF#1pZnUhYinw|R{+j`p_Pi+MT{!-b= zj(Nc33*=8AD9#Ccv;j`ao(($M)E930}C}K>(6m3R7u~R5_Q=fme>5 z`Qz{KgI2yEKzqq%NxzS1Ow}y$Dx3&5(tzt+dnp1YDaGVZZ#YGWD$cI767qYPWlxex z-)_3J+0k{)OQ_bC9{otl+MOE1&cGOyPbY`2<*?km8FTh$h_B}QEQZ7OD}-^v z5W^2)xBJ2^N(7@BipKq=+}22cthWf0vF_>FV6xfqS|*(*!hR4P1n#SQ=^k;FREUVW zTl3uDM0(ZoaX<3!Bt6@!^zzOwGG2;S!3X*U!xTouJc^w?Po5vi+oiJhokhLut3ws~ z7mvQ+6vB-9`7Z1?8AzPHOC-spY>#>ThK~zf!sQAD3P)%PUx>HBX}_+L8Ph{VvsF(H z`mkG92LD@eaF(@s8i!$LP)tzoGqV}&0jE}(_6~s8f^Tj$vs7!Yz0mdQ<_s{|R7fdhh_0i)?Mo~%E9QW2 znvMCbxf|@46F%}C5U}zp57cw0Rl4c6qxQIex-@#fLu4?B9P7c)o5FXRm(4Uh!VozR zhx=GN#MJF#p?FrWa2B=^jVrz^mH5EsA3oqT_D9*Z-t>1hwLF58y}O{fLGBKxtv6JG z9!YgQ4*Aa?`=DtmWOTbw5S(KS3qbPtoaI8m#XH_~E@4=vCeV>}-VZdl63#`#0N0c4 zG#P<}%s#z!Wi+Bsgys=C+3M%>+pagn{3ly3mP1pc(dkD1KD~mU%Jhqw&Ww=tA)y^z zkR*$F0VXg$wY1fA-tAL@L2NykF#zf5fop4)Y9T*~Jg(SbE((nZd?49Xy`wGA6N%W@ zBkZGG5FTY71ii)fh<3B_Y=i$U4X!?aDxE+^cK#2g+tt@%hFcX}KBJmf4K>A|_=xLV zNv;(Ey5T7VuK$%t=$-#&)B*ZOKj8{*;YvnnNZI5d=WoZN(en~sqJ zbs7e+eCKZBU19sV*`QQacTfg*DhQbmQ5iQSn#G(-Dnr?^ajtEqTQl*7;h2pq+sy z+Ci%A&a4UnwHR}D-fp5J34M!zq4;O zNUDeeHz`psgxn*DSml4qx`0u3?ZJC!LL=V=_*OY4%&F9(*6owJrBL^Mxktli3Rlk; zrWEm`kA(ftQyZQ}hH+1PIycDY_a8({N3yPyZc{*`*@jCtm$4An=QO8pkg2(AqEA<| zF9UHylX2O{BkiQ?ddW_lAJKC5iqHVVeSzCE#eIXCU%kB*cUh%{SQs;)cZ@UtB!1LH za;6d`5k_5gNmsA`ZJm-u-Vo(PG^c}1&czEkZqWV>TpMJy}Heu*F@;z4^Gj6@<{ z32hr)N8~V5;A%ta7<`oEfj0a|JfZo%ROs8|^10(9qMf@ci$w*ONwH83`xshnE`)*DHnIf);7~ z2>{E_8RHu&XsGku^+uuLoX`xFviat&dH^{^KBF~)PY zNZ0O$An=K{|9RG{Hw_w5tfNhy()&VDKr?|0TiN?I87*r5e$U`9Ty%Y_YNIf_yO_t9)vQkPiuy>y_WtORgGVTjPvX7kfD=>L9(Bza?4RUFu#P?ea*Awj&ALDI z5WzZ~9fE2dc-0*PSAE~s%__0O-8)+0@EpcbHfQxH;7)1)Y>hj{mIbC4ndRrQPjGnU z8TF^DE%vE_wLBHh;UWWw;X_){jlF|m0HQKv5=|SRUK}dX8BB^qMer1kDQQO7o5{a< zNItr+Gh#!rF;io31B;ufiQZFY@Rc_P&&RL5Updi!BGDMpk08VVlgM3yG*(zsh()kL zj%{5#qdwx7oBmSkss?Zv{&`b7XGRHeM;A&idSRO$*?;|)#_?;K%gc=e_G$k$*B;r*L9wo0tMH+nSIUJDSULU!!B(C&@N-GM+cFt z=u0;SAu-&QU~AZA3#3eH))kqtCcKA{2_z(+6Y^stMcqRD1~z>?@{zG{GpX!6J&q*8 zGw2N@*|y3AWnZ2jM+XhJe)PL3D20})c&PUN${hvjV)2(J*tj|Ec}ACo1&;=nRc{~? zGMTm#R;XYTDPI&OcgkDO75W+}DPxN^Yr#;V3{X%dK-Ds^9uOQ9ZT)-R$Lm1=Q6^Hk z@9k&f9ZoAwJ_m+|3JAfcX6`YksT=*w25+5Q69fjcoHF>>BRH5lCfXO=V%Nh#Ij-#9 zH9l^jYE%G=Zoe3K^hLOfAMOuhbtEy<9S2Tp`jK$f z`#Z!CDWb>AdV}pe406TJzrPhn;$}gR0ch_MrxF6MmB_f~&C>T!Mh5%QS$EK{_-R{b zhlw$0R?%$`AvYIxbT4X1!K~{1OA(GoZDS)7Z%K~tO-QV$&xk&NcAYdVX6(#dS=(q+XneowXa)c0p!B z_fH8LQ-oB6NDsDYtj6C3!2pJl$j@{@zU(jWCWx0E6S}$1POBWmyZ2bQm!PpA_1tHc z{aE{3mX>PQeBug+g-F+uzD{=e{y;A+jWy64e; zfnjgvpbJO1TiQ&UU-x<o$X5?5<2-CdlD&B#5TQkskb8Fa0{}=6 z!uJFRwplI{6(v;-i?HKA%YX-?1LK|0&{!08aQpkLdl@W-?6~9bugy{BM^!*ocAo)@lUN*cS<~kZnH1CCn;CPw^;)d6i?1?jp`5KN1YJUKJ>PiNmEcXB!ubfY`~sRv&+f zrLH7&!ckr7HxJ*}VRE$2JxrJHwpL}Da!MrW_WVJ*6Rk52tP()HIN+1pV?H$p zfxh@QNZ2r;I(a%^ZqMxA12oYbmTkEP55m~XWat6M-JH|Bmb}Ek_lnDG={xx&_u`;` zy?3CL7dyRlJoy~Ck|{6JE6165nNEz9GlbSW>6SH#hC4qms6RSwqS6P?kE@~3cN%NX zH7wwauLxVH>%8&if-rgHlP(K_$K|#HKFjZ9e5)hnUZfqZMJLeX&1t{Ddg>=N0SP^l zg1Ods!sQ&Wgli8w6NiamXj!c~K}Vmxk8 z0Ci~}%5DN-%%5YFcxe5Xi^qw^yJ|$c6>$VPjAudVJ=|L^UyZ!)!}50NyzJ@U0E>%!t(0U7@N>VZKG}XhJs}@uM z-lanPB?9{k^lC_+#)ua9o1niOCL1XVr}L!R#+wo=*`6XKTc6zZDQnhB@Y%O-5K|M8FP<2Cnl-f1xrk3|z8%!&-7lAyLOjh$9+; z?lwcrSwOT|1LOtD_u5wfT77eL7{9nd7N-=D_Ixv=MwRxG1DM`}Sl=EMD=4}5fh8E~ z@GC!|rF@Cl+JHxQJa)xu0MaVXsCf0`bmyqOsp38$K5FD zM*oUF;6Zi<;=G)5-%$A`&cuWmZMg#=_ZfDPcSy%FPmofj427PC-`Dw~p!RJHf$UrV zS3|1Bo%iTdXg`rtfwb(WU;!^^6t+bFWurma3_z>_*K-LehGcAyJ|B7S2rN{z`r zCwi)m=Y1R+St|inSnDYJy5}m-!}omAb_o}O1Q{QBy)z5^4b^@5%8gtoot{u)Nn9oh zHg9cY0;zA6j|)sNUc)BB0K%g6j_*p5Xda{379lRHFvX^bzodt@B{#-bcbLt7m>6R zO4OI;@OttxutQUIvVt(G;jhLc#7pSa=@++&WYIL5ifoF=>1%7FyrS3!Q-VT$S^$_E zQm<9r_IhNeiUn-=fZpjH<{k5dxEo4rE;4=4tllxzvPZ5a;3CL`u--TXUxRw8%D;e+ zz7ed|=PHqDfL?Vl72OrHeRl=|Qw5yt?y-RPg2+&;q=1E*FqjfkVA5H_$`d$igLts7hHF*{N0g7b~o)Cs} z(0S&9{N*ud5&GHq_*9o4~&YQ}76$@?g&iU_~j?;&23XOL_HHO+ z6jhBaJK^14-cJBec4f>biICr>=Y2K8C@rtU8@deY9CN}KdVLto8oB`p9jh~!&vWL2 zqjsPeOd~afyF#Oou?`1f`dd7|P&w)_ICbd*?nzfpSU4fxCLC>DdDlQ*UCrvBv-$gX zFa_9SqatpAAVe9@#rpSC=1k|i6t`aZ4$L7NCT&?Q)Lo(E5!>7Cr7VJs^FXxQlOm;aAimUnxy2hI~R5db}gD% z#^?uH4%b{>sB5mb7s(?)_Z%Q1F4;X;f56rHNFd7+yMZXN69WQ^$Ut~Q%%mD^*L)%F zDu*+C4%zaO)?{*zLnyb5)fIAm--%nMmD)-V#0=n1aeFE3!b+xFi)U&$g5F!zJ8m zVC(H+c|*`jy(2ouuk@VWQ*^oA_1Pj5gT8L%uR_QMdF;|;qJ zaKFMu#zc5ZXC6N`U~W7`6a3rVzKMC^Q#U=)T#ZJs1gu;mZyW{H`f-5334!9k`+{Ym zz5k0?)+9x4{G78Ow-JJ5mjGQk0HJf-W`=D@(eqY%1r+n4P>&>|L-9(ISXEPJf5NxLlkbN| z55;L8J~ekgmomX?-bX`WO}FZ3o2Vt1KPI+M!~RhQzwd*(4_>arGLn?1F50|15RnS* zGXc=17<cC{63!+^%P`GEc1Ytu21o>dW$f-T3(!gQ6m?226Cl&cIqwzDeK1Dz6?Ru+6 z2dshPo$hjT{Yg(WX(*MSe7x4$8dnS(u63%ko(q|Z?uNv3WHG{zoan$YsA)S0Aeai} z_^x2C%-g$c(klat;au628~tpW+Kh(3i-6UxR)j{gdT|u@*d-%SnI7bg`=}8#SwZKg zEk+UpRE&g@Z_m>6;o(#1N^%(4IU zN96r`|FQJgdti>P@)|xu#Snyhd0GkJ;5Cfhdsx8JeXfubeT=e9&bV|p$zpJp1}lRv z5t{E6)YssTl20D;sUb-@Ar6Fpke)}|GU;DAiq*6rCUHt5(@S1l|5s-&{120nH_ZD3 zkT?89VzlgV;)(H?0ZK+r>Fi;=XxvO$r^87mb|Sj2C9m;bLKR&0vnNAP%{VOzzqnVW|JRmgA=Q=3=A|%PJu4q zLF)}H5;nhH1F6n}NuwO(9m@OT!V@ zRTJ1#80_Bts7oDES&T!((Sn`~JaxcL3dY2fZu z>Z?l>B1f1D>nbUZxoh43Y#8*y? z2fV7TwXF~)1Zr3?=nJ4#N&y=eTHuVhE!NjNMgr*NTPBOAz^=7M$-_$;_9VRtaGx&} zlo4OF!kdtllWB3X6!6^ zOv+{_M);sa&UlVynusA9c1zlqdVp57?1EKOp*OHhEv8XD<@k3}xn=hM&>U$v#`$F* zBxYxFV)c>G;Nx=Gh~qAL*Njtf>NfiSKwBfj7zsAMLv2)RBk9pDV!Xl7QgjlU9|p<{ zJ3SX?N-BbDXNzGm)N8yEx3;a#-=%ZE>09H&Y+=9k++(q$w^P{G$ydK7TSeD0mExi* za>tfXE?lj+I5I}ovT_+1#BcDnnWo)W(^PYI#HlB(EiWd)U!*H2;l9q#zc!m+u+?dJ z79S^-OyQx8`meFnOsJ!gF7OrhW}fT2+Z_4$zFHMRxf)iWZOW@X_xKxR8;M^iyi;^Y zbxeGpsG=s2C`4JRn}^k{jZdzBOob3QcAbqp3c%}=x6VwrU2ns(^Z3D&Sifh2KFv(M zcs6SfclFL?zvvRY4~g2?N=aGbq0-MU<>7M?KNV$!H&sh~XZ0CZYd%P8Eo*2S_C6UR zoq$Eto6IqAvj~4=W0&#}6$7>FmgIVwmK=$VhGs~1v^+=T8tH~)k=>jYzu}tVOh5sj z4Psx(HKT!dXty^&?AY>C;E}w7I5x7_Wl{`w5qcP!L0n6O9+nZMe*?lM37=6BD?c39 zB>XOD99)w}7*$Hj@nGk6>S z+&a|$fidUGDAXmfGs^1$YFoUheL$POWEE_5LW-qU-v}lw7B(m5YbSb^#F4mwKg^r= zq`88 zkvwe=Q`r;$Z@_I7-aO1trl(JL9ws*$_+&H$Pc9CmLj4G52OG5v&D^LrfwfHXP8ZE*QcIH@`AFnhi`$$ZrWl z6qU?)8;3X>1+6iuf2G=*zR&DsDQ3G~{_=3e0wE*Pni^$#y2MoDHsy8YcjPsqyjFgs z$!72?l9Q>AOj{xV6U{rysV*}Fj}~IR#@o_!Nz3&bS;?Qn&0SdE1pIMnP`M$MF~FGg z-Kpz#!)Q{}Jk^STped8m;-}hierr4u({@fn0-54X+KQ}UI*!q}?MWnP3Uz(}-cjtt z;!o|b?U~WP{p?q02*8xUQjM$Jr=< zV-h>Xz{Ib(^R6@HYIvX^(ozJRbmxk_X{9j5dE#D>P#ns4z>paLD%a(f0I@uzX}Emr z{%dlofi_i)39HF}uILyxPdvP3AbR17#M_jFTJeQSd?@kb1F)*d&U5qTb;3WCoD70w zXH`+(Iq*LuCGv*}Tas@dn~S(jY}rRN4t$RgAPo-p2ZiS7lmUDhv8OtIaDwzS`ATJk zPIvW^7y%-WRR6%kD6Y4Xp)rq{Los4n7R9jXDoR5p(GFvq!tkMf zt>o-#Nxhtw?_7!s%S?LZiIAWrujI`2Wl}3w_=3D8C9Z?2la2P^{YE6!+3kf{#ED^% zRX^q^x%t@dqr^Is5e?X@m-ERsa*cX_;m!usE?c+cR3R75tJ_bot(B2VwBUB^{=7}B zQvg`1k5wCkASj+QD570&yx_VcDq$5bX3DDyVHLVsZiuF0{gsS0f65ehKG!CxKxfF$ z(;JRAN0Jt#=h1hi4DS$|th(~xwlr8Pulwn7b)nUB(A>FnYc5AfV1_QXfTMJtSciHf zNQjPdLrP-=_Xv&K^1T`5dJ(Wo^Ede$ZyuD+2k;;{$Pm*`vRm5)j@zOT7Y+xR`S>nU zAyb%uEBu{T$2SA{W(s#(lRU(Np1RROa6QAE8>aDFoki^SD!2$mZ5=J#8PSFEt9Ba2 zn_nmsllygN>G#dWH?MFJ*i6wQSg*K6(;2+M<@z`DiwpI>z&)s*s&5zymi~cjAp1=` zJ}`Va|L0>Vnvu|pd;c3&%^%B{-aNF`WV|~{w|mmcvtYn&xb5p^b_%T%%U*ZTC4YY& z@s6UigAV<@OODF8aai^lm-{2?3&Xq7fLCLa+zNj4vYxrsuGB453*eD*92aj1R;HW- z%WE2%&V~J+Rw(2~xlvuh_DW)>uA&iVi?Mr1dxrqek0bR!kdHf~;Y9-N>c`suua~a< z*fZAgGkyWtN>|+#8l&27AuO|JWM>=camaQBXJ^)czaqLlGC$gmx6~JsgLGKCz#Ed$ zAt7k4Bc0sZ&hD(mMjJ@$)Rs8IK@5oanN2lNmiP(8(GQ}@UJ=Vxp7lb{zixl*$UrTP#ZC)NdDmIy0 z##s^%ZYXGbiDVU(xhpU7dBiGC!w)1F3pjhzW?h*8n7eF9q=>cAHyNLZcqvU?I z^H{zEh0U=gVK#v>0`A~%%Rw?D_XdBkbcfSQFB>2i_Ox`$ZwT_bJ&9+(^i1-DjO@Ms ziK+?20r5BoTZVH+ z0~wi)S^V-q4({2Vq&<^bexbx=^GxZ<a6Mh(M?P7DR zoImV;u-bi;;HSvTL{pzjvdfjsPzc>Mk$T0Nt5|A+IiQekGGU=xM_?~PZ@t6lJeW(f zvk;(kk9Fy~=d_gA4gX6CH+NLk`G~y?^?q16r3;{VDCe(uy@n7%dB6PjYVN{1cld|Y zTa?;O;QLlDVpGX#c}==zGr|^?H(X{7;+8&2XYh;F4oa%WUD!ni|Cqi7HFX;JrKMR? z!(?9*PMm9n=#yN7pHOE%#;5HJ@BjB7K)W4lUo`6WF;r(q%&S3Y1L>u4WP|Zn<<3{y zXs=qS)7m8RboLs7lfGw|dWw9T3sv3hJfoVlbGmz9t7S=Bu2Utmo+zY>hBm$3JznTT zfcAm?-I$JrNINqCH7{F7CbX|q9M+%?n(0g7~DA| zv0N93`QcYRN-v(obF^1&MjN*jR$^D8AY>BlaO3s-acC z0mTj0w}`TdEOUO}GPA}7PyD`i<;Ja`MD2AJLn)wzOJv-FHQ|gqMDZ`%k<1Ok^pYzq zhIF*CpN!yX=cAWA*2Y+bhC$F76`3QFFx*8|$f(khaP`6}&N|mRxO&oz{l*1{x-sOF z7t)_rV#DpU8B<qmDu< z2|mCbpHE*z(k0R~_%DjL!`e;Pr2PK zg=He5Gotb4Y5r^}wxIcu)w#rXunWuBGNn;RE8eGTyAbf(uEId6N3Vvi67hH(ax++w zhD13{0$OVANPG|Bd_irz;;ec!m+glvUml+0M?0e!M+%lQLbS~2tEh%rggtZwn$nl~ z5(9g8pe^vZ-yAiBp-VEtB$bMM&m^m4o2chv#R^6gZVXv#>E0KgNXK-zf7wmW_NHCh z3@axTTWNcGr%n|?F$1o?usy*_J59Mvl`m&SZF+<7eB)NDO{?Bo;d1inX$BYtGJ&T10eHqCJxYiNl$-Y))HjtpZJn;G|6kI z52Btr<5OLxey#ji|$EJS9K)Z0d(ST}P|U%@@Vs=dtPyq$?iTQUlCxU{meEDNFZ=}TM6 ztCRr??`Xmj7qTFHaXpK3RG8_MN~v{fQO5fL9j>v9D59B>#f5A%1&3g1z-l5~y`llQ2#7I`pcaf!2G;+3Ulf3thrR zX3{@I=VdO?M<9iEykmDQC;YMJJrc;LFIc83%uw`sO)nleE`#>2%fXE1cN?__$ad&V z7_Kao4StGcUmrptGB_IW9RteOcy}NPjVxTweFX;=9~JSP$f@jy`&yUbKFneob6Gt+ z00j;wfGx1_KmRK)BjBrirLJG)gI#BokEO63@+!9EcR9(|Vm((YUJ_g+U9#sR%m902 z2jD^{qrg3A__mVuC;})L#Cz6=7&KKV*A9IRKc%MC27A!ehux3i%F}-QNEg@QJ@36* z(TOo~0Zurv$Iy%;m6PYuaR$d7($FX^WXw=3@x?EQI7XaL|KF9G6~;N!ekZ2ebd9b5 zMr-(l_2sk0uD5B7S}#!>7aw>rYUDw@;v}3O_fmyB&V)JUhmI+y)p+Xf!A-v0O)Z)( z_5@5FZc#J>H@MMLt`Q^e#fN}eSDLV=IKe+ehtMlSEFDhdCm>RDT;c3A^ABhhXk{jy zQ{QIx>jyZ_pg+H&i*yZ+>)OAbjV^hmK$fN2rnUc_SnntGJd6T#&wepksLd#D&4?ED zhnpfRZDss|u)4Y==Z9sOHCNrf(Dhy(dYXOi-=iqessyT>SEq$=Xqu59%hSqo_0kPq zgbY>`#e+GGiR|Ke!|}&T$A@~T0a#9|t**ua!8Pn7qt;}!`Ni1*EUK@~c>7ab<(F$6 z6s<%GlNhsx2h|^$C`l=9V!SO_*<`TFb0s(mbth?^e#| zqXE>Q@TU-bFN7^_V$&jhFa;Qs++!s7#OeGWz51~iGU zm}Ip8J)ESPA`) z%uz;mW?#)8_P(!KH)cIt&jmg3!R^T8^5lJOnHB-+$J)Py1eE5W?(Zyag>4O)S1bog zNDrh{Jcfznrrll}X#UjstS4q&g#eQB)v)2ZJj{po2p!Szu;v1@JjGfT!NAwDewl^9A^iN0dVGpT9 zAUHc>E8aK9db6di)(4!3Ycb&J<4eMjF+n2m2))F5E?p<01PsoLZh?H1bMN{ zpSsMGQO=26p5_l|_y@<&vB9kiWdhM?c07~)NK%>Cf`XQBScK*3@GItitt09V-Ai3= zE5tP}J>}fR?3V?S#*(HNmCbghXk+v>4?e5qWN(b75e-ZbZ5FV;5C7`xTZnt>h1W1+ z%1$+q0%B0`BDLHL;@)L$p4@)FxzSiNJbX{Yas0J(wCS`w9;;jTab;0Pa{(D1 zXsZ|P%ieDNetWBdYq0mGulwkCS&4L5DB*4?D25Ff(dzax(ye1N#lGh%`DC*{`F5(`S49umSZI z2umEimDZu9T$ajzKFLRqi>By8o={v|ZIjOVrkS`FKVqQgt6TY%!&Clw#G$oJl;TzQ z^u!fK7gF_cc;FBaS72%{#*Ji2vN2uOrTe8b0f0Z$=fcBdUwla!Ho|+t=DH&qX#Siq zbo808z4VR>3`hp6;MeVBgGO;2P&{orv@U6Eth6fuJm1E zw;rCx2U@JmBv#gRf2f_wf!WT8fU8MS`)FoluYGb7tq5pfPfRj@viJ9yAUK15dRk{B z4snlz0B~e2B z$uzocko5UWom$O@xO|#q{3)ABae}CzynKd->~xk(G*}sO9I>CaOP{kfglSzGwO~^3 z#1OAEH3adnGuZe}OV%+!{sSeCD_Ke1#JnUNBv3slkScQ|`-D?aOECgeCnh}uV)lrM zA=Ufx&R0L~EW3Zr1z5y}OBRaC$v_oejBp-VNuX)ig( zWdj9${OlLyg<9xhwZ4^gE;y~<^=MqJEV!LP)Q?Yr-a9&n;>2uWLekERaHJoMpb2M6 z;jWmc@u0qnZgr_`W)LjE+8KmD!96s9$H9%@te+E3>uDY@q9yiCzLlNF+U063AmEV;s1sV&9fK zkyz3uzx4HZ~VHPn^bskNIx&C zPCf*KT6%xPzjG3MAH}a6RiGsFkaP}&8)>z_KJT=Ru{h41=QnpuPRokbaUKdb;!F|` zobj*pfX&CC5Eb)jj^i|F4;m6i4s4IOo*z_KhWXZc(NDK0sG6Mj+WCK~j}P|?kgo)% zc5Cf9HpIHLUnWIFmFoX3%@qhcLzmk*LJz92aMf;uIgGpb^FM)?*4E}Z!j=apG018v zFWejB+7s0tc&~c1YhogIdAwdVGK6c;z6hPe5O)yv?hakH^5q>Ie(2DQ-X8C*95ojE zzRo*u2cF(hui^7{G>|hP znPhKVZV~WzzRcH*Zr z^b6$O642;oBD64w{$dM-b$2CdFv2k1BFg|g0yh}&^yAHp!DE#4iE@!X^6A3lAui8J zcpTD?BB(f(vh223bkLDhSFNzc0$k)>`J$`UpkrjQSPZ8gK~0MLk3A?@0a6M(u>674 z&yB1z(VOt-dHf!Ymv|44xc=mxf{Z_WNLPpzxmt%xoRl!7W!DXVp$Ee^SpT!Btj-9v zL!m%bg-I#}3*}uj5stgC3Vi6@T8*8{7eUVCnp%l_RsJxMod*ty zmwfc;?_%e#-gUh9s_U^YJjKeb!U@#m)MQx*yJ}uT($e`S}TMCUdTgDXnx{>`ZAYb z_z6S7HR>S{x`u4}Dvg6_WE4gd)wj6rR3z7|j0P-kw%u!yO5u@)n|H0%c2$;>O2HPT zBlx|qegJ4m^nq>`BE`pTm3+m7_I;#Bin`(z^O3Ao zZh?1($0Yf%JCQ^44xlin%KyGQww-hsvnAD7G4s(%x8ol;DP1O)JLl|4^r8nJ*JMPV z<8NN6in2hyx8;2`L}qfjSz6c!I7RAQ?x-gXUZF$0(Mv>?4x25~gzuP60n>X*ap?P3%4Ychj49PW(p zuv+Iai`lJ!C*Jz+H}pP06Na6XWJvDnMhh6zC;pAmknIK66ZnzC>_-s+Lq?_cc6MG^5-_` zadG30_PO-FmNz@wfV+83(cWz&{R^cdGl_g6-1#vA566(!L$D{Q z(vJ6{5KT83w~%DlpwBduw;S3bZ#>u_JA^(m?HVtR7gWwJU+H5t!P2HY_RJ3~_J*-0 z5acjbcPTuHi4m-_7|x9|S5={w0}Y0>9NCOxezEf2v@1F78P`*TCiuB|YJMwpR6ds$ z>Lb1Miq9R?i4sGYIg`)DH7V7(v%_EA&W6zaLrx!uhxDZ;(6}eZZv^Q@e)QYODR1GV z3&{8MKjYYVSUum{7K*nOWSCtVcd5=7Mfo?v&zkG=r}RHLZ%b3GR`8HFf30Qrr7W`b z-*GSxzn;Il`|}aEvZJmYzqz8lLiUgUa?*+#+>(pCxh^&5=Q@8wCp&32;Y`d+H?|Id z!P`Yw-n%yF2iL9}<6#P8`!cflregs5Kh`z6zKf~tF6FR886s^9+F+GkP6IJ$EvZ<_ z|9yA*couC9oi9S`HIaxg*oB;gS_zYFG0-bu;0BjF;EMNuye(U(s=cfuHs)-tj^D7c zJG7N+!}9pgG<5cr8bYe@*+#6gJAzrEgytJbXf|CQTLA3>mZZ*m>QT}^J_7S?T`5h? zwK)!frjC%dDwj_PiCB63_H!E7UfH<}xH?@&l70j)Ylf~f!r-Wa33W*>3UU!-T=@rY z;yT+@v0uy{I4HeU2I(-`#|QhBhCkj_z0p@jtmuz+q!RKHN~A8Lh-hx%OYF?}Vz4RT zzbaO!e`FIyL=l$*;8iK zt-Pk}R=jd7aD8}%3LN!F@hyg$ zrQ_&m3=K?(%(NOZ05{##8virJIey@avX(s8;Z*C@<~)6~?=v=DeLe2262cn>$6Cs2 z$ho%mgRCm6o$57mQvXBf47x%7#{rkg-%w*xe`-N74;c=w63R9Z={{zCc z92lZ2kY9A%+b)_cTTjX9#kL$K80&L1LuUnG!tUb!l=1_3-IpZX7y)~@m_N@pX|AryR=x6_h4PD39>S6LP<1;ZRViq953< zMTb>W=yqx^o3Dm&M-aqG0?IK90EPu1+t2NE+UT@^7qk;kv2Yl^%GveKO|@u@D$i;e^>`9$HF8zW4X4_cEQFlW2sxkTnr}hay&awKi|%)KtHw*j^ovV z<(P{5$+Y#hyC`=Io$`Q>iV0@YW|^oX2cwG)8b(e>jg;6loSui#HA^uUEVM5?Hy&pm zXwP);PaF)JE__u8CdZGeMUQeKxHx6hkL#-!>(uJfgUj%gORg6y`s(}z4B2i+ZiKs+ zusuB)IC*=Cqk8wpz;l8y)(4tu`(-?#Jrdw{()UEFbUX<@PkuW5De|+o=_25D4ykb5 z8)`1@DrJ+y|EmlZ#fWd9pC8i6b`R4e&JP~pqy#Uo0aXVpFOEeDaM6>fq8$l>vYDFv zl5|u+rhWpmP=g0YZosksBjHSPx$Tc}+IBDnMGr9nuu@A4HfFhcpAK>%PcmQ-SR7EqHMiueR+2qmzt3Q%QZ z&=0xjxk+{H7B#iGjX06!f1W#ifzs9rm_AM5v0g|bB$$wJN8!XPuV21DxoyZ&=wD%p z##{%9dBBja*XFxza%1ADY6?H9G6%gzkab5$4H*3GX|IjLTp%{ynBCmRzN=V_=NZHy zG8H@dUwdoQX^|_JErh-wqQP!LHu*z9)Z-{Hg&nA1aPj7l*MxTQes2s3-lEwxSYEbr zC2OdX)lyZz_RPzn1qSc4NrjUhh|0hM^KlVqnpLz)sqp)eA#{1{eU!tGWE#1UaiypN?{+b%guB2|5jf&!V?dn+uWBTMN z6FeIwqiE4m0d)eNq6;sBYKT?Az?%waq5OWnpqYeEBEx(f!#RIyBv-OXFssbRf4Lb0 zyV+g!-Do*D;8O-C6zpFt2q!jlZJpS|I5XSXxDOcpi6yndfy3>FO@U^%oB&2Opcgs2 zhQ>cFDYsQ~WQJ>~6#V0=?V^)k+JXnsR-1_ziZwEU7^g*1;;Cev1_De5><%`$)}PIG zCb7YCfY7Ird%5$^2~2FAvxmjgR`%TLvc}cA+)d1ZGwd1Vv4^`u5e^933JmtT7rCrh zf-04S{X%K@ObWJpwZgY}MnOT<#&>=F0YPXXanK=0D@Fv+SOaL$&y1^a%{OcHt96xM zq`u`)HIoB9E;qTsL6RTXc5@!=h78WNQ{>!j3!6`!PiX?v7Omt9h~FX)9qieePh67m zUy8%B?EsaU=3x!kJCMi*G zbp#X%WVuy^E_TF0)FXfgd3{@q8GP3HIAf(f7{tl9UDMbyU>)p6+6njOm}!82>j;Ii z{h>Xz@XWuAOp6&7)YUMb$vDP#sYKedSh{jO*F;g0E^6Jhkf#!&3>G|xO!R9VCGU8d^g4X6pNC)S3qrs?u#ffA8ZC(lF(FH z49tf@#eS$vd5tQFneHpHBJXOe*!#$k+2HS048s*H3qLRNJxO2eAPk*Q`UoZy6$lzq z|Kl48x%zPAJ7^mPKdTh}kPh{a(I1CFM~+|d8jqJFVI)5Imb@?T-jhsVOwS^V%mziV zXe(2DitKh7Am@*Yxf^$GHQ$G!S{e>N_ zqgh{nfdfDzf)Jwk{Y7$!UVSHpq7&o$8Hm*X?KIC&I`i~SeE}7bTl)cDH~1|5?-@DC zo87f3X+Ji&s8Rl90!RizqkTYL!F8qD7UMYN9PK7#g{eWHkw9o#qR1{c#Py3~y9n?; zkmW-GMeo81xD59Rle2hxWGKE@-6s5C>-v?a+|6D?vUGgck#@I>sEcCPG)`GMS4*Lr>&w-Hb4#j?WluEPZC_ zP+W6L&R#yHcLSI6cwpdY)SfByrZ|u*MN0<)LmU!cW6ciGK%4PQ%xrZa#j9k+^F)GW zWL`kL)en@b3!4VDvM0)AA5&T}GD!ULs1z1wK;f9OrB z&QYiZmX!|dBHS%->HI%KTX&wz4ee@;W}Ndrefa=}TG*EJR%*rT8KAQbP^Cl#^`(E< zc;iTbBWq#>JxNa|(b`J)^AlTKMbPqGuPC0Ek=G3pzN@cQ!8{nn%n8Cej1Ph!Mmfqe zl2Brro$JzT0N^2KC-am^=1j7%$#kfyT;d{sUxu3b}T)#5k`B5!j`HNDGf@U^B= zEn>9wQm`Y$y-~?Z0#XKROKJeit+A>tre`VZMvO*TDU`WvJ;@dF* zcXriId(8FFN3|72?E{QOft=FC(j~CRWy=>Q_P~jo4E#Rsw?N;xiOXe9qeUGUnaz3J z0Ib1L3Dh5+MNTKJ2>A6d@Qo8+av+EkMew{R9lyhThb`S+cP9B>`x><>B zyHzOJ+-(OC_PBtPL7ct?Aoc!f3v6I!XHkR;J*0N=Xsa9)3aqA7$QHx(N3gZR4L_YW zhbKbQ&d*wx^+k-y_0<#)m@OR1YW)|=J?!uvYjkfK5uecX13veRY(wnE&LExB3+6b3 zg%&S(J^-Jiz}1N$qGY{9gWVCt@WE8~=37t=%Y8lHx9Y_KW9QN`Hl=+)V|Fm^LcSJ( zq=+Twr+S@j++P@P8!FTuHqmUDIFY|NT2;s=9mQJq#6;&+iFX2K4(3ODwSFzZ35eh- z1(gPy=l-eA)&8uw;j(2}Uk!XfPAto7yC}Tuxz-dbJNS5>#SU2$U0V*k%r@<0tN*X| z@V&qT1tto;Og}eGG8Ux;iEcuv|5%rEQ?U`ns%m01oq-G!rT{i4Pu?`}aX>($4~hh2ZPKA^9P|K_qw zWub_40wB==5^8-u+sO%qVR(6hJZRIrRV_`@pEtH{m5^2|{G2Q+-sO%rMfFZt;(>4! zne)(SK(EfCtm$txWppD$U3luEn}-FnuY~N4oOiUYSc|+y-7Jj&u#0=X18X zIrU}&&)cZ0qUq{-M1oa?F4*O2=1QfgACm=>#XfzPhYcRDSUcMFPe|4Cjw5uS2k#tU ztCu!*>7_wf)mpE=YKOXiT*9Jp!KmI=fC7n4%KfWp+BWOg**Jh)>^6(PM9cZ(g^_as zhrjv-abZ%LR|_e>2kaAc{oB+M8@UWp09AK)?jnzD;iS ziZWRlSnj`GXs}A1*LpTi(66;;Vep%FjxIx|3`WQciN)1z3ljj_`Q`hLo{W*LPY?0s z{zuz?xoF%OkTqTQefwn51?FFVgBteYd_^&m-YlD;O- zA}_`;JBX6;t?hd@68-wWCx3aLmOg_6wqlxX{iqP`!6`79bNX=aq(Zs-jkYt;r@Wz5 zuM@~QEY*DV9r>vbmv31CAivgetrp(0YNlsQ!zE{wR6lL3v*Yu;yW3^Dl4R%;@6y_b zjqGT&r)}J}R)PJP7ok|!_Lf8I#(S0-{WmV*jP8wlGV4_}r8oSt1eC%ZE<))YrZno(h;J?-N27vm%ekKgtr8ivxe%I9S&Q++* zV&t=He<3_#Sb^nX6G87I^XU6Xss@q*+10W^fAb}C?fTF)fF!FCsgdVR?-LU-KR2f) ztw$b;Gz`4b{D4U4)niz+r4hLI<}#|zfJ1W4*(eW&(%T8kd44&I-Wy21<1b|n11G$r zoD(m3t;Jvp{bM;!T9DDcagN0k-XLKH}QV80+bPnE`V{4G?Mr@-Lo9^21Kz zd}W$W*JRo3&)KY%T>pb6P!I+>K0~-29MhZx~w^m+Y*x|D?Y5qf}MJt?lk}& zMc-CyNHn4Ls>&ZqLT9tv%iPg$2|>riuRYG>Fs0Y{^@{i}mOk}Z>rtP7YboOG0zl!2 z2&0s2n4H(9F}k>{O3pgCv;jP{#wW-c(ToDiZv`r*yZ#ko=$saAvh_gl9z7H8dnlrZ zqlFk<&CbOAe?p9@nLgwFdceTWUjy9Jh?nDd2V6Pa=vnd8ZG(cXr7FvCd&M=H0mo`Bs%k zz8Nc>syKDM%=57@uHDhyP6xhP5_qC0e8LA;zide1nb|cjfNz1erk4ES(X+5dUUOKz znqg%Wq}j(0CvufjcY>$Fjru+=8|7t=G2tfe6pBn}&=+7-6t08qUJsb3Q4i*+%jpCp z8xhShXS!vfA+t3Zbx?7hD}FK*vMmfrfy~;_t}q@7P;dxt{ug@iw0#K;qGwNyo%`>i@9&*uu(TYKgZAtRSO3P(cVs5tPtfLSV44uMQ~erPn)GC zb-zB@!pei8op(gz>KsHkO_TkIjjat^muL8xA1*Tys#5;y?OEga?vDox$4dH#nHHlg z%mzBB|1k*tLOi@2~9vCnh?+egK##<+@VThBnIrhi)6RxmA%Y7e_X*fcb@@K*uOK2%?{sI z#6e;7(dtx}TQNwHeJJ)F1VVRe!As>;n6_uhNMS}t)l|t0|M(0LP7{xk9ek?rH$-2J zTa5`?S;SPQlvt-Z5S3bRHv!-)dN|3u&H>~A`HB%!$*vY|>kHchuq zANQc`T!2L+Pv~z&p72OHS|?2aroK@Yu^?=FY+s@bMc4(pzk1)F#o4nwrO9PF!M=RT zv{IiH&*!w->Q0Rf`w+h`n}X)lG`au=6Z9y;kwzpGHpoov07RKG@`;F02;mi}XkJxT zxf~t&dvoi-VYT0Pn}!RpmUHK3-46+!n?ztrW(JIutAa{+-=(#{b#qL-alZ})1}^@1 zj@!C+@lpq^QTnnC2}%3p^ZKf*dsLI3dZyRXfW5OhIQ2>ZbeH0oCS8T}lslUA-Yt17 zS7R3pWXT&Crr}wZD`L-^Y9qysuX~nt@8b1zTFJ~C5!SP`qI#J@=W`~pWj|j3fD0Gd z!z<~>xC}Ovr=xHrX*w;HwQ4JtVBEcek7s7{4zNn@45X7zT|EqJ`ovH9!09P*Yf9wy zYK<6$*+7-zHUh)yl=xsD-%|8d7%4Ag}b!ZCF0^9thg#F z==&fq7{u;-sXv= z?O8ZcIw4)=?>=I9=M+GYcp40oZf$2jlh>AB{*r95+TKah%Qg)|*gJYZj<*y4DJL83 ztok~GDSQJ;)Hmzf|0Y+KVYH?zg&RPK@`u!;GPYWCs2UcPt?r;o)aS2N5z$S{7MXgT zpDrYo@(RJ~kzrV>tX-)_n`GeK@)B(tE;*nJ`})O`NaQhIBk4=UrfjpMEZ$-^i@ZSb z%vn|g3e5u|jJ%WKh8^-Jj((&>QVpCXUWN5nGlI2}8MLuqFoh);#=QgV#>$0|VB0zo zY2&5SdfncGa%MFN|BjVoKkgDV)`VUKEja6F_XAxhmw13Ns+{~psE!x_E;KioNG-_T z`o5Pa2hki`d%DA-hmkXj(9laLvz~~l{dcyJa1=Brt@(!h{OIPT2+`!cQ-e}MYaa`{ zCZ7t7+o0tKNcBv#)_ufHKl?jlZ+@nTNVD1@+sPp%IMKAemgqwbAUT>li8qwx(e<7c*OEhVrS=u>1;=-N|_Z z;JH3WDM+T=m_pNDs7bfYDT3Iil}I$l>K5Q|6*xkBb0oUzmvQK;spN-xry0K_(iLD&t|8(Se-7YHvD9h9s#e$s2`!|JPFPhPcX!8b)Tx zCH^?x22xq+sm&?dfVM$x!;}&d!Vy+P9P{J?wW5JTo+SG;QFE1J8cR>~ zQB&tyt1<~OVXM@b!|>jZl2oN6?bUVqft*nxur(Wz2aE@f%}gkJI16-}>35?943DW# zX>Mk*TPqlh_{C5p=kpi6*>>2(=Yh0M-BN04gFqTLDSOaA)F$$ zEXGk|0B>^@MG)W?7tY=(n*>DL9HjF(@c0Xn3Fy%7Pd3S0sZEe++P-hFCobQAB7@=4 z+kcW77-lm&P9yFyZW`5#lAY;dEy$mr+)?@PW4d=tQHrm&5-U;(J{hgL1L*(i^#axL zBtZPuIo+KG-6~dLyuoMP`;>!3F-_p)$;lXyKHq&GJL~CT$)VgdR!#PcOf*$cqR}iF z3oCOOc7j&13_pBk#c0kd!KO86FT0Vmc=)D&thwiDH~1N1_1rj@wm5uXR`BU}#~cK8 zvUhTKuhQ_c+}=9|3Bg#K|1&kg6uBi~Fk{IA?opa|cSx;N;APdVwqq%Xqijb;suTAE`@sNIbRCWE978O_QY`a^I|+IXa~;?Z64EKp?x@YaRGbGEIQv-ZU5jZBb< zE&Vy@)%>0I+|#(U`GeJ+af3F%8#(mJ=*gTboJ~JwQ*|(Wppo8~T;m)5-;C#!oiVeL#Zk`i7zLto{) z38*AQ$wV?nD8_MQ7+E#7`eqR-yb?*?GF4xP5%vFb}xD7zA zvf7ytRA0xQ(>Ri`#npv(>P?ckGNpwo<EEW*%Uvl8s_2f?zlcDsId0QV2KXx0kel zu%TqtbJV-!2pWH+^#y~~{K?!%Q~Ld{WO4I96sqGQmir&H+o*hELJwC$*n7sy_mDb} zc{|5Pc^N;Xc>aFtuVIJj?hu5UTnKtB#XIe{wq%`7rGa^9qL12m<}Y_FAIaz3%Q!*@ zLbf+J({udD-h`vRi7DPYK4Uj*yK1IV-{I=RZMn=6`vpcva}Ek@eNj25K2X>G>Jj><@MSfHV|;dF2Td1`_8wF zoNca46_A9_&D`bq<7J~vMWi;-{R1_R_g<*j?&iLcm0~z?4=aMsJwbIEgqi+;HCwfL z)Ejh4J$94k$n{FJspHs0)2rpp5l;=y;?I^ID0@1vRFQ zx5@TT`bl z2&&w57+I=cud3E>%$W3ZBYdj!tKF4E3%Vyn3FYi#wEsyB*47j7lm!K zR9>PM*!nt%Slx191DqZD6xv5RY_#K)Tk*3P)nUSxyO zwTLVVW&Cvr?oE|Ri5H

    -GP5+@6-M#Pa&eIn^4Q{gHx14To9H=;Pv*_K6s1n3xH{ z2w`NIzwd`f86H2Cv$HDI@5j1TK7|1p@WD(7@%L?C^pj{&-@|te&9_YZ9w=VJZh{ zbx6);(>qf=e_y6}>Q~8lrkY!8=NGV|s_9ChE<+BiA<#RBhy(d}jz6{f%qrQ5&pJSI zgCsaxVBcJ5tqR(%W$XQSv9mSqpLuXBhEQ&&i^PtHB>lm?Ee0Ne%0jxy*{0s0F8OHA zZ(PjTaZKa%OwN!dW-^hTabz!{E|*@N93ZS@AEm$YGx`^5m`l92e&NvqL0LT8s!qhjJl`K`WHyjMI_i0N~iaFtN?SyX?%@)sP!j^7H{z6`n znOM5HABX6AyD83L7hAQ1DTq+;MZ z!sLw&0Gr~-w3<{eeA6j)+5v}=w>T#LF$`!nj*0bpJc1vc6wRx?1jXHGeCvk!5lk$* zuZ*y&6fX*7L}=->CjBc8z7%a|I`tv*rHd?UpC`32HnT95*0%0f5pP((t^|v~#w0Pj z(W70uoK9Gi=ZNalWj?TNgpl@MBkEEneVjf>nCe1Cv-HZqV8BpHO6tWm4YY~(yo#<# z!Z+!}?TjxUOAvS0{~N4mthr9?c5-{^O$I)VXs<&pVO8PM?UO6~VyY_`b^r^2bPSg< zjq}3*J$?^`ndovf82hl=DkaG)^+z-RR(lu@QVD_yNi)^pm1@!v9buW{mBKq}-3cC*odyV2)w;^XSrg2uItW^CCW+kq1CNJ%Fh zs;Z0aZJ_bC5`gN2p#!}ZQj0}7U8V!mM?#yU0qx_~xb}I@m{{q*C@g?YTm;jA|H?V` za9lU3lr`3C$2RUt4!7D<6Qm9A_aER(~lT z$O{{tnIjMRLoCiww*)^Byj{>XDCY!gPiRZ)cFt4?sXds31 zOFJJvQQG7`drk}}OXxH2!ZW^6M(G*5QMCrhski_sV7xMc>Efpqp#W38LdC0D&Pktk z*X}o&90;Bt_Enf9KnJKjTA#c^!^hDZP|Fd5xTs%YGQvFhl$k*~Grb5|A}iuAD`~?e_Ruh2*Q4B$ zVFzqy^|p9Zi9TtC zbkD3$vSg$D%dVn}0|RC&26FUgc^w|58lHANiQXnQWF)K=^K93*=FDN9D0Mx6E+ z^?&^1{)8ESav$y01qX`nlO>L1l)`oj`^;;e3$$cHQSSU5YOPyqZ9z*ia<$l8Z}bMN zDDZymUul`@4|c%8`X{$fF3T$ud7ND@5u@s&kq)E22npLjXm? z(#&NFxziA8U}$8CJH$06{445zj5-y9c&`!R;wEI_r2|&yTvH_J_qMze4O+@L^MU?uor_&_((MU;F(GmYWmL3Q^WDM{oF{n=;X1 z5oQnBybPCYL^ZxlE+Lig#p}P!+RxzrM#7ktB2f0GOj#mTqA$) z32BjU^Jgbv0M<>#u3~1hf>l8lHNNI!Uq<0wJnA0k{Wb4fbg(bT0<-xQd`|Y0JEh|< zye78%XFd^Alin#o0{%$!1|XlFvAr@oH{mHK?K_nU`AT2`` zq)NxWEZqra1FmU?@JOCadk99Xl0YTRxHj1k*lLp((!hl5@jJLPecjhQXYi5u@NUWe zGO=&6Z&{77*1g13@4|+2Hr=d*He=?WQKzx+od5>`MZo`-v;Ys6t*)+NyNdFHRtsLv z^|kX3G_zop@IPn%R-?U1W*AQ?v2~KKeEL!KpAJ;FOSH4{3|Hg;0000Xm{=eH0m}6Z W*r`pQ*A`7aFb#_W000000a;oGkEpEx diff --git a/data/qtlFineMappingLbfExample.rda b/data/qtlFineMappingLbfExample.rda index b9a921187f89ddc153985fdb69bc449eb226617a..7537bf60c029236eb27ae2d25a8ea1fe5e1d03cb 100644 GIT binary patch literal 78140 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


    iO%Fo!C0TeV&%%BJoaM7490tdPxMn zL~Xl5u2yvF-FvjdvW$-`xg+!BNX0RCHXOFc7~y@Y=FvT-uR=O)1T-D27P-v>SVt}O z?R)Ky9dEt1wqj+#f9Rjk##hBVu>I!Jx_x;$J+3$3?+QFi>d_p|dg9peRsUcJ#?QHO zRy%-SCR<29y88b8ZE+yE!l~KiY`l4;ndXK&qvRp4+{xaEVEHyj4!BNWNa3UR9ApL^ z+A;kPRA=L|SRTrIEKdpVNsGF|Lq1HWH9$0kLX$BX(ysF>%qOtpPNovph{-UJfh_nF zT9mQ{x>?P;fJw~GjNh^0gnrEv)H@g`OW>x7bcLOQUDWzzJ#9_#(cL<^0z3ncJP0Mr z(n{eXdVU?AA}EVp#wothM%xZb z)KLXwP3@f{h2pH%6kNmTTsNhJuEwg4j!Dbi;q@r6@WbVL1;CdoxX ztWStlY^Iw&G0%T#C1V(3qscd+lXQKi;Ezf4LWzClRcNqA)&1~za%cp7c|rxOneHD~ zc>zKu*?&qt+h`)|W;3io9jWcw(TW@i<;(opsk~UT%mgeXkJHCi7YwE7(S{h^rsk_Q zdV-k*Sk$|q7ogzy7C>w3jOf_vi{ zp@ltO`WH!H$xk}WwltSe6(*}tovp|f@^+KmY%TP!TPS<=S6)Vd>-7|TrI|8OD}`!$m`&;$MP1D^D2a08qT zN6ihgTvPsJk6)n{z_`|B4=gFP^oluXz)6!ZlbNEH-e0kLjP=;(K9&;t~aFQHuz_}d_3mCD&PJzOl9WoWPfw< zICn~PNfFl*`3>%s?q|54X!dbB-EWUgI3DB*cnG$9U0QC!?P+^*wnbv#j2UtS{-fB+ zMeek{YNY)e=mwGbYeI$TG+hd%3lKY=I5b%a{%B@9rK< z(zQ3?8OrqNsotTy2WGxd0vwbOVp^*Bu2a*-w!Y^LdYEeKiom6?@MEl*%)Hq z91)r(mS(TFqOM0sbCDLvhyDfQIZ@P8NeTQ?ueFT;7lZNGxs!LiRi}h=ea$%K!Vk$A z*S|$URKVu^w+hp4TYK<>N8;`uqP0fdf7Fr_mOF}IFK|^bzjK`j3h!aHR}_Ddmuq_4 zAUD!#BTmC-NT=Wj6l3O0&Fftz6#&`~g#fXV2Y?aC0UzR|XPpjA^`1+X{}@e;$OdCm zV4zpcD!Z?fGwEjtAhY55|5M;#*mOBH<%sFqFFWd6qagsHgcSJ=w6Sad&E1^797vYA zAmw9hDqH?}4AFNz6J2S_XU9{B^pxQ(Qo^A~Xv-K=Q+>ztIa7vEP#)e&B}pN+piY>j zV!gyM86Mf+Aj(w<8&8y2s~Z@_i>d9`x~VKHPXUxFH{b^7_`%db`D3<80jp#=M7~k! zD#r3kzn4=Um@1^sKGX98Or9~MswpV`4FeIA>#*LTv4M`p6)*V{J31uE-0woN)+jPc zkIOy1T&?b5a_;&K7t~kDwRkch+{RJ}_YhH3=+FAEy|g3w$Jc@jV&}4~Yq>^WfJEgA z8I&4Ky;9#zw&7Th5 z`@p{pufE^w2U~oW*(I7CPWt`e4>q92_QfWzdeI%0DG!dZ^=*qPJb~F~2m;Y$B%HqS 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%0DO3{z?;d0%s06t#c+I~22YSi_M{tahZU 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

    Vb75FUcubiYG}PC(XFr`M!FWI-K;tux4*Gq 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 OFb#_W000000a;p^y34`< literal 79176 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%0D`GhbujgCC*+S&*vroCMUKWR~)&heU^a^Zp;+^ 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

    4jA-qvlM-6xDQ8PS>O(WLnozd}K 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 z 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 z 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%0A-5{#M9pr`ql?U$4LyoA3 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

      JxYzx;PI!;=KlJe^f(YCqqg{LsJt8Mll?W{`$R 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%0A{*q;%4m3f3hM& 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 CO@F-r diff --git a/data/ctwasFinemapExample.rda b/data/ctwasFinemapExample.rda index a9e01ef31c976a863a72c481045eded4e1b9233e..70c1e43149bd4bca12d20da6c91ca3f4a94d1cfa 100644 GIT binary patch literal 248272 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�!n_eLJW=65@yK>n)8UE58!q;`-32 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

      3(C8Mnj3(eZ#7K_RLO5I}n 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

      kP0%&`S1vQk;~D4GZ3b*^(oACCUoNjy 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%0A?bgdA_*2bHb&>Iy{yVRBOE2 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 FSz5p|vbq2O literal 250524 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

      d{kc+OE8X2vM&abUwE{8Lw^?^1*E8*N4Vup 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

      1*l`2s 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 z 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
      fGektMhuJey5ESWrh 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
    1. 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�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�F9V{@`97iIcQIjR@Jgt*qe{_KonZcKJtJyQbMF2dTQAIgKGpnEi zysyZXd5%(oYo$2W2c(edH(2~nu@ zz4R0z_qL%a%*shp!ZpfdO!H$4xhGrv1i#epG<~l&Z@HTZjEc{dZz2Sir6lHN*yB4c z7I3Xq@}&DUnu5i-l=My}TAngJwR}J=WrsQnc8alCGu-TkSa~l#V)?$7(%_6$?;3G3 zFJ6A}9yrC!?3jaZQ*acPyC8qXeYXAEb`4-#AIc!>`rII8SsZ<+3;ghmNaCpZQ^m!< zwmtnO1JFIg|K*8ebQ;A^ot&=%cLs7xn^_Jm0{j9jkYA&I^m>+V^AWO#Nbt^xv@%yd zwqMCKYLLpC+wT#q#ZHhuxLK^%D=#8<1otL$kpy3nk@qR^jRs}uun2#oyi?g!Zpgd# zb2Qqs<<~Xlhn1-K6rPQw$?ifH^F!E3;7~i@q1=@KhF)ae`Zo@fH*zH;)YDvl<}2MT zI|{zV9n5dMGG_@_ztty3aU8(_7h4pQPgPxTiqdaEp4f|>&aWAUc9@+}EY|f#YB(yF zKG?`A=*ph}0g6gUMVo&iW8)5;8zxb)ND+_Y3EN7zlNZHO2>DN9)YQHkK~9>L;5H^q zDx+4%l4DRDT1UgxmHmo!xO*^@%Z=QZf$=?7))o!N?9l%r@SrglpEY>f zjok{h*3;`R&iHsyP-B9*K&rH@pIb^M-vYd`MUH&TaBCkL!*YL;tPop9+MS~B&}fV? zO%SVKG0vnRXz5f}sPMJdpWqV(?x5{%#wJJ><@?PvTj+m4B8zo>!Y#B-MjDCxg;bB8 z%rvbRz{4L?MLb#{;IDjV_W9n4#anAik9caS*L^f{`pvgOaBM@tt5Xlx3tKKR^J;Uf~UG;wp-$F(TjGWB2+gO+ACE z2X}MshEEzK=kpwWH%;%p_hw3!j~Zl}u)KeXZ_0%|v$a;4k%in&bgD~pkX`w5L3B;a zS$C3@<|E@Ne*DnHLOI;y+i((=vLBi11w!!$6W@QH!@}h%7f$)9nXA10Ve_f&5lqs_ zNr*ubFmWTSHO2_%s$@C=8vo#EtQMq(%t`-j*^{fYk3bM^CYg;4H?AGy=%S8aiy{ts zFKVZyu4US~1`7-B^Y)(sBh72nPeQ+SHaKvX1o>~L z<3@ikwV-G)-0gl2Hh^J#@CvRt+D;i*H`1o~xm+&G_nK=xI1tY_1;RmwoU%nR)*>Juv`L`D}1{czJf=gcJ!w1WNs6 z`VsWsZ3O-gZNBO*->8NXs>sX1U+7#9vV4EXe&YW%>KYF7DKDC#CEGjAQH&l+yHC)Q zfNn>`F4Pqudrz3>GPA5&`O2Jknpb=|kJ5l2h?Ga}1{Rx>B4!9r~D1_jM8l^iF z6LjV5sT*@bidB?5l`xfOPLApZke}lPSI`Djbc7|drvfNs`)7?apApVW&0^uH%JqMR zS>~zA(_Gd_UvS`!%wLovvO};Zz0McWk(A>!@9QjLi8U2P*BP!l4#iAmd)?ur%B5th zo60u_L6{afiMhzL;@HI4ki42V%g0Ona{x3Jb75vL*NVd%E`Z7H&l(w2$#Q!Mf7B(X z^?~Ys-xVS?faHlgTDxf+tRr9b?WupRg8F{IRrrWal*E@GK(4rtEOlGHA&PIdh|e-- zmlN&YDMZ=6Mm=X6pw08MK+%H;xJtTbfkxFkeJbFT3|?#q;*|ljpzhZ|%kQBOJnzO@ zL%H#~rR;lNjg>wSZKT`4F+}sF(KC?%zJF3pY?=^lQ}q%Z4hk{COm`O8T$-d>cxfY)jfrpY)jqvsz| zY`5^oQ$i-UDMZ&H=q z4}q>`2;iP%W{eF>Hg?5cS6)S22qM; z3T99AVAp21-))#MIk~hu)Cr2vLT&?rM1ga;!J`Bzp=lmL6mf+uT}^*z@!5aFX{{nB zF07laoAbhYi}qI1Q(hCmhI`YLMzi|C|1uP2T6d0{(?@#xw_tH_p^Ry;$s@NvZ=7?q zy>714dt0YUZnT+AIf!J$jZ^a>Vr){!4;cWFw@G1QQ?IWMo%3kxx7V0yuiw4+f%V?w za5%Natn%|&N3$g$LBW46mOkLe^)eH3kOJE%TOiMru0_9E`aC2$X3B^xW0sJ<6F33N zDMP-^JdN6Ip0{ixc0PWv+AzME)U<^d1UL-&h9N2H*mNMYSNjZtVp$m|peNJ`MA+Id z_bPO`nrsKw6g;^fKU~PEf^j0`5?ASK(<~nIWy*t8FGaa<n!9IHmZ7|BI|n4zp7GDp`LNh;*L`dj zG&U@}uRmaNz0||Dk*$7_Wk5iLpy_41<40@awq$Wd@@1YR0W^QfzEDFta83exe+RJOqSLD=c>W zkt1!^u^5fOCI>i4-9ft1SukLM;wbzkc||s40z4 zRm1fGHiLVo5s$TXZLyALUd^$wbV;{ozf@0vs5#WhnFx-*ELkna0RV@ti~Z}_%N>}{3Sft7Kmvv;kyD|BV%_iCips^KsND?uww7e9^_2voxAKSDZ+z~%LZ_nm2QckbZvrC|DE1q~e<`WL1X{>JO?PK9&eHIc zWm9-gRAbsUS%(@LSMez2B~_ zc^ttnE7_NraSLRai6crX2@-+E@Yu&AcMM^SR#JHrkqX~|z|Ad~CY}jBrMfw0KhVyE zvg3H|Wtxl1(&Sxnn64$8VHZFmQ5{ioA^FdW*7FJ2)8sqy2we#d9R9VgmM@9TmS%qo zN}JFaO!8I{3L1F*=zV=R&r}^(zisKRl=Zw}UtJOhj+rn8h1zS!wFw4FqwZ<%8no+* zI4GCuI@fiqQgNQhSLe@~6I*T0jD00V1|Z9G@F!U^RohO5*V8DtuR(>=Us|{DaG=s@ zN{Zy@EhoaL2WkPV&ix5P1I`!`^D=*Zs|6cXyL77}TJhI#lCW|MydZd}_oFn;DNIB% zs|(+u{0!&{x?72p!4EQ4y9&XIj;aB4N5?3abMk^;SPawE_K@wRQfhU*L1J8nE|je1 zc~;GBDc|kpvH*$YXh4bugylO}_hBUJXVaj|_mv-D5>)7^mk+%A@P}_W>@R<2?1i2R z<(2qQat!jc>e+hax2#UfY-AnquVw*waz0W}E|8kmF5=7-^P=j^PXXwTN~bzcCyOLb z`fbbNx$JGk^^#vmwUm=ftWF=7pYhT4jML^5FT>|4q?JFW8XVsM}~CI016p>L#VS81wuL{#onz(Vk= zJEzTD-yl7mM0~p*?tn1%{GaQnyS2KrD;rk{P~2VyF_6yuoL+!DUub{uQ@bl1R$_hF zfan3X=~+kw-mw8>RXfd3AVl=PPZ7zHz0BegMQf0-nQF?tlxb%l(b9){YRDQx^9uh-lV_}tq<^-v)L6@{)hxvIC zXe2gJnmdBNm^VD|Kr9(5h8o3?+;D_WmUxDVva(D_`9F!Q^4NbKrs$9Bj+h((2&$ho z#K#@6?4^^&cO@x0NGFt$y_Uj4wE9%(RkdzRcRRDr#|pj20=8>AB#DcXAR>FiA#bH^ z)ppvFNqBgOe;aaT8E2#!u_`1H>5w!%n18ePyh5rQuB7YiP`5HV;`lzaJSB zj^mb)I^UVY9OkhDZ*&ABnC=u4wSkZ`pt&NqrgN$Kj%5mfhu(-hRr?rQeOj0Jd}UL1 z;S3&^B$l25B7PUX5|WrtHg3K4> zwTy<0H;{FP|#2BQSk|)8t3$Hq+#?;FmA@6ZCH8PqnzQ z@;7Ve8GveZmBy(&R~q@gAG|c_1VBU}UAw~IJo;_22aThr4{SQ^DxbIBgv@`eB-L!e zH>dVg>h7dn7@jQ!Kn{l*ryv_kLtVf zF`W#eY^d3*9-X8EEKEb_e;||WQ?~J%f6Z(22cWZBrp4^R1+VU_*n)Cjf4G6}lzL#( z+COICpr{{3SX7I{mv!FybF!?-&1zS^gl2m#zfymU&P&1i~|6V@ee(=#>H z?1q0L&vjiVo3}UOw1m)N1}pxmq^feFaI-=>g_ZF_qQciJ$vZ>I&oQg_H?7xFMMFcHuAyLEP5GBP(N0w@pd_Q3wOxAiJwf|q$1m9TEG8R@ZRo)6 zzPbDny?ega4TaUz^X8sB?i)nrzkOQhpt@I1z}0)+tv6_;dsd8{rK0Ve0=?tD68IOrcpYk=)8YOF)jExhlinG9qZyeSP}+fTv;eX%J?4usqjy%P5qrKjN%e5-d{*(us;}vn(9$@>uh4j;!Z%wG7h%NI*z<9fP#jG4PbFR3$Vuu7OSJDjtHND-Zk<+W z9*H%RDJKF}!=7MwCk1%!Ld}1JOuarw!6ZzcmR!(pVJmu<>Kz&K=wE0-zvg2s%VQ;m zl+_hUSQXjn2Mo8uX7I=L?9L5%=fOpM5!QEWKbCnwzx~1=RVY@5Wh|ku2E_>n`!3tb zfY#n!d;wt?L}+(CXFu0zMA;mduFf2KrO0@btjFW6LY4Q3#-CVXbkcu9jIrSey0h*V z?C2m+g(4x~E5kO=K8Tw~aQ;kE6u9DQS5N^azRN_g`XpW|UHi|SNXZ=u!{woe0QnMw zHglmJnGfkVVvGvVslC#-b1G#b*v=uOdvu;WEn1UkiQ`t$gnq6!1kiu}`{RdqTV3+DTTK08 zJkJt-()B432vG17rJ8nr_*ZJwZ9~z5WVe_mkxX4r7BOy0>9y`d(lpl&U_jE;*Af!h z7x9_TE28m9<^XG*Q?<^10SvGOf=th5$vZ#qj<$qIis%>|gyk{P0FNynp@Un)j$#{1 zbaj2H?Y84YRY!lg29a!PoAU$oN|NX9fjtKC@Fgj>*FA5d$iT%zZU+PxzJhOq5z(3f ziKL(nR_cy_-{eHh584)&;U0Mp_Tu{izYuu^1gIk60b$QN9OkyPtC;3|(2=#}!ci0+ z(*C^(>IQxo%a0fJ2_j2n88kCT-~to_b6qU@>RTTy6e)jKJc!7e$^1t-kYimoOV(*s zQJ8;kVPhA9tJMS5E!Qk6vDDOQxNDGE=iOO*DTt9&py4ped16p;ez3K)&tCjO+f6Z0 z1h!vg)LQ+)Y*ZDEtz!X0Jqx7`$wC-JF?FAb=8TrOMZbLmdhF0quOC|w(z>#=?j!=| z3>zF$?Z|&ed*>arZ}P^!hZhMt#K1(E+e62D@H0jmbC>t<{c^NZ3{yo2>_aU*#cniq z1==SxE;-wB!pFOyk@U@TpG`C&b!uI8!3IwkAyJ_~(;`W|Up)0~kPi!xNxA9cEN9g4 zWu?vz;LAx+-G(@Lmsq*9ljMB5BQd^uuJ(Q11%7|+I{HsV@9U^rgYN1OG{5Q(x^zI^ z^q%(@T*0#~H8d?vxrWY3hMVU(oOt_6{xM%e+Cm{->G``@^)`nvLV95PlG(|XF*l+* zlcg*YNw;k8`Jn~|7C^IDChRN*o0EK?EY!vm*+=K2&X-7MJWd*;cv3HjRp~Mrr+#4P ztp9&-R|#cDHmIC`WaKAPOW-R3gYjRaA{bS%5ZR~JP5XdTXTB$07kN%Z#w|(Bs>JR|LR*La= z_GZ*bb^oH8CFv_HX$zjksI11g@sNMrTL0QJO$?<)6=o!Gs9Lt5mqYqgK|TugU#Esz z3xelC%$_|J><863P0G*IN#mXMueeAO!TVfq$U3tc`y9%!dOh~Iliq|Zv)FXVW?8yp z!Bi7YBu}^M^-`v#luKEQF5DSV~W=z#GL_7=e z=7GCv%4x4<_x4Y_SjKvnj@R{po=PWPq^f6i%M!KhWGWw4oX~POXz)Ys=v|lv&l-H} zi~xH>X_p?|ooVImQ%C6(c(#B4&_#&kj3GtCOPd#reAsZ9mMpQ(odOn~OpbyWi_KRA z2hdFx8p*ZL9as?FHvog%!)AqKUF6=H4kSNcy)mTDHb}mBa$l$LlD5|ABTFpFTQ9XD zAH>}f)k%%l9NJ0~&-3K-EEG_G(F40XM~s+C2MHDq6Lh|FFoRGyXkmZf;m{2GtRI!QsxHs_DJ;=1Ur;JKmbzz(;#I7ac&p+_~ zYUGF(UWO`6lXelhh0R1|z%OrdWSLNq(mx!LlU0k%EX#?ZvvUYF@8n^KQz+vg(%zii zTUrfJx3%VYN{jRuNm76M6YjW~Gy|1UV*TZdA8x1rmw1eUPLU6x^(QHYL4b?4)vxIB z(MD+HlSwX&7irnqP@2sPA1Wrgm?j%@Evc{1&|eD&guV|YgKO%4%isu#xWsu6>N$5f zmxaUswyuWZY&!ES|2wC|$4Jn1T~UWvddbbTcr9ZUHsteuqn3YPPoR|E@(yWxZq}0p z4fVZz|HEXADEw({0a-tkM0)mtp4%y6r=1giNwWC?3t@uQ#y1hBF*ikcuZkDYa_Oli zwUTQku%r~8e-0-k=d&yYRm*g&>N{Af-eLh$&5 z{wz6%b_07R>lOO-UJAe8pCm|YL$P@|zlXi0es*!|H}U}DE_}MI09Ri4q!MXRro<1Y zgd3!Ph6~K}$d1O0y*DgPY5-{BlZRJ@T(>Ujg9JeuR?UA^2_O6!q#o5d5z@Xu?Q3y+mJx9$!0u0IKrO`J5R6}1F;7a1 zijfeREf?gYlfzn-T75_t5tC*e$q^eHa0Hmj&Q)8&!2!bp+vD!)_ZF=)FAWsd%p)ZT zn^J$&p$y;ZKhI=z1yP^0u3Z!bg%D0>TCcwfC|(#tQ}z$zN9%(L@|`|`BH3>Im-<@K zOZH;qaTb}Rl1Bm8sr$W8Ry>I4RBD5__pfV0T&5dbL>6% z8_~b$Erv+Hyvx#%jCm&NaI^hj*7v|T_d&;jV`Jz zR6KI?Xee)_8=5WN3@Q`?EdW=$VfR_opy#%mYcmp;J9oVE(#`>TEH1TfU$bdM)kS{| zUPB#>8cw*$4?pu>uIWJ$H+m+WiQcAp_A~NHFLh;cmW(Kq14gAx8M3+|!9*|JHHa4i z=%4oFq|Ul?@)-O2-4n$>+OBeQ`LIq74V}I4@=|exE)RMK%t_t(ruMgA(z@dp12)@Z z%e-BAW*B|btRcPqT&|VlY-4M`SzLc<@cN1q%J|@FnZ^Nu9w#OHJ161q9W7ygl1^v@ zpu%((!tm^!K4EA;<&$TK4MBeahZY|=1d&0Wrd<><&} z87chjQk*zSioJ|46GG!cfm?sCnFY(1%u~huedhg6S?!@Qn^!KnvIVi0=2^{!;!Ufg zk7l%PM?}Q*`Gl^Yg`ZSLPfeJdsIaUZyB_0dEjCTee)xE&x^sDWzR(#-83bytC?IL0 zWpk#VC+gZcA~1k9?hy|X_Et$Q-I#kvsO4A+lW^&;{le;%6_)bbLY99E5O}uRQLR~4 z(U*<%0`dZ%idG z0`)hSf5Lwenmqk{g~gEdjSQcmU1~_fgu8^A_CQ`dAPC-xw2!Zsn<-uyzjjHkS)YY; z0x}=vFOHXyW_@!U*zJF?x2g4iz7vaX=%R&t9ZZnW*HyAhq@)dw`(7&}4kKrL`aBtb z8lNU7+;yWg#Y9#K$t%1HzX^Pvcb5u_iZ-kKQ6$Y`MXK^^bbe%$W$WQ7$)On2-CO%Q0aY1*TB&Rrk z2jQ+|U{Kgvj6>oXJA&i##_3aHo9RbIn$UR(%QG>#(?LyH>d3rW-QEo zUeuP|Er|S4%r$>y;rkxC3I|>XYW@&&mL11lz;t%~EhH~SIt*}vb@?&F6*ZZ=o|L>d zGkVX99frlQXu=@~Y;p zR5n)E=xE(~%>AS*0IDk*2W%R-Lk;3|7nfKtr(mbq(>{ONBa?uO<=&tdoxaeqq`~xm z*+MVN4%>8?2+m<=%skUc0}@b&9k?>#`UNptGl*ZWY$ZR#Dew50U zyQ|FR)LV*5JoOI(*Iv~W6R?GLHNV^6g`CmpKK)4ckAYwe+cGa!1}(0d-5 zDrmezO9{Ci5+n?EcvW1hD$y1boJ{Ba9p;I0?=XK0(~jjbD=IaNj@^0*%erx-lZ zOUPmNTCUpPje-!B%E31`?(6;AQQK0OSsTon!HXG?+%jJI?d0nT>+z4yNX>9q4DHUV zktdA#03@d2$&$+8tbafUgOe%=v*kN~X*P22p|h7Fa6>=8mS+_rL5E#$H276xT}x0z zPE3F5Lk`rKSO|gJVvmiZChcdXE}Nro3D=r60uhmzsv$l7 zFY3%w&#BcVqPv1c_r)ix9iKoU0pm5!GD)b3y;GV zOZ#<-Q+^Kci8chW^~&!qP5o`NB@*s7-Yo6XN(YMhyj>2CX4nOb{65u?eU{pJiyq47 z?56tm?1h{vO{#Z7wOuJ2G^1*?aWM-360dP<=xiE{()h!%^&qi8HAUP>z$vpK^7MbS z0?UbJXo@p$d){I&5y+6+X+}Z9t}cOOf8Km_NZYxq_PLCJYPxy7WyVSH`-?5)&~WDv zD6WJBVBL^lPKW3nV4OEr`jI#GN?Af7@PvVnqAVPe%9Ze311Xr|cI@pvZuw*P^w zo_;`PdvRZ7AYw|}{gtE{9KL`R0yG%wDI7g+S~*N5_JUjV+-4nEC)|kd4ABwxcdQcw zTm;8uwuv}%I8JpRJH}Vms)lu^wf(S{D&0w1A zm@GB8Q%Yq`@x!9WrBlWFw+LQQ|4h2IYVK>eDktDX{E6bNdFKYtEDCAoe&UK+tG%%( zOpVaNf2@7Abax(?<7e#G13N2Y3S)*IYi3wP@t%s0R)N8a0KoBZx#=Glw>Bw`l$QjS z(%+W@+=1SNhddS>j!1w`esZ z;{yt~h%-FJly|-gvetusz_dW6c;?TZQ_bI1)GtaT6!0^IGM37ykie!4Vc=2VWq3;c zfVLD7DTLb(&K}8(?(TmrLa=Z*>1!nomw@!G?*_>Fhfai^GW=r_H$t`-BtfTEztT>U z5rUrw*dyDoL9O9Kz}VEj+R`@Z)Qd1VRb&03Z5f}eAA0|CbL&`Qz7yApt*1-cS!Xu+ zVAQ|M0e}`1jAl`+^NYm#(|h2+vq^%4*khGb*D+2j;nVgzilBdKjCbnvRZ|$KSEXSE ze3%&X>f8SA6;tXnL0`+1H71>K-$XHsubxsp{Ywu~HlyADG$ATHGHw?VN!^4!3E zg2)apL?1_2(7kI)bwi}|^fHfcG7)jZ*>N~T9nzhO7;}Jb|A-q6GL@0?E4;(+ryIuu zT{b&4^bnJjUaf!nIa$%Opjn?>Wn5;UbusOci2}zGCl0_g=m2TXu@dswS8ZKC#=ZkQ z%dDR0+5Y=_R?*(tS0#3*G(RRAtz_9d z8VQ%AB)5NaoPXG@Lm!j*=P$4>VFF#{Mx*fN04ANt6YNs!jp}QCJGq5D=y?U#uMW8t z-X0o#LNn4E#$8U)>m#yv$v`hdJz-410^_FmS`G8ag#B7F+yB>ut*Wk(cy4YE-vIf% zaH)m|Iv(;(jQY{CXEA?ltgm4lulmxq1lXuEWAuL>VZ0T3*X(UqjT5BCG!~B;MN`79 z{DpXa46Hkr>tO{Q6whMOvt_HP?2E+{7h-*H$Uc{33#XHWzu>mJ^L9qp6P}c~EbYMO z{xtbggi)0qQ>mr~JBqa9@cuOQe?+YBfgz2%e$4=-T1QmMScmq{pa>W&qR7esec_e{ zS=N6MQK*q=MRD#_*F)8KjlXR1oKSpP0?-?uZFqq*k1<992x&>9i8Yc#649;`y>n4$ zz=hQ>;8H}qxh=;rbKz{C-$x}K(Bs|3jMLd?zm&|f@&p?k|F7&!U+naHir4QB0&i;N z_U6p4kg<=Yd3QqSU}VBhyT4X)#++Z_j+}pJLSQKc@4T(I-g={!;v)BD8%HcHdm3D? z-W!1AETAZohBXYOoPEr?Pp0k#0DDsqpwXT@@o2pMq29={#`UcGET9g9fCpN@Bl?^w z99?d_&DjnTFjQ%uJJIvoHJvs*qZvlxTQtNS;=gFB8o|f*DSB5AL*qvsum5|>OJjfP z75Zhl>6wB`d+)S!2^}>thu%1t+cLysA(5T6^!b){p_|R*V|E z>RO^W5O}wIYdCt2Vpb9wThCh3nsy;{*G^w)BuaO)kk&27a?`AsJK({s&>~FL(r&_e z&t)=WAB63o+a8?Y3w|Wkpg2NIqbPrH78DtdeS>RVB>wf-1zNDq4cJry%WH`RAYw@W z+w5bss*{x*d#bXPGXePa&mc}n1lvG()h&Cr4uF|Ai7(@zEx}=L4WR?32@-RV%{3dsa z(0&t4n9+)Ue!Jt(_&OnCs<&9s-wp0QkdB%`0x*|IUK|fCta`cO zMeGh4Tlfad)&>~AKSH$wqP;GxC9R0U^=}i$BD6%Y94C&j{ux&!Z+TtFq{g2fb4TK8 zXj)cFLrRq41&jMcuik%U>zjRRQhrVD9vvKi=bNodBCoffxWMo@UU1_EcF!ah46z#* zfzO+%DHA*H7clslS+*W0FiO(gI1VU;zngC+u@kxoTxRXj{;2r^=j;{U+Kvjn9dtv( ze1#X^GxiE;i}n#|+hT{FS(2xk-Sp?tqaN=5DY!frku<}6m+OBta%(K6Znke{XE5%E zjYU)+DX!eyahbPX=|-z4N-VpV>*S&F@}-vVTF(J_C!c zX$xwCh~B@)aK%!R|F(&sRkgDnA?B31gf6{&&@?6MnGT%4;EWCN79;Ke*tid>rA0kG%|SJ<+F{<H3i_(MM(k~OPM}rqmy%>i~rLen=PF=p@CY^$Zs37?bRk^ z{9Ngu50HH>cL4Q}U{*Xf9oAnk(^%B(T~CfcXkH|xaCuv--I^tPqgcY~(li!yGs%lL$(Hbn4DXUWw zGB7q65!d*`F8TJxNZ36}%r-h1Mb*;sm`~qosm3;ci%lrOwNeQY{s-qfOvLfYz3nsvGiNsTz_%dAB&C6T7aqrh5>8^Z&T~xejYY(v=MO&sV18 zv33>YNV`rwc>rR2h|LI>+Csxn6^Wk4TuNcJ4{?`7zMSZD|ZU>ZE!_5<{jrkGtUxC@@GRUHX;36YID~G zlU@lF3hD4&F3vh;J={VbB@-> z8^tiLvNzh(wdWRV=W_D)YP*|}iAu}%kP*-<0TVw6+gv`om5Wv@4xHMLb4d1Vb5=II z-RBl)hWQy;j6g@mAai1BY(A6DreWt<9g%!`mC8aYjy$`dI>iywEv^=v?Uh%>oav$4 zD+(=nzv)^NQn~?d#K9kkl`?-shK$>P(cmEluj9?Bn#pXr;`6mcV^J>QSR0y#1zu4*bjKxy2OEG#CU46aZNzH>iwag)Cn*s2V zq;tuV6vDFakH+v+vWE_gnFrdlBinbskHmf@wwZ;O8}Glul7{qz2g{{Drm8o8PiJOA z8Y-(yl9td@N7M^B2$vclq72={B2PgtN{~p2HM#`9RPJ zDS7>DlCRxgfQuYIhncI0`}a1V{SfEu7bvkxe}&MrFgr0Up3Mdm2nJ@OGV?OWs|t8{ z0-OhmD7n?if6rwnm{A$gK|RHP1zSt2wm9q2pu&)v?oO1#k%5lnojUG;5~`kL|Ev%u zfM>)W1s24D@+DJv=JxN`_j$^nV4Gjy-6LCtOq(Zzj`ln53 zHqlxMlgh`$kz!I)o%51^ycnrkT#vWTaY-^tPXrzuhECepFqlw5n$ASx?BX(Y1T6H} z!Gf9GnLkg@FEt?S)SMQvg`l*Z(lnu7G@P0yYWtsRoa})m}*NNf%;Y5n*uxP!G zrbk&a8-rW#7^U+^dp!?>1J#T8=4F`LtXlqZ>GmhW6H&_g~^> z^&Z`ro$(x^ipC0mLn{^{MU2Lt$2!Exa0VN@^ztI|D+DOu(EKp?atz!EQ`sv_Akt$I!ReUc5IDgrSRcB!b*@C?xsG^s9VbPu3xy=g>k3 zFbd9@b&wrU6x^)#Tde#>Z&ouAGW>~_-oZ8ou0j`m8`-~t1C^4a*BQZX?$p_6`>|!@ z+sE)#cSo9kjEwHSCOTLlU?DU2cW5n()oxfQqO{Afo&IV?%CLnPZr*yYI!!oFNp5D! ztAoWMHYnE^O0Trb@~P192m+c67zIMOqJ2k9LjMOZBrRH1Jz&cID;0f~W~eAz(P>^3 z3C#^Szn)DL6K~eOF~Xsdt6Gw%0LI#C^3AQ^U2i{s;a?kgA=Txl+$2@(>l-^)P3}6; zGs;78^Mnyb8~)gvTQX>ntHihaMR9(moK@!A10eobWX_S(uA=0l&6&T^_J4nchGIMgfjsHe$7hT^3$Mal0zG3V0-CpSNZ4(Es21tPv@zPhGi&{ z0fOg|24nS+35#yOtbzTQp)hza!l*RYPkWrT#Yop^qyxZ-O2hPfZNOgQI&(3P!m|!% z>!LUHc}6RYPd3RPV47Ml$J&UvY?>2RLz_8&F;8EekP?MoSPn6`VxZ{3vz zbbpgMr0f?8GwG*#0R7Qj_ z)cSGwdWhP)Iv3)RNq+fnb9dukSo&lA>m^@Bw2`O5U^<(Uk{Nj+xU?XWS#9V3$|-1n zlPB=5wOX99Q8@bg9hKv~^3ofu0+j|9(w+0?s47zlx=BDu0N0`ljL;=T)o?1?6ME0L zw~JjH+W9pexWtbEVx-$D?)0b(B9hZ6O`WM2Fkt={kMeT{I0lZgIJD0|YF=JRldi%~ zJliHDqI8S=hVWtCWved)8eIet`}m1}|I|)9&Y9I!atDH=fN1S`^6GHq2|gUK zHA6nGM`V<#+P1%_^^>b^E2Cy^*_iSM|3%BR;L0h-9~TJ-|H5lEYB%(^guptC&LG)Cjt=>a(;S>gSK z$?jmphVC^~t)#6J>Lb(2kKq#`ZEg5ymyAB1GiXQgNoE`0jV$}`5mFIr=$sVHm3^-N z7G5q>x9)`_)hdYNKdC`G_V59JbRO~m=DE^Y!_0*fOg7O20bBh)+E*A}e)*8<{Wf(U zeME$nVzPQrz-rY-RG&NP`s`||;pBLY$bh>Iz zB)##SiORqL)WF?hein1}W`CPqiXz-)CMgQV^5cSGcfS|nTwfVCri;^mPsF3wk-zW@ z-u7aL!BV4$*D8L{VcC=IBkEt~;yZ?EfqyfdzJj26KJ$@1d~MBOqu1D@G?D2FE^Vm1 zsUJ;-Y>sd8@cC$VIp`%g-iB-O0XB}9S(cErurrWd-(J+xUv#uv!8?=YihRAaPvm`D zPi(}f{*rvw3!>iH4m%isKdu^AZ)e5av?+4ZVoeW-Q4}ZV-q{7he%}EMmw3O!D<6HJ zZrS<#{ouqM_TlU{k91EF4R7*&9}WN>Qw-2GZ72Paq~x`I@79h3|Mo?#Q#817u&4i$ zt#z|2SA{Q7v3{Z2@PZ&N+YnOLRstW8km9h#L^RF*2;aP#QFfSr?$KCeb=cNZz+qqg zWj~7>cDJzZBPuLr-Do*NnHzPEA3tGDl6CV1(j_cG8@@1P*4{kznqtZ5WT zgZEU3RGWOzl5FLF52&^fk#K=fn&I_1U*lvprAU5A(umN2>0zFqY zxxRY|`^9)0xoYYL^1Ph9q7*LeC{UE=p+DRRo_gG6oy#49_XAFl46w|!*y~}Fa1xr0 zgEL6=j4M+`=>up^b>Z?zNR_g)MYq}ywujT$pVZV>-+H>t9R#2jkh+Z8djOaY;iVb) zmEOxQf-m2Hyk@G`{1(PZGzAKoccCimt2#p~PCO*ay02dQM%@jCB*;M(s=p=*(IIp4 zQkbi=C!Dk!#9|3VSi;6YiDv{dEqSqP`kGjGs`RCgVVg}!992YPxhWRwvPZLK&dz_+C^Ld$ns#IeQ+Wryb$u@bP4N8@)+2%QY zpa`9h;^nNiLJm>!ig)${14HlU-eoo>eP7MI-R0NN(@vZQEt#8{ssMii+x|qi z2Xf|5H&sbuG9ocLIp2N2%-4&x3~~k{Wf@+g4eF4=*HmeUOBUzStuBhEMPi{I2vICY z#$&jD?8+fGkA*Jc4uZ@B^@w>tPPb>dK>mUT57CMA(q(0^N1JM_3#-HJKck0v8SgIT zTeSNRC2~OFj@>K;9K@6Jm>)oI*?XAqr)ITeGOdNTUBsg z;7{W8BxWdpx*iM`$`a>T8$OQ9SnFvo9y85$l+mCQNJi{R(KX64kvYPwtbuKw?IAHn9fB;ABAalmN#f111q(7`xX4fsv_v@$)z_zg7ED*Jgl z?2Llwqs2@CTIu(Ol zByd%HG<)Rzpv}CN016;T5<%`buG%^mmJz8E*|7%lVH#_{w7t4O97w_z6%x96H3ZU( z(@34rEEY$|QyV@k*f8Bx=P#36Ae(2kD4~!}tBDzYSUS)cc6aH?ifk``jtFujm_KpThzXYBd zrVYb@=TyW4(o+31@|Z|}miA?VA<3Z6xzg&9sjD(S#|JvMy33;rd5Z4;7S2TzNfvzq zS9!80`R%DBxtt*?8ZQ5k4#oUm`ePH3Ltwl3&EDF(htjWdYN8pF6-8g6T26W`^G`w= zO04QZ;L=3iJ~)kgO^<>&+AAlFq<{`9sLQ5+Xt9a!*bDh1Ypv&h2k~-sb-GZk5|z9{ zJxXy%nZ|)Z?kS71Wfd)W>;SN@=Dl0!fUGA9mk`L3c_^()vw&;pGwzLU+g5oI4<2 z*@+Y)wpT_LkA-i4P-yTv+(5u|aV!Lt&Pbg-3?K4fbC2dYN{^NpQY%eRN}Z^9=}1fK z)Z>#ce11>Qd{PsZWB8uhc_2uv1*TFQ+zMsli)4rA23$Zbn~BfjI_R!@?BWPD6wkz? zKM=D*y7i!KfrGZiL+_9BvgXGZV#Gp)Y#Zp<3uu`(X3^Py9sydl3gr&ok9zA9&T8=Y zKDo)>4B)KMu%bQKyqZVyh{dj!MbtAq9#uvWS{h6mQHwo+lGJ&(vx1Swpfld{0FOTj z64+A(rG=SNr`l@vBN|_WuAM@5|9aGE0E^4-c|Gm~M4^W)1EWoE&u@7|^}J^GIlVWy zNN1rhE)hb1Ah3V<{&Nnx`10|34q9v`inGdsd2Ec^JP@8(2lR!Q0y}P-_Trf}#K znZS3p{#zzmQ+U$Vs8eM&W{SE;M5#Ei=f9Z+;oh#8gC&mnVMfZrO%1x=OcMi)&Iqgx z-AxOBb%!{KGu4S_4YFBF8--u5NO$B;i%sJ)^W00Me8H5Mjn36p&9(5e$= zcIiybYE&@^y?+Wu(sCnwErhKudo;ygZtsbN zB*v+giN%a$lHz({fNAXpY+(|6Pn7#mwj-NaAGw;ns5}cf5`JOp+U_^HS5i*=je4Dk z*NrQ~jB*@knShMCU{kIv=m>zz`l%KIaW}u31W+X&LRr>9EsK^<=mky;Q^29LWoCST zPFQ`}nuJz{ugM@meb`XZHtkH;ITsphC&WS-%dMO2YzVf@AIqM@62ZiTUDuR+k-5GK z33s6gqu*>Joi$Q-=;2bE5ze3*jR;}fT)D1nO<4PjLg0%THTMPRvTsgTqLIbNU66`h z9m|#~sPU5mA-7ZSc{hsJ1~L*`hQwBXIr=d!6c6K3-{a{<>0nw6NV$dmopi@9@9$mW$?pzw;osDFvV2<2FTH|DyPo-r#PBX8UNJ&cbzql!*?TTJ z3)q@c1SU&1@61Q3WFhuf%%II>`l{xSYm#@gtwRcjMd2JIWYe^EJOHGyUnT>8is4%^ zWW`ImUFTm@)3Af+6@3%?W&%Q7qAC7KXIc=;TP6(TU{Z zmKUyh?~yn1-85PdVaX9b6CLE)oL9X`M;Y!IO|%ShqlX@s`&uciX_?D^YM9g1o230F zt;3%X^t7XVt{&C2e&=yEk*tqsR6QcJZG6}y*G_*X9FgeeRP1P2qaS+s6JUT;u;eL* zyWa|BXQZ`cm`gti%!AC*|ByibdNUg8mHK#IdW+Y~uEy#ddWVp`3pkSw;u?(+!vB$xMK9uGiu z*`6g(-{+f3r%PM6hjLd%;RrvN6CFTi%p~aQzj=l(X z8b$SRQVhPjRhqwly~vvUrabf`R`Ed3an(}d#uO|nfYfk9j%R~}^Wr&~x<4^%U-8Mi zk+fM*35g=5JK=%HhehzR`ai1PaQ`B$Fp~QH9yO#0{KBn27k6xrX-{DRA-+p3WN)YF zL-nJK#AaUoucZb~4oG=aW<5#FN^S1&TcCo-mcq~eWM z4sBs6A}4j0uv~5jnmZQXL>R;#keHrnOh>okcUxU}?dGZ$-fVmh!Jsc%TMC>f;MjeO z7x`UuO;90wBchlK3O%Qh@>1Mc)m?h%m-QY%JVzPJ10(pH-QlJAX52#7w}P?V7j{wl zs5S&@Z3Yv6wabqOPoWnP?+Fl>Llo(tElGwcsB+u&c8d3hK0D_+rBC z>YNuiR;4);LRf4>*~i77@Q;t7wItBg$O-8GolLQ<>KucsOb;-1<`^xlvII2Co>}bX?RTgP6|Kf zaL@+KTU=f({2baQR<@E#tdFQ@y)OUX!SwC&QF9x`2b;dfBoZ07iY-+onBB&}s80ge#zqIrUs3feXSo~k%ov} z#yJLL8xJVr0cWEuxi}%Mvd0_$|4H`S>0|(cd%=p3Q6u49>>r_Z$*)l!V1yxKLy&s7 zD(b1*F-G%{%qpj$G_m|}JCd}sglsmzx8I|GJBg=&dA=xvpiXK_wDT-%-f5W+BN0B1 z+&@(G%$$1bd)M3)9pYe@6+1pKg9uk7zZVicpl=-|P8S1mz{#n}dzky;H5F~n2J2GSZ>=-2oMJja{HoXdEEcsY{EYB77L5TG+o$)egGUIVt9+LkZA)l>UA`p@lYLP|EfFRs8A78na4si)YVlChK^@k@ zMZl~`5-9G|zCHGlQqrji4J<3ZIjZ%Z^=ZwZdIpE!&GBsrSaDZqT8Z3NUoPK`Bpc2X zpNY5^!xl!LzPHk8x#6nLalu4D@DGdrc7=|~tJgE%xhVh^$2jS#zQu%=?(xBY0??l| z_DRP`M4Tw15j#o@?imkuHh&_g{r zZeZGsLC+DT=!$GzjG5m*0sTsctBWl%@RJbL1ZY%^2FDZ};){jI6A?9j_I_-*O4UXE zpi4R6jdY6vBNKMuBQ#ek<; zm$2iTucbn|SGT2cfeC^CgKaxLuoAwXq(<{u8?EO zE^A64Yl7nyX{=c2@Y&rxT2&X43AL;XKWB>PDEQ=|Fn)uMh3MFPwS4n`lZ*bk^ijB% zP-v!#8+%TjVi_m?MU-M7dFUx0FvA{~cpos3fY!;ukp6&Mn=GpRww^Ad< zsIltPfQ3YqU=|(lxy-w=GdJ4kqYzZA^o}rc^Wh3UQPJ?e#;ofA{mP)ou3)KG*4Bwn z**!7;-#KkhkyTC6c}cf_^w#iUFiP%j#1+n#<`aW8;WohCZt#GWw_criBl-18bswU3 z9}+VMvQyxk8phnX<_mG;YBrwbQI4#D#az*kZ>fe3`ccGZVw^y#+ z1^Dl9#Bj!gzjEmvlC*%mSAta0c}NW$9YDBY<#WqvN{64CJ%c{;(uC zEN^e^QjJ7I>LJ6<>SeuM;?AVlJBx{+NK?RmD8mI3Rm+#}dA|1FzU*Kg-Ox(Mq!s5X|6*r!B2~EXu zQQC`qAXlL5=0$rc5$3E|} z#-`UvED|0RgE`t_Y*JSi$dY+o;i482nt#V%vV4+odq9;wao}zo3z)~n{}Gkr63JfF z?>gG)N1VlfGmtcid-hrK{24NZco_WNqgFc7dbLm&!U!3$R59}mb~j(;0AvFdK38b$ zAfw(V@T(x3>=B2vA~HdJDJ1rzTaguyn%(SE+bXR3BavK55ZsRsK)c|VLm58es{`bs zHT}hwVzEmmnG!_}%-!1CzJ{!Hz)elmd?I5T+)(;|;jgtZp-aGSIsq+(tK6BVz~2qq zxeG6}tvDR}=t5^9B>*I3LbATU+1TM?g`gxjwk|>Qb;hD=dEXcIjr4eiSc7J27MlPT zM&~v8`F@=Le0D9GkZEyKyzg8+r-jZX4 z4N+kju>7u-0M*iLG1zkys^oaKY{l;gj+us33U;_AlS$YV>eJTVS!-Ov3W%SM3qJ{V zYhP#%qkL`VXE1s^X^pQ8ZL124hV=&x*n}#7zUy;r{f!hUK6cwcx-o(&?atiZBtYYl z;Bs$*BWrAl=Gp=K^3M>Zrs*T|^4NhP;dNo@=BNJ2% zvd`p03%rCnd2Gg#NZXE<@tfd!t$ZiC+={_2eKTb#hF$EQ3RI>Z!f}G1#53G^W&uZk zWod(WF2w`Ei0^Dz%4)A2wu;Gnbj<{kJmqV(K0FG3Sh{2Ik82bV-f)=B_+EC23u zhb)Ir=oefK7bR!O$p(nRUeZ|@K#SfG0nyS9*m~jHaK_F{K|YvTDn7$j^Mi<3$|_2+ zYs*rzgsPX0$Sl!`iYu+13JA1@5_S_3YI=GFq$1%s#%@55AdM~omn7KGT`{VEB7Jed z{^e0q_wsqw8{J?}7QI!%y77k@6QN;nYBv?3;1DBChU0kURCTx6IhraN16ir)$?kgb zy=5vq1$|)oFJP(+AzjvwX+5jkt{ce8Mz=$*piXf4ACAvNOu0L2kgR)9m8i>y>{kXE zDHG}WMyk){vU;u6nJ@a9DPZb%O>*w(_w1ea|5C41QU&D- za7HGEL4`QaDVH`w08tr0)aa$_H-DPPUyx9{;X9|tKlXkMpUt{>g<;hF_aeas1Qz?) zLYHmg&v9XRG{mS1L%a{u0r7Yt$sXlQfv*bqTAR%#ba7g)H?)d$kZ3M{5_OOqWWmcu z@3EZ08o?G~3*$n@%CXIYSt6Ev(2jgF zOcMUuMWeNYo$>c3(=|}E&b)TxD2D$aO)(xBf|A?vD7CGGDV$L!YQkvZS4?#s(wE_Dcs^^d<34H zo-Q0p_$(`(J&`gQ|KM-~+HT9YYIHj9DcIcGO`1db=&tt5;vRc^uVBN6(60kkP+Eo& zTCI8L0ak$-HM2F&lRHr);;KvZ4kut|nf05Pa@=nu#IyQ%3g4rr)=FE$X zc=LET(m065{8lb>rzDj!yOCixLP%nHLixY8-G{bB{2OqZZ3HDb3%Z?d?CEF%|x(_fT)<4>kd&6b7W;mH-`WM!zP9L-`^JSD5 z7!OsCVA@k-udu~`X&#yAKlimz^V+^?VHA#J& z<5bxVU&F+=egM=>!e{}A1EqeDp<=Q-WxN8@aeY-`@Q#UT6+Wy#(G(>Id zo>0vvT9K<+^}@|+MJY$0k3KpZ$_7ggFcdjWwEScC^u?WZg2^z`b&1Wv<*TGPUr^m~S3rCA*Kp+Aq z>q4_Emx9ZGqn4n?I-cx_J-)It-h@F+n{+XVPnB<)>5%+rzK>h1On0D- zl@ad#D-fY)aiV(-M`LWtmdvhilo=f z7MCu8_d_6$UIWFSNMFKk%Ae_vkksU6B8SD#L2P!Jw!}x zx0nb)76`b<7|QPIOVLuL0yKmclRrtmZ>|eeyNG{( z1xuD+_E=UUY}LFX#`qrrD~a=N@5?4AQ66&sKsvg-sp;}ZJMhWBUuuY_<_M!yDF_$r zssmSC6}|dB){P>i?=*V7WzSz^$ag*3)=h5$!P8%W7Z$2xSb~b!hHx=`nDjk9u!%z8 zEVM3rfdb_{0dYc}xik=D3=g2d0X-pqI(F9DGBCnJq>1;FWJ|+~h3PQ%tk-y){jyMH zX6wX~jp;&18$cwcQz>9CoYKRF-~m1$1t}3NNe`8|c<9B-4$LATyVGiE-b(@eNU=f1 zuis%PzOdtzeNJHD=b$7oG z736K9RJw1PwF-$aTy@s5{^1)~HlcE9*6eD}+Z?zesQ0)RReJj>O*xXou@ z)<;wf22&|+tnJV{xjHF$;3-c}R!}e>2jBH2QMdLsuQtrcXzz0+6TQ;&+ zLI$RZx2;KoaBHcSRXsc&3Xr4VlSj1ozsoJ7L4;Ny#`{Q0( z{}1VHYbeN2rHo;x=Y40^Ss}f&h>4;E{xIT60I$(ktR&wLC$!MY(E;>-Mr~o5(`1Vx zZjq?^_wSF?zsZU!L~{X^^PH#tYTfG6lSZNG$_IA2)1>MEn8Zp(7AVb(zjMxVnXjlm z9W7u~%kw2Q*#&nEMM59}x@|aN>e+7R&TSK`aRe&&gm=WSm&-M%x1d@8ksl zp)4{x;Wj$OB};gJ6b3LzLmU!9g|>8mXAg_zh7u`VRnm|9l0Afq9nyQ;;;%i^L83EV zRHl@qYXiDH2dZa-HvQA*YnRX1S3O=au)vwgy73o10#3B(6u@0)0xEAFrrNM&7Q&Kr ztAX5FiG(L#C*vr%Ru3T7ZH)m5Ff_{YBO@_R=(Lk8U6OPuuP>! z%n)0zB2a8@|9JFz8;eS`Gc}as4=J`(lkJ*P^Q^w7A;~sJ&F^2FyR=lF139tCB}z~D z;{)F}x)uPk>Wc9}hkaUv_ru~*fxxWUDkxJvp`vrkOUZ72v7pGs+ch_lcEgLyl4B9= ztN`S~r+zhm%*Q}P^D5ZdTnzcl;}cU%yPl8G+`lAy-ydI)?1&AnZv ziey&(1sjKbq@)@V#<~Frl0rV`1>=njh3?J4)yh8(?u@gtM_VqAsC;ZsRGi*z-+dvR z4G3cb&t|||Xn1thRMKtnPizep5%Z^;8@kSu%@JJQJEq`^ z0i*uEzQ`2W33|e$x+W?W9-dIyB!#BW)ZwRny8E>)iwW>6r-YCyn=_!r(A=hwd#8l@ z3?|8cz#c@=7 z;-DX~uBlRaX6PEr%~<~Oqt5{*NpU;EKuqNSTp=LEd+y@@WX2*)?591T{`iWikYf)$ zqx(MP^94$=J{d&_7DdI-$gkuBHPsX@I5?z#1A8D{64GS}xwsegkN{|*nmEgjey+nY zk;P|smU8zCVHIg+8r{w+h?K(k)_1LMn?j}U8I1L=p#~=rvz$tOE(qpy#IXEOJEpA# zJA>Zi8k<#<6jC#Bu88DB3E|%XH zGk9elw8NRGTTB+1y|nH3)kt7Hv4QaFkF@eP`Z34XTJUL0fD?%C{;x6(K0)Ec3={_$ zr=hwlCQY?OSIf84^&ALHkutcr^^f|bg@5++-5Ih|h5_P^4vOc}<}E?+bJWS9UEUl# zUwBT_tghT!LkN8RRNtbt*PNw)+AGR$fI3INp%Xidhbc*l3qq%@hyZx}t(z)%*qzh1 zbg=Gg2D%MtM~|(?mKCB^dfWdtdSw`gUpbrPUl)cm^hiIqT((^+RJJ97|CAXy~g&;Qu!}{Bw4&mftURsCQ_sl#uzx-qN?WES*pwDo~n1!FOBxx zZh#~Dl$9ub$gUW^AJS@>KoGSjaI&3M-EJg!b~`4Jj&xbUZv!I2{s1VqepVWq71S_f&G%~M5%hzuDw^G6SLqRh0&Y(D*d@=5uvpaSX{lI~c~bMqNcp zv!1}59?JYXDq&oIB~AMY#@#G?%4mnu#}$8SG*f%(;zknl$)4`zDU6s2;g8Fl(4ZZ~%!q*<4e2q*ZQ#v-a^>|}NV2;V`*5ELDy7OtEY`vZlE zy`gMCWbu*Wt5NQ%*zWb_Arf7sCrvT((dDgJDNfFqKnH|N|J#-VcV4!3gqDjx8-0PA z3`!dO=T%aFrd*+@;y@Eus#8wSk1DVan@=XU`O^~j1jjMFcZ1Njla*tzW7F@~2` zvnxbe@F|}7RdV_j3B%^J97cWTubR&yE^#{9(7hYKfJ*b<%r~_vxa~Y)Z%^nNd1RCH zpN7VNw1F?5a%W1IOHRviEyD{yH|scPq%g9;EUYb1s&G?a`4B*7mG)zIBN9Na+cDR$ z8Gg~hTLOK1ZVL|A?ZE)H!6$Rky9960&}1G!@?5jv1(mq9K5;2)k~{VXf+91Xe~ICd z(3IB%=tfs-Kp8%=fPmwnrW8;qO@_rO6{D+vSYP9`V{CvTWD7mxw?!f#iCVhWEGIs{ z&LKcbK{hH0I_*eyekZdbupcpl#4qZ&Pzg!+z)y@fd1=oLQONpO#|N^f?%Mof7^I48V|eo%T$ni~Ye(c)7gRCTXY&&0D~bCNJKeVbiTubPXtf zU&5pGG;DA9!=X~s(S76$EI_qt+VKf82z;* zyzu8lsB?qW_1jo1PP1v)sLjkjS_1w@QXXc>L%f~lM)Fw(0Vai(u?vcJbQL52Cfz3B zRf_J%wF5O1g86>uui}h#l`U)EYS1!&(F~Q`<1hc)1mU>y*(u8FhaxO%hg}*Pee?36 z)bnT-^AV65iD|-v%XNJ5S-%K~+|_>L3SF@u&LWKmQz#Yoe7M|MuIw6BDp7rkFYWoO zMW=*q1n;*$#%`Oa;lOH*9;0JxO-W{q(psTO-QYSs8_znsTP<>Xe_pTxttw!DtNaaj z+>@aP)3m>}##aAYK8M&XrW|YXu%;L)j;4(6jaEyY1c^ce1~gj-C0KDxfEuS2fS_faH`^W z2?3o^RFmaq_K>(+p+SWOfvu^TCAB@XPSpQjp zr>VRiafr>0UyievQ9r%)F&H*9zq?VUjj9YpGlB>H=l1v;^%YV>%EDrQTPqOee;p!l z1IX|1>JOyD$W5*GDpTUlNq$X2KXrb1Sb8fYs=S?ZWpceWbpL$Zq{XA$LdsLumZ#dT z12OUzK(*;-#zFI8Ynb0Tg>*xrDLdW1((m2EGEdr&Wwpx7uS}uJvnS#?9dUfAE{`@G zYKaCU$(9cE4Y;Jes+$OZ!Q?j56qi}E0Re#A9`MCr4~T69Gz%iYV28^!n;rc!;oUce zq;ce4pHyQ7;!sBgIz!O561T(k{76*qmT#J+>(ni7MDS5E@nAN)SEfYa4=(a5ub_VN zr3ef$6Y+9LEWMs8MBD!N2J(Kv#j!h;Yb`)9oWXg|Kv~UjS<3`}#@9$YA)(H9bBJ|k z1o1HLHCQrmcY^}vBd;K6K99DwEF~Qo5T{JY%LW7Q(m@ez!_#Ce}StD zaT`UB29!}hbW>HGXfM9+FY2`K9WCWKOdJaN{Q17HovzrIRkfjc0a`#a0p>uRA#h8Z zUQDMS4ge;`YUW3Oq5SC+4=Pz1hrxgMUC5<(#~@uroIGA_OO|+4I)pbJr@Z!phxyTd zd7APpnwgJ$r6IUgLMHjBFeVTJWLp<0nd+=Fn->D0+S?-VBvD!~u|!(aRn%s%;>TZ4 zm5@Y(sHnH8grl=I$2-hmOhVx+=WbuRst@n`Fej5eJao-}x^~#aV0Z2(vLhNLT@Y^+ zrOt`&DDmorODh6K6e7`3P}!rqG|<5f`NUi>Gx~Prx#N>bdF$PE0ywx~TNbi@5`DGX zSiTvfKao$!q^7nV%9NKGEWchc=KRxp%h{K*Da4!DoIEk)$Zy~ND+7qhZa`6tCC9uZ z5LYknz-Z-v(%e#;*J^joP-3gR9|9VL3h!M`AQ7JD%ORxjOHHB%Z4u?qo;=GrzqemB z06}EX@!z8_;j3bW{&+vF&%A))RGB(|njRnn2%39f;f(b>x#@hd5HTRV zNR0;jc3z7G=>CCZY8Y!xZB4Q(&jwR<64H;10SY+3V(s+c{U$=Qwkp9P`>i~-R z6pICaK1pBnenr>J^071fYh&Jnza6K(NGlbZq)YaIk)kvA?%rT=CpTL^`+nwJ4f)Lb zLXcd$U*A$+;xUkpp;)8%(6m%gbFo-Qlqs8@f?&!Wpf(a*TNeS5~5Ln zOm_*qKajAza!R-BwcwU)tX88xAX?>B!f-V^nVw=<-5|52tpbiFYDANvPmQ0;SZcJY zj^)F{&_);}akbKrdg=o36(tqiP#_d>z*!*_8-vNlZAkjJ+!D28J%Gt0mdKC0DldG0 z^Fg%BaTJSc+tx#WFJrYY(pas;YP>8Br)=)y(|k^mVSS7N%!h5Uxs;>TNh80hwb9x1yKi6RH(v zZ(<85lDg-Ak`QBb+k%Bc_q)b#z&<{IFkJV!Aqp0r0l=^bM;^>SD+v)|(ePZv(hNrL zEL9+lBXOeivV(BJ*A&F`ksljiaa3+oUF2

      +$bT#(e=P+FEsw)6Q;`^UxkUYPoE}x!4Zt9;-KFqN_%1vtQ&D{b z5|pcdtMi0x1Hl@3fkv>#?vor<*05Ib9mu}H<0)2B!7qSS?o~FWjlfGp3W9Vm8cl@B zJE%;dmU9FmLZ^JU$FPVjXjn19^8Jg@Pl7(SNH`_yjN|8mTZ>f|e*(7UE=9~>J<|)P zHOr)&3-vh>v@$j&qp5?NNH_YgJ*qun;L)5=T*tihGmAASc42*%w|~iH=|K`{ZKRe- z#0ZQks$#e-+=qO_DBXK9D0MYZvh?7xhr(!nzkIFIax60g@^jPqk;QrvXZ-CTzJVS* z3&<(R1sZ_rtM4e^e}2u%kL5hML@wVEw8~1D^bo+n8i(_q5RTdPLh$XzFPjfF^g3@* zRWT#NYomLd5|@}5X)731ZLoDUK31ZVJWnEBh4#62!Ns3Rp9V8GVPDzA=K1k$twSCn z*__YHNFZD$HOAOrg!_)&U=V&h16Y(P`)%HiKb9fA9~;5TAO{Q#IQhtbEQo zq4#Img&&0kK9!WwVkB+|#OUv)u6jRQeM@MB@9en)Ee1~4)9bMf zWal@tg0n_ye&A%QFu7pw%-kIX!rw%*NqTHCUIs!Nvlf5ye_PeV!$gS z#NbqItC*3?A-H$;${RD#w}wif1Q^4UNxb!MOcr~C_EQcJ*7U?ey#Gu!?H#BOCilYe zM(uTdI-^jT0sdGt(EunH3vr3Jr9SzQP?`^mS%HkLXkl|f33Aq((V_Y&^s;pf9*zV- z&?2pde})4_$p!`T7#k5uV;1Q2fM%0{`x_;DH7cq$$T9Cfo)h4kk11*D8O8xZkFGZm z#>>KVBLASh){~?!gy)p0{5d8l$FlSM%q}~nE^?TaF8wL@8rbCD7r_IcSRM43A}3cr zd{iDT28QLkaW{vFq(rMEDq!ERN^SsD0y3;-e-5y~i4+BzcdMq6wI)uz5Uzki6&Cn0 zPEggs78z`W7`CQaGvh-JZZP30vjV`jH2)`91Qw()(24xe@EF%Ik$H7V0Ihu`-^u^SHh|fpa*mh& z=NXwWC0YwT?xgAZ8WLDV2dInkX`h61fBbzgY3XJ2etM1*Os4EMiO>S8Ai^7d(wU>& zw73D^0us+eJ9pZxFXj8S0DRd$JATlU2@$j9)c%qs#WpoKU8%!vi=<0UbqJQ7w^ki~ z1VRQtf`LhpB#CJ)M|T8)sWUwRV8|>~2&N9E6K<}g5qwj4cS=f?=`8dOGr<<6e=-tm zARWCCmgP@lvy?O~ea#2E$m}OPA@4v$h|w_;-zso1%utZ-yff4(8-;w7(Jv?{$MD@bj_Z?(h=LQ)0METfA1m5vZ% zg!e~UC20eS+l^>@o~7?_UCy8Kf9vrHGaA{V!a0c3(CbT$tPXSxC-P-z_3mUNTQ52IyAHixy>tE;yBzO-YjPg%$SsVxlmr7OGUN~Xi1 z&BBlxn5$Szsnld8yYok)X@2-ewEMe=$t8`l@b4o9qdO?;hUP>T@7oE_U?NboN||6HHxZTBt*u z_7Swg_>f!rGshhyT9LZQ8}wvBu4}HXIY01Cc-&cZY0(^NgPQ+Re;nADYkQ%d$ltlq z*{o{%SoI9@7Q29viLF0lVw=R~s@hR+H@mXvc21CvL}Tyy#StbmW5 zTsi35c@|$21p+bvChx2!CdnkD+%K@)Hrgbpri371jhf4YEUZ)@VV(V}a_U8j;rrOl zx$@4&l?;W$MeAMUf8uOa#jvM#!B$J^M!MMHpZ=y`g)V(irHw3~C%h&fKiu~p?v6pG zgfMWW0;$6^fJy`lYV-ah$ieZVVC&h?eMg)N+^b?>>Yt`+v!bWk1_(R)YPqpM+&DZvLhbgMkQWWZ05XhbWb^yM`(Y3s;1;aFg zL7EX2vqa}If0P3Gc`4S`2FDB5uNr#bLS&|6ueD;^(Pt(-3k^rjdcX57a#$2EnRFDs z<*`&w1AY3bV-7Uj_jgO_tUrErr}S?M1|zkAYSiBuFoP`(x|f(WCQTmlR1h^00tO#(=v zO&3uS8z5BdVfi_6yKwaS0+xLBrrkdcZyJ|Gjf)TRm#|g>dw+$zD5qJ}8oYiQB!t~K z2nc zPFmy3XAB(>r++O(=llew+dpwXKWgOTuoyeAMpfofbr^&mdef#PSQj(JvbNp$>~ya{ zELA)I&;@1IJbX<`s%ABK1;9210Jrh5%4Ok1*xdv7-kw8r@uYH8U<#9!bx9}Rh7Q?B zz%ZM5vjlrhOiLlcfRfyi+T{_>EVqV&m41#c@J2P1=6}kUDZR}>gBPFArSl~bp)+nB zaKWBv*NR!A-8CW`5pycn&?(nNrzhn|{Lx?tK^DrJ*;1mqmJa#s>?AzGfmOC+ee+C9 z!(X9Vi3ZlNMb$L6=Td6Y9H6WCztv7f*oz*D;iKf&4|6M_9b+t}PFeW#w9#a?A}aSo zHXC-zcz>U7Qjak#PPm3!x+#p?|JZ5aX8SBj6B;cWgYHzzlMKo#Zyq=O`Wn5j;Ib2c zj+X(Az>P48?1Y3=rDcJ!4GottBCxHfe60}}6$PXhK_TP;)Lldp<3B#i;8>WL!IJpx zAFo@6*iA)eAp5wydCpw`GsjMZ%X362;ELg_<9|$Dn7&pDe>DOhh>emLdGAn~r`fwC z>eA&w-i!iy5MB9+E89RFIAAWVWQov-GE6?jy|#5^35UC-f)h1+v`h>)Ego5xo!=Bv z3$@SlW-N+!qONCd1e-5b8aGI( zbEKv0*mCAGi9Bx+*V-7BVc6T)ab(_wT`7IgG00-TZKi|j`g^-$e)(9BEiG)gy9g21 zV(fl^THj#!^CKO>eo^>P&gIB-=+{0_-1}Pe*MiN{M<$tF2Tn?TQdJX%2G}%4bAw7CK3q-@Ri8INqhVN@U zmEfAvp1JdY%9NQyQPO2|mgk08dv_AVy{z#Z**wLHMI!ah7_8rXP0*8Sh3piU0-fN+ zju}TudO^pA2gNTm9h%2zWamhc< zJuRGg8aq|qs-hwFC{ZGT3(}+q8(kUQgstrH{@6;pK9Y*iZl$Q1!8~|4s@3)eg{Fa- zWAbXk#p?GMo+$Nu2L(G4BY)5tJD3z6rw_eQJO++~`#mjr$@j}=P$oi6O}!c}=@jRrE|@lFcf7tVFNo`${orKxP(zMeD23b$Z*>t7uH|T=C$RpM5>b&3`D2^yLT?3sLz2)^2nEMrXkoGI#0tS^6i0+J`unmR`+poQBeDQ6TV1%cb(^*J zQkI>Tfi6$}XEttpWLtn>A)h+c?DMVsTXY8d=V}xJ!*&WV-Sk+jhqQRr0* zMj&Gz9SU6W^5dSmh{MXJj>Wt~<^kIrVAI#Rb!6z&t(O)A_9E$yGYrDOm+n`J5{qPP z8HUl*xci{efPc*?Y^%HG8pl!32r}=^jK=vPIF5hC>7a;Tz*_UYGXX%_Lxyjw>6D1V^xT_@-4M`VoeBw=tu0JbHHPc0pMWz01`kdQX&AkHL(oQdBKl$X*b2&N z0(>3MRT%6{t(_65nr$jm2~%0N_eY#h3F{~@@KePcS*Z9YUYLOm4y{bSsc9=*vNQHW z@Lm%ycYnFv8n9RSak{|g=&H;TmFvwz8l^Ury|DwZ+UX?h>HyL*t1%yw;^M%Ef(kCp zk1hPo5M8K75RxyizI7WAz5PDnaIA8W(4yR_6>f{iWGq@k>?jmdTe}`PjYdL0m?g+G zmjhS~Llh{hm2C0xS~2iicG*PH^h}`a-}%t*Cx6sNhdY2fFeWz8zW+vA=f2Y?EUCxt zN(ZZTN@SV)^$GNC;D?w&|I z8?Q&4i8lw%@p=tO8)t$SsNT_uB9XWg5VIupKmaQ?5#larrseslH#AP%Q$N?(#xiV} zCV&0J*xP7Zt%uieMGgAh%Y{2d9sX!)tm73(tp~Ux0|HBMYf)S~zN8>TpD_<9-`r+C zs>J8@O7cI<^#B$9JS{Dg4ZpD&Mars(Jz`8X4M1N3;L~#uHB$7f*F14RAtfqSy>@+$ z%=GRwLnbd)IO1I>d4F#*IH3{z2GxGHUVjTH!;2wQ!x_kL;yqZ#Qfu~W1pX1-aUw_A zi6~^$b(jv8!gFvSdJMvC+?*?D?qcf()KRmm<)eCa4W(lTsk>1U@C~RML6JR*FJ5Lr z1}|(?TIoGAEK8^ng~$``pF8i(D=@Mj}pk&~lz@2?pmTRLghcQak;F zrgrhVL`irVlBsG-i-F~<7G85g zlMO8PHuyleGl*8+!tU3x=ebUTYkypv48K}z)J!4FPtB^_hr(GtrZ%PYD80n5a6QsO7cb+kaM-q>Ls(!Y(tndOl=50( zu7$`}w;xVw2`H}Lm(fK>r?(LKKu_Xoqys5r@>qM6_mNF!QfqLwHYRfBx>2+X;_dJE zqYP1~T9A8+e)vPVqc7u0`_a_|VMgC8&qb#Q0-+=BQds`nx(M4u7lgBNYH@i-ptCT9 z&2S20Hs=j=Z{*pVQ&1B!Kmny9DOYWau4d=#0FNKNrqYkujtW^ z6wuU?pajeyExARs^!84VRNN(wgp{$1_ZW6*=0o8=PC+4_N{NsZ3)svD=1PNUxu{uFzy`mbF~2f~rM zR`>c@f>}9q@d$!;O9w<`6$NrCM7NP`PjCFXVr$t#9SC9cmIHIAS?C_GiyMQOSAcOi z<^!*@bs%mh2!FCcCabmAtK*9DVr}-Yc9 z_@C#8Y)gR1XkqHahOn?~(wU9*lY>dK7r{}0?YFR|ENKx%j*gOksFnR4JqGU%D^|;( zg;Uc!l(pYcn8`O8$Bal@s;a&>-m=QeMM+eQwApiq$$wi5Hp=2D+m`(Y`TU=sf&#Te z+GsMGvpnUZ*8!!^Hz1^WKQLcG{BS=VdVqxCR=`q#^JGw@bHew~e>)w3^DL9-xS}wS zahvG+KB6)3qZv!IysZ9Aq_An>7vM#4O`_(h7HLFDyy^g*#?y4K)8=fFBlJiPaVN#f z;95pR%YW^V%7#7qm6~y-a(Zcn_G7w@J-|h|fKePQWDOt3f-o9X5`}#_=c4u*03WDv zqv_?Rf*&^$c_zondYx#<+|1xS?7YExL#ej_Jz^rD-a&=kv43n}at_6HKPztwF_5!_n?|fqphljjNBVVs5B6C>8O+*Uj zP6g_GfNuzrmz`{c%F*M4wJJFY+OncB{V}yLG~=k8gd-@r7Jw4 zdVgFY^_gQ^=|8ikf(f@kTizGU2jCN0h(0-g>b6!m1U`(bm`M~#!UaNGKtXr*)Nq1O z)J_4!?4*Uly~njDKtEQi+IJMUebN;Oe#%x)6YKbXnFWUh+v8@7^7#TtIzBF2S6=ca zx%5S2LWOI=FDnRPL29VXwj=kIxB>jZet*Y)T@t?I@s+{)`7+o%=Iw8Zu@m(}o`{To zL{writJJe6K-d6`)t=}e>++Z=A zGxa=L-)Hc@iuOIK?^1)fGL)%(>{JG|i(+x~O)ifz_TOjAoZVQxV?IMehhY(($jl=d z1AaB+1Cio5+m0&#|5~iJun2vDi+@9o=V8S1Ip;oDdyb9xhkySi$@T6SDwsa5*3|oW zUIY%-WUZdEb=a-Gb#VTrzwH@$_9HeLsGm730%KabNgOHfKg9fS__n%nKt3W`apqQ% z#5n0ZhKlun?3_EdpIZ!wYk^;ccM|@sX%)C9pYYc_9)9GE8K*ul;7SL1ynp0@(tCwn zrQXwP#rL#dWH04{z?qwXAa&MwK-LMPvkw)ca(A3bh;T_twT#a<9(QI1dA@TRqe9#m zhoCJ30^!-3)k?GbEch1PpH0l;_CyNzH)Td!aLIX1XIpZJcX z^h@3zjm06z&5PKjaFkinJ9^1Vw$V2E#Yb4))B&64jXwyN}V>pF$-Ubn!V!S7?W9 zv|)q?TMkH_M5;+7E_ZlKM9V3791HJK1ZX+vNr+|fI_Sh|x#Pa)6o3om$qwd0N6SG<2M+0GIhzm_2S-szFf zO(1eanH=tP(D`Vz%$8b*8Q^n?K&-;I1y?oXs^1J<{^o}G3pz__{lO&J0@U_Q%!%6k z^80&e$)ni#=w8+|3_j?sm3SnB?G)&EtgZ6P*<;TzSOTrT3L}6i1tY$`H-BjVt>5z7 z8FeQD&)FO&CeeR^`Dk{DFp$DcJb^e^S6fAC{&C_KwZD5c^}xN=Gp%H&xFV}}HEEeYerWyETVn-70Sz-jNdSc>Ung0@%S{46q}e4%t<+crh3O@u z5|{{Q1vzRWpyMV(J20Q~LBJsBC}6|x{O4MsI_PlBwAK12s}mC+Vd<%Yn?{b#E+ycY zG~=otGk<^VWXfpdd$V6zC-J|M*lf2dCU3^hoXacC&b){y~?nt6`$co`mKvHw=Uator-x$ z0l|NZIR=HWo527~w*wcldS+~kA=PjV5p>V@vef1mo5RaR_vb6z5i1o*Bs^#Hy-v4S zc>6T#`f`fN8atwc?WDa!;G>{Gpkk}TRks79#EhYY9MudqJFy2(jQ2w!^p2r-SMp81TB_ANNo(^pWq_8-A9x&rMqy#V*9`QRM zYe)!bus?H%|ETxc8zJD~`-L(xe)@krnCZkf#B^-CDofar``C4PEz(V}BoOfisYW57 zh&#doRO@3_wNpMZ3Um4OT6`+t-XxwRl4UMrRufm)QGc;*daNCRKR3UaY*@SZjsMqBvv>>gSP<%Epw z4P?x>oXyA$S$Mn)u@M&c<5z!Un)S#d_iQ8ch`z+gr5@`Lma9lZmn>~39Z)Lr z=;d1wVJ0hZ=@Jw-ozp(NRA?yXeIY!8F-f?8mmf+iehL6ia1r*g8JIS17JyFyz!YhD zJZ8=%@%|lmMoyvT0R-dujd^1_1LrLJrOrt52)Fo;Xhe72n*}{Wc1SQg>XQJjLkZ$Iiq7wS{VB{5YEtu7X*U?q0Tc(fCvgG<0e`TxgGgZu zI`tbBi*Bf|SUHxYJ}=i7EUAe9n6rk41zCdjP2=rFap5gVB&mm`^&{$8 z_@+KCAEQ#5@6A)tTbB6I5LZp~gL4Q5zbS_&;jYmY8>Gsn zFR~>!;>EO%Z^>qbpZ8ZY+<(MVrC$mS&4j6=+8m8~?MU~T?}C|U$(_#{0sPf*TjIEz z64Q_2c~;CyMjG z(g-!n%#^grX$YIJNAF#|-2>ucND=i9qGw72rhx9+u1ali(HN&8eg~vSqyi4n_m?np z0v3O(P0Hn5^W_~Br&lDaib8P^+`J|i2GH!8e&_2m<#(AsU5eSjFJAn}$qnvi$-~3{7!yFjIduW3pTNZoe^=&M%qXV*9~ja|Z0D{}X~3 z>B&fKvJ*JsRfm@`&T4Ri{or&afU(Bhe?-el#;+^vFPO6U?INR2TiyJFT5G1Rkwpm9 z;5L=w8alHpN$Qs=vMVLi73NV@Jtg+6%G4b|At`Wo)d~)FYwKFVEN&8(WG>VMuHb(| zwt14DSfFKxAc!Jg*ovgB*+$%tb&qKd(e&8iWhl<>T1%lc(v@xQk4(SS3y_~<1)pE0 zYhg6NBxXK^!kAZ}*N+$TW#!sxp98Pzs>r57ofK0^^VS|;vyrTpgg?jMsq}--$$UJA z%_!Q3jO(yRcnyX@5kvRU<$$&O*MDZUlbmj;i(G#q4iTD+8Yj%7n;@Vd()kC z_0z7PU&BKbBF-3$rinu&vbppYYDs5|ruF;G!xJa{WNTelh7W+=&wn`4)X)_n-{$*_ zO>3oGG84~->PXWqy5Dd$E;`8D9ivUqKB5%$8;XP^2j z5rH!L#3EJhkwx}licmn3zh^rQj8lE~C508oFVMIUPsF!*D0Po;l_A|i2&7=BMy z%(OPNce{g|_Tonegg_z#Lnn|{bJ9!0zGEa4Qz1d6A!~i9q+LgJeS$N8cEtj;HA7Yn zJqRUR?z9opG!>Me+ZSq~`HA1*6fopGv)N1#<7G@SE3Va#Lb*0@cwL&LI`M8`X*q8- z-MR*0n7GeWYzQ(UxOjha+p5aaxnSQH!S#=m54{awHLVFdCJ4h@6?znJ2+3pH{mo8s zNwENGfKA<(VN&Pu&_U7yh@XGe6P?^tMMAJ`?Y8I|`$w6UzuC2mZg&-6|Yq>-l?8MVvxV#gwNv>>e4cLllc9_SmK|C?~gk_uq; zgZ>!5J}*xM22y_ok^fwx?=ZMLneNVnWn`0aXBA)=PZ;90n6hPF&Y$-t|HL}c20q^B zS0iWk?bRFKfx;*LJzIS_&u0sV>XK+wmDc&Ps_~|yCBBG)S*5#-Bwu}NW~)M)7#K|b ze6H(&C!1{`apG5F|wmcS`RdpUtvRIuk zpY+WEj-5AD66&$4L*sThQBIHmO~r#g4d6&ZOk^X6uK>N^2~`? zXgYbNjFGpZ!~`|U#+wN#Mzms4_-RGOj3-vVL(WakZ5Vp| zx5|G?P?2Qu(-m-zQ^uX>~l?~u$p7%5VmkD#NlRRC7xH)7p1Tnfx;&(N zN})lhvG!BU^HVqfzf#H z&1N#FPiQ$WbaQu+hB+XkA%CwZvE~FcfUke3BEwji#AMGOG|9~0wlk96O*hzPFiG@k z_r&@6yAj*f#%Vhs7r$_$LBP=_RO+jo;$<`crZc@h>KC!1Xt0v# z@0sKVbHD;gPcW?O2va>@fwx0{X=XHoOBxE-4O|j$QS}Jf+>jaSE&HSXi+b1r+b6z7 zJH)p8F%8=asn^0Ui|Ns^znOo^(dZ8XrO^mgt-Ga|cPma&J)=5J;b>i%b-m9kD4!T? z5Rd1B1-Cnm&O&HJShFutUq1xKrWfrMjB)|41OT)r;fa1rfoD>sH1@|m&l6h0uvEg$ z2xliDlMIbDmq(UaXVuo}?jWBP!!yw+tNn!&j;CO`BJ2IA-6+yVr8R$v8E2n{5AfR# zU(`dxn~a%R*zUMjNf>{(ivSY^PhUm|B96O2cp%Mhs&Tc7Sex_^54f%m{`$giFUm4gOq(C)Ac%l7z31O3KFUfb#4n%p&j+I z_2*XlvX{Xp`}D~q6G0r5R3qOwgV|!u{Xea`#&imvb0~Sm|_kxoB`>TF*7$KFD zVlK|)nF1#cY-v88i)usN-29)&FeH4WmM{*2?YbHm<;FUJy)}QgskH+lx%$&?P{l?x zx&a=Qt{ne2sS&huXOOGpEv;&7JwvXg0C3k`cb1#OQYn|3ETbkk%lWvrBCux1^y0=$ z>oU|S_j#%7Zkl%B?SZ()*w*7{Nrvl>W2zx`?V*i$CWADZV*bm@EJi+RruQ>(GqfVu z5EWTVUpWEBj(mUK#1H4T`Av@f*hZPv5IO|AWK82Dv<%`m-*Y2Qym75HUkN_;A7DXt zE!ML@lR4Ef+@;UJ-Gqy2qA|%EXBCf{4LL{e`piRNF|=F!-5;h{9C~0|zs!#BdFK9# zYNuY=D~;A^%{J`Z%ynWj#ievZFI#9#oBp(KL*o+dynJA)$EtkEL_< z0BY)ACIx>U|IQ4^2`aF7)0qlPGWdm@oB}>k#-x0>=yDFbEWV_IKv@XE56g>)w>X{$ zUD>ShzU%Hgyv6X78TIUg4uO0%VXo#@12?8J4d?OdjlpAE zUDc;Y#XFej5*?mj#4kY>O8U-k$X0?btC_*Krk$!Z8JCwAyw61(s_4|dkT_jTBQ2lMU*}h+BcSbgBT}V z8%5qcT03YVDqOTcuvP2e3s7JAw_`C^%SQvZGB~O>%Vz*b8isG*44gH7D~6aqyF)fv zjOu?%2m|1TLctk{sGYsUv9Lj7I?OUO%F*2u*JijO+G81iQtkWF&(~|sKVkTVlaH(8ciD>E+3j*w zpaK0QwBjke`mpdhud|5nu4TD_ZcXM<8v}pVt|^W;@VpUpt<1Dn!bE?3s|eTf5(e_d z@6NVV5M}2n!)8hWN+7+-lC2y(A|ylBjThW~eWjz39S=3Aw5%wrEm%{r^ZDM^3mN86 zhj|RxQ1L-nZebIhM!FiSEX&F?IN0(XL{z6{M29d}LZ5Zu1!Z@}3LDe!;}KQ(_t_ha@`gOKnG*3S+2MDmvVoZ8WB8Suumua+(t zr5Lk1n$-}0gDadE;OfeJ+gMQw{^(_YF5bBjdtK4w*0_GUs+Mz;F*PV2Sv&dD;v9TD zkb2;s35z2V+pu6CB68RzCpr=dNB3C3AW~hHzJ&-#i zA&afz1QRBBB9+3^q{8z!tvplYycdskXyeyxvhbd^^)s36`+l)YgreMXAr(4a=i6A+YKhlY`re7Y?_s_ywCG*|f`A{KkNRLI7t;1o%@s`Ov8tB3XZjam_W@e13hh#8px#F?dot?_Dr+HR&jNQY~W|Jb>J6!S-s#e169hNDCMgPZdKP8pUzR0KArTf zf?B@6+3uJ|(qQpjwl{w*3~xyxPU}DOAh%ddk>9KIJ9#6bP(dG0H!xUbm4|clRr@-X zwoz&`683|l043ef&?b}QRU6MV7fy;`0+btcG}f-K>ubnTxM(2W%*2T#-RqhOI(0Ev zTU=$R-VjzPdYkfaD+K#SHrMv?esHIwiu#WCdpT2n00}q7-OGRAh47a8(L!tF=XjST zG8C=d${uax^EW;&HneWbvk_)zC17n4a0)W(2`5P#Vh?X+I1YY1>^`~0`GMF^qSc|N zcsFY>u6zf)wPNyZ>ti1W!CZDP{YKdjTT7**U7`uFjAzv`KgM{Ld~%!=1x{H2TR}6C z3Z|I3OtsfW-mrf`i)h{^r@?j(IHgZ~LpH;7zs#7a?*335k8??Hgk!5i*zjldZN3a; z%2D?DUAz`TTuake{CUKh$M$U__yn!e?PhJjJBR?_|JdwBMT_1wF>Ndv=ZRh7=fVg4 zaNKqkdSSDcYV&zWynHBc~tQ~slCp2NHb;N%#)TW4Z5{FBhyg1t9qJjs! zA@7^@sWODSZ{1Jrs9D!*RtrR7^^WVg_gCVThVX1ZV_mfQ0f^*KDrGIS3q&r2Mnu+v@hx+W2Rr zLX!~jrlGG^1)c#O@c~cA_28I2N7;S!R93H>y*kq&7;7iS&1VNn&$bIj@hrMbDY?qQ zNx($AZv^|9&V_Ypg7rOXQi(_mz0bcYsP*kRk-&eq82;;Z-Qb315&#-Ketl}8zB+SZ z{7?T<<(%`sgFW)wQYMx+7Nwu>(ri`dtZ#8i)?MU#$EdmfG3as6i)O4^=XJ@)3l>Tl zB{5pnUqW2VhSmRR~~218!|Ec zEsd-7+O;NW$GJM>1Iises%|YTJpr3Z3bqApjuG*<{;~LhOBF+F5HgO4!j-3Aa z)X3z1{A*PT6v^yr7ytY4ob%x~YSb#ZHne{^MF^R9?=TwVTSfZU=B9Ft4-`am*xd*{ z#0@E@=evbiXo{&y&zZBk%j{u=Gf#JB*&!yF9A&4Q4aE$@FkJkoS8sYm5(7AB_9nQ; zgEF#C+ASZGF=Wz^5|9Va_}k~u?y9@RpH!K3yi4j7GfNK{zd=9hz=znIX1AIxopUAcOQFU?Kwf zWY8UsaS8o6POro4X_uiE>~6iHG@F0A7 zF(6l~({dG5^A8+T(#c1ib6^GZSGZ)p2yCk#-RpnVwGl<4 zu)F)#j0qrNVBG{$_I3M1?tF8+{r?mhF^v(;PO_a6FvD8$@n_kuBHcYfErm$$3{3xf z4Yn0RoZaw2Y*9B4lTjDPeQYd}!OGr6wyFMf=9N=jKbZJhD4C}^YchF3DZ=k~OZp?F%)C|>>#*1seEMNTq| zoJ}Tty1SVt&>2I3-CINycGj}LylH;xh9od2S9*eMw%g@oeuYIsU$cKi7#)Y`ev(ht zrsGgzCD6?QYlG#mI4!FAMzu|G=%|XkE&UilN-6XGbqlA)lcLh{tL4=6|GfzE71GxN z!0xEUz>2V~=cbNR2kpp=Q`N&8mg`^TP?n>ChFiN`$8UZi)Mo{A)m+ay8Sflw?xs@~ zPTJ={l~==?u|>Lu97welmMe{D@OpF{(Rx3Ee6vJvU8& zJ2GKpF>5|Y-lxOnnZpD>qrYLj#{89}%BYm;y+31r_dF_HbvsWIi`Q+d9U%Fxvk55gx#BgG0H|l>6_3h0`(NjZYfMUQC!T$J{ zU3knevoGGK8d%O*AHrk(tGaYkx?L9}g{Onx9D<<33hO$%UON+{@wtY|UjGmp#We^o zT*PhXVRvYOo_%_|Eu7i9Vzxo6NXsl>rqLp7*<`oFKiIq*;8#Nfrnx&d4o>WxcHJIw z1T$jilO})F(kV>0sKmtZhaDtnccRP5MV~Bne%(p~V9mZrB+rlTYIXgOi1sT0^tsJz zPK#i+Ho|z+J3=psb|-kFv53-IdvTiu855^rp(n5I4(1@|)A|8}QgY&EZ3I9^311~h z9{i{+QpU;SRdMaw8%*vtqKT%lbbi$L4a;w8&Afk_&@lekZ`K)Ol~56=%uI-|&J2<= z{4Q*T8)79gjw0$OU$iE+BZXCuNoN zVVQ%(JiWXcwm5%C?3r;qns)RtOm~dT=twboB5cT#-UbC}CU;kCazYsJG=CX`!!&Y6 zP0k!KPz-6NO3_U)^_3UqywL)ozL2QZ3G_q}56O@3&YOyWZsvM!w4h)?<+}X<`OtrX zrR#o5jKwxkuE5d9G6jBNDG{Jq+&qveKmEV7kGmDpsn++=U_GXbe&1%@e+zOl5j~^> z8>2}}H=jd^ib=CYr{S0JP{2GtNk{t8)Y3X37-JsK6#rx?tl9<{Fh2IiVBodXv335; zE)||eOf|05)8F|e29QI$u~ub{K4yQ6VDcC89uqFeoj-hf^cGTRAaBf>Pkd;`e%v9z(E;BOIH5~xz@bz5>9URG-|=gO90i1s5y%=f9UX}m+o zINsLUE6p6Ql?$k55w0=$x1*%_?Jz!@n^;Ckc7%q`co7RV8T=nUhUH@|+u?tFfXAHu zNvC?m!cffkjkKl9if*x_qSsL=s8U-5qz+L4ex`3v7DZ?x~vDxFesHNhG`>RA<+f(sA zp?=$`<>1T^*S{3IWhEQP{R2F$mp@H1P@N4ni@!)$9c= zZ1QXP`+&HeHN=CYYAFv*8#wqC=k7%QJc2|~9{DSD$_xUQPPi6=xk=2PmY<`p$8nPc zw};WxN=cF~lp(baA3e<}l54SI z=9-W&*oW?Wxn{DBN#DA2S38ZX6b9cEXNdU3qjXmV(g9+B2$p+z$^p$pR|@AkY>4%# zoSx3#s0aBAfB7!LM|CK<03WO*vM|)#J#tRTH&>l$FgP4jbk3; zsM84qV|{-%xi+xa1~zEqNUJ7uDpzSDB%M!+)Kc!9TtZxzs!S< z_U;w7(QajsG{o(Slg7!z={TYDxWBi7fF1wXN$pQzSXV8pGMIEMh;%5ta!e(rbhKMI z$#o>NJAMg;u-J-3PGec+8bPwy^v5R;0iW#v4h2*s3P(5L<|qKO7?lzZB}Z9F|9HkY z+H`+MZEF+QM^4-4b{$enmQIwnrmz05XwUZ~?ocEXp;`5Pnk79?XAxWyEAf_O_TD@Y z+4gWQ?F7Y`QUbBky5>3Fy)Zk()lRF#T$(}O;5Ce2lHx&foJ zsQ!Dj{lK;{JhN9Pb|T@Z%aO#^S?M2+JCo^2B(jM~(a}g#qJ%#PWaV??c*+ftO6uUWv{qiOH(_n48a%rwe{no zT(JleweW99cv@P#upgsDQqV2plc*GY$wy$zowv)kw5UV*Ga6s{e*eEg>CsnpvfYSt zlR%bG|HEYelYnjC<01L;r(u!%9H*dImc5P<73Vf99lgp*d1}c}zeD!J6qvhK_atfpU%eQed43th{O)@pFr^f3Av~S zmZ}96nX8Q2$<9eQV(Ql~BDH37;+AJW(CgAaWkl3KBu3(t1BB?_iSieTcy|gYevIY} zh7N6h{HIV6K$pab3J<ZJl}`R2X^egcP;Dku>qdOqvuC0 z^~kJTc-EpJ-6#4_XBd?$e&3rqRxzRzVycu$YVL``UQM-AR^L*BAM&btIIUN6Oe0J5o1+U6&#O3y0Yn)P zUyezNzVje885w8?l~+G0ZsU=BNGAP5fB4ypd$BXZLR0H?-XtsR00K*edf~)~NfJ|oUe+`FUm%HTCs zg2V@<4uY1Cnw$pf}jP&N>ac?85)F71v8zs#icRRGAb#LrW z%85a`tGVNtoeEfh{N?g%C0jK~&Crl3@^F_p z7tSOdZqoIxSNXn3HWIyA!(oHqxZ2$`d}i**iPD;GrFka-0i3OCQa*uSF=q1#h&&Of-_3R2+jVxBN zM7#-2Y8Y$7-wT*3iD(Fwjl9*7Q8Xa3X3y6KZ|CQR(uOa{Zg-{=becVCQ4A=UsPt8| z-BuFt!wl*tdH+K}Tp)ttf9o&|r@5IiV60*wd?+zl=Nu?)4yJJGxv1+hC;3sR@Cs5y zst2R_b+3~wv+|R;Wo~J~#x*EtOmt;s{QrtzVB)k~)Btx$dlc90zxR?xphH)3PUj}V z(Ya@@UYIm&N9FAq&8>hj4KeOVaW3Zq`eB#0_j8vXI(6~xM-uHxUA!Oyg(CpT7xkk3 zBelZc;~h4<;+AM7y45@?A^{}+erl*;PJ9Qv)%$0(m4_-$!ijhwj@v=y67ue+?0gF1 z@Ec&mtO{0Z%kTFu1sCqHm_4VX$kMqn$BN)n+Bdg1n*wwJP~RdO{Kd6Q&m(`>-JN1g z`Bz|)9=K-z;Pz52VIDPt=yKPHBiTzywbde>23U@~sNhLJf|CH6C1g>=A z3P}uqP#V60qP@9^mbd$y0_6dJKt;B%4@h2#GdWN+f>NvcLK|Q{vik7&s7Hr{Dm0?N zXxDgVMu$%h^sc|;fprgL)!+d&q zYJd8M1W(TOe{Sqy2~As4!rFV^E53D#k1HcrMed&S2?=W)oGO|(zeyH<%FqY{UN>xx-Mv0P&&| zrHDI!RtVOi6y;j5{jpEv2Cb@PQ8xhb;Jbr?-=`W^57RJAFk~%~aVK8(2-?HwX><xg&TyDYCy$D`r_{(dbjYJ~p+dA!M`U?ufJK zu9PV1XjS>!e@}@Ed$irGrWIJhx2Bp)zKV0=D|JuDwfp_`T|F{?0)`0(nUCr&;8P+a z2?**EvD1=B=i;SNWV%JcJ^4#Xs)32eF+1Ff$DC7$@T>2_aNAb*%Cq}7xmf1b?j68y zt5A!Je{O%W;i`#f3xH>q{X^{I+_d=QrpR1R0=TN0{uI+)BiqIxB{bi>sWeJoZ4!E` zC9tKDP=}zo*a=L3FdVM3yajv^(p~9;u%VUyR59${{W#>8n>ucrl}c7Bc}rg!Vu@xifm((2#mpTT)Qz zeJn?#U%PQ=fnvEYzT5v#lG>7%IK$lKbCE*)tsU+s6-o$yQi+W2ddjRJ*MG3Br6Ne> zy2Luh+eGzgt#56hUT2Qsy2n6i;p;esu5YF7Gh-RRG}#tZt?-MXx>j;55Z9q437<%A%M?!||&(AnC~gM9;-v{FryxWlFS%U4JMvNVN$QwnDVFsZrib zWu0Gi&^?0e@kot_ZLLz0eO<*iV`Qw}y?-TI+=TEY^}Ok46lJ7xX6=@OPKS z{gWVf9UG7b-AxxF`7u0Q7kaTZyj@&kmQB6A``iy^duX z8A1~Z3L+j$o-}d_oWwW8>50e-z@x%(k#64Eu`O4{L7S};>9%C$-=`Jy?5eW(YXPU| zYU#(D(c_S5qXn;9-HoyeOb08E_ls*WPRIypnFE6Z=yU8_IP(OF}YWN7n$ zyZo$?(pj!MnzR_~a7&Pn%|oy2ZYQ{81x=g6h(}$F686O)s{Bbe5`6M~9!>HYP>BR{ znO4l_WRk}ZjK%$hPGsD~1#5MejbKPrv)d;wbIm{Ke(iU=M}}4JsbKc9k2$d{?;ulu zo0N0*@&T!k6nj<-YDY{FfO6f`QddIDR52%SPS4w|+@#GnH282eSP0u9tJK_cb3C8{q14VVQ!|*) z2B{cn7^2-S=jpv6+IneF@7U7dG9Ofbu$w7909#vq=lV6&&Zi`?Y9IZ-)E-8h3G2FO z_4Xw-<*Dygm=e)Oj&7 z8)ZI(EF`h22_&IgCD?Ud%rVQPC4O8})mB{$cBrzDt~iMx-?*X4_3Y5aV9`5&4^qL8 z<%%PW{rwtamPL|v>P8JmfdNYaP4h~>Jc;Le1H;&|u?*Yb`veXE%YF2J2oBx8=z{#Z zXtZ~=W-1goY}_uoP1-#?-6ZxHt>LWLKG$2E3s-9`rOvJB7Z}%;v0OpKpNW9r5>@vB z<*pwh)sMH&O!j8eqr|roGl5ipS~!EqMP+rXfuRkxz8DT*Tt2sE$5$i(p|aOwzD}3W z4RLFYih+}VQ7_gKt{_pWUM$!ohZ)ZoI>6<$QxjG+?{+Fy3#K6NSI>R#W~)5-g~A2I zmoNI6e^08_&8P8FTGMR}X=tc!419KWOGHt5V{p5fDujc z$%)_?OXGKA?tM-yTLmYl{==|dgmSux;iJ{#AQYH^-c3ktq-zgjWAz|G;`s2QTt!CwKVezYB@cA z{Js1uIKdDJF8VXgfGN;_#Ubp0NrG(@0OB~hEVr?zS&M%l_%Jgqp=gKzzLt&`H1~~I zef5I?Dh(ksO5_mA`bNQ=);+j{C{1kKmBS6+crsEQJ1RejCxA5$xhZD{f1z>7E~_2B zVJ<**b6z5=IzaODs|4>=y#IvhZ(eEs`WvKWl&TTCX?__E{b7B7#R+{bb%wI1;_@w7 zuONP=m2qn?nsh^~Jp5C`4df!?>_g$%kM=__w(oOA{Hi`gvZsf`%n!0X5W&3D zqLE)1vSV5&YE{n>Ic5vM0EGgJ>OH^&eo-KQAx?D*^7KM0IB{XleK;N#ag-~*JASl&2O&JV0g?za@ma|;9N zkc5EXT3EMibmUubwQ(V~?9nRn+MLrxZ+uou|0)V=sbH0rzYeDu{ZJW5HAM)Y-eLmXD<&G z!Z>?VW$jc~wX!=Y17poRUBGUgFgai>BCyfZVTa^@I1f!b;16wVzG*I?PaWpB3_s2u z88}6{atw{$Qq>soQd+?t@O+p}a~9C81{6;)R&RpL7m{^BTtG8Aw!VdE#zfILe{ogf0xqSKR1&}f8dZ&djf zoo|4Dw0l5t#43_X65E|6{*j5L72F~=xP{v#uOtVg-WU695~>6Zssw}=^0p^V?xG94 zBeMs%*KWiyEHQ7@&I=vz0t!RtRY<>3OZS`qRX%Dh0v;xjMVn28&7Gi!EVvS6Qr`@{fv&;? znngOS)Gjv0XFm_E;yYvL66yu(MOSSvo31L{i6k}uDJR)1ESy*5Uuz7!Ek{QX#QXSv zDoI7t&&yh~YOV#-9=iH5Pb(wB#?yn>8tPI zF!xOoHH*T=l%u)EZlSRJ`%j2fpj>w4F6)Q8bi^_^I^@jM5ySn=+%x^oVoVVn;;pl? zkTGg4v^EsVS;<3PR!=<166SO(Zv?x4Hhv0D}i;$5Lh+z1}Wi)ZBa0zg9i)6!b=o1aAfg+t+n(< zoH0qtlVXcah5X|R!Fhwh^Y_Sj0}Gq0(QiD{Yho!r3}V`Wl^V#0U2kcB_8lHg6&wn3 zCCse1(SW^ZxaijH;J62OPTheaAgICp`;lhKtZb?o`hkEc(iiQJwWMY~`=P{%oELVz zA=AS|q~~EW%3utAyAD8%kk+k#vR&Z>9Fx+}z4POtW^YolK{-lQD<0@ZPswE*9J$eB zhf#J()QfEtiX%rcjehChQlEq}1 z8(ESFktg&N;MI)6#|(dQB_s@$fQMDQ&#)M{W};m11fb`G1;djuP}o*~Dk#PWlM5Q` zE^=SLZ=c*kNlZKtu)sdbE6t1Nac&7}FMpZ_m%R4Jy? zar~On%WHwd8Ye5DnQJ!=Gz04_IOFrk_B7m`5L+KTT4xAMWT8W6Wy_ZBguHm9@&dv6 z%;&A!yXz}%RzrWZxvsZ=0tXt_XKfllY46nmRHHZsOO_0!FA!d`F*Fzp9EFQo;yiZA zT)&y8AfL*`(?>MK(Jm?B|2}vR!7V5Hfaxq{>2y#`!r>tzw1_V55J}@`*ESPx%9I`j z(RL{E_Od-Oe#j2GPe7f_d=CqBwS^~7d)+A-(K$Ra;LZEc>IM9N_|A(;G`B8G(^kB{ zJiE`QH>gQN9k6C>GTq5;T{a+i#7yvb!W&VH^Hg_uF;Z|Z&b~5m+}9VjT4Z1sZ@$=y z1cFi<>fOOmFr{pu=PnWONmoBG5u|;|5PD6;WrN!bjiNp9kUcdGNF<7NVOUaclRWqd zZFlPA{j>f48f=GuZxB$0QcaOGGj4Ft=+zFSq6@e9e&J5@lVeY(#z*M#<>D?D6S8UW z!cVLL=6Nib`q;tz4rao5hOsTe>KFURIK|+6W*Hj^Akf@Ldf@+Xe^gxxsm$vT2f8R1=qw{ZlYVYy| zO*Gf@L|>Uj=}cQ>1aJijE)Vk36~WHF(sOT`5(_pjrdg_)7S4tl2c)n;2n3+p1nnn^ z)*L|BU?W#4r1QeZMZ9(U6TT#^c>m9-6f3Joq1v_$N? zZJ|cL*IF zjO6%Y6g!2L@d+Q#D#-T_XV{qX5e|j7jn~HmC8o4Q^m{#ze{0R8U9*syumQcRp6lTJ z@@NE5hfYp#_g+K9+I(KIh~FBaGHn`id_r-qSKH*H)6S;#T%&j>n$U4k@ z#JNbD*H{_2%mkD>da{mox|L)|xUW$s_ykU5^`l3zv4_mlJ9c1IQEv>twXLU}0uIq; zXhL0V=LN5de`JR+Qr{%?&sSSI$zgaoD9(v`U>_J&VZ{twA=1X<6vWpRs~@NyG5%A$ z_t5Yq(7)}aM*Bm*N6`50X*QS+yxWV-U6aYtfEzU%^A{V?X2BO!$ zs~f_#4kw0JFkTh3K(BYX)h!^pJV1h{B4xCNNzf_yV5#@JM!ZL<%$cmh$eiSv*#3>n zm}|CeWL zqF7r3P34b6Hp~|sn62S2?dXm(pi{(O+sGn&jQ?wSarJL)NZ&38Em!;+hT;bMGVq<5 zIsw8Bp~!&!QGbVf#MvSe_zmfoE-f@9Pl;J) ze_q56Ic@>nmCrg(CYVP&QHvw_NcnoWL6~_3C?=BiqcsOww*)OepK*SZQqh#a13`)m zW(VYqMEV1ei6!pMC6+^X?(@*I+?8H;PYaR|dvJVP%#AdZykE`woj|qdC zm86wJmOPFg&ELqI>!%t0bi2XfZtE-wCQzjh{AQpq+}ct&i>DUS@nsLpp1Y(C*uVV> z;8_WUg#l5LiT`T&pP-ls$>X%{f!iCdAo>NFkR5JrF!P=%_`h&$W`HR>J*{v>f5x4| z3%|qEldVN?rG_BQrzi*_d0iEOyOk{OTccWF_rZHI$B zy+v}@y1C8ECQPv*(c~jQZo(BvgWhy8;V)@fCa9@$9Y}4vBlB$a5C4UVXz0ZdAH7cG z==Sj%1kngnzdG!gPz1f0h*)7zf2-sh*){DR{&;b}4W7lwcWnw=a=P=?Xsh26s@7+I zyy-nvqM3_sjK>7;*QlMbY)caLh*K46`e^)7sm3Ka9^DjDrgq6u*5AwWYARZ_NjCjvjT!Z`Qr`Ry3oVTMJ)4;li^!b2)IOmmO(!wIi2`-y|#kwsSw@#_J4T}sZ6Mhtm&2=XH{rP6ZtbwxE zE8q8Wg&ZND=+v?;4pVSPf5vmUEX|J^j*^56(0!yCJzKBgWTK8AToj7~d^-@6rGo>H zA(f`QFNl2(5{6ezX>1mCQ96nlNey=O!HSn!bO?~ z$MPN=c zx8^|f!Lr&|dFR)N)Jj}Laz$pb_v(6Oi-C}JaA`pt!sEXrcscUGl1L8Y)f)LHBt=qV z;32{PhX!=Ikk2Pte-HGvvI*$TqV>>C2QhpW-C1aOQ+#NV7(oYPOk7rU1p3�RHO` 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 U0Hg_i9h>7(Kmz~(00045S}b_<_y7O^ delta 199381 zcmV(#K;*x$+$W&hC$J�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 z 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

      3eWG3=aSIUz_2k#PsG0p`o}Z*^N}Pk)xs zV;BLdVD-l3C1R23A{RlsduFR!zX#6;DD6`!DReQ|H34boiD;QUo$s448P-|~lN*+fKwH&R{BEZ= zhBRSAH=%kiwz18|(mp7Du3vu(SVswZxe$P1)$T+tfH1`VecW|Lb;l1y$bHXTk%?oW<>A-OaH6xD-ONF-)h=GV>s4uWd^ z6kPVhpofYtJ$xAMS@Z?=g6wPRCM+^%g^3!v+J6!Ljcc&B2jHzpmQE+!cn}V5$AFa2 zty?v`S?@0k`*0sFbOH8foqtE9!&^9ne)-D~j3jxG$b$XBqU@tNw+c{A-GJrRygU94 zTxW5peosR&h_WlV+QbiddiaqH36LsySXqa0$$} zT%^kELJnyQKm<7KN}Myl1^RyNedk=!0fC2@Zu)_c$|uPw7Y{fJsecHT8K51ITLxzS zT3g>I+&+27ewPJQh=t{sBf+`YNB_Imd+i9OaA{(rA)im;6tTRl^(VMYui|Xi|8fVFq7R{F`9S zaQw$po=pqItsbBOQd16eS+twzo~da@w9kNEk?VVF{zH$E6IE%hX{!Va&#{n+MX@j5 zL!R_F@lMOnDwzpj#KkvjYPWKDrIwObv^;2NC(hK9F;!zATYo~gjh0($W7N`pYR$;^ zmUjFLT+6QvLXEK^Nsl)3Eu64XVm>+&DkG3Q6R7ZILj|f8h@h=Bn{I9>lq+$$5vpZw zK}tMDZT8m}wOSMV22an0S$GM;-6u)?7&kzgrb0ZO$^yk`rzUq{oL^ontEEb<;sh}J z=z$0#298%KcYoNk1g+g$1rJ4Arz2QpAJnxp{Kxqc{`@Xf$9A5EL$-b0WbpwneHvac zZ_ZV)W_?5QfePk5z97AMqz{_!1dV0=hqv3mF%V#oB!Gt2m2|}*S`Ih z{A?+81)D-RcbKQuiZ1JtS&~dedv!8qC{WQX!OmR8?|*WI&Q63_SQp5xU}VEo9`YZVu8Xw+=FYd0}RaoyRHON*%2*FUztg4DQIxZQvRpKZq2)YR) z&nCLqP=9?m5hGppI<^-V?bK7{WCP@u;OpQ~m;z0M+-m2mK@y*puUIiVOWa&bR!sN{ z_Wn~*mM&?qC;S`gU^wJvT5?+9EyM4WEo#YV7;{a#t~A*T5e&<`*2mx3ntt#sE4xo| zD4);QU`+u^`Sy`62DtZP_<*O!}ns-M=0qo>p z9&*07xD-{V9O&fcc4}Pj-2>RQuW&Bh28mY#!rFn_FoLh!OtnTd0Vj0fP+fb6&m5?0CQCdUnCZIHC?}l)-dLL6pcEFW`G{7!+T}yYI4H?) zPZMZHB|h`xuvOtg@Z8w*isU`qSRw`%L&m?vHmiSw|>fZD4_siq9y4(!PO zGMz$}Up+XrMGyaj2Dj7YTWWod^iW6a$bT0ClP>(wF+2eKF2@-tC2aE5J=}qOCFw0^ zL}RWrijFC)>T10CdYC#`e%Q{R7(IcG9K=tw||TT zkJADYW4Mm3H);uNCQ+Wr!-x@-8>TV(K^^dHFML1Qz*jkK_E9_1#zB__(l zKG_j|?b5&gI)#{}SlzdE0!J%nkXNQAL(l%@>D=PvgdHB>RqxU`SEo8+_i35Nn&qdT z$x!qKndDh`bCK+H;B%S3k=<{s#8UIrhbRC)*5+0Fi!=*KKh26x4N{526MquwstBDx zzcr1BtN3_ouOx7m`=|tnAEuCi>{YoY_j?u^vKx&#;;_OM_ts$-1QpSzI1& z1JcTAD`~GN;-erk{wiKvB9A=Ld+V~%%JkFEJM4i^Q9@;mq87?kQysP}gU@ISLks&| zy%sP5-i!J-&9ILOKfuQR41W!-6DkGa3RanNl;M)3+09Kco{~-%i?04;Rmht52Q&+G zl0|$EzHiqHAi)_&>7^ic1`zc#>D4rdR4)`_h!UK{qO#bYNR?E9-ER`%+VznlxoP;p zc{-5lH*xojt)_;|*{?*31^LIj$iKTQG zv7d6f*~CazN=x@yWFDBIJie$E?5x?OjZM~fkF(O~p>P}A99vYIV~}2Q{iqqWi3j^5 zK`LS2)upoFrwqWIHh&Tg=W5V0Gt}L*>|RYuf{^HB5=5LlMDddSqe@wMMst$9W)jMd z^w4EcCWA(XTt+X#DqiY3BX|&P22E&nsSngO3UYDWewr%Hum1dt0)7yueJc7yqXY4f z{w}oiIQ?%q*X!=J9NAHXPqswZXlyv@aN1ldP6Z1+zmI(0%zq4lkG7u2i_6+>rNs)J5`HX(5beb1)kv~aV{BSHa@UUGSY+X=KP+xva}T*3Y_ zwRFB*NId8C27gLa+5p1(nYLuoyt?oA*n$c%LrF(U2u942+pqHuRkC%$;wx^(&2B!q zPn!kzzXc<2>FTF7@F)8Y#PdfV+6sex2O#_u5vPi$@F7m)fKBAcArDyoDc%|W(AHuH z!M{`^=GE0sOkb`Sl3aP39gc7kx|8wKqjkGY;}=X`Vt=b@tPCat8`dQ24y4x}e8Zz$ z`5XTt(6#X*VK&F?K4sJGf1lc1z4_I32A_UU(F9VI@_N_h&WZbW^9FJYpD>iyY+#`! zm`vECJ=R}%vs&Cd>~h@GEpl*qjDKZ)gE5Xr7zJN;wWQ`Xk^f*LMXRW zS2`ceqJPjm@=JvW0aGcf_Kt8CZFGw*{*;=@+n_pqzvcs+Zm9$So&@0LSn2OhR;Zq` zkng030+>}}i6v~fovLD%c?awUb`jMj=-=Ko<7>6Etyxke#uIC?QU%QVd86qoWj#qK zVV;Szb0Omu(n<0QiAR{Tk~f|8l49~U1YiA3w|^_Z6bAz7<0r_dJ&21Ur(I{Kv@k*@ zw@zu|iKPli(Yb5~UKO4}FrB59W=3T$W-n3@(fzo+hha94m2&KaN8#XH5MA1QXK-*y zbyqj*l&&aVqJ(O1_JakVw0BLA&o%SwYLf60pUCL9}FOX-Dpx!r2DkpYW!jAiYT4`gCgtgM81D&!%D4ASyo=()u#49v!<@C2)}f zJ-7PVYCt$cZD(69?z~k|koAif?3)N4l7Bqws)Ebu^0JPu*K09Te0#*~^sTKf@FDs; z8%8(nie5IxtfQA^188J7VrjxORLS}A^s@O}&{AewGsHhi7DpXrQTya#&~Ss+8c#n} z>Z{Y7*;Uw#2oCG7QfMsxWE$2e7+4t1^KPU^IG+*aK|2VzX<;C3XLsN-f%z+eJAc`W zF_B_rtY7dMNFO^FOxR1ylD>-#9K5Y7*`~B7I&Kp7QG2$g0emEehNL(42Lwzgtim?o zl?dL)S<$P+U;->=B9XsCT3iXgDSYg(n<1#yySN|Jw;bZdTB*W7x_o@J(5;!bcAhRU zG*u1AZdG0Zowe2pFn*1%Tjp(5$bUJ~0oD*j&kmy4lb1v~Vf%%hg3l*s2*$dSrH<%I zGaJug1wE5sA0+MAHD1;Om5{a`w6VY1)ldDT;dmyGkM>C1YI@H#7+J1d@i_P>(fV_R zKPL-C%!>OPAC$;E*YzluvI8s6m-6QqNYOeTE5^>kUiFrXzDaJ}9- z!|$XBG+dbc>Otf|RlY$6qko;~M!FL`hu=T(?~sK_gd)@PI9(OW5~@o12oxg3d%lJx zO5VT+@-rYWztBaLA1*ewFT_CN(j%! z^F`%af-MfPfL0x)s(COKK3M{f&A}L-Y;qf#E!oNKd$hWc5WznGi7uUe&Jjca#dnFl zrl1^Ri`q$&pe{m1*L8)OG0V4qH>2=g=c;54QeOd#t%|Pa5PIPt#Q1)VXW>=C%xAo_ z+ud#k()46Q6FiUnRexCijMlm(L#C~>^R;Nz4=oo(L}m}u-!J638M^U~A!tVK8!j86 zo;GAu?zxO6l=Mjol}CqjfPX$phX)&43sA2OZhaCSA+W~+V1upPA0{e>?!?ZI<$l)@ zB^#v)qrD_a8{rVwR&l0lTJB8d%30|oU!M$1e=tQcq2Hfx7=KV-cTng77a|Cp4u*lN ziX><}0pkcvUxk?n;ToX(@_udZ%aq=@(jnGl>uejkBuN3erL}e@oC?y#U=x1=<9yI7 zcP|!<%x!%__KB?_4SD>*Hp)cACyqgJ z-@7o9xpk<0*MC&9ll-bN-}%&ZjiUD4F=_KP+n7P6n!|XKF^{2=36m+{`f>f3`>%NY zH3!h&iYSN3K9JV*s^9BE_B7hAg(YaxraXLwRvSQcTV2=-adv-L#n@!0v)92`ogr2dR z`9Rvbl@1p|Ql6V@Y5K!}FteaR+~oE&{MT*j(wqmkZxw$!=mHUr9l)R?y6e%xCp z$+p<9jY#>8-t<2iO)5j?a~b2zf^)$`34T2KMHAQ}&mC|%95}d@wK|33ye-cGd#nCy zj~v_OVSh~<-ZasI^{=>p$v4M*#n<~J$Fb?LB<=RDw=?}`GG#mSJZJNi&+yp*54Pei zHy`slj=N`h4;MY=={PatMYnnKQ`xY}VMMGMf&nNe9~lC?5hBkJxHAjknW1ijtz4={ zP4oF5&Z|Oaqll&^7kzxoW&XeGns&5IRY@}obbnkVE9NmPLfL3d@RhbbcZQw>){`xM zVEqQQK#*)pV(haIV+rbHOZhjWaCULW-ajT`f7n?>C}cs!aWg|j`LXr>YU_swKg}K> zN$o{7o0$ibhv6_T2Tt~1iY!UPCKlc{jHq-mnJG~Gvn%3U-l}`=0tuv-*T3E2g!kwt z^MC4fJ4kWl0+L+%(vg9i_>cH>Qk$Af$TS$In|eiRqnDMRwPjVDeqhhHZ#u?420U7n z(<-VLk~K?ClAeXwF4a8sCsbCxTeI%3{3)w+@~xwgaX=ri7mYnf>?)^nM@cQ76Q|>} zPj;Z%J=1Z0yskdF`(_f@#LcNJ!1VUk;(tSv5K-A(mipw?!*>=11<7fP33$#gs$tZx zJJ}uzpo~kd;Lp;oEi5CZ7}Np9HyZE8-lS3?Z2Pw{G1!q0l~44AZOK&}m3iFgJZ8ee znSH(YcF3nfvtvIcMp~_#2ccqk*1O3pM{}87;p~z)F8}BkO}*7$S{-U*-Fh^0j(@Q< zYxiIVoj0inT1(1wtg1fplM3zMk=O~}i&$&-$yA4O!(X=-bcKS=p(#FX!|#(Dlh=|J zv+anDl5zi%_9P7ZkqT8VWyV^9%xAH8)~0xn87#_oLcbn(+;!~JpW(lm3k^slx?kZ=~zVD%GBe1cei)n2yYl>lD>Daz8fWIEZr z4{}>qTSpR#achgf??CY#h*=i^(A?Ei|0chdf7;ATDAF5Go(4Jt@ELAX_kRJG5t<<` zD&4NpEz-AA*WB6e2M@7tM}V%r>4yFM%ebZ0gy&S8my?>(^t*HmHaTg>#!`n~L-VB= zEolo`o1Ckh)t6j;x=lSWDg$P489t%DJM>>(a&{BSCq8DkW%yfXBXo>2pQV7Szf~!pa1?Et% z0nP#n)FR6HZQt@FltqNidNb2wJ>O8o*u!o^K>X@FQFmtu!;@vJJ$f@dt@E|#P}TTu z9nq;&8qGnRaSny^Gm_`sIL#KTbBF~CKss4{!|HS>nzQWc?>31=B|XLa><8s zv12^_Z03lr27*s?yGB>F9en?A*9#kn3v++lWg=GNIR7FkN6U4h(3rqn23RaZEXS|q zKg!6*Mpm2u@}WCm&OJH&0XCzd;8>3kQCMJnW#MONDU0 zFyS(2E`OqA<8j)?6Ej`guYPm_g-czG-Pn!xWweBfQ4qpXh5(zz`@O?P9!C?r2q;}T zlwMTVYiAzyj$p^&ImmY}EOQ83O=y`cD7$%me>xf4!w(uaxqo)*^8tii;JPsGZ9djF zayj(mydq3cj^;M9ZPfdxzq)`RyiUkeJeS05k;d!hhwP`t=Ka_YhTJ$_3ju_!k%bfu z){+FD2!iKzjl}k9o;u}6UYeujEPN|NyuSBI`|%@WS*!+Zk%(9p+oZ0S`a)uivz%6ZkkoXT*Ci<6@Rsqk1hfUG9Ai`Sp4O)b~r{= ziZkFn%-j+l9$9%VezL}NrNg_9f=Bq(`%`#1_O?8gtM8#hAuOTs@}X*ejH{s9~i=Mc5#Eq$q~AED)KmbC~K^=DAMqw2DHMlBcBc;iB5+w|!q# z1(L*fS&TA$3W4$!<)sC9b{XkiN?=fv2KC^)6Msi_Xx}_`E*OJ z31(QCDn8)miV#&YSm>Dr5o$Gz=1!zaCDcgoY7MBuUQq`gowf{YaaHg%fM_S~uz$ zx_{^flKcMBw`q|QIl?Eat#;Z{bmyu*4j`>5i`|&jRPmUG-}}EC;HUqG zlbxTL=@$7nsb1oi6|1ErPo|gv$;)xz@qV9T1{GB>m|B3p~cr-Id_VK*J%aVb*vzg7b6y4-F4|5pkLkC_eG1EtbfCk z+^D4KlFPbTyC=9@$%2WSU1hz%jN!sqdutl4Abno+RU}aaFEWgRTlQ*5n_s%?=^sKR zzsf!kc~M7TD6WF;bq)<&5`)M#tR~t4jv>wn0zF>_h2%VZ8W;S)vz&nNqLPO@GEB@U{SB zVZMjPMISB@A-g@I)n>!R14;Xr@khX8{w_m`N7T=wgo;lRRcnneNF*9%7tMZa1@i-{ zHpW-qj%G}o$>tsFA^9N!9gpMz;G2xJI}CMfPJo%7nmS|pNsfihce)}5IB<@fcw{Qc z0Yy!`Y~q&8aEoTwF-2+@#D6tso|(L%N%!B6+2(tNnap7&VLpD<5xEijEsanx?Bv)z zbm934vBirHGQ!ZL8-w}CLCLT)`lF~nQbDGgj;j=&>;u|^T-;{fesj8Td z((|1K0oaFi{G{LIp-Lw7QFwLlCUK)%WNb%f))^d+V%Gf5n8NHX)_+cBwNtHc{I0QK z-e^r@W&kowk^sx6H})^Y$?(><_tc+;7VgFw$r~jL^c(*OBz_4P?{At1!KA+_`wHl2 z$$j7e;n(--rhP7uFzF7Ju1s!odK(nK$YKmaIS8|I(N}AHZ)s9adSjEXR8N^Fqdlhu zC^avxjCo0S%5yW!N`Gc*%I4p*&bxzSOuxhT>c}wY5N@H^9YlBg{uJE6r+MFih02yR zQY{0TI2Sjn)B@LAkpEk|AnF1?JPZE~DADHd#M#l3VYmrEu{HoAYQ#fcap>EnoS|ui z;)vg83J^j&A-6Z<1&LNI*M4>vJ8A7P^_-6*r|aFcVZx!ye}Am`^TbEY0{s)b*fhg4 z`R1y<_VFRlei%1I@O`l$M*m_(%3WC>CRo7;SN}W?YbfK1Fk^^fs{mpQzovo_L*c)nbFhOfX7pYwer()BT3W&2uQ1A-`8Su`~b+Q~X1~ zM7QnP#{kUr^?$WKZ&_PiT_K{_=kJSf=ggo7-afHeR1eDgjgk=-R-Xi_Z`>l$8JKxj zOe_{mCI!wLn5&uKS&|asIe}Q3xDkA`#g-GGD4r-x>?aWLM0Wrw!9eS`MQ;6*-e<)^ zQ_Aa#75Mo`xnOAj!3ut|?_>QCtuB?Ak?&_ni{aOtxPQq=(Wj#s%sYYmFX`*-*VQ4S zkr9G+4M+@d1XYmj$>{G0sZ-yAhx}-@F+ULU7Rs+t?uzf+;or60T-+fVBQ7Q#*i^`# zdM1+Dd8mT5k7g>~DP4O^gMZBBcXg_Z_~6qr6T<&YeiAl4TNu>T>|PC-;gu|4)8^a3 zw8aU@Gk;@2b=}$H+i$2*#3hi;C<>K`-#s`J_T7dtOq~O5ibzE_U>| zteQA8pl1*Tcq?r`)*w{%b#kwlgc@=V#TkNW31UG?_rLqTIw( zegY!FzJw(u)&pzhLGp0Y@FND5`r)c#q{a1wP{=EEV9Kg78XzM`VG8#%wVD;M$*72h zRpO2KF;#0j<^EM7{hD$s_Ml;1dx= z7=P{#5cC0*{<6}q;Xat?M)VHz7$P(-CUHElU4RrzB0NLau6!vo>t{ygF~z<_8bq97 zumS3GIKg7hh7uM)q#VKoVA&HQ3`dlNB8tU)!pqOQ?c=R_D28sNiRu5HFGj$feO*YV#(%z`C)+R*QM$CO$!SylaLRsUSKf?GYoN=| zoHo`PKCBb(#yprZ{CtZ`+5(M1^fJGH%HAb!k2ejQ@-$l2R=C@bX^M=1#Pnab#An7U z`LhBz-DI^H0lJe=op|2nezHr7@FhDA+3*W`^X#r=WLv|399Cp-S`8|kww2LTAAc%C z9cxcpjdior4{e(*%J5Ac29&C^CT9lU&`^I&!vp;D1MBbm5x#sImV}jCp#xv1AnR8- zaYz4Ir=bOz^Y%a6wNTRB3!blh76K^8XLCl2tO|qrN26%SwF9W$cnre9P!gthX*HG? ziPQ@5&1rp&ohDO7TLlcH)~PGbO@I6rP=n+^>}h<;9Kr}^1Zf1?&q=nO+|-X9vfDyt zLw~B>M%ldI!+rGx*`jRLTN)%qr(0Cd>1y$hU%MFmFRgS6_gH$wCvWnmAwab66%@5Z zbz5ETH773u!N_I0ckx~oaS&(FQ>5g_;6JDs4gYbqe_a{!L`w#$W$9wzY95QO`}Ke-^f`81uku0dtRR7s2 zdH2meB#SdY1M^<<0>!_^xc!A!v)*I;h5PS?*>DI#XoM1Egc#D(3*MhcRQ6hdf;go0 z^2k-Huin56-d90`<>BiNi$nvl&X(+P8>J*73#$DnC!kTQFRzULK>*&}^LL_#1BP(< zOLUA_7ResPVhWb#-G9E`?qVmW0vW6rg8U4Tyj@EqC=7g{RFZygaYvRPRwCKGtmiH7 zIk0Rtcu8|3`2Uf*&WKpmT3qPc+l^OJQExSAnl@+B?Yrn`2TW`^cC;8DiuHaxVe9D2EOoz%Kt)U@_(z>x4g>|g$owDD~KH_ zx@}%^INi;!6Mn#XNhQt7!yBO2V}$l{McY_TP$*+tQfmp7gj-$)g25Rxb&-075vYi$ zxy`6RO4FwCijQE`WuF7QfR$;abu1_z>WGWa<-2SC>3ovp9`rnjg(= zQOlxkf% z&nl%gL*}iZlxtElP;kg8>&*N$158*4hb=n>s-MB1z+ke+g+^UX+9i&7#Sxb74$vRa zVA%me{&ANdGSyX>8f7c^I*uf{fsy-&=GlvCJlt>aL2VvHNreT|D9QggV-v@v?j_LQ z4*?=dY=6>YpSpk|2VGDlq0MQgXa^7%qC25w;mxSHa1s(m{wZ+q-aG>;v5xwA4*_4m zpMd)*Z<#bGla~3L>O7D&ub6uH`=sBi*qar53R>Jo3&&$dmJ~BF_<#|Q2T>&Zc;2>) zbFg_%P5Zz*B~o<{yT{3dI6t_sNVR`{wA?)_@PFR7e@|yHkI7zfbj_za5-ROz5vo+n z?NF9wQ%11k%BP^H*r1YUPM5*Kr_QbT5-EI{sCO)*=cn?IeU7-T}pB3v?~of*dW!pW&> zCq=lzexeO8qI$AM#XZ)v zlYl%*^?6ZMDz)coALU_-gAwf(c=2TB)M-o zOSP9ZK)z}F<~*Ru;MYQf+}x{C_Uj}>n?1;j35@!g6+)#)#d$mZ%(^9$ri30i_f0o~ z6h#)+)+Gp@)bUgbxoZ#~Ch1FNJJ-+tGfx687o}fm4yQOMj@khp>k9qboSL#)dp?yP`=%(TA=Ocs7Bm>M3 zrWXawTWIS!3StU$|N%AzCtk|O7P=AvWR31cg04zX%AVH;7(zFB1_)vhC<=vEn!3OFG z6+)y&3-@bPTI4e>;LqmHk_`t06&k>z!1O(-83^8Iq4b|HRx0=LVnL)rEU{NAW)RZ2 zb#8}o76G;ZhovhJM1`6m#JJ*4%yv1RnhJ|8igb(D@B^Y)x#A+SuifMSG=C+uCrGms zO~faa+HX~CM!rdk*E}Kb76f`I?VL~$dNdHrScB*6QJCw0C6M={D0_o@SAp}=84l)u zO618`UB{S-T5FD@X-d@mtigijP*TSJTbZErsw)NXmgT(?AOn=w8RjWUsVx$ymh`0M zonf9pHkwot`bdVnY zK|1^(Q)<=FOwmMmgAgqHYl}Ka4m42quT7pYj6$6}_ulEkr(KUBt6K|wHl#f;gJZ8F^956SpxRIM9y zg>zduXGqu8CAkN{b1bBTTbu{mto3N%q%zm-w0R@dc%Z-;O(mF7p=qD`1d4R}z<(9P zwHnIAa2S#hBhz!DNZ9`@fyPdXh$GDW;>kuJTP8lTIwJfze5ej9G}Xgc-i=JOw_*oP ztJ;&!nBr@f73B!w7QiD&#<^+BSEMDfkWC}VQ7jqL22Y8Feg}Z~7G2j96h*QnzZ=#@ z{BQDoZCxChb0QYC!kA)jgEIAgCr%?D8M495(rE2(%AoM#LJGW`Tw$Ljwjs-rHbwC zZcC?TzW2V+j$7lxSLQzQyQ@|p^?0ijR`mk1is#k|EWt&gP*E zbFD373i+y2MF!Y-o0a_MJ6SI}rs)O$DpNwY>*4{A0)H70>c>=G@oYV$CLBP&=^Ph; ztn~L1y2O+G1NFep_q#t{iy2QW;_JTNf!E;lYymf6PTatPlyJo}@07FLX2+^_Pa!yC zqn}N&AzB~g?NyhENasu0--?2F5Ca+ka-a_L?=7`B9*UI#-j5`eU)|{LRKIAHX$nni zbMPwV8h`OEcvW{c5ZQrw>{0lZh0*G&4LA?@UL)(?Pd%c}QwvVQkOPzf9c7K6F!9uu zD5-Sr8xV&;vsLh9Z|m<{6jVxdl~>Z+ zC;U%#gY$Nq=HOJ`6ewT7zyiIvc;7hdBy*hU!5mp7*pVm3#9Y2fyLgDMyBx?SnxTzu zT7P9S)dn{meTg?st%d4|wE#Kh{I06%#(vgXz#SuniUgcE_O3W_d+22&(q2vWbNJQP z0S=4+cK(3Q^^)5}^vutc3i(9E5fg%v)!Ov|S%FT-?$>C(qrF2G4+{Ssc97r+MUp~q z>7;dQX;;huKL1WfX@A@3Ym(de^cJ3a3xCJM90`x>Dq602Jv0GT@sbwKz3%cSx7{4{qBP!B;K-51cfkqc^=l0{QK2`pMRPGLN z=0;^3r1|1PJCsi_y${f3-%aegoPQvNbwkcl%D1(DYji6nDP(D%OGk~CTZ*5{OdnlK zYav_OrAJu-v^Lz(yj7UamdE_=^~J!GW1CyLrHdY1Pl5aLvi6;zjz0uVL<(*2?G%K5 zJM_=qbGi|*IFR3JB*7MspfftXY{;lg3~czrL8`4rvH#K~0u(oXyHs<2et*Y6eGeMi zoJ;^aK*YaL!ddY>?;*XJsiJI4PwA#6D)$|$FQ2n}{YiS~SIQly&9!X|X!5#5d_ccr zCO7~9Mu_l-Df^(q$+fZ|O?6z@N?7e(Tvn0vnu@zM+Y+G@g{i>t+7;4!HUlEA^(}03 zpHI`e0*%w1$W}wJfEOr2!dvmZuW)|{ox=4$DUt)wfQl;qp^!l>E(A1TLk+G4#B@8; z*Y#1hbsZ zz%0E<;uHwv3w5`(EQ|}cUXEIW&>KVG&801;Q%uCcz%KM;O*L)#nJHCo(JQgEK%HQ> zWv#WbG+H(H#U+JEgIBlw=MUG1eSw&u{Id*rdC**{-(KPvkr4cJGbDduX=EK1{W~7LcnT)cQzyKi?N5)y|eLU%4zTb6IHr zny2sQ&djY}mvR!mgr9;G_*w};iSZ!{ePvN_6#GjfVwIoPLGBd#mTxLS1(QF--Gz1p z+wJL-h(K>{Ny%bUIyryHF}2fNp}=fbsSf-sZFWD(%2K88A``}km-b;wWc>K5BdES( z*iV%~j|gIWnfNDH6(>?t(T%ogMBpF(RIq160l~uT!ZyQJRhaG)N})GFYKi6T!k(;4 zlH*dF_;ybuy;*;-0U-p3q1QP0ho(Xi80xcrIxE;jFMb69%^81;;j@sXqU?KZh8ufp z{u`5zx$4rIZ{$I;pP!}S<=;F|gl#viQ5^a`Tkw<6y(7A+txnnhck*XKn?$lg{=!+Z zur1q;PUsZQN}5=Qyvut*q#E$0#dIze7VP@PKJ2L12~nIMCy>tjdN3?hW6|U&My7Ll z+cipVBg(mN0uA#hnWq$g>#OKQLp$gD`-7p>YXh{B(LZ0>0zc_x2T{_IpFzm{;G@$s)7fYilb z7;v-PNKilScS^`kb9@or3s_%+n9TsJAdd9yCVgIPduda3DM@5~mM3K|-RNxo{^cIU zuIL0={GI@-;=pxGEg52^X$7juPJvC{$Pdc1UHxdjNE)xZl*IUk8Ea|kF)HRuY{&kl zT%*B+NMC;r0Cmg6{48?g?A;VBrjGD2kXnqm1M2tps#P)~p$i^8-yqYz8je0GJ5@LK zPHGpB6t)wUprh7u3u#)JWOLNB$ed@@JR|mpQ*#SO-1FP5GdWjK#&S4#S2Ib2=h$}V z+Kn;6xx=^8&NB#UGxQ4r|L%R9BSEUGm4rd@Yt?@U?w&j?O_B7NU>yy3-N$GxhFAh# zf)!I+qlGT)Yiq3*&ECNWOitVuT?2$k*?uISl2PNgw78fJzrZ_`_E4-OMtDc3F9*Co z2Oi9_n+-p@KTu$YdHI8eFjox&1as*Vo)RlTw1o8J3Gge#XM2z|Ui`-m6e4!|uq%7A zF+G2}#+m+!T7!K=D~fiGi@C});RUXi?>kl>$a-m_62#r_eR*Ty)_guyLuV)xfIgh1 zq8ToCc@Sf+q+@nC<|xc?VEs=al*@N<`qE%+1o6<4Q;JQj9hi9jO9xe9 zXFJ>9u&tZr6b=xyr9_z9XB*{`8#pOr%cE&pUv2CCc9r+ov2OElE;7F zCfeMVo;+9UyRW6;i)Y&&m`I+V9qASgSY`SquwUoBEjmWT$Q9KV>{PgFvWc-XlfKSK ze^H%kTHq)y@-lYu1!Lu+^|!aHx?Mp~*oDABi!gXWAJ6Fjl*a~J#ISfgtCGagK1jGi zovp4pz_2eDeFS)j&@rxW&{iDLpTmEwlDK8UYVb>Kh;#0y8D^q-_-*P6HAV`gCVEf` zKpEe|D^&^`RnayAlPQVl~<*@2PyhIDiNNaG*&pEmMv2(*9rF{JT< zVMNS@7ruE5yi(`_$kGTsL%hUgd~v18Y}@?93aK5)^eU}mb*rVRWSmZT+GbB1ak9R|+{S)CRP!M6Me7VxPE44*7*UA0E&r-4sXnlySZZF3rS^V=9?=3AHtC$Kh= z$fW(pcGh|#1kG`wOmo@`N%nug-DmwnlMp;gWA!pGL#x#hPV@&FT(Y4x*%yKEn!Caw z-rqn9M9Ig(_2{=|baYMvUcUBtMQO4c-?T@W!Va&}qK@!sQhk#I;K24C{DJa1Qcfeg z{Jg~!e$3}&9yaVYnoLVpDL(F0Tt{!^t1#xC98#Cim(ri-cpO5*oQ8i){^sQ~`~tI1 zCuIgqA~S0b>0jMigyaqH<+Dc)iAb}@l+jC`{Q*Dh-Lr>m4@T%<#*wNax3; zTC^_UGeVo$lgZf(itascPKmWxaYQAT4 zgp4Lj#FrGUY3*>S^-LtOEri?pJ*b@C)g>@MwZZ%*Z1s-9JlcQJC0N^~T#~jFDF21$ zZ}i58V|-eT!jwB@cPXi42Vw4WcevR%zk__;K94Xiy1bIo%_WX38160+0S+^AeU#$Gc8(9I zer2`B)<6HCz7A+$gvyz?+0IL6&&>p&ie_C{Q=j>W9E&;9p`pZuY+&5d%g!&TwgiAE zHsN_Ue1d|$s14)jC_p`0(X6pPJY7xB2e3bS3MBX(_di&>PDFQcp!N5}m z%Wcv}B!5Z7qMvDE2%7q>YSw$sTz-$jQ!?Tr5uc!RlvJ7xpn4bH?JwD%UM>B48E$@Z z!4`iqA}SaA(GPWiKfhjog`w}QY8;gJ++DV!KxmWVyv=`1fI?0jx3=S!xK1pEWd3D0 z?W{imza)9~moEkt_n;Mgtl8W1HB1h@#L%4qZgFli_qhufopVk;^mb;M+p3}Auakbu za8>4?weayIrYh3DSeL1`OPZgn132?$B^jD3V}NvAUD?epd+1Wz>Nmr4?b z4^{mOea%u3D17$&1JeNIkCuQTS1(BHjG*dA`Eo9mW~&@=7LK<1Pi~IHcn*IF;G8`E z*hEt$Gr;XFCrJIo>Kv#krXz~Ay#SJUw?@^{nBJXntNLS`$i@5v{iE=tEA4$c&YMQN zOD|OrC~4WGpX?P!$f!!Nm}#gs{vqr2k&k}3LYLeMS23JdL$y;yib2p5 zv9n$b7q}#a+r3JxzD*kDO4(N4p)$iS@0$~w!YV6Rl-z#YB=n&$W%+-6_URsBGAXzv z%}C7~?qGlP!~cC2K6?7OmKOn@7EirTb=ea8{&zcsV^-copQk-%P4hq6n2>G4$i>;R zg9kR*1=t0hQ>W;PL;{&fPy+qfl@eg*;CK8eKNgHAUKZtjN3dkFVP$!daYIyv66}P7 zkbT1ZFdLhDlw;3&NUDG2nQ)7Un~m;Wd8vE_rh>PbMn08Y)VGM z>vV*`Bkkgzw7P8uDE#DOI7ZGns}-LQ5v2R{DwLL%g{7su^`bmB}+cS zk!M$zNi{NF=Am}P96M+UOzhABB$Qz7sGX`%!w+!P1;$%MZ#7X`)9Vd57j<@qW-Zi^ z)$ER{kD3e~0xq8P?dEhAMG=i*woa7!Sks4W22^4yY*v{P68Fcmi5ZXbkjDdEYA{`9 znc#n1moQjBBg22}Y@-z2`ZKWi4&~w~{&h^6+ZzB|tHI!<1fhc~1J4zW?&8d{LLMyM zQZxABb*1}ujZb5J3tlvoTQ?ls$xJCmi|rXI_WW-^#+*ZTiy>$V?xbu@of80_6dLU| zCQ>%D25Lnl_r-pbef^NxQcN-YE@?JdVgO>7ur0}lPmF&mRpl)}$(aZBnnVktQbND< zhRf5J=^1_p8}lYXq+?q_`3!XgnK!rwr4&5QGs$9^?bU^fX5>MrL>pyJ^FZ#mTNk#e z`?N9^4EsHW(z(DF+{iH)wkI~YEjT5~>SVlb%79U6=1UZY0B<ZDXvIpb)}JlhOzH>S&Mcyg#V4pe%$7!(FG^^i#s{4jUtLzRsOiiIZ&N-{J|J z4^5>!GypzvZ9DQEURm-;;*##QW8o!^79;=oD1?7T9mXmIezA8E`2((WQfDK9ca*5{ zv;E5cY8LpJCN0Kj4$PS(?8yAZfbX|nq83@CRGR>GUEUwcNs#N~G_4>p_3D@wF+F*i)mS4T>vZl&^ z7Knc>I>|-;gPn)9MO;6GRRAoVz7VI`_H@t$K^!dmGdh?SXSpR^yiSU9{-bT z(%O$2drMFcni6?`pG}%W3pwADR0K-Dhh|_GbwlBT08jbc6gsoa`==|^z){?TkzUt3 znBD-~E|JF#4dS&6Dn_ST)Cq5Gk{(qSwHC_`$yqeo3KUY32ZrgT>ARN&DHpg+%{Ybb`UR-qPqGr?o zlMQE93L?NzXPvNrh7I1j%AXIJd7XbJQ9s$~sz4E~3|n_uL^-sj`tRN`sTw)vjDKLG zwG$ci=)bS&9FE2K4jzcf=vfgbq{PZ4)eD&*?ZNvv=lIvBM#)Kp!9kkJynS|F6Hc?u zHG1h-mg7TYbxoF)sOH{6cxss?kWdLNDGyDbm20dAo^V;QQnPaf&?T)&9wC3rN09G( z2w7EY19hyov{FDNVvI;oGl$0$tcN+{%Gzw%t#aDA)G zKT3X^RilzZMBuND*pRH}z4=CV3wEMrt|$1g`@+w2WPPX3878XMi44yBwY?knTtcn1 zCT!8N9;sRs+!WSXgOHKk*hY->3h}|TM7_hm8D`>Yo>a}nXYt29Shm=`f}SJ zsPVz?sXTenc;AA)hY0@(I~Q#n0Acym{Tc4W0nh>&pI@H&?~6!K_rI}+5&JuOFwr)G z_p0lm58%9IJYaD0L8*U8IKOTm4U(&%tTo2QxKQgo4iExCdre+CzCe(G65#SzG>RPm zt|P!o5Ij-Ql^3yw9D`IQRf>F{@*D_f+UAJ0L)H$6cFV=!v$GAiC$Wk7|BI(d^MKjD zq*93mgowMj@c~Rxj_?ihk~NJtZJ-Ne5-#6tQJh~u{rb%qYCwOz@e2W0Hx!}j&4r|O zpD;NE1tjp41a17(AV=v#w`RDOmces4$!%43#9d7?gz^d>h%cT~jc7S{u6s79dwKwl z_pYr8U|K^CM`h=QxD<~D^6+F8-Veb!v}h7$7|Z_|YTQ;2ut<*r5SMR8Ogg_DxPiTl zC}pfPk-WwDC%S(ez1h5F%0YH3Em`ifo!Epf^I2G!D=ibT57^-)!~S39aB!owI$c`2 z;#|Dii7n2){l57{uvbG6>uWk3#6Mg_mgMQa5}we*2$oQADC~-p>gVr9no@)2kKiCI zb}`{bK9l4G!;8zQ4?lKwEL5Q;uCLd|$Sc4j@lG0K`Bi@y$lx$##pV5o0l0>7Y~hl5 znC;CSb2HGv?(V}23+`?izr4_uD}+MlKHck@2|o-53IQs&De(+8XDc*(~l*hw+1l?@7| zpCp<;z&n3u!#5KzAh#=8VgskJi8v9Y&!WWLK>&WIdiZ3NN3g_9yK`5eRG+Pc zBNb9WI`aeHg9TWNAs1Ymvs$1SULQ}-BYvT&&{S8QU_6$eX9Y1rCy3dwOqftg>7uUt zfKPRQE}3$aaNWkg=~v3ra*AK1%J~lxAKI*JX7PWX&YrKz;3h)EovFP4q;jl-GqfIv zn0Bxl<|Lo#s%|2eHQ=cK8DB@xv$1wZPf4h@g3BOhuWe=Nh2acc?)Y#gbBL{FfJoB01V3czVq&s~Tw+V-FI}A(o zlIzn#nnj~A?3-x`R5|Z`!w2#yfYeDRv3qhIn|wi;A{xa1Yp7SK)pTxXsMrerrA2?C zq2*{M9zYcuwEPW{I{;m^an-lOlc#k9Pfy=2^7@^ebPnN~|1FI7{q!uQNcM0bwjBUo zgMS5*MmxiE2T2S|*qJ8ypWW8>wgpe{pdU(3zLi0%BTi09A2Adh58}XZ6)ftYe>Ef-XZBrDukUl3^*<5U){C@OoL+P4>yuQB$d^$k z@TJRy$2l~5@@Giev>Vjd@{fNmzmiVuabr}66l?src+WRj;;+R}D}*LoY@=KACybwM zn-Ryvw@^cfDnU#0>HjC&2zkmw{jYJ>5C>7umbszvAF(g@NdLCROCt`^uO+sQK8s0mueY@y%%~85_?S;KR2A{eORdP!q*_LR?d- z)Q3Eld6zZ2UJNbFULlExzw~x+0t@#_qD|(bOH{yLwUy4=a5hfa`;6>$_^5&quFIz4 zf4nH(N&>aMuUbC%^&lVs@>@8$+`-=$R{4T1{f^})d!b0j)QxfHOYFO#Zc3T(aU7j? z@ZI%~2etCizP(S7|M`E`DM|OHw2AFhyF4L>rV!OAY+ICcxn+ek^3y>1P$*BqPk+(r z8zbstz28(I{3>sL41IGSXE|lc-t(`CL*amh3^QqW7@!W(RL+mB>0n^jApDR61YIA; z-1T1kd`1Aw%-tmC`xNBVos}E%$N~PD@=&_Qsu1`NN4T-@I}m^Re4hdo+@xOco*Eo( zBB`y#-e6I%l2r@DlBJZ|2m+tdzd~+7m^Nc}@CdBuEbuFcL$oZ^5=V1`t@AlHLHNy` zP5`q-OfEUQjQpUEwC|U$-0Gqwr7IeTEDec{1Kt$&y(KB;$s!VCWV}9RIo{KvCsLM$ zd-_SZ&iTAiHyD5MK`9P^e?;9H`F>dB#OP)fbG}9d^rn_lG-PM|eEvNK;+=G*IWYYx zQ2+GyU%-5no#6X`h;%*ECSwA~S*D(MO2{83yZrQ`mxplye5?Fo+q_S1y%&P-1;_lt zmIihHNXr3U8Jp1kweKr2vN^y+g2yrrw2BsL1G)-hxV(Q}!}7bgzidRF|JF~cH4W44 ztmHbT17;cuFqTx4>a%d;e3gN+zSk5nTLc0>r5E<*=1r_3=sa8C1N&K*U&^e&tBbo4 zRIS{{mpXk?wk6N|{<6Xt+JB0}s-RLQ;L0jhM<+<-INrxsOaf9$;2TB&CKgt#T`&ns ztGRc|VR3)H8{$}QsJu|ipKe2GLS6nqcA>RUG1P|wZfe=HCU@~`-=+8bA7NvTj`cIZ z?4J_oAn4W+wnIGc5>1IFnki+j&=p0yF+E@Z4l*^UXK+;T4x2MDVP&9gV$JOjn}96= zC-3TkSC6 zdO^Ih_&HkzM=;Jn;y)Hb+@Q3_r8tIE9~`w4rwb9=MfM|h`i|Pw$4(IWV2nqKDaqh8 zgo$j7qFkGu()io(#DQ}tz7L@$&Dmpq9h*^b73Xn{mvz~SI5t_z?j>>GSQAC+1^44W z;l6*koriba2HbSiK81WejztmLZv;&q)sna+4h77WUxz{0G8r0qiUqlimK2<)`=?55 z^{QJ)<+vFoLNq8$g^5)GX-CR(5HGL;br;mt!qzhT3NVkUpG3q1FAN{&S|CbC5s+sNcF z7$h|M=Hq4mTdOa3Pg7a`=?5y=W;G?u{i5&ddt{OkO-4c{pka|b$RGEDeO3RU2}}_n zpxaIc)c%hdWzj)Fn(a9_p z2mg+5a5o)@lY`M4H?l=I#%OxuQM;7U>~v?a>r_$`)!t%DFE6O_kfn=&KIVUMK>D@a zxhF4CPPq>7kVW3k_$^|Ra2wkGD?L{z_{hkUdNuSM;^OL}#n+Inzy&le+SezfC%7Fc z^$x!?hnxv2yWC+?dt{%sfDsgNIi3FZ5cfnY^-zAjC)aemCmV6|W4vp55FcDvwTZ!W zz-V(!EtqIm@w<4p(Z<3h-S~fDGjB_lAmNIr&~@IA+5l+sHV@_xC=wyT;&Ok+Ep3Zq zdPNHillib)O4?F#jNJhbXT8Y$aS~PXR)@+cPx?b*K+@p^vWNIG`0Kt#=RDl|AYSc` z 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 z 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

      W*@#Q5^g8WpaSs%iufM4!4^o&sq;4 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 delta 28159 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 diff --git a/data/gwasSumStatsS4Example.rda b/data/gwasSumStatsS4Example.rda index 746fb08926a09aac7493b7575ca1054504cdd7ba..3539a1cfb56602f51ee1b70efea14fe73d71ad93 100644 GIT binary patch delta 4531 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 RRf#?@4T}N*00001Sz5*iz;XZp delta 4434 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 YIsUT)05W^VM?NqOivj=u00045T2{}U-T(jq diff --git a/data/multiStudyQtlDatasetExample.rda b/data/multiStudyQtlDatasetExample.rda index 2587422d1fa8cb4b1c457407f149fb1c876260d7..0ae036dd88e40043c05d285126491b2ebc0eeced 100644 GIT binary patch delta 7033 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 YH`d+;07yqp;XW`8ivj=u00045TIC|^Hvj+t diff --git a/data/mvsusieFineMappingExample.rda b/data/mvsusieFineMappingExample.rda index bed0b42905d0e713f4882516de1504d2ee5ef7c0..80aee8adbde396b135cffce2ecc252f75f715432 100644 GIT binary patch delta 103132 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

      1q_aMe;CJ|P204AZ*NQG)1 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 delta 103019 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 delta 5604 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 I00045T4kHg(f|Me delta 113920 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

      t9SCbMXMM<`;6JZTAyRX~Cz+#U94p}g=Ke)O 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

      A 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 delta 52522 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 b00Ecc1jv*Pl?7nxJ}?c70ssI200CKAs$t;n diff --git a/data/qtlFineMappingPairedExample.rda b/data/qtlFineMappingPairedExample.rda index 92c852a1e98427db5ee8ad54c040971545c5265b..2c572b00206fa340d01fdb25f8e98455f2967627 100644 GIT binary patch delta 10676 zcmV;lDNELbmjUFL0gxF4exFOFu^o6Ke?+>u+hEMuw}QMtY(3g~z4BP6X{zgX^XBN) zgc1MwU%BS6CvjaXz&Zr^`ldVuRyK0SjjFYA?GQe=`fw3n{D0v`H9vEmoa>kBZNTud ztOy(uT5O2Z*C>i_-E^l*PX0XpM7~qWoC@3Qwbp-D8bkO|ItHr}J^SzC_H%^Yf6uRQ ze~$^ZH24Yj92HV4)0|SZV5lv_9JM;G!Q>{ z@P)6fZlpMCv#}x_?GAn)f`Jp~396ikEDb(492tnu`>1 zqL59z4`oHUd`+sq#<5fAR}5%ttC92ty2p-+KQSJ==X=n^MhIQ#pf&)gAh~wdo@%<2 zwVDC1!ybJjkywh-WF` zIx?_@oS8w^YGYOl4E6&Se*?#5!0=|&bU5@VcrP*GfNE7rb6z6)0;=}+D_@r_W^ygz zvql1(S++reEyfA?RyP!deN>d~0B@&YA_d)yobt$xE*$h}K?!piK&>MHi`H1GoEV2s z%u9lY{FCV;nM*UjveU#H!B#A?fLZUTvAH2V-Q6#gFSZAp=&5bke~1FBFTkE^DbmBL zi57lOQ_}ZTaS%+=U~kjb4Im>!n(+rp{=zc6E%{mO1n(J`2N(T^OQ#{Eyh(c%2OU|khxo>@6XI#qM6GlXHtg1m(Ewq2AKu9)8r zJo�QLQ(ncf40OfA4FVX>5*11lonWSHi>0KVjAW;l(uZ+^7`WgFCIFtEuQlT!k>j z8%HL^z~=DMTmcHApm^GmS-Ly#cGflmoF^t(X{{>iB<#wJ{?Fu&f&Ur#nx!160vvl% zup9Z92jng%wm>k#5{Nn4*i(W5($Wjw z;}n120^&`pEnk&C#293s^4sMO&nTSmeRld$-JcHGRImy#EhAk{&0Q~yEd(TFbj&r? z0iQu7p~s*aug|Vg2hs{(u!klVX^`obZSluJ|8*PbJ<}4SM~bRj{AWNtzbFw6jWC9` zbVU!X@Hw6ze_KZ$jzcfsz-9H}nj@}KfY$CNn`yGGA4Mz>twL<_4o(6ZDF=RQi%F~Z zVtzg1FyEeO#p|@n4pML1peuOslPR`B;u)iCfu_Kn(q|QhlXBv!SG(D==cN48Jz1pJ z{?d23k<;*cI~E`eRi1)pMMS1TjQ41KkTwd@59r{|fBB!jJ$6T1Wygm;6SMn1gw^Xx zq03|#@5JuD?K(V#7j zgg9#$e~ExHr2;qY`h<|~&;xS{spV_HjYeFt3kH$-*&oKA~X+P{L~)LrsyP1p3pXf5nnW`P8CtmG2`{LYJ2xezcaaxb9iW zU0j9TlD<3#J@iaNv}1qI%;o*^hz~AyxExUsp!;Wo$79NFabvjmZT~*wVWbTcBWQMF z`;AuX7N;K=9W?ILr^jSOYz;T~t+0jq2QoL~&%%Xw1n^D)%Cc)P*EavJ4Zbj(@dd1@^Vp`akFC^2#NHyxBeK5O@Brsb4Pv(wT{V&@8C6B0wD+`^Ky82@zyCV9HC64r)L?ob z*$YbbfcnTQ zl->8~PEzUhP4xW_hYla{JIrIOLT7a=1!%yCj4wJL4&QE>3`#HUVJI$u_uFs)`9`S4 zQ$@k6-ZdNv$nxZukesFYkcFXCUhDR|_Ie#}CRjKj!!JOydDRXclR3-S&13ciN^Oot zTj&5+fj*F)XT5DzR*$b_f12g2f2xQG>l0*#sI2)ET#{Ee83gWgj<;*@>6!9KiFKDO z94(pcAB`V3h*`iJYWrtx+Ff<4lcr@JmfZ#dYNu>1)EgP1Ai5(@ExWW$)nxU0ZUlPde?>_)zoUn%{aatWc8iK^z zYCryjUR$=TkC0_+W}M*?LkDX&yT}cXDh#9MTO>wb@VaB*t4g^Yzi+CE1^gH_)x-*= zJZ10=TqT*)+2PdzYI3zpe>^mT;O;9`JLTWV{e@3qa#cvTj0$4%2CJl|1IJcVU(eN2 zI(z?6J~_es)N$YrGZGa?X;$2`QFn&-VnXF;vj=b*Wt^hFbgUnA5@c(#0a9_jQ#{zc zO5DI2sjAcj4SAG_l(Sq=6WfZIOlqb|=q-RCZ!i|E+TAAUCFo0;e{U!R(KXIdquHtr zs*|4f!$V;2vz4JQL?&1NCSCjp1jSm?OiKLJCR$OQFNZy+Bp(AY(8<|( zfrM%yQ3SOdB*y*20m{tzHijG{3+MsM!=k)0&LPJK-mF}?nsAy=X_H}GNrq5UkCm~S9JHi1QN7{nzGd{YVfvpE(SNN7Emk`q zZfihgWZIQq2!;l)J_%zhYt>PQ!L5>lW~kF!@}W0EJXQL>#O>W1r}Lo_UbrWWZ=u`2 zT!4?#l?Q`(f6IH9$VlrLBI+~K7HwHWjP`!1m2&+)D`0YRzW^b$LA^&AJ{Q6N;REw- z7S=~}#_ZP+TSSAsFvP2q#L)9E_gNe+e=pt4%+2V5-9Nk;m?1IZ+?wsz4-nzDAOj_` z$g&*^vcewAb76uYNvk70%+Yb-L#{dfZtA14-Y@1Qe`k$&AEr{O1|W;E#Ukz_#2O#O zAZ2Z}wT_Yy@y`3Q8>`@7$m~1N;GaK`cU{R$`8e$3C8gPu9p=xJt6gK7=3Ex<>e=Xz zM7x(f&UZ7qI1WL8Y8OfbEfX`lvb9| z;EmU9@_0 zJJ^JY5BFml?{!e(+aS;5;qtxf2iEyB-qBx777nxN1BI1V7yoq9k)@f_|7k!f|N4&REj@Rm4 ze}a$*?w+SR^(nHxKO;ty5HL0Se=FTHOUn%dhd ze#1uhi~xn76JC@9w})OF3&{8ZzRGfKdkLkxMSH%bMZEHV2H>)C-^UV6nF!y2PT>ie zBpzRgt>`@cK^lgV7QJot*qXe5Zm4k%e?%Ra<4-eYP%AvI$=#0>HLf`|l$_}}{N4qT zz>NN44%l+BoRK$z)KBVi!*%Ies_2I1^6lURuW{ojN+_J?dC+WkwD|WZ>Tz1}ED*v7 zq_T%>;X*n`4eHmIxnjtOvi&hl7l<92&w%s2uqY6oD<^Um(BIn{6RR;)8n%3pe=oUi zDpGA~T9yvN!HVvH0f}z}QyN$9!w6eiJHLrr9Jr5%{v%G<$)mQ3)M7F_ZA^7bN!?JH zq5h3qG{~#4jwRe_L~l;lqW#R!c`A!ea&$L>3Rscg^L$}mhV@&}xL-(J@mDWV8axWE zMCOUYKzDV7p=!~JNB!{PF$(1be}-rT5LL>cSBA7mYyYZrHlMs&C`#Pw1w!s!H~cWG0EXgRJ~Q;k&vU{&n9vdN!gZl2G|x3t2>{DHl-Bs(YC zQnXAd=v=|g%<1s8>!l_W+BM(**%E@W`06}3Ge>BNK_vF@O%&EATL|iIf5FHfMI#r) z0@|i;a@=I#2Y7>}HLAAskKjA$hZ|EmO*lWw373wMd#BL%+%u`64WuQ{g3PiQWivZ5 z=Xl66i-ln&8AWk`V7|Y+W*`m!KFw22z~SvZ7o)<!VTl&FDXR||zS;a+e>O7Ql_|EwXSQGR*gXrQ^ZRF3Kss?7f{*OE(q_$P{I?ZKjt|vZ zZp=tShG9H*b_zHcp8~(-FXbEF3#uGkKJ96*L9qR*7fDX0^Fq)JBPV6r- z*Q;dh0nfi_wZcD&7&Q}aQz5V-@?A$mz(obw=v8Dj2)I9uvLX3L;T$Y<`VV1rNt%Oh z1L@%<+41B@6@?q>e#1xfF^}j9|Hy1$z@YTr+WY$|7ys*`oRqKkcQ%O9Y$+7xX1}SU zwP)|U`JV?ff8blXl96OgCtCjPl%Bh{d2OR4@H5c_ZEz)deEzFdDqHpfKYDvKc`bM_ zGZ|9SKFc29WKYxL{+Iohcsy=5y7i18@tL0YPxNB3_^doJwnME*yGMjKbW;t7A{CTS zzs}g1GIT0zbmd9MnKZEjA_<>+4@>(Szh#QyLBlEle?rK*V#id`t9McKfmprl-=Z;N zfYb>uK1L6mGnw~NEFbebURTBL!0#2V7$X~PcAbH_Q(>+KJExhSBu zdu> zgQ`eap8~9*Bf|=6J|5%Vqe^XtKouJ{Ds&0{fA{s`+}=%w;5bF*glHS4^?!sXqFJQg z&DJjyX|RdArwU<9-W`^lf2_e%1S)5;|Mcj++}7nwmqDhmCL{Ul4r>n|=*POJ=oNnqu}|sqL96dZ;$W+W*HV ze>wq`JhOFd%fUK?=dXT`YwAnXfo9j0t*ea*rz?!NHoro~avb%h8Z8YKth6!`F+tI9 zHLa9iT=k}dUA;W%_g_&xam4B+Y8;qBuzQ~Zn- z3D8gX`XsY)A%`48Mqg3z5tE;{uLvu^(mwR1vQ&Ylo4j$2V38+7MJ9Qt$LEX&Nqx__ zyd7=$1glC$QEXe8-6c+gn;T-Rb{?4qs+?Cnvx}SYN4*CTZTU^qid+b_Tv`1of4Omc zUdnbk`S}hk@Q3~);_BRi@Fxe>SnzEWMf|hGNE7%Mn0A{@P+}e#CwCUsNw47wkhNe} z?d;pHVp8urUve^X^#2t8whEN;GW2aOEkvs@;S>3gRd5pnsaAl-t zDb(qg=Vm9Dngd)R@!EE8Z*t9sh0Q}5NYi++*6ddijM_L*T<-Bq+WqeP^Dj%XML05e zPoMW3B?D~!@uEHVh<+ulJu(Qh=~5uO+-|W{@RdSjv&`$&3 zZ>#bWlPFFizdw*gfO>mIVgkuO6D5S&DEfbRlca)td4hJy$Q?*7cPxae*oDuMIy8~7 zrXawoMC*f7etlNrVyE-2XkfKc->LiBZj#cQkd!m+$K3A50<-GPQ(k#Rynp7H7m!f0 zKqx5fv?&aWEvqe6^>gf&e-ZchY{15qdh(%}TT##jf^gFg;=uV2b^k#bhzG^`iW{)@ z_=~5J<;gwFGSuY;nLly zd;}7wRR-c>6s2F@NH8*%0o6JaVNJk?A|_f=^&wPeFH&Io{JFyXf6Fw4vJ$*33q+6+ zNNgnRSS{QNB5is*!G@5@0kEIrjb5JiTx>VLx;NRX!TS7v zONsQ;KTZ}4lS{bQ;q9}LgSfW3%VhA1UQfnY3<*EYbh5drbq~oWrauWp-@k~-0tYV- z4HIkC*fdt=o(Gl>e-hE&hwl_ns4XKN1`aln5#o2}P}r^dF{T`GOZe1S;m(IA+}E)m zVe#s19heB+7%M{3ekG5qRdH~fKR;sAAKMa0$wi$6goGz!|HpMDIc8XO{NXhRR($!) zR%8NLh5GhH=ew5&_rJD7Gj`*1{XdFPzwEJM^+~zZIu5{te;KGC-BZFtumW`#nq(8t zHGW^GI^`jNh>xr{C86?{cLX#WM&sFx)7#D*5-dT={CqUV)I57e=0+jhzpGv5W_AgU z(>QCP+O}Xx@~WIXlf#lDc8mxN6+A{59H|i`2Sk%g7bUxNZ9$ieFXVbfq4ovX_1`pa zRgfDl?7WkYe|#(>P`bhEtz)~On1Wjrzh(Xl?q~{YUF%Q*BC|sTJ~EpyV}iIpE6tFx zvN&PVO~neaZj~LeOrDYmqrK6qbWZtm3!3A$(^vyaQi8m1DUw6nI-;u&FuZYl12rwVI7Jn?yJj?EC2<*O`{ii5Lb7%mdbxxBTw2{AP})rk)!T6e#XJ5|5bJHE~tkIv~v_a0@#vHmT{<4%o21` zE+$X^e?Y|H&Az%^oX`OnV~=N*rcgxKH*#54EaECAH=l2OE5I%)fh zbRa8rwahmHAe|hk+)9KWOq0E>2nf$UNPk1#e?s@P^qUeU1t4gk1{aR}13>f=7AWSM ziv&wQeKrTL5=TKD7dOz0C<6{PQ+0HuH7OPLx>@-cg6OIQE#n~pb?Rz`67X!W(?fjO zo`9TtTuG2hu!+_3dWZZI;fFbZ^p125;K7YUxr3Y zfONTkjsZwI=aF}d6*1S*O}myOWoa#nf28PHgzJ{Y;P(9W4S9R$dEmAN`Z3|+N)E9_ zk>`2@aoEMXFC@AWr`nXsJPKqHdNSX{JlZMhS*#$1CdC@KOU3-b>QzT9rZekQs-iBu zMM?s|&Pk#7h7`T1@tnhhYfYx=?y9{e<4NAC6Kz&uV+37u_tIWF$az`=?K(pBf7z{Z z4Es-^zRBKw`mD}=%k)XM%kckjBZ*o+^G-fxC;lUa%}~*GSlm3UmeXL*70GAP*wJ4# z678K_UdJ+OTdKR-uknw0@EwT`7z~R+$bBxIykD=xwOTs&G$DM^gdm49rCPK~ia2{7 zE$f!0l+L(8o7pDUo|oKir3%$9_S4>IZ?ivl_ajWaw0&b0Apb zpJ*|SwQ@=$B_0i{cN$3aK0flS+GDO6Tx3zFVoJ~Sl{1^4*ivR%-f%yge}AhQr>%v? z9uad+#q!HgbzO(xU&n*)i)InFHRNPY>j)v4yeL(|G8Io)5}Ow(?mFnYB9SSuuUpdy zSL)D6RX#97(y>!L9VD-gH%<-aQiQ+rcLn0`ZxFF-AhgQ^c>2p)yp)9c@CntEaNfE= zS%s^M#T12orKJl5(r7FyxyAAsbz+Wq|bxU>rBdC`nkSzfr5f0SJ=&+sPqJl(yo zs7SjtRqbr4N%=-5AH<(Fg{i^1@w|z93I~!qK2G5Jr=Bt1UXy+`F>2|oYox(|IQDet z2j6PVQxq;;#F?L!H8Y)M--zzhepR#0yWM%PZ7<9*!e?epRa@FYZD1$@exZ`E4YgE8 z!Xy6X&?3n#n!N}Uf8{Q;)mT+fk)zr>C6d!e>9v{9Q7!HZd1X4x@lalE7U5*LcR$wz zEU0q`4g%F$}rN*eK7U4h|35j)RovOVi? zg-!tVPS`FMi+-DB0;AgE!&w{MJZ_xJXJC431HHjzBbStVfBwl$s##`OXzG@O~uu6;)V*77~gx z<^hyuHvzqPu`Hm$;cvVsm7dGFMc%qGFd{mtzNCLIiu0gPgzsk!|s42A@ zGYpS~(b4aAe`${E78uM;tklE^W8wJHy7PP1{Z9t5!e#LqAg7oGkwhIzE8tXlm}Tx^ zh*w|JJIbx+Im^?cFB9J|fWg$qywC;b^s>YYMA(Yb{@(^CP|HEI3RN)RYw23CGS>R- zBqkJ3CJzMF-up{eIAA=HP(@sgN!i|mJ~ynIB(03ze@#l*S@4~!Ev47G3J0UQ6F1K~ ztK)5SP|o!RqU1l^NB!~{vr?dA#G;he%qarSfNO|NOZ{*gP|w5<37);_vku*bt@A9F zqsJG8wq|#sE0C<=cS|jYBul`VWO`yZa)geRzoARfL{fV0i@8;HD@f+^Z)2h=ZO4YI z6{=w;e_K(+IZ%WcedPzaHcNA9DpEG>dkMR{O_}U@T@IF#Cxs9Ztz$w8KDs+|u6;vE19DdOQE9TZ1kAe+>8)cRh z$x?Sm;lP{wZRuDK^Fr@__eBkZI7DFw98cZ2e**=5Q-(E;@WIp+S}3V=;|{lngiom9 zp=vLqQ>q=^cOa*DDDcs16q zSl0gFqoIlFDQ!Q5;v*%)U5nm(Le2KCh4X56K(JugA$&K(`sv$mz}d)l$j|nxL+~eb zHa<0=M}5*|O^f3|P@xcIa>kKn{Am#bX4iDCV$k57z{bYs zxlU8@CsQXm6h+?sE6(~T_E(d{qqUw`5+{CEXEN-BZr0$8{mq4yLjs(eKH9q}?vl?& zcivF*=fxb4n^lOPl@x&j>kZ%IEo(P5uaYJA_QAUz4 zmchIy8&8qkT20JrlC9a2I0w?ofeG$jBKxD4O6Lo+nRn($LSJ+3yI!Y>e}Ri%9$FW} z!7ghv7;#mJ$DJq@j=oG`n4A~$7;Iwu!LN!p?H)J}L_L=BCW|jhCM%?Oa3#=D*-9A# za@aVkp2Wz18g|Lp1SkDrPZ1f*a8{0$x0%YFEO6Hx*ZSDJjbWlnOeeI9n3f+Xwy(l%kTeaGQH zugSTyon2skhln!F)xfn0U|<5Kzm!vaXNB7FfTVb*t?QQM&VIL~dU ztAZQVtkmNW#BaOdEC17Bt5ry)#|oGU&(1oWQk0FlrK12Tz0dxle>AE5a`)Iu*xIa5 z*y?YGrCWOw-*Nt1@E7G?w&M`4Go?)Ccn5+zo@GS*6j9Wm$J8unA<>ci1<HXerZP?S?{k2wY%XzD2gpRWCQTRKjsY|S@W3I+s3WCVRm zG+3C(K?c{(@=pV9!Ly{-nkuVw&DU`?XV-JJ^!Zr^1Fyjn;Pl6yEf2_QT!!^}AZ5fU zy^NJ4lq6wSe_-FWvx5=Vet*c_o3~-T+-9=x3jHpSPUcfc&6)%!Dsb`dGu2Gi_ZhT5 zF~DHrHP`ze?0DDp!UNicA49w>=Jw8Sd_H%#*G9z6yIQALiP*6M)*W)VOt^Ft`S?;* z#^gcU#}-gpNfFF1Bl{Y9YPq@PsU@CUnH z+LpMQW0lt}q(y`V&BZ2aFbRUTit;>L;+duFrVF!s0PUhe)*(p?f-yK`ITO61J~Y8G z|C<7|fB&GCK5x13a4GYWj!+fdUNhF)2c*rf+n1-5(V7Vx+FjCl4XYc-F{H_3p9OSe zXAQqIt+H6D6;dWeAz|fts;Fy-%p~fK+Tr47G|jXSGyRnUNck3+AhUh~Zfke&U=8## zj1L<(#7R-<1QOUm^MlmzV+e2|y@7^~?X4$IfA2renHO_eJqwvXZQroK&`^=&>=EA4 zdPpzCPDY@osjVu$Z7b!JS6Y>xoC!K~*2HJ;F5@H#wJ9{IvuUX0JpX?k{BrdQ5O^gO z3%)N~`xD{U2nYLPuD(hGuc|ux58)zq(lG^lu)(&;vh%W)aE)$}RnfwWR2g0KF16uc zf6p@|QCNPE<067tJOJ+@abxFafkLNqJG=I|?Mf-^hyqwm^#utQs3|9XtCeQi`ODRM zku8q}h=#D}@d7M+Vy0+X(yNnSxo?G}f7@T+0lY-+ z{i-K_=43pfd(-TiP>z-NKA#Lct}X=czp>=jPZ46(cj++tqT9R6M?glF5_kZ3M?7148F5s^S0&)~{Z+g1 z*?IZ@2y!V>heW&+o{iGoRn?4$GV`dabXY13w+=4M1(q)|a!oLAk0Sd7Oq4w>Ww9mC zQ6EQeYe3hqW>k54;}YYk`3*C?f49dsx^pThPW#BzV_}t6z!==jciCP&nOi15>>Iwi zP?mr?7YSzz3{sHkPg`}v|Hk%c58lczGj#EyPIov(19(za=-%o!A`Wdo!6axZGR8t4 z)={#J>d1n3M;&<6b(($U!ue;?NIf||70 zD*D~oaB)_nz&YW^v^QuercF%T;Z`JvX}33{yWWWeg{tc@U7=>QQY(D5a+eJCXK}xs zg9hafr?T`EKA*=G?BEoL~0002jMZD$! a0lk+2p#235ew(&FFb#_W000000a;p*y1%jj delta 10579 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 diff --git a/data/qtlSumStatsExample.rda b/data/qtlSumStatsExample.rda index 4a7795e2536d63024d2a4d96503dc219a55dc9ed..203f2dde37301800ec2b30baa48c04a1807a035a 100644 GIT binary patch delta 5498 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 delta 5426 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 diff --git a/data/qtlSumStatsMulticontextExample.rda b/data/qtlSumStatsMulticontextExample.rda index 7ca92e3537889bd8ab22e117b8ebe8290f77276b..b5c756f55edcb0113b1e87fa3a56c53f4f812a3a 100644 GIT binary patch delta 13664 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 delta 13588 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 aj(`E>nFg=$dU)9KV1 z>Q$%EZheV{0jtH~TI~); zf!}(G&AMwWZRAE(^>xb;E`UHL-jx05|zm*w(*HypEy z|NJ1tnHA%H6BLdYwVIQx%F3@Gom%w$`BM^&xyt~{buzrm*pGtsorHQH&>Qq`9#E>O zM?iy@t){5C+6m%{d(gM}1JeX)B=U5p5}mIp@FAA{3BlEqw{q28Z5139wosQt6HeK$ zO@cCJXGH!`m+u(V)U{+Q-}$^MExeWc19bw9s@ZHw_UiV9+Q)$l9(zedM|93?uL z1UtCq|I$#}Muc{ZpY0PNbq*i67YT(6XyyGrQf}d#G1R9tpeiQ05YIw64Q#P2j>6@E z0P|L)HH3`yjZMfP-voOF*O%!u>xS5zywf|9fjWI-C;(@}{t=UA*}(FDDu3N)C|mT^ z=U!wlNGt5<(b;a`loTIb#mMg^(`Gv(`+S0S^MiVMLiMt-==<@ZW0d-r*71x&-y~S# zvfjpj;u9b=Ws%N27c5MMg$B{(NnKiQT3PLa?%Dx*Bd9F76sK+E2Q|yyuT(mr6mH7B zV{c-DQ%gc;A^#?$;l4|Mdc47Cx>9xop>&})jM5BztinM~Eo#U?ZEu{`l+w_;=6h|t zxc4}e#mk3>&M8i7S&#b8Xxu0ZpR8OzTzR2w3GHu+AW+gCtEZ+C0T(4=p8p7xTiZ$d zX<;nQoK!PIQ1#f3GkaY+k*b_e#aYU}(hX~$1w ztR!B#dt;qRHcRA0gRB+0PXkDoU)RW{TsdvtE@z5TsJ&5y)n~yf&YCxqM~$)Rx+98}>k@E`E3{lj9=y-w+%AUpn9b00000 f39|b300FH~xbzJG653&bJ}?c70ssI200CKAHfY!m delta 767 zcmV!?qMHM$NG%?J7BXBC z3)Z&^s~FE2XF|LwDru0izftRZAJXB={wf)rrKC$bz0J;#Re|63&p-cEqTWjc5 zNsPXn_u>-W;q%4E*nT@dCs$;bQGq_h(*zj(v)74?KXX~zhFe)Gk{R!`T~i(;`fdKq z!*PRce~*^K~8X}Mr6P3(>^Dnv~J44UC`XzVPX9?3XKF$K0#x39}7@VBJ zYLyq3kPp%G@Efr9n=X@u74T*53&sYnW*^9C^G5B5?&3$L$e4F=v$pqt4hh39Gh{|@ zk$^?@3D7EBr+%9Oi4sG!EU}9%uIS>}m@D$VG)4rW#us&_PhyT-m+duoHc@qbo}$~1b_Y3{ZF3Tv;BJGx)Y60rvVzYwz z9UQuNFF08Z6PnK@hve#iyf19z%NR=^K-gq8<3ju9F|Y|#7B*s4)% zM=88p$>{<42L=s&UP^+nX1$nS%MU`ivzj#Y01dFKw>~w~i_fd`hTb||pa4h(`Xx_S zR{C6A<_1}okA9oS>4Z8?%x+#-VJ8vwbEARFFmfY20A~~T%PEd-eUy#dqoU%L7zq`_ z_Q`nNMud7r81O|9&P2Fqhg$9w<*^iH6X3jnIco%%j74T}N*00001Sz2*~bwdCE diff --git a/inst/scripts/build_ctwas_examples.R b/inst/scripts/build_ctwas_examples.R index b0e9a097..c0667737 100644 --- a/inst/scripts/build_ctwas_examples.R +++ b/inst/scripts/build_ctwas_examples.R @@ -70,8 +70,7 @@ gwasSumStats <- loadGwasSumStatsFromManifest( manifest = data.frame(study = "gwas1", sumStatsPath = gwasTsv), genome = "hg38", ldReference = ldStem, - region = "chr22:10000000-19000000", - ldBlocks = blocks + which = blocks ) gwasByRegion <- summaryStatsQc( gwasSumStats, @@ -112,7 +111,8 @@ stopifnot( # ----------------------------------------------------------------------------- ctwasInputsExample <- assembleCtwasInputs( gwasSumStats = gwasByRegion, - twasWeights = list(ctwasWeightsExample) + twasWeights = list(ctwasWeightsExample), + method = "susie" ) ctwasEstExample <- estCtwasGroupPriors( diff --git a/inst/scripts/build_examples.R b/inst/scripts/build_examples.R index d6ca6d0e..043a39f5 100644 --- a/inst/scripts/build_examples.R +++ b/inst/scripts/build_examples.R @@ -116,7 +116,7 @@ phenoSe <- SummarizedExperiment::SummarizedExperiment( ) qtlDatasetExample <- QtlDataset( - study = "study1", + studyName = "study1", genotypes = gh, phenotypes = list(brain = phenoSe), genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0) @@ -158,7 +158,7 @@ qtlSumStatsExample <- QtlSumStats( entry = list(qtlGr), genome = "hg19", ldReference = gh, - qcInfo = list(prebuilt = "synthetic example data; QC bypassed") + qcOptions = list(prebuilt = "synthetic example data; QC bypassed") ) # ----------------------------------------------------------------------------- @@ -192,7 +192,7 @@ gwasSumStatsS4Example <- GwasSumStats( entry = list(gwasGr), genome = "hg19", ldReference = gh, - qcInfo = list(prebuilt = "synthetic example data; QC bypassed") + qcOptions = list(prebuilt = "synthetic example data; QC bypassed") ) # ----------------------------------------------------------------------------- @@ -210,7 +210,7 @@ phenoSe2 <- SummarizedExperiment::SummarizedExperiment( ) qd2 <- QtlDataset( - study = "study2", + studyName = "study2", genotypes = gh, phenotypes = list(brain = phenoSe2), genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0) @@ -289,7 +289,7 @@ qtlSumStatsMulticontextExample <- QtlSumStats( entry = multiCtxEntries, genome = "hg19", ldReference = gh, - qcInfo = list(prebuilt = "synthetic multi-context example; QC bypassed") + qcOptions = list(prebuilt = "synthetic multi-context example; QC bypassed") ) # ----------------------------------------------------------------------------- diff --git a/man/ColocBoostResult.Rd b/man/ColocBoostResult.Rd index 06381778..0235550a 100644 --- a/man/ColocBoostResult.Rd +++ b/man/ColocBoostResult.Rd @@ -11,7 +11,7 @@ ColocBoostResult( outcomeInfo = NULL, ldReference = NULL, computingTime = list(), - includeUncolocalized = TRUE + metadata = list() ) } \arguments{ @@ -39,13 +39,15 @@ objects.} \item{computingTime}{Optional list of per-analysis timings.} -\item{includeUncolocalized}{Keep the outcome-specific (uncolocalized) sets -as elements flagged \code{isColocalized = FALSE}. Default \code{TRUE}: -dropping them at write time would make "no colocalization here" and "no -signal here" indistinguishable downstream.} +\item{metadata}{A list of free-form metadata about the collection, +as \code{metadata()} holds on any Bioconductor vector. Default +\code{list()}.} } \value{ -A \code{ColocBoostResult}. +A \code{ColocBoostResult}. The outcome-specific (uncolocalized) + sets are kept as elements flagged \code{isColocalized = FALSE}, so "no + colocalization here" stays distinct from "no signal here"; + \code{x[x$isColocalized]} keeps the colocalized ones. } \description{ Assemble a \code{\linkS4class{ColocBoostResult}} from the raw diff --git a/man/ColocResult.Rd b/man/ColocResult.Rd index 69bacd43..13681a46 100644 --- a/man/ColocResult.Rd +++ b/man/ColocResult.Rd @@ -4,7 +4,7 @@ \alias{ColocResult} \title{Build a ColocResult} \usage{ -ColocResult(pairs, variants, ldReference = NULL) +ColocResult(pairs, variants, ldReference = NULL, metadata = list()) } \arguments{ \item{pairs}{A data frame with one row per tested pair, carrying at least @@ -23,6 +23,10 @@ frames with a \code{variant_id} column and a \code{SNP.PP.H4} column.} \code{LdMatrix} -- for every pair, or a list with one per pair; used by \code{\link{colocCredibleSets}} to compute purity. Each distinct reference is stored once.} + +\item{metadata}{A list of free-form metadata about the collection, +as \code{metadata()} holds on any Bioconductor vector. Default +\code{list()}.} } \value{ A \code{ColocResult}. diff --git a/man/CredibleSetParam.Rd b/man/CredibleSetParam.Rd index a2dd06b0..83599c88 100644 --- a/man/CredibleSetParam.Rd +++ b/man/CredibleSetParam.Rd @@ -3,69 +3,41 @@ \docType{class} \name{csCoverage} \alias{csCoverage} -\alias{csCoverage<-} \alias{secondaryCoverage} -\alias{secondaryCoverage<-} \alias{signalCutoff} -\alias{signalCutoff<-} \alias{minAbsCorr} -\alias{minAbsCorr<-} \alias{medianAbsCorr} -\alias{medianAbsCorr<-} \alias{includeAllCs} -\alias{includeAllCs<-} \alias{perCsColumns} -\alias{perCsColumns<-} \alias{maxNumSingleEffects} \alias{maxNumSingleEffectsGreedy} \alias{CredibleSetParam-class} \alias{CredibleSetParam} \alias{csCoverage,CredibleSetParam-method} -\alias{csCoverage<-,CredibleSetParam-method} \alias{secondaryCoverage,CredibleSetParam-method} -\alias{secondaryCoverage<-,CredibleSetParam-method} \alias{signalCutoff,CredibleSetParam-method} -\alias{signalCutoff<-,CredibleSetParam-method} \alias{minAbsCorr,CredibleSetParam-method} -\alias{minAbsCorr<-,CredibleSetParam-method} \alias{medianAbsCorr,CredibleSetParam-method} -\alias{medianAbsCorr<-,CredibleSetParam-method} \alias{includeAllCs,CredibleSetParam-method} -\alias{includeAllCs<-,CredibleSetParam-method} \alias{perCsColumns,CredibleSetParam-method} -\alias{perCsColumns<-,CredibleSetParam-method} \alias{maxNumSingleEffects,CredibleSetParam-method} \alias{maxNumSingleEffectsGreedy,CredibleSetParam-method} \title{Credible-Set Construction And Reporting} \usage{ csCoverage(x, ...) -csCoverage(x, ...) <- value - secondaryCoverage(x, ...) -secondaryCoverage(x, ...) <- value - signalCutoff(x, ...) -signalCutoff(x, ...) <- value - minAbsCorr(x, ...) -minAbsCorr(x, ...) <- value - medianAbsCorr(x, ...) -medianAbsCorr(x, ...) <- value - includeAllCs(x, ...) -includeAllCs(x, ...) <- value - perCsColumns(x, ...) -perCsColumns(x, ...) <- value - maxNumSingleEffects(x, ...) maxNumSingleEffectsGreedy(x, ...) @@ -84,32 +56,18 @@ CredibleSetParam( \S4method{csCoverage}{CredibleSetParam}(x) -\S4method{csCoverage}{CredibleSetParam}(x) <- value - \S4method{secondaryCoverage}{CredibleSetParam}(x) -\S4method{secondaryCoverage}{CredibleSetParam}(x) <- value - \S4method{signalCutoff}{CredibleSetParam}(x) -\S4method{signalCutoff}{CredibleSetParam}(x) <- value - \S4method{minAbsCorr}{CredibleSetParam}(x) -\S4method{minAbsCorr}{CredibleSetParam}(x) <- value - \S4method{medianAbsCorr}{CredibleSetParam}(x) -\S4method{medianAbsCorr}{CredibleSetParam}(x) <- value - \S4method{includeAllCs}{CredibleSetParam}(x) -\S4method{includeAllCs}{CredibleSetParam}(x) <- value - \S4method{perCsColumns}{CredibleSetParam}(x) -\S4method{perCsColumns}{CredibleSetParam}(x) <- value - \S4method{maxNumSingleEffects}{CredibleSetParam}(x) \S4method{maxNumSingleEffectsGreedy}{CredibleSetParam}(x) @@ -119,8 +77,6 @@ CredibleSetParam( \item{...}{Unused, present for generic consistency.} -\item{value}{The replacement value for that setting.} - \item{coverage}{Primary credible-set coverage. Default \code{0.95}.} \item{secondaryCoverage}{Additional coverages to report credible sets at. @@ -161,10 +117,12 @@ where the engine has one. \value{ \code{CredibleSetParam} returns a \code{CredibleSetParam} object, a \code{\link{MethodParam}}. Each accessor returns that - setting's value; each replacement form returns a modified copy. - \code{maxNumSingleEffects} and \code{maxNumSingleEffectsGreedy} have - no replacement form: they are seeded onto the fitting tokens, so - changing one needs a refit rather than a re-summary. + setting's value. Change a setting with \code{x$ <- value} (the + field for \code{csCoverage()} is \code{coverage}), which returns a + modified copy; \code{maxNumSingleEffects} and + \code{maxNumSingleEffectsGreedy} cannot be changed that way: they are + seeded onto the fitting tokens, so changing one needs a refit rather + than a re-summary. } \description{ How credible sets are built from a fit and which of them are diff --git a/man/CrossValidationParam.Rd b/man/CrossValidationParam.Rd index 6ee6ac4c..360169ea 100644 --- a/man/CrossValidationParam.Rd +++ b/man/CrossValidationParam.Rd @@ -8,7 +8,7 @@ \usage{ CrossValidationParam( folds = 0, - numThreads = 1, + BPPARAM = SerialParam(), samplePartition = NULL, maxVariants = NULL, weightMethods = NULL, @@ -21,9 +21,12 @@ CrossValidationParam( \code{twasWeightsPipeline} used to default to \code{5}, which made an unspecified setting mean two different things.} -\item{numThreads}{Integer. Parallel workers for the per-fold refits. -\code{1} (default) is serial; \code{-1} uses all cores. Only consulted -when \code{folds > 1}.} +\item{BPPARAM}{A \code{BiocParallelParam} the per-fold refits run on; +\code{SerialParam()} (default) runs them one at a time. Its workers draw +from random-number streams seeded by the pipeline's \code{seed}, else by +the param's own \code{RNGseed}, else by one draw from the session RNG, +so a run gives the same numbers however many workers it has. Only +consulted when \code{folds > 1}.} \item{samplePartition}{Optional pre-defined partition \code{data.frame} with columns \code{Sample} and \code{Fold}. When supplied, every method @@ -55,13 +58,13 @@ A \code{CrossValidationParam} object, a \code{\link{MethodParam}}. How cross-validation runs, shared by \code{\link{fineMappingPipeline}} and \code{\link{twasWeightsPipeline}}. - \code{folds}, \code{numThreads}, \code{samplePartition} and + \code{folds}, \code{BPPARAM}, \code{samplePartition} and \code{fitFullData} mean the same thing in both. \code{maxVariants} and \code{weightMethods} are honoured by \code{\link{twasWeightsPipeline}} only and are \strong{ignored} by \code{\link{fineMappingPipeline}}, so one bundle can be handed to either pipeline unchanged. } \examples{ -CrossValidationParam(folds = 10, numThreads = 4) +CrossValidationParam(folds = 10, BPPARAM = BiocParallel::SerialParam()) CrossValidationParam(folds = 5, fitFullData = FALSE) } diff --git a/man/CtwasResult-class.Rd b/man/CtwasResult-class.Rd index cf833834..8dc50ab2 100644 --- a/man/CtwasResult-class.Rd +++ b/man/CtwasResult-class.Rd @@ -5,18 +5,25 @@ \alias{CtwasResult-class} \title{cTWAS Result Collection} \description{ -S4 collection of cTWAS runs keyed by the identity tuple - \code{(gwasStudy, study, context, method)}. Each row holds a - \code{\linkS4class{CtwasResultEntry}} payload -- fine-mapping posteriors, - the jointly-estimated group priors, and region metadata -- for one run. +S4 collection of cTWAS runs, each keyed by the identity tuple + \code{(gwasStudy, study, context, method)} and split into one element per + cTWAS region, the way a \code{\linkS4class{GwasFineMappingResult}} holds + a genome-wide fit as one element per LD block. An element is a + \code{GRanges} of that region's gene (and, with \code{keepSnps}, SNP) + posteriors; \code{mcols()} carry the run identity, the region + (\code{blockId}), the region's per-effect susie alpha table + (\code{susieAlpha}), its region metadata (\code{regionInfo}) and the + run's jointly-estimated group priors (\code{groupPriors}), which repeat + on each of the run's rows. } \details{ Unlike the QTL family, \code{trait} is not part of the key: a cTWAS - run is multi-gene, so genes live inside the payload. The optional + run is multi-gene, so genes live inside the elements. The optional \code{jointStudies} / \code{jointContexts} columns tag rows born from a multi-study or multi-context run and participate in the uniqueness key, exactly as in the \code{\linkS4class{TwasWeights}} and fine-mapping - families. + families. \code{\link{ctwasPosteriors}} and \code{\link{susieAlpha}} + stack every region back into one \code{GRanges}. } \seealso{ \code{\link{CtwasResult}} for the constructor and diff --git a/man/CtwasResult.Rd b/man/CtwasResult.Rd index aa22f6f2..8e8fe068 100644 --- a/man/CtwasResult.Rd +++ b/man/CtwasResult.Rd @@ -11,7 +11,8 @@ CtwasResult( method, entry, jointStudies = NULL, - jointContexts = NULL + jointContexts = NULL, + metadata = list() ) } \arguments{ @@ -19,11 +20,13 @@ CtwasResult( \item{studyName}{Character vector of QTL study identifiers.} -\item{context}{Character vector of context labels (scalar per row).} +\item{context}{Character vector of context labels (scalar per run).} \item{method}{Character vector of weight-method names.} -\item{entry}{List / \code{SimpleList} of \code{CtwasResultEntry} objects.} +\item{entry}{List / \code{SimpleList} of \code{CtwasResultEntry} objects, +one per run; their posteriors and susie alpha tables must be +\code{GRanges}, which the pipeline builds them as.} \item{jointStudies}{Optional character vector (length \code{length(gwasStudy)}) listing the joined studies for a multi-study run, @@ -31,22 +34,34 @@ CtwasResult( \item{jointContexts}{Optional character vector for multi-context runs. Same shape as \code{jointStudies}.} + +\item{metadata}{A list of free-form metadata about the collection, +as \code{metadata()} holds on any Bioconductor vector. Default +\code{list()}.} } \value{ A \code{CtwasResult} object. } \description{ -Construct a \code{CtwasResult} DFrame-subclass collection of - cTWAS runs from per-tuple vectors and a list of - \code{\link{CtwasResultEntry}} payloads (one per run). A single-context run - is one row; a multi-context run emits per-context rows sharing the same - \code{jointContexts} set and jointly-estimated group priors. +Construct a \code{CtwasResult} collection of cTWAS runs from + per-run identity vectors and a list of \code{\link{CtwasResultEntry}} + payloads (one per run). Each run is split into one element per cTWAS + region -- by the payloads' \code{region_id}, or by chromosome when they + carry none -- so a single-context run is one row per region, and a + multi-context run emits per-context rows sharing the same + \code{jointContexts} set and jointly-estimated group priors. A run whose + payload holds no posteriors is kept as one empty element. } \examples{ +at <- IRanges::IRanges(c(100L, 200L), width = 1L) cre <- CtwasResultEntry( - posteriors = data.frame(id = c("g1", "g2"), susie_pip = c(0.9, 0.1)), - susieAlpha = data.frame(id = c("g1", "g2"), alpha = c(0.9, 0.1))) -cr <- CtwasResult(gwasStudy = "gwas1", studyName = "s1", context = "brain", - method = "susie", entry = list(cre)) + posteriors = GenomicRanges::GRanges("chr1", at, + id = c("g1", "g2"), region_id = "chr1_1_1000", + susie_pip = c(0.9, 0.1)), + susieAlpha = GenomicRanges::GRanges("chr1", at, + id = c("g1", "g2"), region_id = "chr1_1_1000", + susie_alpha = c(0.9, 0.1))) +cr <- CtwasResult(gwasStudy = "gwas1", studyName = "s1", + context = "brain", method = "susie", entry = list(cre)) cr } diff --git a/man/CtwasResultEntry-class.Rd b/man/CtwasResultEntry-class.Rd index f6890474..1fa7b057 100644 --- a/man/CtwasResultEntry-class.Rd +++ b/man/CtwasResultEntry-class.Rd @@ -3,6 +3,7 @@ \docType{class} \name{CtwasResultEntry-class} \alias{CtwasResultEntry-class} +\alias{coerce,CtwasResultEntry,GRanges-method} \title{cTWAS Per-Run Payload} \description{ Per-run cTWAS payload: the fine-mapping posterior table, the @@ -30,6 +31,12 @@ this run, or \code{NULL}.} \item{\code{regionInfo}}{Per-region metadata, or \code{NULL}.} }} +\section{Coercion}{ + \code{as(x, "GRanges")} gives the per-gene (and, with + SNPs kept, per-SNP) posteriors as ranges -- an error when they could not + be placed on the genome and are still a table. +} + \seealso{ \code{\link{CtwasResultEntry}} for the constructor. } diff --git a/man/DentistParam.Rd b/man/DentistParam.Rd index d152f77d..8fa4ca8c 100644 --- a/man/DentistParam.Rd +++ b/man/DentistParam.Rd @@ -13,7 +13,7 @@ DentistParam( nIter = 10, gPvalueThreshold = 0.05, duprThreshold = 0.99, - numThreads = 1, + BPPARAM = SerialParam(), correctChenEtAlBug = TRUE, seed = NULL ) @@ -33,7 +33,10 @@ Default \code{0.4}.} \item{duprThreshold}{Duplicate r-squared threshold. Default \code{0.99}.} -\item{numThreads}{Number of CPU cores. Default \code{1}.} +\item{BPPARAM}{A \code{BiocParallelParam} whose workers number the +threads DENTIST's OpenMP loops use when they run on this machine +(\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +thread. Default \code{SerialParam()}.} \item{correctChenEtAlBug}{Logical; apply the Chen et al. correction. Default \code{TRUE}.} diff --git a/man/FineMappingResultBase-class.Rd b/man/FineMappingResultBase-class.Rd index 69a67103..9ebb68c8 100644 --- a/man/FineMappingResultBase-class.Rd +++ b/man/FineMappingResultBase-class.Rd @@ -24,3 +24,22 @@ from individual-level data). Used downstream to check that the rows a pipeline combines share an LD reference.} }} +\section{Narrowed rows}{ + Each row records in its \code{fitVariants} column + the ids of the variants its fit was made with (none for a row without a + fit). A row narrowed since -- by \code{endoapply()} or \code{[[<-} -- + keeps its fit as it was, so every reader of the fit warns, with + condition class \code{pecotmrFitCoverage}, when a row holds fewer + variants than its fit describes. The readers are the accessors + (\code{susieFit()}, \code{lbf()}, \code{cvResult()}, + \code{credibleSetSummary()} and the fSuSiE views), + \code{computeCsCorrelation()}, \code{susieResult()}, + \code{extractCsInfo()}, \code{extractTopPipInfo()}, + \code{writeGwasVcf()}, and the pipelines that score the fits: + \code{colocPipeline(adjustPips = FALSE)}, \code{qtlEnrichmentPipeline()} + and \code{twasWeightsPipeline()}. Values held per variant, such as + \code{topLoci()}, are narrowed with the row and do not warn. Nothing is + rescaled: \code{\link{intersectVariants}} restricts a fit explicitly, as + \code{colocPipeline()} does by default. +} + diff --git a/man/FineMappingRow-class.Rd b/man/FineMappingRow-class.Rd index 12603144..c5bf877e 100644 --- a/man/FineMappingRow-class.Rd +++ b/man/FineMappingRow-class.Rd @@ -3,10 +3,11 @@ \docType{class} \name{FineMappingRow-class} \alias{FineMappingRow-class} +\alias{coerce,FineMappingRow,GRanges-method} \title{Fine-Mapping Row} \description{ One row's worth of fine-mapping: the variants and the stored - fit. Build one with \code{\link{fineMappingRow}} and pass a list of them + fit. Build one with \code{\link{FineMappingRow}} and pass a list of them as a collection's \code{entry} argument. } \section{Slots}{ @@ -18,9 +19,20 @@ columns are the per-variant \code{topLoci} values.} \item{\code{susieFit}}{The stored fine-mapping fit, or \code{NULL}.} \item{\code{cvResult}}{Cross-validation payload, or \code{NULL}.} + +\item{\code{fitVariants}}{The ids of the variants the stored fit was made with, in +the fit's own order, recorded when the row is built; empty for a row with +no fit. A row narrowed to fewer variants keeps them, which is how reading +the fit can tell it describes more variants than the row now holds.} }} +\section{Coercion}{ + \code{as(x, "GRanges")} gives the row's variants with + their per-variant \code{topLoci} columns: the element a collection + stores for it. +} + \seealso{ -\code{\link{fineMappingRow}}, +\code{\link{FineMappingRow}}, \code{\linkS4class{TwasWeightsRow}} } diff --git a/man/GenotypeFilterParam.Rd b/man/GenotypeFilterParam.Rd index 175f51f6..a887a35b 100644 --- a/man/GenotypeFilterParam.Rd +++ b/man/GenotypeFilterParam.Rd @@ -24,7 +24,9 @@ GenotypeFilterParam( \item{xvarCutoff}{Genotype-variance floor.} -\item{imissCutoff}{Per-variant missingness ceiling.} +\item{imissCutoff}{Per-sample missingness ceiling: a sample missing more +than this fraction of an extracted block's genotypes is dropped from +it.} \item{keepSamples}{Sample ids to restrict to; \code{character(0)} keeps all samples.} @@ -39,26 +41,20 @@ A \code{GenotypeFilterParam} object, a \code{\link{MethodParam}}. } \description{ Which variants and samples survive when a genotype matrix is - assembled, as one checked bundle. Used by \code{\link{QtlDataset}}, the - manifest loaders, and the pipelines that build a dataset. + assembled, as one checked bundle: the genotype QC of a run of + \code{\link{fineMappingPipeline}}, \code{\link{twasWeightsPipeline}} + or \code{\link{colocboostPipeline}} on a \code{\link{QtlDataset}}. + A \code{QtlDataset} records no filter of its own; \code{keepSamples} + narrows it once at the start of the run, and the other fields apply to + each extracted block, against that block's samples. } -\section{Unset versus set}{ +\section{Unset fields}{ - Every field defaults to \code{NULL}, meaning \strong{not set}, and an - unset field is absent from the result rather than carried as \code{NULL}. - That is what lets one bundle serve two roles: - \itemize{ - \item to \code{\link{QtlDataset}} it is a \emph{specification}, and - an unset field takes that constructor's own default --- \code{0} for - each cutoff, \code{character(0)} for each \code{keep}, \code{TRUE} - for \code{keepIndel}. - \item to a pipeline it is an \emph{override}, and an unset field - leaves the dataset's construct-time value alone. - } - So \code{GenotypeFilterParam(mafCutoff = 0)} and - \code{GenotypeFilterParam()} differ: the first pins the cutoff at zero, - the second defers. \code{\link{PanelFilterParam}} needs no such - distinction and keeps ordinary defaults. + Every field defaults to \code{NULL}, meaning \strong{not set}: an unset + field is absent from the result rather than carried as \code{NULL}, and + takes its default when the run resolves the bundle --- \code{0} for + each cutoff, no restriction for each \code{keep}, \code{TRUE} for + \code{keepIndel}. So \code{GenotypeFilterParam()} filters nothing. } \examples{ diff --git a/man/GenotypeHandle-class.Rd b/man/GenotypeHandle-class.Rd index 6bf82178..d5852c34 100644 --- a/man/GenotypeHandle-class.Rd +++ b/man/GenotypeHandle-class.Rd @@ -13,7 +13,7 @@ GenotypeHandle( pvar = NULL, psam = NULL, ldMeta = NULL, - region = NULL, + block = NULL, genoMeta = NULL, chroms = NULL, format = NULL @@ -29,17 +29,16 @@ GenotypeHandle( \item{ldMeta}{Path to an LD-meta TSV file (columns \code{chrom}, \code{start}, \code{end}, \code{path}; the \code{path} column may be -comma-separated as \code{ld_file,bim_file}). Requires \code{region}. The -constructor resolves the row covering \code{region}, then delegates to the +comma-separated as \code{ld_file,bim_file}). Requires \code{block}. The +constructor resolves the row covering \code{block}, then delegates to the appropriate file-based handler. When the resolved row points at PLINK2 or BGEN files, the corresponding reader is used; a row pointing at a pre-computed LD matrix (\code{.cor.xz}) is refused, as pecotmr reads no pre-computed LD from disk -- wrap such a matrix in an \code{\link{LdMatrix}} instead.} -\item{region}{Region specification for \code{ldMeta} lookup: -\code{"chr:start-end"} string or a one-row data.frame with \code{chrom}, -\code{start}, \code{end}.} +\item{block}{The \code{GRanges} window to look up in \code{ldMeta}; the +whole file of the row covering it is opened.} \item{genoMeta}{One-file-per-chromosome specification: a path to a \code{#chr,path} meta file or a named character vector (names = @@ -49,8 +48,8 @@ chromosomes, values = payload paths/prefixes). Optionally pass \item{chroms}{Optional character vector of chromosomes. With \code{genoMeta} (a sharded, one-file-per-chromosome panel) only the shards whose chromosome is listed are read, skipping the rest -- an I/O optimisation when the panel -is genome-wide but only a few chromosomes are needed. Chromosome labels are -compared canonically (\code{"chr1"}/\code{"1"} match, \code{23}/\code{X} +is genome-wide but only a few chromosomes are needed. Chromosome labels may +be in any style (\code{"chr1"}/\code{"1"} match, \code{23}/\code{X} etc.). If none of the requested chromosomes are present in the panel, every shard is read (so the caller's own absence check can report the mismatch). Only meaningful with \code{genoMeta}; supplying it with any other source is @@ -112,10 +111,10 @@ payload files live in \code{chromPaths}.} \item{\code{format}}{Character, \code{"plink2"} or \code{"bgen"}.} -\item{\code{snpInfo}}{data.frame, SNP metadata read from the index/sidecar. For a -sharded handle this is the union across chromosomes (row-bound in the order -the shards were supplied), so \code{snpIdx} stays a single global index -space.} +\item{\code{snpInfo}}{data.frame, SNP metadata read from the index/sidecar, its +\code{CHR} in UCSC style whatever the file writes. For a sharded handle +this is the union across chromosomes (row-bound in the order the shards +were supplied), so \code{snpIdx} stays a single global index space.} \item{\code{nSamples}}{Integer, number of samples.} @@ -123,8 +122,9 @@ space.} \item{\code{pgenPtr}}{Opaque pointer for PLINK2 reader state (NULL otherwise).} -\item{\code{chromPaths}}{Named character vector mapping canonical chromosome (e.g. -\code{"21"}, \code{"X"}) to the per-chromosome payload path/prefix. Empty +\item{\code{chromPaths}}{Named character vector mapping each chromosome, in UCSC +style (e.g. \code{"chr21"}, \code{"chrX"}), to the per-chromosome +payload path/prefix. Empty (\code{character(0)}) for a single-file handle; non-empty marks a one-file-per-chromosome (sharded) handle whose extraction is routed by chromosome.} diff --git a/man/GenotypeMixture-class.Rd b/man/GenotypeMixture-class.Rd index f569ded8..9cda9439 100644 --- a/man/GenotypeMixture-class.Rd +++ b/man/GenotypeMixture-class.Rd @@ -11,6 +11,10 @@ \arguments{ \item{object}{A \code{GenotypeMixture}.} } +\value{ +\code{show} is called for its side effect and returns + \code{invisible(NULL)}. +} \description{ A \code{GenotypeMixture} uses several genotype panels (see \code{\link{readGenotypes}}) as one LD reference whose LD is the diff --git a/man/GwasFineMappingParam.Rd b/man/GwasFineMappingParam.Rd index bcb5a1ea..4d5d1d12 100644 --- a/man/GwasFineMappingParam.Rd +++ b/man/GwasFineMappingParam.Rd @@ -3,57 +3,33 @@ \docType{class} \name{fineMappingMethods} \alias{fineMappingMethods} -\alias{fineMappingMethods<-} \alias{credibleSetParam} -\alias{credibleSetParam<-} \alias{susieRssParam} -\alias{susieRssParam<-} \alias{panelFilterParam} -\alias{panelFilterParam<-} \alias{initializeWithSusieInf} -\alias{initializeWithSusieInf<-} \alias{fitRetention} -\alias{fitRetention<-} \alias{GwasFineMappingParam-class} \alias{GwasFineMappingParam} \alias{fineMappingMethods,GwasFineMappingParam-method} -\alias{fineMappingMethods<-,GwasFineMappingParam-method} \alias{credibleSetParam,GwasFineMappingParam-method} -\alias{credibleSetParam<-,GwasFineMappingParam-method} \alias{susieRssParam,GwasFineMappingParam-method} -\alias{susieRssParam<-,GwasFineMappingParam-method} \alias{panelFilterParam,GwasFineMappingParam-method} -\alias{panelFilterParam<-,GwasFineMappingParam-method} \alias{initializeWithSusieInf,GwasFineMappingParam-method} -\alias{initializeWithSusieInf<-,GwasFineMappingParam-method} \alias{fitRetention,GwasFineMappingParam-method} -\alias{fitRetention<-,GwasFineMappingParam-method} \title{Inline GWAS Fine-Mapping Settings} \usage{ fineMappingMethods(x, ...) -fineMappingMethods(x, ...) <- value - credibleSetParam(x, ...) -credibleSetParam(x, ...) <- value - susieRssParam(x, ...) -susieRssParam(x, ...) <- value - panelFilterParam(x, ...) -panelFilterParam(x, ...) <- value - initializeWithSusieInf(x, ...) -initializeWithSusieInf(x, ...) <- value - fitRetention(x, ...) -fitRetention(x, ...) <- value - GwasFineMappingParam( methods = "susie", credibleSetParam = CredibleSetParam(), @@ -65,35 +41,21 @@ GwasFineMappingParam( \S4method{fineMappingMethods}{GwasFineMappingParam}(x) -\S4method{fineMappingMethods}{GwasFineMappingParam}(x) <- value - \S4method{credibleSetParam}{GwasFineMappingParam}(x) -\S4method{credibleSetParam}{GwasFineMappingParam}(x) <- value - \S4method{susieRssParam}{GwasFineMappingParam}(x) -\S4method{susieRssParam}{GwasFineMappingParam}(x) <- value - \S4method{panelFilterParam}{GwasFineMappingParam}(x) -\S4method{panelFilterParam}{GwasFineMappingParam}(x) <- value - \S4method{initializeWithSusieInf}{GwasFineMappingParam}(x) -\S4method{initializeWithSusieInf}{GwasFineMappingParam}(x) <- value - \S4method{fitRetention}{GwasFineMappingParam}(x) - -\S4method{fitRetention}{GwasFineMappingParam}(x) <- value } \arguments{ \item{x}{A \code{GwasFineMappingParam}.} \item{...}{Unused, present for generic consistency.} -\item{value}{The replacement value for that setting.} - \item{methods}{Fine-mapping methods, as a character vector or a \code{\link{FineMappingMethodsParam}} record. Default \code{"susie"}.} @@ -124,8 +86,9 @@ result is handed back for other uses.} \code{GwasFineMappingParam} returns a \code{GwasFineMappingParam} object, a \code{\link{MethodParam}}. Each accessor returns that setting's value --- for the three nested - bundles, the \code{MethodParam} itself --- and each replacement form - returns a modified copy. + bundles, the \code{MethodParam} itself. Change a setting with + \code{x$ <- value} (the field for \code{fineMappingMethods()} + is \code{methods}), which returns a modified copy. } \description{ How \code{\link{colocPipeline}} fine-maps \code{gwasInput} diff --git a/man/GwasFineMappingResult.Rd b/man/GwasFineMappingResult.Rd index 24bec1f3..f5d01ed8 100644 --- a/man/GwasFineMappingResult.Rd +++ b/man/GwasFineMappingResult.Rd @@ -14,7 +14,8 @@ GwasFineMappingResult( dataType = NULL, dataSource = NULL, weightStandardized = NULL, - ldReference = NULL + ldReference = NULL, + metadata = list() ) } \arguments{ @@ -24,11 +25,13 @@ GwasFineMappingResult( \item{entry}{List / \code{SimpleList} of \code{FineMappingRow} objects.} -\item{blockId}{Optional character vector (per tuple) keying the external LD -block manifest, e.g. \code{"chr22_10516173_17414263"}. Provenance only, -not part of the identity key. Supply it when the block BOUNDARIES matter: -those are the one thing not recoverable from the variants, since adjacent -blocks' spans leave gaps.} +\item{blockId}{Optional character vector (per tuple) naming each row's +block, e.g. \code{"chr22_10516173_17414263"}. Provenance only, not part +of the identity key, and a name only: a block's boundaries, which the +variants cannot give since adjacent blocks' spans leave gaps, go in +\code{region}. Where it is \code{NULL}, or \code{NA} for a row, the +row's \code{blockId} is its own span, as \code{"chrom_start_end"}, so +every row is named by its block.} \item{traitPos}{Optional per-row trait genomic anchor (a \code{GRanges} or \code{NULL}), carried forward as provenance; not part of the identity key. @@ -36,9 +39,12 @@ blocks' spans leave gaps.} \item{region}{Optional per-row analysis WINDOW (a \code{GRanges} or \code{NULL}) -- the interval each row's fit was run over, carried -forward as provenance; not part of the identity key. \code{NULL} -(default) omits the column, and \code{\link{genomicRegion}} then -derives the window from the span of the variants present.} +forward as provenance; not part of the identity key. It is recorded as +given, so each range must contain its row's variants. +\code{\link{fineMappingPipeline}} always sets it, from the window of the +input row. \code{NULL} (default) omits the column, and +\code{\link{genomicRegion}} then derives the window from the span of the +variants present.} \item{dataType}{Optional assay / modality label ("bulk_rnaseq", "methylation"), recorded as a per-row provenance column. Length 1 or @@ -62,9 +68,17 @@ genotype panel (see \code{\link{readGenotypes}}), a \code{GenotypeMixture} or an \code{LdMatrix} -- used for every row, or a list with one per row; \code{NULL} for none. Each distinct reference is stored once.} + +\item{metadata}{A list of free-form metadata about the collection, +as \code{metadata()} holds on any Bioconductor vector. Default +\code{list()}.} } \value{ -A \code{GwasFineMappingResult} object. +A \code{GwasFineMappingResult} object. Its logical + \code{regionGiven} column says, per row, whether the window was given + or is the span of the variants; \code{\link{fineMappingPipeline}} + carries it over from the input. See \code{\linkS4class{GwasSumStats}} + for how the pipelines use it. } \description{ Construct a \code{GwasFineMappingResult} collection from @@ -75,13 +89,13 @@ Construct a \code{GwasFineMappingResult} collection from Rows are identified by (\code{study}, \code{method}) plus the element's own range, which is derived from the variants rather than stored, so it - cannot drift out of step with them and stays correct after - \code{\link{subsetRegion}}. + cannot drift out of step with them and stays correct when an element's + variants are narrowed. } \examples{ tl <- data.frame(variant_id = paste0("chr1:", 100 * 1:3, ":A:G"), pip = c(0.9, 0.5, 0.1), cs = c(1L, 1L, NA)) -fe <- fineMappingRow( +fe <- FineMappingRow( variantIds = tl$variant_id, susieFit = list(), topLoci = tl) GwasFineMappingResult(studyName = "t1", method = "susie", entry = list(fe)) } diff --git a/man/GwasSumStats-class.Rd b/man/GwasSumStats-class.Rd index bf89ec67..87712f8e 100644 --- a/man/GwasSumStats-class.Rd +++ b/man/GwasSumStats-class.Rd @@ -6,14 +6,30 @@ \title{GWAS Summary-Statistic Collection} \description{ S4 collection of GWAS summary statistics keyed by the identity - tuple \code{(study)}. Each element is that study's per-variant - \code{GRanges} covering a single LD block, so build one collection per - block when sweeping the genome. + tuple \code{(study)}. A study is split into one element per chromosome, + or per window when \code{\link{GwasSumStats}} is given a \code{region}, + each a per-variant \code{GRanges}; \code{\link{sumStats}} and the other + accessors stitch a study's elements back together. } \details{ -Required column: \code{study}, unique across rows. The class-level +Required column: \code{study}; the constructor also adds + \code{blockId}, naming each element's chromosome or window, and the + element's analysis window: \code{region}, a \code{GRanges} with one + range per element, and \code{regionGiven}. \code{regionGiven} is + \code{TRUE} where the window was given as a \code{region}, and + \code{FALSE} where it is the span of the element's variants when the + collection was first built, before any QC. A QC pass carries both + unchanged; the span of the variants left is \code{range(x)}. + \code{\link{colocPipeline}}, + \code{\link{colocboostPipeline}} and + \code{\link{causalInferencePipeline}} check the QTL variants against + these windows. Variants past a given window lie in one that was not + loaded, which is an error. Variants past a computed window may only be + ones the GWAS lacks, so more than one in a row is a warning. + A study repeats across its elements, so uniqueness is on + \code{(study, range)}. The class-level slots inherited from \code{\linkS4class{SumStatsBase}} -- \code{genome} - and \code{qcInfo} -- apply uniformly to every row; \code{ldReference} + and \code{qcOptions} -- apply uniformly to every row; \code{ldReference} holds each distinct LD reference once, and the \code{ldReference} column names the one each row uses. } diff --git a/man/GwasSumStats.Rd b/man/GwasSumStats.Rd index 778eecf3..7e852968 100644 --- a/man/GwasSumStats.Rd +++ b/man/GwasSumStats.Rd @@ -13,17 +13,20 @@ GwasSumStats( nCase = NULL, nControl = NULL, nSample = NULL, - qcInfo = list(), - ldBlocks = NULL, + qcOptions = list(), + region = NULL, blockId = NULL, - extraCols = list() + extraCols = list(), + metadata = list() ) } \arguments{ -\item{studyName}{Character vector of study identifiers (must be unique).} +\item{studyName}{Character vector of study identifiers, one per +\code{entry}. A study whose entries are already split by block repeats +here, once per entry, with \code{blockId} telling them apart.} \item{entry}{A \code{SimpleList} or \code{list} of \code{GRanges}, one per -study.} +study (or per block of an already-split study).} \item{genome}{Single character string giving the genome build (e.g., \code{"hg19"}, \code{"hg38"}). One build per collection.} @@ -53,42 +56,50 @@ no per-variant \code{N} column and no case/control counts. Named \code{nSample} to avoid clashing with \code{nSamples()} (the LD-panel sample size).} -\item{qcInfo}{A \code{list} recording which QC steps ran. Empty \code{list()} -on construction; populated by \code{summaryStatsQc()} with a per-step audit -record. Fine-mapping / TWAS pipelines reject inputs where -\code{length(qcInfo(x)) == 0}.} +\item{qcOptions}{A \code{list} recording the QC that ran. Empty +\code{list()} on construction; \code{summaryStatsQc()} fills it. +Fine-mapping / TWAS pipelines reject inputs where +\code{length(qcOptions(x)) == 0}.} -\item{ldBlocks}{Optional LD-block specification: a \code{GRanges}, a -data.frame with \code{chrom}/\code{start}/\code{end} (plus an optional -\code{blockId}), or a path to such a table. When supplied, each -study's variants are split into one element per block rather than one per -chromosome, and \code{blockId} takes the block's key (its \code{names}, -else a \code{blockId} metadata column, else its coordinates). cTWAS needs -this granularity: its EM estimates parameters across blocks, so a -per-chromosome split is too coarse. Variants overlapping no block are -dropped with a warning, because a variant outside every block has no -block-local LD to be fine-mapped against.} +\item{region}{Optional analysis windows, typically LD blocks: a +\code{GRanges}, or the path of a BED file, read as BED with a 0-based +start (a fourth column, when present, names each window). One set of +windows applies to every study; a list gives one set per study, +\code{NULL} for a study to split by chromosome. Each study's variants are +split into one element per window they fall in, rather than one per +chromosome, and each element's \code{region} is its window, recorded as +given. Its \code{blockId} is the window's name: its \code{names}, else +its \code{blockId} column (a BED file's fourth column), else its +coordinates. cTWAS needs this granularity: its EM estimates parameters +across blocks, so a per-chromosome split is too coarse. Variants outside +every window are dropped with a warning.} -\item{blockId}{Optional character vector of block keys, one per -\code{entry}, for entries that are \strong{already} split by block. Use -it to carry existing keys through a rebuild; without it a rebuild would -re-derive them as seqnames and collapse distinct blocks onto one key. -Mutually exclusive with \code{ldBlocks}.} +\item{blockId}{Optional character vector of block names, one per +\code{entry}, for entries that are \strong{already} split. Use it to +carry existing names through a rebuild; without it a rebuild would +re-derive them as seqnames and collapse distinct blocks onto one name. A +name only: it gives no window, which comes from \code{region}. Mutually +exclusive with \code{region}.} -\item{extraCols}{Optional named list of additional per-study columns to +\item{extraCols}{Optional named list (or \code{DataFrame} / +\code{data.frame}) of additional per-study columns to attach to the collection's \code{mcols}. Named rather than variadic because the base class's own constructor, \code{GRangesList(...)}, uses \code{...} for its \emph{elements}: a bare \code{...} here would read as adding an entry rather than a metadata column.} + +\item{metadata}{A list of free-form metadata about the collection, +as \code{metadata()} holds on any Bioconductor vector. Default +\code{list()}.} } \value{ A \code{GwasSumStats} object. } \description{ -Construct a \code{GwasSumStats} S4 DFrame-subclass collection - from per-study tuple vectors and a list of \code{GRanges} entries (one per - study), plus the LD reference(s) the rows were harmonized against and a - single genome build that applies to the whole collection. +Construct a \code{GwasSumStats} S4 collection from per-study + tuple vectors and a list of \code{GRanges} entries (one per study), plus + the LD reference(s) the rows were harmonized against and a single genome + build that applies to the whole collection. Each \code{GRanges} entry must carry per-variant statistics in its mcols (at minimum \code{SNP}, \code{A1}, \code{A2}, \code{Z}, \code{N}; optionally diff --git a/man/LdEigen.Rd b/man/LdEigen.Rd index 3b99a891..ce6aaa4f 100644 --- a/man/LdEigen.Rd +++ b/man/LdEigen.Rd @@ -20,7 +20,8 @@ LdEigen( \item{eigenList}{A list with one entry per LD block.} -\item{ldBlocks}{A \code{GRanges} of LD block intervals.} +\item{ldBlocks}{The LD block intervals: a \code{GRanges}, or the path +of a BED file, read as BED with a 0-based start.} \item{nSamples}{Integer, sample size of the LD reference panel.} diff --git a/man/LdMatrix-class.Rd b/man/LdMatrix-class.Rd index bbcffe7c..2793b216 100644 --- a/man/LdMatrix-class.Rd +++ b/man/LdMatrix-class.Rd @@ -11,6 +11,10 @@ \arguments{ \item{object}{An \code{LdMatrix}.} } +\value{ +\code{show} is called for its side effect and returns + \code{invisible(NULL)}. +} \description{ An \code{LdMatrix} carries one LD correlation matrix together with the variants it describes, and can stand wherever pecotmr takes an diff --git a/man/LdScore.Rd b/man/LdScore.Rd index 500cab4a..835d0392 100644 --- a/man/LdScore.Rd +++ b/man/LdScore.Rd @@ -26,7 +26,8 @@ annotation-stratified scores.} \item{ldScoreWeights}{Numeric regression weights, one per variant.} -\item{ldBlocks}{A \code{GRanges} of LD block intervals.} +\item{ldBlocks}{The LD block intervals: a \code{GRanges}, or the path +of a BED file, read as BED with a 0-based start.} \item{nSamples}{Integer, sample size of the LD reference panel.} diff --git a/man/MethodParam-class.Rd b/man/MethodParam-class.Rd index cbcca80d..d6301777 100644 --- a/man/MethodParam-class.Rd +++ b/man/MethodParam-class.Rd @@ -9,6 +9,7 @@ \alias{names,MethodParam-method} \alias{length,MethodParam-method} \alias{as.list,MethodParam-method} +\alias{$<-,MethodParam-method} \alias{show,MethodParam-method} \title{Typed Settings For One Pipeline Stage} \usage{ @@ -22,6 +23,8 @@ \S4method{as.list}{MethodParam}(x, ...) +\S4method{$}{MethodParam}(x, name) <- value + \S4method{show}{MethodParam}(object) } \arguments{ @@ -36,6 +39,9 @@ set.} \item{...}{Unused, for consistency with the generic.} +\item{value}{The setting's new value; \code{NULL} unsets a setting that +may be unset.} + \item{object}{A \code{MethodParam} object.} } \value{ @@ -50,6 +56,12 @@ set.} \code{as.list} returns the settings that are set, as a named list. +\code{$<-} returns the record rebuilt with that setting replaced. + The rebuild goes through the class's own constructor, so the value is + normalised and checked exactly as it is when the record is built, and a + value the constructor would refuse is refused here too. A setting that + cannot change once the record exists is refused, saying why. + \code{show} is called for its side effect and returns \code{invisible(NULL)}. } @@ -71,8 +83,8 @@ The virtual base of pecotmr's \code{*Param()} records -- \section{List interface}{ A \code{MethodParam} reads like a list: \code{$} and \code{[[} fetch a - field, and \code{names()}, \code{length()} and \code{as.list()} describe - it. + field, \code{$<-} replaces one, and \code{names()}, \code{length()} and + \code{as.list()} describe it. Those last three report only the fields that are \strong{set}. A slot holding \code{NULL} is absent from all three, while \code{$} and diff --git a/man/MultiStudyQtlDataset-class.Rd b/man/MultiStudyQtlDataset-class.Rd index 8befbf2f..9e653309 100644 --- a/man/MultiStudyQtlDataset-class.Rd +++ b/man/MultiStudyQtlDataset-class.Rd @@ -10,6 +10,12 @@ S4 container for a multi-study QTL analysis: a collection of \code{QtlSumStats} collection of summary-statistic-only studies. Used as the input to multi-study fine-mapping and colocboost-style analyses. +It is a \code{\link[S4Vectors]{SimpleList}} of the individual-level +studies, keyed by study name, so \code{length()}, \code{names()}, +\code{[[} and \code{[} address them as on any Bioconductor list; +\code{[} keeps the summary-statistic studies whole and still requires two +studies in total. + At least two studies must be present in total, counting \code{qtlDatasets} entries plus the studies in \code{sumStats}. @@ -22,9 +28,6 @@ re-aligned at construction time. \section{Slots}{ \describe{ -\item{\code{qtlDatasets}}{A named list of \code{QtlDataset} objects, keyed by study -identifier.} - \item{\code{sumStats}}{An optional \code{QtlSumStats} carrying additional summary-statistic-only studies. \code{NULL} when absent.} }} diff --git a/man/PhenotypeFilterParam.Rd b/man/PhenotypeFilterParam.Rd new file mode 100644 index 00000000..e891f2ac --- /dev/null +++ b/man/PhenotypeFilterParam.Rd @@ -0,0 +1,58 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/QtlDataset.R +\docType{class} +\name{PhenotypeFilterParam-class} +\alias{PhenotypeFilterParam-class} +\alias{PhenotypeFilterParam} +\title{Phenotype Quality-Control Options} +\usage{ +PhenotypeFilterParam( + naAction = NULL, + outlierAction = NULL, + outlierPvalThreshold = NULL, + outlierArgs = NULL +) +} +\arguments{ +\item{naAction}{How missing phenotype values are handled: \code{"drop"} +the samples with any missing value among the selected traits, +\code{"impute"} each trait's mean, or \code{"keep"} them as they are.} + +\item{outlierAction}{\code{"keep"} or \code{"drop"} samples flagged as +multivariate outliers by a robust (MCD) Mahalanobis distance, computed +on the residualized phenotypes.} + +\item{outlierPvalThreshold}{Two-sided p-value below which a sample is an +outlier. Default \code{1e-3} when unset.} + +\item{outlierArgs}{A \code{\link{CovMcdOptions}} record of extra arguments +for \code{robustbase::covMcd()}, the outlier detector.} +} +\value{ +A \code{PhenotypeFilterParam} object, a \code{\link{MethodParam}}. +} +\description{ +How a run of \code{\link{fineMappingPipeline}}, + \code{\link{twasWeightsPipeline}} or \code{\link{colocboostPipeline}} on + a \code{\link{QtlDataset}} treats the phenotypes it reads: missing + values, and multivariate outlier samples. The phenotype counterpart of + \code{\link{GenotypeFilterParam}}. A \code{QtlDataset}'s own accessors + (\code{\link{molecularTraits}}, \code{\link{residualizedPhenotypes}}) + apply none of it and return the data as stored. +} +\section{Unset fields}{ + + Every field defaults to \code{NULL}, meaning \strong{not set}, and takes + its default when the run resolves the bundle. \code{naAction} resolves + to the pipeline's own policy: fine-mapping and TWAS fits cannot take a + missing phenotype, so they drop the affected samples (and refuse + \code{"keep"}), while colocboost receives the phenotypes as they are. + Outliers are kept unless \code{outlierAction = "drop"}. +} + +\examples{ +PhenotypeFilterParam(naAction = "impute", outlierAction = "drop") +} +\seealso{ +\code{\link{GenotypeFilterParam}} +} diff --git a/man/QtlDataset-class.Rd b/man/QtlDataset-class.Rd index f2773105..e4c51dc7 100644 --- a/man/QtlDataset-class.Rd +++ b/man/QtlDataset-class.Rd @@ -89,37 +89,6 @@ than one of the things being chosen between, so it is always retained. \describe{ \item{\code{studyName}}{Character (length 1). Study identifier; used in collection classes to tag downstream \code{QtlFineMappingResult} / \code{TwasWeights} -entries. -The \code{genotype} experiment's assay reads through this handle; the -extraction accessors read it directly, so that QC can be applied per -block.} - -\item{\code{scaleResiduals}}{Logical (length 1). Whether residualization accessors -scale residuals to unit variance.} - -\item{\code{mafCutoff}}{Numeric (length 1). Minor allele frequency threshold; -variants with \code{MAF < mafCutoff} are dropped at extraction time inside -\code{genotypes()} / \code{residualizedGenotypes()}. Default 0 (no -filter).} - -\item{\code{macCutoff}}{Numeric (length 1). Minor allele count threshold; converted -to a MAF threshold using \code{max(mafCutoff, macCutoff / (2 * n))} where -\code{n} is the post-narrowing sample count of the extracted block. Default -0 (no filter).} - -\item{\code{xvarCutoff}}{Numeric (length 1). Per-variant genotype variance threshold; -variants with column variance below this are dropped at extraction time. -Default 0 (no filter).} - -\item{\code{imissCutoff}}{Numeric (length 1). Per-sample genotype-missingness -threshold; samples with a missing-genotype rate above this are dropped at -extraction time. Default 0 (no filter).} - -\item{\code{keepVariants}}{Character vector of variant identifiers to retain prior to -per-block QC. Length 0 means no restriction.} - -\item{\code{keepIndel}}{Logical (length 1). When \code{FALSE}, indel variants -(alleles that are not single nucleotides) are dropped at extraction time. -Default \code{TRUE}.} +entries.} }} diff --git a/man/QtlDataset.Rd b/man/QtlDataset.Rd index 3fa67fbd..eb5be46a 100644 --- a/man/QtlDataset.Rd +++ b/man/QtlDataset.Rd @@ -8,9 +8,7 @@ QtlDataset( studyName, genotypes, phenotypes, - genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0), - scaleResiduals = TRUE, - genotypeFilterParam = GenotypeFilterParam() + genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0) ) } \arguments{ @@ -26,34 +24,6 @@ context. Each SE must have \code{rowRanges} carrying trait positions and \item{genotypeCovariates}{Numeric matrix of genotype-derived covariates (e.g., ancestry PCs); rows are samples. Becomes the \code{colData} of the genotype experiment.} - -\item{scaleResiduals}{Logical (length 1). Default \code{TRUE}.} - -\item{genotypeFilterParam}{Which variants and samples to keep, built with -\code{\link{GenotypeFilterParam}}. A bare list is refused, since it -cannot be checked. Each field is recorded on the object and applied -lazily, at extraction time inside \code{genotypes()} / -\code{residualizedGenotypes()}: -\itemize{ - \item \code{mafCutoff} --- drop variants with - \code{MAF < mafCutoff}. Unset means 0 (no filter). - \item \code{macCutoff} --- a minor-allele-count threshold, converted - to a MAF threshold as \code{max(mafCutoff, macCutoff / (2 * n))} - with \code{n} the post-narrowing sample count of the extracted - block. Unset means 0. - \item \code{xvarCutoff} --- drop variants whose column variance is - below this. Unset means 0. - \item \code{imissCutoff} --- drop samples whose missing-genotype rate - exceeds this. Unset means 0. - \item \code{keepSamples} --- subset the dataset to these samples, - narrowing \code{colData} and \code{sampleMap} together so the - sample set has one home rather than two. Unset, or - \code{character(0)}, means no restriction. - \item \code{keepVariants} --- retain only these variants, before - per-block QC. Unset, or \code{character(0)}, means no restriction. - \item \code{keepIndel} --- when \code{FALSE}, drop variants whose - alleles are not single nucleotides. Unset means \code{TRUE}. -}} } \value{ A \code{QtlDataset} object. @@ -67,6 +37,16 @@ Construct a \code{QtlDataset}: one study's individual-level names actually present in each, so contexts observing different sample subsets are recorded rather than assumed away. } +\details{ +A \code{QtlDataset} holds data only. Which variants and samples + an analysis keeps, and whether residuals are scaled, are the pipeline's + settings (\code{\link{GenotypeFilterParam}} and + \code{\link{ResidualizationParam}} on \code{\link{fineMappingPipeline}}, + \code{\link{twasWeightsPipeline}} and \code{\link{colocboostPipeline}}), + applied per extracted block. To work with part of the data, subset the + dataset itself: \code{x[i, j, k]} narrows features, samples and + contexts. +} \examples{ panel <- readGenotypes( system.file("extdata", "toy_ref.bed", package = "pecotmr") diff --git a/man/QtlEnrichmentParam.Rd b/man/QtlEnrichmentParam.Rd index 62fa2d13..ee7a1e5b 100644 --- a/man/QtlEnrichmentParam.Rd +++ b/man/QtlEnrichmentParam.Rd @@ -42,7 +42,7 @@ A \code{QtlEnrichmentParam} object, a \code{\link{MethodParam}}. \description{ The algorithmic settings \code{\link{qtlEnrichment}} takes, as one checked bundle. Everything else that function accepts --- the two - data arguments, \code{numThreads}, \code{seed}, \code{verbose}, and the + data arguments, \code{BPPARAM}, \code{seed}, \code{verbose}, and the \code{alignNames} switch --- is the pipeline's own business and is not settable here. } diff --git a/man/QtlFineMappingResult-class.Rd b/man/QtlFineMappingResult-class.Rd index 0e43c044..55b19291 100644 --- a/man/QtlFineMappingResult-class.Rd +++ b/man/QtlFineMappingResult-class.Rd @@ -6,14 +6,16 @@ \title{QTL Fine-Mapping Result Collection} \description{ S4 collection of fine-mapping fits for one or more QTL - studies on a single LD block. Keyed by the identity tuple - \code{(study, context, trait, method)}; each entry is a - \code{FineMappingRow}. + studies, one row per \code{(study, context, trait, method)} fit. Each + element is a fit's variants: a \code{GRanges} on one chromosome whose + \code{mcols} hold the per-variant values \code{\link{topLoci}} reads. -Required columns: \code{study}, \code{context}, \code{trait}, -\code{method}, \code{entry}. The 4-tuple is unique. The caller is -expected to construct one \code{QtlFineMappingResult} per LD block (no -in-class block indexing). +Required \code{mcols()} columns: the identity tuple \code{study}, +\code{context}, \code{trait} and \code{method}, which is unique, and +each row's stored fit \code{susieFit} and cross-validation result +\code{cvResult}. The constructor also records \code{fitVariants}, the +variants each fit was made with. There is no LD-block axis: a trait's fit +is one row wherever its window falls. Optional columns \code{jointStudies}, \code{jointContexts}, \code{jointTraits} appear when the collection contains rows produced by a diff --git a/man/QtlFineMappingResult.Rd b/man/QtlFineMappingResult.Rd index 5a02e859..117635cc 100644 --- a/man/QtlFineMappingResult.Rd +++ b/man/QtlFineMappingResult.Rd @@ -18,7 +18,8 @@ QtlFineMappingResult( dataType = NULL, dataSource = NULL, weightStandardized = NULL, - ldReference = NULL + ldReference = NULL, + metadata = list() ) } \arguments{ @@ -78,21 +79,25 @@ against -- a genotype panel (see \code{\link{readGenotypes}}), a \code{GenotypeMixture} or an \code{LdMatrix} -- used for every row, or a list with one per row; \code{NULL} for individual-level fits. Each distinct reference is stored once.} + +\item{metadata}{A list of free-form metadata about the collection, +as \code{metadata()} holds on any Bioconductor vector. Default +\code{list()}.} } \value{ A \code{QtlFineMappingResult} object. } \description{ -Construct a \code{QtlFineMappingResult} DFrame-subclass - collection from per-tuple vectors and a list of \code{FineMappingRow} - payloads (one per tuple). The optional \code{ldReference} records the LD +Construct a \code{QtlFineMappingResult} collection from + per-tuple vectors and a list of \code{FineMappingRow} payloads (one per + tuple). The optional \code{ldReference} records the LD reference each RSS-derived fit used; leave it \code{NULL} (the default) for individual-level fits. } \examples{ tl <- data.frame(variant_id = paste0("chr1:", 100 * 1:3, ":A:G"), pip = c(0.9, 0.5, 0.1), cs = c(1L, 1L, NA)) -fe <- fineMappingRow( +fe <- FineMappingRow( variantIds = tl$variant_id, susieFit = list(), topLoci = tl) QtlFineMappingResult(studyName = "s1", context = "brain", trait = "g1", method = "susie", entry = list(fe)) diff --git a/man/QtlSumStats-class.Rd b/man/QtlSumStats-class.Rd index 5c2aa7ad..c2dfe632 100644 --- a/man/QtlSumStats-class.Rd +++ b/man/QtlSumStats-class.Rd @@ -12,10 +12,19 @@ S4 collection of QTL summary statistics keyed by the identity } \details{ Required columns: \code{study}, \code{context} and \code{trait}; - the 3-tuple is unique. The class-level slots inherited from - \code{\linkS4class{SumStatsBase}} -- \code{genome} and \code{qcInfo} -- - apply uniformly to every row, and \code{qcInfo} records which - \code{\link{summaryStatsQc}} passes have run; \code{ldReference} holds + the 3-tuple is unique. The constructor also adds each tuple's analysis + window: \code{region}, a \code{GRanges} with one range per element, and + \code{regionGiven}, \code{TRUE} where the window was given as a + \code{region} and \code{FALSE} where it is the span of the tuple's + variants when the collection was first built, before any QC. A QC pass + carries both unchanged; the span of the variants left is + \code{range(x)}. An optional \code{traitPos} gives the trait's own + coordinates, from which a pipeline's \code{cisWindow} derives a cis + window. The class-level slots inherited from + \code{\linkS4class{SumStatsBase}} -- \code{genome} and + \code{qcOptions} -- apply uniformly to every row, and \code{qcOptions} + records the \code{\link{summaryStatsQc}} options that ran (what QC did + to each row is \code{\link{qcInfo}}); \code{ldReference} holds each distinct LD reference once, and the \code{ldReference} column names the one each row uses. } diff --git a/man/QtlSumStats.Rd b/man/QtlSumStats.Rd index 52e822c8..3240aa33 100644 --- a/man/QtlSumStats.Rd +++ b/man/QtlSumStats.Rd @@ -13,9 +13,11 @@ QtlSumStats( ldReference = NULL, varY = NA_real_, nSample = NULL, - qcInfo = list(), + qcOptions = list(), traitPos = NULL, - extraCols = list() + region = NULL, + extraCols = list(), + metadata = list() ) } \arguments{ @@ -48,33 +50,46 @@ no per-variant \code{N} column. Named \code{nSample} to avoid clashing with collections carry no case/control counts (molecular traits are quantitative), so only this total-N fallback is exposed.} -\item{qcInfo}{A \code{list} recording which QC steps ran. Empty \code{list()} -on construction; populated by \code{summaryStatsQc()} with a per-step audit -record. Fine-mapping / TWAS pipelines reject inputs where -\code{length(qcInfo(x)) == 0}.} +\item{qcOptions}{A \code{list} recording the QC that ran. Empty +\code{list()} on construction; \code{summaryStatsQc()} fills it. +Fine-mapping / TWAS pipelines reject inputs where +\code{length(qcOptions(x)) == 0}.} \item{traitPos}{Optional per-row trait genomic anchor (a \code{GRanges} or \code{NULL}), carried forward as provenance; not part of the identity key. -\code{NULL} (default) omits the column.} +\code{NULL} (default) omits the column. A pipeline given a +\code{cisWindow} analyses each tuple over \code{traitPos} \eqn{\pm} +\code{cisWindow}.} -\item{extraCols}{Optional named list of additional per-tuple columns to +\item{region}{Optional analysis window of each tuple: a \code{GRanges}, +or the path of a BED file, read as BED with a 0-based start. One window +for every tuple, or one per tuple. A tuple's variants outside its window +are dropped with a warning, and its \code{region} is the window, +recorded as given in \code{regionGiven}. Without it, a tuple's +\code{region} is the span of its variants as built, before any QC.} + +\item{extraCols}{Optional named list (or \code{DataFrame} / +\code{data.frame}) of additional per-tuple columns to attach to the collection's \code{mcols}. Named rather than variadic because the base class's own constructor, \code{GRangesList(...)}, uses \code{...} for its \emph{elements}: a bare \code{...} here would read as adding an entry rather than a metadata column.} + +\item{metadata}{A list of free-form metadata about the collection, +as \code{metadata()} holds on any Bioconductor vector. Default +\code{list()}.} } \value{ A \code{QtlSumStats} object. } \description{ -Construct a \code{QtlSumStats} S4 DFrame-subclass collection - from per-tuple vectors and a list of \code{GRanges} entries (one per - tuple), plus the LD reference(s) the rows were harmonized against and a - single genome build that applies to the whole collection. Each - \code{GRanges} entry must carry per-variant - statistics in its mcols (\code{SNP}, \code{A1}, \code{A2}, \code{Z}, - \code{N}; plus optional \code{MAF}, \code{INFO}, \code{BETA}, \code{SE}, - \code{P}). +Construct a \code{QtlSumStats} S4 collection from per-tuple + vectors and a list of \code{GRanges} entries (one per tuple), plus the LD + reference(s) the rows were harmonized against and a single genome build + that applies to the whole collection. Each \code{GRanges} entry must + carry per-variant statistics in its mcols (\code{SNP}, \code{A1}, + \code{A2}, \code{Z}, \code{N}; plus optional \code{MAF}, \code{INFO}, + \code{BETA}, \code{SE}, \code{P}). } \examples{ panel <- readGenotypes( diff --git a/man/RaissParam.Rd b/man/RaissParam.Rd index 80ad15a7..2daac830 100644 --- a/man/RaissParam.Rd +++ b/man/RaissParam.Rd @@ -47,7 +47,12 @@ this and \code{mafCutoff} applies. Default \code{0}.} \item{imissCutoff}{Missingness ceiling for a target. Default \code{1}.} \item{flank}{Base pairs by which to widen the analysis-region window on -each side, retaining LD context for edge variants. Default \code{0}.} +each side, retaining LD context for edge variants. The window never +widens into another row of the same study on its chromosome -- the +neighbouring LD block of a block-split GWAS -- since that row imputes +its own variants, nor past a row's block range where that was given +(\code{regionGiven}, see \code{\linkS4class{GwasSumStats}}). Default +\code{0}.} } \value{ A \code{RaissParam} object, a \code{\link{MethodParam}}. diff --git a/man/RangedTupleList-class.Rd b/man/RangedTupleList-class.Rd index a233bbbf..3095b95f 100644 --- a/man/RangedTupleList-class.Rd +++ b/man/RangedTupleList-class.Rd @@ -14,6 +14,22 @@ Virtual base class for pecotmr's per-element collections. Each elements and \code{mcols} together, but leaves slots untouched, so a per-element slot silently ends up the wrong length and positionally wrong. } +\section{Sequence names and genome build}{ + Every range pecotmr holds is on + UCSC sequence names (\code{chr1}, \code{chrX}, \code{chrM}), the style + \code{seqlevelsStyle(x) <- "UCSC"} gives. Ranges read from a file, + placed by variant id, passed to a constructor or given as a range + argument are renamed on the way in (\code{"1"} and \code{"chr1"} both + become \code{chr1}), so ranges from different inputs compare as they + are. A query handed straight to an inherited Bioconductor method, such + as \code{subsetByOverlaps()}, is not renamed: give it in UCSC style. + A pipeline's result carries the genome build its inputs name in + \code{seqinfo()}, as do the ranged views of it (\code{topLoci()}, + \code{colocVariants()}, ...); inputs naming different builds are + refused. When no input names one, \code{genome()} is \code{NA} until it + is set with \code{genome(x) <- "hg38"}. +} + \section{Invariant}{ One seqname and one strand per element. \code{range()} splits on both, so a mixed element would return two ranges and break the diff --git a/man/RangedTupleList-methods.Rd b/man/RangedTupleList-methods.Rd index c20e7fda..319abb1c 100644 --- a/man/RangedTupleList-methods.Rd +++ b/man/RangedTupleList-methods.Rd @@ -7,9 +7,13 @@ \alias{colnames,RangedTupleList-method} \alias{$,RangedTupleList-method} \alias{$<-,RangedTupleList-method} +\alias{elementMetadata<-,RangedTupleList-method} \alias{[,RangedTupleList,ANY,ANY,ANY-method} \alias{[[<-,RangedTupleList,ANY,ANY-method} \alias{endoapply,RangedTupleList-method} +\alias{sort,RangedTupleList-method} +\alias{unique,RangedTupleList-method} +\alias{trim,RangedTupleList-method} \alias{bindROWS,RangedTupleList-method} \title{RangedTupleList methods} \usage{ @@ -23,12 +27,20 @@ \S4method{$}{RangedTupleList}(x, name) <- value +\S4method{elementMetadata}{RangedTupleList}(x, ...) <- value + \S4method{[}{RangedTupleList,ANY,ANY,ANY}(x, i, j, ..., drop = TRUE) \S4method{[[}{RangedTupleList,ANY,ANY}(x, i, j, ...) <- value \S4method{endoapply}{RangedTupleList}(X, FUN, ...) +\S4method{sort}{RangedTupleList}(x, decreasing = FALSE, ...) + +\S4method{unique}{RangedTupleList}(x, incomparables = FALSE, ...) + +\S4method{trim}{RangedTupleList}(x, use.names = TRUE, ...) + \S4method{bindROWS}{RangedTupleList}( x, objects = list(), @@ -44,28 +56,36 @@ \item{name}{An \code{mcols} column name.} -\item{value}{Replacement value for that column.} +\item{value}{For \code{$<-}, the replacement column; for +\code{elementMetadata<-}, the replacement metadata table.} + +\item{...}{Additional arguments passed on.} \item{i}{Element selector.} \item{j}{Not supported; supplying it is an error.} -\item{...}{Additional arguments passed on.} - \item{drop}{Passed through to the inherited method.} \item{FUN}{A function applied to each element, returning a \code{GRanges}.} +\item{decreasing}{Passed to each element's \code{sort()}.} + +\item{incomparables}{Passed to each element's \code{unique()}.} + +\item{use.names}{For \code{trim()}, passed to each element's +\code{trim()}; otherwise unused, present for generic compatibility.} + \item{objects}{Further collections to append, as \code{c()} and \code{append()} pass them.} -\item{use.names, ignore.mcols, check}{Unused; present for generic -compatibility.} +\item{ignore.mcols, check}{Unused; present for generic compatibility.} } \value{ \code{nrow()} and \code{ncol()} integers; \code{colnames()} a - character vector; \code{$} a metadata column; \code{$<-}, \code{[} and - \code{endoapply()} a collection of the same class. + character vector; \code{$} a metadata column; \code{$<-}, + \code{elementMetadata<-}, \code{[}, \code{endoapply()}, \code{sort()}, + \code{unique()} and \code{trim()} a collection of the same class. } \description{ Container and metadata methods shared by every @@ -74,10 +94,18 @@ Container and metadata methods shared by every \code{nrow()} counts elements, \code{ncol()} counts metadata columns and \code{colnames()} names them, so the collections read exactly as the \code{DFrame}-shaped ones they replace. \code{$} and \code{$<-} - read and write \code{mcols} columns. \code{[} selects elements and + read and write \code{mcols} columns. Storing metadata, whether by + \code{$<-}, \code{mcols<-} or its older spellings \code{values<-} and + \code{elementMetadata<-}, refuses an identity column (\code{study}, + \code{context}, \code{trait}, \code{method}, their \code{gwas} + counterparts and \code{blockId}) that is not character; \code{NA} values + are allowed. \code{[} selects elements and \strong{rejects} a second argument, because the stock method would silently discard it. \code{endoapply()} maps over the elements and - rebuilds the object with its collection-level slots intact. + rebuilds the object with its collection-level slots intact; + \code{sort()}, \code{unique()} and \code{trim()} work on each element + the same way, so they too return the collection's own class rather than + a bare \code{GRangesList}. } \examples{ data(qtlSumStatsMulticontextExample) diff --git a/man/ResidualizationParam.Rd b/man/ResidualizationParam.Rd index b07794e7..9c0903ba 100644 --- a/man/ResidualizationParam.Rd +++ b/man/ResidualizationParam.Rd @@ -31,12 +31,10 @@ covariates. \code{NULL} (default) means unset, read as \code{TRUE}.} \item{scaleResiduals}{Logical. Scale each residual column to unit variance, which is what puts a fitted effect on the standardized -genotype scale. \code{NULL} (default) means unset, and the accessors -fall back to the dataset's own \code{\link{scaleResiduals}} slot -(itself \code{TRUE} by default) --- so this is the per-call override of -a per-object default, and the only knob the pipelines need: it reaches -\code{\link{residualizedGenotypes}} already, which is the one point -every individual-level fit draws its genotypes through.} +genotype scale. \code{NULL} (default) means unset, read as +\code{TRUE}. It is the only scale knob the pipelines need: it reaches +\code{\link{residualizedGenotypes}}, the one point every +individual-level fit draws its genotypes through.} \item{covariateNaAction}{How missing covariate values are handled when the design is assembled: \code{"impute"} or \code{"drop"}. \code{NULL} diff --git a/man/SumStatsBase-class.Rd b/man/SumStatsBase-class.Rd index d47425fc..7865724b 100644 --- a/man/SumStatsBase-class.Rd +++ b/man/SumStatsBase-class.Rd @@ -8,7 +8,7 @@ Virtual base class for QTL and GWAS summary statistics collections. Concrete subclasses (\code{QtlSumStats}, \code{GwasSumStats}) inherit from \code{\linkS4class{RangedTupleList}} and share the - \code{ldReference} / \code{qcInfo} slots, and the genome build in + \code{ldReference} / \code{qcOptions} slots, and the genome build in \code{seqinfo()}. Each element is the per-variant \code{GRanges} of one tuple, so @@ -29,11 +29,11 @@ uses, so rows can sit on different references. Optional: an LD-free row \code{NA} there; pipelines that need LD validate its presence when they consume the collection.} -\item{\code{qcInfo}}{A \code{list} recording which QC steps ran. Empty \code{list()} -on construction; populated by \code{summaryStatsQc()} with a per-step audit -record (filter names, drop counts, liftover target, RAISS settings, etc.). -Fine-mapping and TWAS-weights pipelines reject inputs where -\code{length(qcInfo(x)) == 0L} -- the slot serves as both the gating -flag and the audit trail.} +\item{\code{qcOptions}}{A \code{list} recording the QC that ran over the +collection: the options \code{summaryStatsQc()} was called with and when. +Empty \code{list()} on construction. Pipelines that need QC'd summary +statistics refuse inputs where \code{length(qcOptions(x)) == 0L}. What +QC did to each row is in the \code{qcAudit} column of \code{mcols()}, +read as a table with \code{\link{qcInfo}}.} }} diff --git a/man/TwasWeights-class.Rd b/man/TwasWeights-class.Rd index 0a6cab95..79011866 100644 --- a/man/TwasWeights-class.Rd +++ b/man/TwasWeights-class.Rd @@ -5,14 +5,16 @@ \alias{TwasWeights-class} \title{TWAS Weights Collection} \description{ -S4 collection of TWAS weights keyed by the identity tuple - \code{(study, context, trait, method)}. Each entry is a - \code{TwasWeightsRow} carrying one method's weights for one - trait/context/study. Implements the \code{DFrame}-subclass collection - pattern. +S4 collection of TWAS weights, one row per + \code{(study, context, trait, method)}: one method's weights for one + trait, context and study. Each element is a row's variants: a + \code{GRanges} whose \code{weight} column holds the weights. -Required columns: \code{study}, \code{context}, \code{trait}, \code{method}, -\code{entry}. Each \code{entry} is a \code{TwasWeightsRow}. +Required \code{mcols()} columns: the identity tuple \code{study}, +\code{context}, \code{trait} and \code{method}, and each row's payload: +its stored fits (\code{fits}), \code{cvResult}, \code{standardized} and +\code{dataType}. The constructor also records \code{fitVariants}, the +variants the weights were fitted on. Optional columns \code{jointStudies}, \code{jointContexts}, \code{jointTraits} appear when the collection contains rows produced by a @@ -33,3 +35,16 @@ learned from individual-level data). Used downstream to check that the rows a pipeline combines share an LD reference.} }} +\section{Narrowed rows}{ + Each row records in its \code{fitVariants} column + the ids of the variants its weights were fitted on (none for a row + without a fit payload). A row narrowed since keeps its fits as they + were, so \code{cvResult()} and \code{methodFits()} warn, with condition + class \code{pecotmrFitCoverage}, when a row holds fewer variants than + they describe. So do the pipelines that read them: + \code{causalInferencePipeline()} when it selects weights by their + cross-validation, and \code{ctwasPipeline()} for rows whose SuSiE fit + renormalizes their weights. The weights themselves are narrowed with + the row and do not warn. +} + diff --git a/man/TwasWeights.Rd b/man/TwasWeights.Rd index 43e92413..0098b51a 100644 --- a/man/TwasWeights.Rd +++ b/man/TwasWeights.Rd @@ -15,7 +15,8 @@ TwasWeights( jointTraits = NULL, traitPos = NULL, region = NULL, - ldReference = NULL + ldReference = NULL, + metadata = list() ) } \arguments{ @@ -58,17 +59,20 @@ a genotype panel (see \code{\link{readGenotypes}}), a \code{GenotypeMixture} or an \code{LdMatrix} -- used for every row, or a list with one per row; \code{NULL} for individual-level fits. Each distinct reference is stored once.} + +\item{metadata}{A list of free-form metadata about the collection, +as \code{metadata()} holds on any Bioconductor vector. Default +\code{list()}.} } \value{ A \code{TwasWeights} object. } \description{ -Construct a \code{TwasWeights} DFrame-subclass collection from - per-tuple vectors and a list of \code{TwasWeightsRow} payloads (one per - tuple). +Construct a \code{TwasWeights} collection from per-tuple + vectors and a list of \code{TwasWeightsRow} payloads (one per tuple). } \examples{ -twe <- twasWeightsRow(variantIds = sprintf("chr1:\%d:A:G", 100L * (1:4)), +twe <- TwasWeightsRow(variantIds = sprintf("chr1:\%d:A:G", 100L * (1:4)), weights = rep(0.1, 4), cvResult = list(rsq = 0.5), weightStandardized = FALSE) tw <- TwasWeights(studyName = "s1", context = "brain", trait = "gene1", diff --git a/man/TwasWeightsRow-class.Rd b/man/TwasWeightsRow-class.Rd index dd800cbc..424ff1b4 100644 --- a/man/TwasWeightsRow-class.Rd +++ b/man/TwasWeightsRow-class.Rd @@ -3,10 +3,11 @@ \docType{class} \name{TwasWeightsRow-class} \alias{TwasWeightsRow-class} +\alias{coerce,TwasWeightsRow,GRanges-method} \title{TWAS Weights Row} \description{ One row's worth of TWAS weights. Build one with - \code{\link{twasWeightsRow}} and pass a list of them as + \code{\link{TwasWeightsRow}} and pass a list of them as \code{\link{TwasWeights}}' \code{entry} argument. } \section{Slots}{ @@ -23,9 +24,20 @@ One row's worth of TWAS weights. Build one with \item{\code{weightStandardized}}{Whether the weights are on the standardized scale.} \item{\code{weightsDataType}}{Optional data-type label.} + +\item{\code{fitVariants}}{The ids of the variants the weights were fitted on, in +the fit's own order, recorded when the row is built; empty for a row with +no fit payload. A row narrowed to fewer variants keeps them, which is how +reading its fits can tell they describe more variants than the row now +holds.} }} +\section{Coercion}{ + \code{as(x, "GRanges")} gives the row's variants with + their \code{weight} column: the element a collection stores for it. +} + \seealso{ -\code{\link{twasWeightsRow}}, +\code{\link{TwasWeightsRow}}, \code{\linkS4class{FineMappingRow}} } diff --git a/man/af.Rd b/man/af.Rd index 0bd8a582..3ebe5b6c 100644 --- a/man/af.Rd +++ b/man/af.Rd @@ -12,23 +12,15 @@ af(x, ...) \S4method{af}{LdMatrix}(x, ...) -\S4method{af}{SumStatsBase}( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL -) +\S4method{af}{SumStatsBase}(x, studyName = NULL, context = NULL, trait = NULL) -\S4method{af}{QtlDataset}(x, traitId = NULL, region = NULL, cisWindow = NULL, samples = NULL) +\S4method{af}{QtlDataset}(x) } \arguments{ \item{x}{A \code{QtlDataset}, \code{LdMatrix}, \code{GwasSumStats} or \code{QtlSumStats} object.} -\item{...}{Class-specific selection arguments (e.g., \code{traitId}, -\code{region}, \code{cisWindow}, \code{samples} for \code{QtlDataset}).} +\item{...}{Class-specific selection arguments.} \item{studyName}{Character (length 1) or \code{NULL}. Restrict the selection to this study; \code{NULL} matches all studies.} @@ -38,25 +30,6 @@ this context; \code{NULL} matches all contexts.} \item{trait}{Character (length 1) or \code{NULL}. Restrict the selection to this trait; \code{NULL} matches all traits.} - -\item{annotateSignificance}{Optional correction-method name passed through to -\code{\link{sumStats}} (QTL only); \code{NULL} applies none.} - -\item{ranges}{A \code{GRanges} or \code{NULL} (default). Return only the -variants overlapping these ranges; \code{NULL} returns everything.} - -\item{traitId}{Character or \code{NULL}. Molecular trait / feature identifier -to select; \code{NULL} matches all traits in the dataset.} - -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -Restrict variants to this region; \code{NULL} uses the full cis window / -all regions.} - -\item{cisWindow}{Integer or \code{NULL}. Half-width (bp) of the cis window -around the trait; \code{NULL} uses the dataset default.} - -\item{samples}{Character vector or \code{NULL}. Restrict to these sample IDs; -\code{NULL} uses all samples.} } \value{ Named numeric vector of effect-allele frequencies (names are variant @@ -72,7 +45,8 @@ Extract the directional effect-allele (A1) frequency vector \code{af} column report. For a summary-statistic collection this is \code{NULL} when the source carried no frequency column -- see \code{\link{variantColumnReplace}} - for supplying one afterwards. + for supplying one afterwards. A \code{QtlDataset} answers over the whole + dataset; narrow it first, with \code{x[i, j, ]}, to read part of it. } \examples{ data(qtlDatasetExample) diff --git a/man/annotData.Rd b/man/annotData.Rd index 26e13383..9752b959 100644 --- a/man/annotData.Rd +++ b/man/annotData.Rd @@ -13,7 +13,7 @@ annotData(x) \item{x}{An \code{\link{SldscData}} object.} } \value{ -A \code{data.frame} of annotations (CHR, SNP, annotation columns). +A \code{DataFrame} of annotations (CHR, SNP, annotation columns). } \description{ Get the annotation table from an SldscData diff --git a/man/as.data.frame-ColocBoostResult-method.Rd b/man/as.data.frame-ColocBoostResult-method.Rd deleted file mode 100644 index caef690b..00000000 --- a/man/as.data.frame-ColocBoostResult-method.Rd +++ /dev/null @@ -1,26 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/ColocBoostResult.R -\name{as.data.frame,ColocBoostResult-method} -\alias{as.data.frame,ColocBoostResult-method} -\title{Coerce a ColocBoostResult to a data frame} -\usage{ -\S4method{as.data.frame}{ColocBoostResult}(x, row.names = NULL, optional = FALSE, ...) -} -\arguments{ -\item{x}{A \code{ColocBoostResult}.} - -\item{row.names, optional}{Ignored; present for generic compatibility.} - -\item{...}{Ignored.} -} -\value{ -A data frame with one row per confidence set. -} -\description{ -Returns the set-level view. New code should call the view it - wants (\code{\link{colocViews}}, - \code{\link{colocBoostOutcomes}}). -} -\examples{ -methods::existsMethod("as.data.frame", "ColocBoostResult") -} diff --git a/man/as.data.frame-ColocResult-method.Rd b/man/as.data.frame-ColocResult-method.Rd deleted file mode 100644 index 86f8242a..00000000 --- a/man/as.data.frame-ColocResult-method.Rd +++ /dev/null @@ -1,40 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/ColocResult.R -\name{as.data.frame,ColocResult-method} -\alias{as.data.frame,ColocResult-method} -\title{Coerce a ColocResult to a data frame} -\usage{ -\S4method{as.data.frame}{ColocResult}(x, row.names = NULL, optional = FALSE, ...) -} -\arguments{ -\item{x}{A \code{ColocResult}.} - -\item{row.names, optional}{Ignored; present for generic compatibility.} - -\item{...}{Ignored.} -} -\value{ -A data frame with one row per tested pair. -} -\description{ -Returns the pair-level view, which is the flat table - \code{colocPipeline()} used to return directly. Provided so existing - consumers keep working; new code should call the view it actually wants - (see \code{\link{colocViews}}). -} -\examples{ -pairs <- data.frame( - study = "s1", context = "c1", trait = "g1", method = "susie", - gwasStudy = "G1", gwasContext = NA_character_, - gwasTrait = NA_character_, gwasMethod = "susie", - blockId = "chr1_1_1000", - qtlCs = 1L, gwasCs = 1L, nSnps = 2L, - PP.H0.abf = 0.1, PP.H1.abf = 0.1, PP.H2.abf = 0.1, - PP.H3.abf = 0.1, PP.H4.abf = 0.6 -) -variants <- list(data.frame( - variant_id = c("chr1:100:A:G", "chr1:200:C:T"), - SNP.PP.H4 = c(0.7, 0.3) -)) -as.data.frame(ColocResult(pairs, variants)) -} diff --git a/man/asGranges.Rd b/man/asGranges.Rd deleted file mode 100644 index d06d8fa5..00000000 --- a/man/asGranges.Rd +++ /dev/null @@ -1,24 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/variantId.R -\name{asGranges} -\alias{asGranges} -\title{Convert region specifications to a GRanges object} -\usage{ -asGranges(regions) -} -\arguments{ -\item{regions}{A region string, character vector, or data.frame with -chrom/start/end columns.} -} -\value{ -A \code{GRanges} object. -} -\description{ -Accepts region strings ("chr1:100-200", "1_100_200"), character vectors of -such strings, or data.frames with chrom/start/end columns. Returns a -\code{\link[GenomicRanges]{GRanges}} object. -} -\examples{ -regions <- c("chr1:100-200", "chr1:300-400") -asGranges(regions = regions) -} diff --git a/man/assembleCtwasInputs.Rd b/man/assembleCtwasInputs.Rd index b871e86a..a1714c58 100644 --- a/man/assembleCtwasInputs.Rd +++ b/man/assembleCtwasInputs.Rd @@ -9,6 +9,7 @@ assembleCtwasInputs( twasWeights, twasZ = NULL, fineMappingResult = NULL, + fineMappingMethod = NULL, method = NULL, variantPruningParam = VariantPruningParam() ) @@ -16,8 +17,8 @@ assembleCtwasInputs( \arguments{ \item{gwasSumStats}{A \code{\link{GwasSumStats}} whose elements are LD blocks (at least two), keyed by its \code{blockId} column, with -\code{qcInfo()} non-empty. Build it with -\code{loadGwasSumStatsFromManifest(..., ldBlocks = )} and pass it +\code{qcOptions()} non-empty. Build it with +\code{loadGwasSumStatsFromManifest(..., region = )} and pass it through \code{\link{summaryStatsQc}}.} \item{twasWeights}{The per-gene weight source. Either (a) a FLAT @@ -31,27 +32,38 @@ ctwas's joint group prior estimate (the legacy whole-chromosome pattern where only a few of many LD blocks carry gene weights). A gene whose cis span straddles a block boundary is homed by its single anchor; the cross-block signal is cTWAS's boundary-gene concern -(\code{\link{mergeCtwasBoundaryRegions}}), not placement.} +(\code{\link{mergeCtwasBoundaryRegions}}), not placement. A +\code{TwasWeights} row of the run's method that carries a SuSiE fit and +was narrowed since that fit warns (condition class +\code{pecotmrFitCoverage}): the fit no longer lines up with the row's +variants, so its weights are not renormalized over the variants kept.} \item{twasZ}{Optional \code{GRanges} of TWAS Z-scores (output of \code{\link{causalInferencePipeline}}). When supplied, the per-(trait, context) Z is used as the \code{z_gene} input to \code{ctwas_sumstats} so it is not recomputed.} -\item{fineMappingResult}{Optional \code{QtlFineMappingResult} or -\code{GwasFineMappingResult} carrying the per-variant PIP and credible-set -membership data used by the CS / PIP rescue filters (\code{csMinCor} and -\code{minPipCutoff}). When \code{NULL} (default) the smart filters are -no-ops; only the magnitude filter (\code{twasWeightCutoff}) and the -per-gene cap (\code{maxNumVariants}, ordered by \code{|weight|}) apply.} +\item{fineMappingResult}{Optional \code{QtlFineMappingResult}: the genes' +own fine-mapping, whose per-variant PIP and credible-set membership the +CS / PIP rescue filters (\code{csMinCor} and \code{minPipCutoff}) read. +Each gene is looked up by its weights' \code{(study, context, trait)} in +the fits of \code{fineMappingMethod}; a gene with no fit there gets no +rescue. When \code{NULL} (default) the smart filters are no-ops; only the +magnitude filter (\code{twasWeightCutoff}) and the per-gene cap +(\code{maxNumVariants}, ordered by \code{|weight|}) apply.} -\item{method}{Optional character (length 1). Picks which TWAS method's -weights to feed into ctwas for each (study, context, trait) gene. When -\code{NULL} (default): use \code{"ensemble"} if that method is present -across the weight sources; otherwise use the sole method when only one is -present; otherwise run \strong{every} method as an independent cTWAS run -(one \code{CtwasResult} row-set per method). Passing the name explicitly -(e.g. \code{"mrash"}) restricts the run to that single method.} +\item{fineMappingMethod}{Character (length 1): the method of +\code{fineMappingResult} whose fits the rescues read, e.g. +\code{"susie"}. Required with a \code{fineMappingResult}, since the +weights' own method -- an \code{"ensemble"} or \code{"lasso"} weight -- +names no fine-mapping fit. Default \code{NULL}.} + +\item{method}{Character (length 1): which TWAS method's weights to feed +into ctwas for each (study, context, trait) gene, one method per run. +\code{NULL} (default) uses the pre-combined \code{"ensemble"} weights of +\code{TwasWeights}. Weights with no ensemble, and fine-mapping results as +the weight source, have no default: name the method (e.g. +\code{"mrash"}, or a fine-mapping method such as \code{"susie"}).} \item{variantPruningParam}{Which variants survive into each gene's weight matrix, built with \code{\link{VariantPruningParam}}: @@ -92,10 +104,9 @@ blocks <- GenomicRanges::GRanges("chr22", IRanges::IRanges(c(10000000, 15000001), c(15000000, 19000000)), blockId = c("chr22_1", "chr22_2")) gss <- loadGwasSumStatsFromManifest(manifest = mani, genome = "hg38", - ldReference = ldStem, region = "chr22:10000000-19000000", - ldBlocks = blocks) + ldReference = ldStem, which = blocks) gwasByRegion <- summaryStatsQc(gss, panelFilterParam = PanelFilterParam(mafCutoff = 0.0025)) assembleCtwasInputs(gwasSumStats = gwasByRegion, - twasWeights = list(ctwasWeightsExample)) + twasWeights = list(ctwasWeightsExample), method = "susie") } diff --git a/man/autoDecision.Rd b/man/autoDecision.Rd index e71547d4..a759ca74 100644 --- a/man/autoDecision.Rd +++ b/man/autoDecision.Rd @@ -11,7 +11,12 @@ autoDecision(df, highCorrCols) study and block.} \item{highCorrCols}{Character vector. Names of columns in df that represent -high correlations.} +high correlations; a non-top CS whose value in any of them is 1 is +tagged. A CS's own column of \code{\link{extractCsInfo}}'s between-CS +correlations (\code{cs_corr_} for row \code{i}, its self-correlation) +is never read, so passing every \code{cs_corr_*} column tags a CS only by +its correlation with the other sets. Rows are taken in +\code{extractCsInfo()}'s order.} } \value{ A modified data frame with additional columns attached to the diff --git a/man/blockId.Rd b/man/blockId.Rd index a6d53181..73da3b50 100644 --- a/man/blockId.Rd +++ b/man/blockId.Rd @@ -29,11 +29,13 @@ Return the LD-block identifier of each row of a collection on, so the returned vector is always the same length as \code{nrow(x)} and can be used to label or join rows directly. - It keys the external block manifest the blocks were defined in, and so - carries the true block BOUNDARIES --- unlike \code{range(x)}, which is - the span of the variants that survived QC. A collection with no block - axis (every QTL flavour) returns \code{NA} for every row rather than - erroring, so code that handles both flavours needs no class test. + It keys the external block manifest the blocks were defined in. The + block's BOUNDARIES are the \code{region} column, recorded as given or + computed in \code{regionGiven} (see \code{\linkS4class{GwasSumStats}}) + --- unlike \code{range(x)}, which is the span of the variants that + survived QC. A collection with no block axis (every QTL flavour) + returns \code{NA} for every row rather than erroring, so code that + handles both flavours needs no class test. } \examples{ data(gwasFineMappingExample, qtlFineMappingExample) diff --git a/man/buildLdEigen.Rd b/man/buildLdEigen.Rd index 81797552..280b6d26 100644 --- a/man/buildLdEigen.Rd +++ b/man/buildLdEigen.Rd @@ -26,8 +26,8 @@ buildLdEigen( least two blocks and wants many more.} \item{ldBlocks}{With a genotype panel, the LD blocks to cut it into: a -\code{GRanges}, or a data frame with columns \code{chrom}, \code{start} -and \code{end}. Each block's LD is computed from the panel variants +\code{GRanges}, or the path of a BED file, read as BED with a 0-based +start. Each block's LD is computed from the panel variants inside it; variants outside every block are left out. Not used with \code{LdMatrix} blocks.} @@ -63,8 +63,8 @@ Eigendecompose an LD reference, block by block, into the panel <- readGenotypes(plink2Prefix = file.path(system.file("extdata", "ld_reference", "chr22", package = "pecotmr"), "protocol_example.LD.chr22")) -blocks <- data.frame(chrom = "chr22", start = c(10000000, 15000001), - end = c(15000000, 19000000)) +blocks <- GenomicRanges::GRanges("chr22", + IRanges::IRanges(c(10000000, 15000001), c(15000000, 19000000))) ldEigen <- buildLdEigen(panel, ldBlocks = blocks, genome = "hg38") ldEigen length(eigenList(ldEigen)) diff --git a/man/buildLdScore.Rd b/man/buildLdScore.Rd index 44a83dcc..e779235b 100644 --- a/man/buildLdScore.Rd +++ b/man/buildLdScore.Rd @@ -27,8 +27,8 @@ buildLdScore( least two blocks and wants many more.} \item{ldBlocks}{With a genotype panel, the LD blocks to cut it into: a -\code{GRanges}, or a data frame with columns \code{chrom}, \code{start} -and \code{end}. Each block's LD is computed from the panel variants +\code{GRanges}, or the path of a BED file, read as BED with a 0-based +start. Each block's LD is computed from the panel variants inside it; variants outside every block are left out. Not used with \code{LdMatrix} blocks.} @@ -78,8 +78,8 @@ Compute per-variant LD scores from an LD reference, block by panel <- readGenotypes(plink2Prefix = file.path(system.file("extdata", "ld_reference", "chr22", package = "pecotmr"), "protocol_example.LD.chr22")) -blocks <- data.frame(chrom = "chr22", start = c(10000000, 15000001), - end = c(15000000, 19000000)) +blocks <- GenomicRanges::GRanges("chr22", + IRanges::IRanges(c(10000000, 15000001), c(15000000, 19000000))) ldScore <- buildLdScore(panel, ldBlocks = blocks, genome = "hg38") ldScore head(S4Vectors::mcols(ldScore)$ldScores) diff --git a/man/buildTopLoci.Rd b/man/buildTopLoci.Rd index dc14089b..0fd4432c 100644 --- a/man/buildTopLoci.Rd +++ b/man/buildTopLoci.Rd @@ -56,7 +56,8 @@ carries no sample count: \code{n} is left \code{NA} for the per-variant \item{otherQuantities}{Optional list. Default is NULL.} -\item{region}{Optional \code{"chr:start-end"} string. Default is NULL.} +\item{region}{Optional \code{GRanges}: the window the fit covers, whose +bounds the table records. Default is NULL.} \item{conditionIdx}{Integer or \code{NULL}. Index of the conditioned effect (per-condition output); \code{NULL} for the unconditioned fit.} diff --git a/man/causalInferencePipeline.Rd b/man/causalInferencePipeline.Rd index ae6b4169..276e9471 100644 --- a/man/causalInferencePipeline.Rd +++ b/man/causalInferencePipeline.Rd @@ -16,9 +16,14 @@ causalInferencePipeline( } \arguments{ \item{gwasSumStats}{A \code{\link{GwasSumStats}} object. Must be QC'd -(\code{length(qcInfo(x)) > 0L}). A study may span many rows (one per +(\code{length(qcOptions(x)) > 0L}). A study may span many rows (one per chromosome or LD block); each QTL tuple is scored once per study, over the -statistics of the rows its window overlaps.} +statistics of the rows its window overlaps. A tuple's variants outside +every loaded block of a study it overlaps are an error where the blocks' +ranges were given (\code{regionGiven}, see +\code{\linkS4class{GwasSumStats}}), since they lie in a block that was not +loaded, and a warning for more than one in a row past a range computed +from the GWAS variants.} \item{twasWeights}{Optional \code{\link{TwasWeights}} carrying per-(study, context, trait, method) weights. When supplied, drives the TWAS-Z @@ -39,7 +44,9 @@ Selection runs when \code{cutoff > 0} or \code{pvalCutoff} is finite; it keeps the highest-\code{metric} method among those clearing both gates that also produced a finite TWAS Z. Otherwise every method is carried through. Ports the legacy \code{twas_pipeline} -\code{pick_best_model} / \code{update_twas_method}.} +\code{pick_best_model} / \code{update_twas_method}. The metrics describe +each fit on all of its variants, so selection warns about a row narrowed +since its fit (condition class \code{pecotmrFitCoverage}).} \item{mrParam}{How Mendelian randomization is run, built with \code{\link{MrParam}}: \code{method} (\code{"ivwPerVariant"}, the @@ -59,7 +66,9 @@ effect / weight sign-flipped accordingly; when FALSE, match on exact alleles only, so a ref/alt swap is treated as a distinct variant.} } \value{ -A \code{GRanges} as described above. +A \code{GRanges} as described above, its \code{seqinfo()} naming + the genome build the inputs name (inputs naming different builds are + refused). } \description{ Per-region pipeline that pairs QTL-derived weight vectors diff --git a/man/chromPaths.Rd b/man/chromPaths.Rd index 5f1e495d..360d4cc9 100644 --- a/man/chromPaths.Rd +++ b/man/chromPaths.Rd @@ -15,8 +15,8 @@ chromPaths(x, ...) \item{...}{Additional arguments passed on to methods.} } \value{ -A named character vector mapping canonical chromosome to path or - prefix, possibly empty. +A named character vector mapping each chromosome, in UCSC style + (\code{"chr21"}), to its path or prefix, possibly empty. } \description{ The chromosome-to-path map of a sharded diff --git a/man/coef-methods.Rd b/man/coef-methods.Rd index c4f1b14d..e7213691 100644 --- a/man/coef-methods.Rd +++ b/man/coef-methods.Rd @@ -7,15 +7,7 @@ \usage{ coef(object, ...) -\S4method{coef}{SumStatsBase}( - object, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL, - ... -) +\S4method{coef}{SumStatsBase}(object, studyName = NULL, context = NULL, trait = NULL, ...) } \arguments{ \item{object}{A \code{GwasSumStats} or \code{QtlSumStats} object.} @@ -30,12 +22,6 @@ this context; \code{NULL} matches all contexts.} \item{trait}{Character (length 1) or \code{NULL}. Restrict the selection to this trait; \code{NULL} matches all traits.} - -\item{annotateSignificance}{Optional correction-method name passed through to -\code{\link{sumStats}} (QTL only); \code{NULL} applies none.} - -\item{ranges}{A \code{GRanges} or \code{NULL} (default). Return only the -variants overlapping these ranges; \code{NULL} returns everything.} } \value{ Numeric vector of effect sizes, or \code{NULL} if not available. diff --git a/man/colocBoostOutcomes.Rd b/man/colocBoostOutcomes.Rd index 402b8b0d..e8108642 100644 --- a/man/colocBoostOutcomes.Rd +++ b/man/colocBoostOutcomes.Rd @@ -15,8 +15,9 @@ colocBoostOutcomes(x, ...) \item{...}{Ignored.} } \value{ -A tibble with one row per (set, outcome) and the set-level columns - repeated, plus \code{outcome}, \code{study}, \code{context}, +A \code{DataFrame} with one row per (set, outcome), the + set-level columns repeated, plus \code{outcome}, \code{study}, + \code{context}, \code{trait}, \code{dataForm} and \code{ldReference} (the name of the \code{\link{ldReference}} entry the outcome's summary statistics were matched against). diff --git a/man/colocPipeline.Rd b/man/colocPipeline.Rd index 0b842bc8..1e024b6d 100644 --- a/man/colocPipeline.Rd +++ b/man/colocPipeline.Rd @@ -58,14 +58,16 @@ two different things.} \item{returnGwasFineMapping}{Logical. When \code{TRUE}, attach the fine-mapping result computed from \code{gwasInput} on the returned object -as attribute \code{"gwasFineMapping"}. Default \code{FALSE}.} +as attribute \code{"gwasFineMapping"}: for a \code{GwasSumStats}, one fit +per set of rows a first-side region reaches. Default \code{FALSE}.} \item{enrichment}{Optional data.frame of per-pair enrichment factors with columns \code{gwasStudy}, \code{qtlStudy}, \code{qtlContext}, \code{enrichment}, and optionally \code{gwasContext} / \code{gwasTrait} -(which the join uses when present, and which -\code{\link{qtlEnrichmentPipeline}} emits for a QTL outcome side). Output -of \code{\link{qtlEnrichmentPipeline}}. When non-\code{NULL} the pair is +/ \code{gwasMethod} / \code{qtlMethod} (which the join uses when +present; \code{\link{qtlEnrichmentPipeline}} emits all four, the context +and trait set for a QTL outcome side). Output of +\code{\link{qtlEnrichmentPipeline}}. When non-\code{NULL} the pair is scored by enloc rather than coloc: the priors come from that table's \code{colocP1} / \code{colocP2} / \code{colocP12} columns, and the report gains \code{RCP} and \code{LCP}. Pairs without a matching @@ -80,7 +82,9 @@ enrichment row fall back to the baseline priors with a warning. Default missing variants in the GWAS \code{SumStats} and the QTL fine-mapping input has additional variants; (2) the GWAS fine-mapping result contains variants not present in the QTL fine-mapping result. Pass \code{FALSE} to - use the FMRs as supplied. + use the FMRs as supplied; each fit is then scored whole, so a row + narrowed since its fit warns (condition class + \code{pecotmrFitCoverage}). How much of each effect's posterior survived that restriction is reported per result row as \code{qtlRetainedMass} / \code{gwasRetainedMass}; a low @@ -101,7 +105,7 @@ enrichment adjustment reads them too.} } \value{ A \code{\linkS4class{ColocResult}}: one element per tested - (first-side credible set, second-side credible set, block) pair, holding + (first-side credible set, second-side credible set) pair, holding that pair's aligned variants with their \code{SNP.PP.H4}. Pair-level metadata carries the identity columns (\code{study}, \code{context}, \code{trait}, \code{method}, \code{gwasStudy}, \code{gwasContext}, @@ -120,9 +124,10 @@ A \code{\linkS4class{ColocResult}}: one element per tested is what readers of enloc output expect to find. Project it with \code{\link{colocPairs}} (the flat table this - pipeline used to return, also available as \code{as.data.frame}), - \code{\link{colocVariants}}, \code{\link{colocCredibleSets}} or - \code{\link{colocGenes}}. + pipeline used to return), \code{\link{colocVariants}}, + \code{\link{colocCredibleSets}} or \code{\link{colocGenes}}. Its + \code{seqinfo()} names the genome build the two sides name; sides + naming different builds are refused. } \description{ Per-region pipeline that pairs two fine-mapping result @@ -178,6 +183,37 @@ This pipeline preserves all three. } } +\section{A region over several LD blocks}{ + Each first-side region is + colocalized with ONE fit per second-side study and method, however many + of a GWAS study's LD blocks it reaches -- scoring it against each block + separately would split one region into as many colocalizations as it + has blocks, each truncating the region's effects to one block's + variants. + \itemize{ + \item A \code{GwasSumStats} is fine-mapped once per set of rows a + region reaches, their statistics stitched together on their one + LD reference (rows on different references are refused). A + region inside one block reads that block's fit. + \item A \code{GwasFineMappingResult} was fine-mapped block by block. + Assuming no LD between blocks, the blocks a region reaches + collapse into one fit: every block's effects, each confined to + its own block (a Bayes factor of zero elsewhere), numbered on + from the blocks before it in row order. + } + The fit's \code{blockId} is then the stretch the blocks' ranges cover, + as \code{"chrom_start_end"} (see \code{region} in + \code{\linkS4class{GwasSumStats}}). + + A region's variants that lie outside every loaded block of a GWAS + study it overlaps are left out of that fit, a sign that a block it + reaches was not loaded. Where those blocks' ranges were given + (\code{regionGiven}), the variants lie in a block that was not loaded, + and that is an error. Where the ranges are the span of the GWAS + variants, the variants may only be ones the GWAS lacks, so more than one + in a row past a block is a warning. +} + \section{LD reference compatibility check}{ Rows can sit on different LD references, so the check is per pair of rows coloc scores against each diff --git a/man/colocViews.Rd b/man/colocViews.Rd index f727020a..2a56d54d 100644 --- a/man/colocViews.Rd +++ b/man/colocViews.Rd @@ -5,19 +5,24 @@ \alias{colocViews} \alias{colocPairs} \alias{colocVariants} +\alias{colocPooledVariants} \alias{colocCredibleSets} \alias{colocGenes} \alias{colocPairs,ColocResult-method} \alias{colocVariants,ColocResult-method} +\alias{colocPooledVariants,ColocResult-method} \alias{colocGenes,ColocResult-method} \alias{colocCredibleSets,ColocResult-method} \alias{colocPairs,ColocBoostResult-method} \alias{colocVariants,ColocBoostResult-method} +\alias{colocPooledVariants,ColocBoostResult-method} \title{Colocalization Views} \usage{ colocPairs(x, ...) -colocVariants(x, pooled = FALSE, ...) +colocVariants(x, ...) + +colocPooledVariants(x, ...) colocCredibleSets(x, coverage = 0.95, minPp4 = NULL, minAbsCorr = 0.8, ...) @@ -25,7 +30,9 @@ colocGenes(x, ...) \S4method{colocPairs}{ColocResult}(x) -\S4method{colocVariants}{ColocResult}(x, pooled = FALSE) +\S4method{colocVariants}{ColocResult}(x) + +\S4method{colocPooledVariants}{ColocResult}(x) \S4method{colocGenes}{ColocResult}(x) @@ -39,16 +46,15 @@ colocGenes(x, ...) \S4method{colocPairs}{ColocBoostResult}(x) -\S4method{colocVariants}{ColocBoostResult}(x, pooled = FALSE) +\S4method{colocVariants}{ColocBoostResult}(x) + +\S4method{colocPooledVariants}{ColocBoostResult}(x) } \arguments{ \item{x}{A \code{ColocResult}.} \item{...}{Additional arguments passed on to methods.} -\item{pooled}{Logical. \code{colocVariants()} only: pool to one row per -(gene, variant) instead of per (pair, variant).} - \item{coverage}{Cumulative \code{SNP.PP.H4} the credible set must reach.} \item{minPp4}{Optional lower bound on the pair's \code{PP.H4.abf}. Applied @@ -64,10 +70,13 @@ the five posterior probabilities, i.e. colocalization is the favoured hypothesis rather than merely a probable one.} } \value{ -A tibble at the requested granularity. +\code{colocVariants()} and \code{colocPooledVariants()} a + \code{GRanges}, its columns in \code{mcols()}; + \code{colocCredibleSets()} a \code{GRangesList}, one element per set; + the other views a \code{DataFrame}. } \description{ -The four views over a \code{\linkS4class{ColocResult}}. The +The five views over a \code{\linkS4class{ColocResult}}. The object stores one element per tested (QTL credible set, GWAS credible set, block) pair; these accessors project it to the granularity a given analysis needs, rather than any one of them being the stored shape. @@ -77,13 +86,19 @@ The four views over a \code{\linkS4class{ColocResult}}. The \code{$summary} granularity. Every testable pair is reported verbatim, including both halves of a credible set that straddles a block boundary; interpreting them is the caller's decision.} - \item{\code{colocVariants()}}{One row per (pair, variant), carrying + \item{\code{colocVariants()}}{One range per (pair, variant), carrying \code{colocPp = PP.H4.abf * SNP.PP.H4} -- the posterior that this - variant is the shared causal one. With \code{pooled = TRUE}, one row - per (gene, variant) pooled by the rule below.} - \item{\code{colocCredibleSets()}}{One row per coloc credible set: the - smallest set of variants whose cumulative \code{SNP.PP.H4} reaches - \code{coverage}. This is a THIRD variant set, not guaranteed to be a + variant is the shared causal one.} + \item{\code{colocPooledVariants()}}{One range per (gene, variant), + pooled across pairs by the rule below. A + \code{\linkS4class{ColocBoostResult}} pools per (analysis, variant) + instead, with the noisy-OR stage only.} + \item{\code{colocCredibleSets()}}{One element per coloc credible set: + the smallest set of variants whose cumulative \code{SNP.PP.H4} + reaches \code{coverage}, as ranges carrying their \code{SNP.PP.H4}, + with the set's pair columns, \code{csSize}, \code{csCoverage}, + \code{leadVariant}, \code{leadPp} and \code{purity} in + \code{mcols()}. This is a THIRD variant set, not guaranteed to be a subset of either input credible set, so its purity is recomputed from LD rather than inherited.} \item{\code{colocGenes()}}{One row per gene, pooled across pairs.} @@ -108,6 +123,7 @@ res <- colocPipeline( ) head(colocPairs(res)) head(colocVariants(res)) +head(colocPooledVariants(res)) colocGenes(res) head(colocCredibleSets(res, minPp4 = 0.001)) } diff --git a/man/colocboostPipeline.Rd b/man/colocboostPipeline.Rd index cd7ce42f..998beccf 100644 --- a/man/colocboostPipeline.Rd +++ b/man/colocboostPipeline.Rd @@ -16,7 +16,7 @@ colocboostPipeline(qtlData, gwasSumStats = NULL, ...) traitId = NULL, region = NULL, cisWindow = NULL, - focalTrait = NULL, + focalOutcome = NULL, xqtlColoc = TRUE, jointGwas = FALSE, separateGwas = FALSE, @@ -24,6 +24,8 @@ colocboostPipeline(qtlData, gwasSumStats = NULL, ...) panelFilterParam = PanelFilterParam(), signalScreenParam = SignalScreenParam(), alleleFlip = TRUE, + genotypeFilterParam = GenotypeFilterParam(), + phenotypeFilterParam = PhenotypeFilterParam(), residualizationParam = ResidualizationParam(), methodArgs = ColocboostOptions() ) @@ -33,7 +35,8 @@ colocboostPipeline(qtlData, gwasSumStats = NULL, ...) gwasSumStats = NULL, contexts = NULL, traitId = NULL, - focalTrait = NULL, + cisWindow = NULL, + focalOutcome = NULL, xqtlColoc = TRUE, jointGwas = FALSE, separateGwas = FALSE, @@ -49,7 +52,7 @@ colocboostPipeline(qtlData, gwasSumStats = NULL, ...) traitId = NULL, region = NULL, cisWindow = NULL, - focalTrait = NULL, + focalOutcome = NULL, xqtlColoc = TRUE, jointGwas = FALSE, separateGwas = FALSE, @@ -57,6 +60,8 @@ colocboostPipeline(qtlData, gwasSumStats = NULL, ...) panelFilterParam = PanelFilterParam(), signalScreenParam = SignalScreenParam(), alleleFlip = TRUE, + genotypeFilterParam = GenotypeFilterParam(), + phenotypeFilterParam = PhenotypeFilterParam(), residualizationParam = ResidualizationParam(), methodArgs = ColocboostOptions() ) @@ -66,41 +71,68 @@ colocboostPipeline(qtlData, gwasSumStats = NULL, ...) \code{MultiStudyQtlDataset}.} \item{gwasSumStats}{Optional \code{GwasSumStats} with the GWAS studies to -colocalize against. \code{NULL} to skip GWAS colocalization. Its -\code{ldReference} need not be the QTL side's: every row's summary -statistics are matched against that row's own reference. When some rows' -references are genotype panels and others' are \code{LdMatrix} objects, -the runs that combine them pass colocboost the panels' LD as matrices, -since colocboost takes LD matrices or reference genotypes but not both.} +colocalize against. \code{NULL} to skip GWAS colocalization. Each study +is one outcome: the union of its rows that the QTL data overlap, so a +study split by chromosome or LD block contributes just the one or two +rows the QTL region reaches, and a study none of whose rows it reaches is +left out. QTL variants outside every loaded block of a study the QTL data +overlap are an error where the blocks' ranges were given +(\code{regionGiven}, see \code{\linkS4class{GwasSumStats}}), since they +lie in a block that was not loaded, and a warning for more than one in a +row past a range computed from the GWAS variants. Those rows must share +one LD reference, but it need not be the +QTL side's: every outcome's summary statistics are matched against their +own reference. When some references are genotype panels and others are +\code{LdMatrix} objects, the runs that combine them pass colocboost the +panels' LD as matrices, since colocboost takes LD matrices or reference +genotypes but not both.} \item{...}{Required by the generic; the methods take no further arguments.} -\item{contexts}{Optional character vector of context names to restrict the -individual-level / QtlSumStats QTL analysis to. When \code{NULL} (default), -every context present is used.} +\item{contexts}{Optional character vector of context names to restrict +the individual-level / QtlSumStats QTL analysis to. When \code{NULL} +(default), every context present is used. A MultiStudyQtlDataset applies +it to every study: a context no study has is an error, and one only some +studies lack is skipped for those, with a warning.} -\item{traitId}{Optional character vector of trait identifiers to restrict the -analysis to. When supplied with an individual-level \code{QtlDataset} -input, \code{cisWindow} is required (passed to -\code{residualizedGenotypes} / \code{molecularTraits} for the -variant-window selection).} +\item{traitId}{Optional character vector of trait identifiers to restrict +the analysis to. When supplied with an individual-level +\code{QtlDataset} input, \code{cisWindow} is required: each trait's +position \eqn{\pm} \code{cisWindow} is the variant window. In a +MultiStudyQtlDataset a study carrying none of them sits out; the run is +refused only when no study or summary-statistics row carries one.} \item{region}{Optional single-range \code{GRanges} describing the analysis -window. Mutually exclusive with \code{traitId} (see the \code{QtlDataset} -accessors). Individual-level input only: summary statistics carry no -genotypes to window, so the \code{QtlSumStats} method does not take it ---- matching \code{\link{fineMappingPipeline}} and -\code{\link{twasWeightsPipeline}}.} - -\item{cisWindow}{Optional cis window in basepairs; required with -\code{traitId}, optional with \code{region}. Individual-level input -only, as for \code{region}.} - -\item{focalTrait}{Optional trait name; when supplied and present in the -assembled outcome list, the colocboost xQTL-only run uses it as the focal -outcome. Only \code{xqtlColoc} reads it: \code{jointGwas} is -non-focal by construction and \code{separateGwas} always makes the -GWAS study focal.} +window. Mutually exclusive with \code{traitId}. Individual-level input +only: a summary-statistics tuple +keeps the window it was built with (its \code{region}), so the +\code{QtlSumStats} method does not take one --- matching +\code{\link{fineMappingPipeline}} and \code{\link{twasWeightsPipeline}}.} + +\item{cisWindow}{Optional cis window in basepairs. Individual-level +input: required with \code{traitId}, optional with \code{region}. +QtlSumStats input: each selected tuple is analysed over its +\code{traitPos} \eqn{\pm} \code{cisWindow}, within its \code{region}; +every selected tuple needs a \code{traitPos}. A MultiStudyQtlDataset +applies it to both kinds of study it holds.} + +\item{focalOutcome}{The outcome a run treats as focal (colocboost's +\code{focal_outcome_idx}). One of: +\itemize{ + \item \code{NULL} (default): the GWAS study, in the \code{jointGwas} + run, when \code{gwasSumStats} holds exactly one. With several + there is no one study to choose, so no run is focal. + \item A GWAS study name, as a plain string: that study is focal in + the \code{jointGwas} run. It must be a study of + \code{gwasSumStats}. + \item A named character vector with any of \code{study}, + \code{context} and \code{trait} that identifies exactly one QTL + outcome, e.g. \code{c(context = "brain", trait = "ENSG1")}: that + outcome is focal in every run holding it, the \code{xqtlColoc} + run and the \code{jointGwas} run. + \item \code{NA}: no run is focal. +} +The \code{separateGwas} runs are always focal on their own GWAS study.} \item{xqtlColoc, jointGwas, separateGwas}{Logical flags selecting which colocboost variants to run.} @@ -112,8 +144,8 @@ analysis to; \code{NULL} (default) uses all samples.} summary-statistic sides against the LD reference panel, built with \code{\link{PanelFilterParam}}: a variant whose panel genotypes fall below its cutoffs is dropped before the LD matrix is built. The defaults -filter nothing. See the Details section for how these relate to the -individual-level cutoffs recorded on a \code{QtlDataset}.} +filter nothing. Individual-level genotypes are filtered by +\code{genotypeFilterParam} instead.} \item{signalScreenParam}{Individual-level pre-filter (ports the legacy \code{pip_cutoff_to_skip_ind}), built with @@ -141,13 +173,27 @@ swaps recognized (flipping z / residualized dosage / LD to a shared coding); when FALSE, match on exact alleles only (names-only), so a ref/alt swap is treated as a distinct variant.} +\item{genotypeFilterParam}{Which individual-level variants and samples to +keep, built with \code{\link{GenotypeFilterParam}}: its +\code{keepSamples} narrows the dataset once, and its MAF, MAC, +variance, missingness, \code{keepVariants} and \code{keepIndel} +settings apply to each extracted block, as in +\code{\link{fineMappingPipeline}}. The default filters nothing. +\code{QtlDataset} and \code{MultiStudyQtlDataset} input only.} + +\item{phenotypeFilterParam}{The run's phenotype QC, built with +\code{\link{PhenotypeFilterParam}}. colocboost takes missing phenotype +values as they are, so unset keeps them; \code{"drop"} or +\code{"impute"} applies that instead, and \code{outlierAction = +"drop"} removes outlier samples. \code{QtlDataset} and +\code{MultiStudyQtlDataset} input only.} + \item{residualizationParam}{Covariate residualization settings for individual-level input, built with \code{\link{ResidualizationParam}}. Reaches both \code{\link{residualizedGenotypes}} and \code{\link{residualizedPhenotypes}}, so it governs what is regressed out of each side and --- through \code{scaleResiduals} --- whether the -columns are scaled to unit variance. Previously absent, which left this -pipeline on the dataset's own settings with no per-call say, unlike +columns are scaled to unit variance, as in \code{\link{fineMappingPipeline}} and \code{\link{twasWeightsPipeline}}. \strong{Ignored} on \code{QtlSumStats} input, which has nothing to residualize.} @@ -169,14 +215,15 @@ A \code{\linkS4class{ColocBoostResult}}: one element per \code{separate_gwas} runs. Outcome-specific (uncolocalized) sets are included with \code{isColocalized = FALSE}. - Project it with \code{\link{colocPairs}} (also available as - \code{as.data.frame}), \code{\link{colocVariants}} or - \code{\link{colocBoostOutcomes}}; timings are on + Project it with \code{\link{colocPairs}}, \code{\link{colocVariants}} + or \code{\link{colocBoostOutcomes}}; timings are on \code{\link{computingTime}} and the region-wide marginal probabilities on \code{\link{regionVcp}}. \code{\link{ldReference}} returns the LD references the summary statistics were matched against, each stored once, and the \code{ldReference} column of - \code{colocBoostOutcomes()} names the one each outcome used. + \code{colocBoostOutcomes()} names the one each outcome used. Its + \code{seqinfo()} names the genome build the inputs name; inputs naming + different builds are refused. } \description{ Protocol-level multi-trait colocalization analysis using @@ -189,7 +236,7 @@ Protocol-level multi-trait colocalization analysis using \item \code{QtlSumStats} -- summary-statistic-only QTL data with an LD reference per row (\code{ldReference}). Must already have been passed through \code{\link{summaryStatsQc}} (the - pipeline rejects inputs whose \code{qcInfo()} is empty). + pipeline rejects inputs whose \code{qcOptions()} is empty). Every analysis variant is available on this input, including \code{xqtlColoc}, which colocalizes the QTL studies against each other with no GWAS involved. @@ -207,11 +254,10 @@ for either side; colocboost has its own variable-selection algorithm. \itemize{ \item Individual-level QC (MAF / MAC / X-variance / per-sample - missingness, sample / variant restrictions) lives on the - \code{QtlDataset} constructor and is applied lazily inside - \code{genotypes()} / \code{residualizedGenotypes()}. - The pipeline does \emph{not} run a separate - individual-level QC pass. + missingness, sample / variant restrictions) is + \code{genotypeFilterParam}, applied to each block of genotypes + the pipeline extracts. A \code{QtlDataset} records no filter + of its own. \item \code{panelFilterParam} acts at ANALYSIS time on the sumstat sides, measured against the \strong{LD reference panel}: a variant whose panel genotypes fall below its cutoffs is dropped @@ -226,7 +272,7 @@ for either side; colocboost has its own variable-selection algorithm. imputation, etc.) lives in \code{\link{summaryStatsQc}}. The pipeline rejects any \code{QtlSumStats} or \code{GwasSumStats} where - \code{length(qcInfo(x)) == 0L}. + \code{length(qcOptions(x)) == 0L}. } } @@ -238,11 +284,13 @@ for either side; colocboost has its own variable-selection algorithm. \code{gwasSumStats}. Works for either data form -- the individual-level contexts, the summary-level QTL studies, or both together when a \code{MultiStudyQtlDataset} carries a - mixture. This is the only variant that honors - \code{focalTrait}. - \item \code{jointGwas} (default \code{FALSE}): run a non-focal - colocboost model that combines all QTL contexts/studies - with the supplied \code{gwasSumStats} studies. + mixture. Focal only on a QTL outcome named by + \code{focalOutcome}. + \item \code{jointGwas} (default \code{FALSE}): run one colocboost + model that combines all QTL contexts/studies with the + supplied \code{gwasSumStats} studies. By default it is focal on + the GWAS when \code{gwasSumStats} holds a single study, and + non-focal when it holds several; \code{focalOutcome} chooses. \item \code{separateGwas} (default \code{FALSE}): run one focal colocboost model per GWAS study, where the GWAS is the focal outcome. diff --git a/man/combineGwasSumStats.Rd b/man/combineGwasSumStats.Rd index d75419ee..5b5f56c4 100644 --- a/man/combineGwasSumStats.Rd +++ b/man/combineGwasSumStats.Rd @@ -28,12 +28,12 @@ is carried through; a collection lacking an optional column is NA-padded. \details{ The three collection-level slots are merged rather than taken from the first input: \code{genome} and the \code{\link{summaryStatsQc}} options must agree -across the inputs (a mismatch is an error, not a silent first-wins), the -per-element \code{qcInfo$entryAudit} concatenates in element order so -\code{\link{qcDiagnostics}} keeps addressing the right element, and every -row keeps its own LD reference. References that are views of one source -are stored once: genotype panels read from the same files union into one -panel over the shared genotype handle (block-parallel pipelines narrow each +across the inputs (a mismatch is an error, not a silent first-wins), each +row keeps its own QC audit, so \code{\link{qcDiagnostics}} keeps +addressing the right element, and every row keeps its own LD reference. +References that are views of one source are stored once: genotype panels +read from the same files union into one panel over the shared genotype +handle (block-parallel pipelines narrow each piece's panel to its own block, so a multi-block collection would otherwise hold one panel per block), and an \code{LdMatrix} or \code{GenotypeMixture} that another input's reference covers gives way to diff --git a/man/combineQtlSumStats.Rd b/man/combineQtlSumStats.Rd index 09b25154..5322794e 100644 --- a/man/combineQtlSumStats.Rd +++ b/man/combineQtlSumStats.Rd @@ -27,9 +27,9 @@ lacking an optional column is NA-padded. \details{ The three collection-level slots are merged rather than taken from the first input, on the same rules as \code{\link{combineGwasSumStats}}: \code{genome} -and the \code{\link{summaryStatsQc}} options must agree, the per-element -\code{qcInfo$entryAudit} concatenates in element order, and the rows keep -their own LD references, stored the same way. +and the \code{\link{summaryStatsQc}} options must agree, each row keeps +its own QC audit, and the rows keep their own LD references, stored the +same way. } \examples{ data(qtlSumStatsExample) diff --git a/man/combineTwasWeights.Rd b/man/combineTwasWeights.Rd index e8f13575..b6dd671b 100644 --- a/man/combineTwasWeights.Rd +++ b/man/combineTwasWeights.Rd @@ -26,7 +26,7 @@ assembling per-gene weight sets into a single per-region collection for cTWAS. Joint-specification metadata columns are carried through. } \examples{ -twe <- twasWeightsRow( +twe <- TwasWeightsRow( variantIds = sprintf("chr1:\%d:A:G", 100L * (1:4)), weights = rep(0.1, 4), cvResult = list(rsq = 0.5), weightStandardized = FALSE) tw1 <- TwasWeights(studyName = "s1", context = "brain", trait = "g1", diff --git a/man/computeCoefficientsGlasso.Rd b/man/computeCoefficientsGlasso.Rd index 9a7473af..27b9b11f 100644 --- a/man/computeCoefficientsGlasso.Rd +++ b/man/computeCoefficientsGlasso.Rd @@ -4,7 +4,7 @@ \alias{computeCoefficientsGlasso} \title{Compute initial mr.mash coefficients via group-lasso} \usage{ -computeCoefficientsGlasso(X, Y, standardize, numThreads, Xnew = NULL) +computeCoefficientsGlasso(X, Y, standardize, Xnew = NULL) } \arguments{ \item{X}{Numeric design matrix (samples x variants).} @@ -14,8 +14,6 @@ computeCoefficientsGlasso(X, Y, standardize, numThreads, Xnew = NULL) \item{standardize}{Logical; standardize the columns of \code{X} before fitting.} -\item{numThreads}{Integer; number of threads for the group-lasso fit.} - \item{Xnew}{Optional new design matrix for prediction; \code{NULL} returns in-sample coefficients.} } @@ -31,6 +29,5 @@ Fit a group-lasso (one group per response) to obtain initial estimates of the data(eqtlRegionExample) X <- eqtlRegionExample$X[, 1:30] Y <- matrix(rnorm(nrow(X) * 3), nrow(X), 3) -computeCoefficientsGlasso(X = X, Y = Y, standardize = TRUE, - numThreads = 1L, Xnew = NULL) +computeCoefficientsGlasso(X = X, Y = Y, standardize = TRUE, Xnew = NULL) } diff --git a/man/computeCsCorrelation.Rd b/man/computeCsCorrelation.Rd index 79269927..6a1e8034 100644 --- a/man/computeCsCorrelation.Rd +++ b/man/computeCsCorrelation.Rd @@ -13,7 +13,7 @@ computeCsCorrelation(x, ldSource, ...) \S4method{computeCsCorrelation}{FineMappingResultBase,QtlDataset}(x, ldSource) } \arguments{ -\item{x}{A \code{\link{fineMappingRow}} carrying the fit (credible-set +\item{x}{A \code{\link{FineMappingRow}} carrying the fit (credible-set membership and PIP) and its variant ids.} \item{ldSource}{The object supplying the LD: a \code{QtlDataset} @@ -30,7 +30,7 @@ A numeric \code{m x m} between-credible-set correlation matrix } \description{ Compute the between-credible-set correlation matrix for a - \code{\link{fineMappingRow}} on demand from an LD source. The correlation + \code{\link{FineMappingRow}} on demand from an LD source. The correlation is a view over the fit-time LD, which lives on the data object --- a \code{QtlDataset}'s genotypes or a \code{QtlSumStats} / \code{GwasSumStats} LD reference --- and is deliberately never stored on the fit. An diff --git a/man/computingTime.Rd b/man/computingTime.Rd index 934c0460..fe632827 100644 --- a/man/computingTime.Rd +++ b/man/computingTime.Rd @@ -15,7 +15,11 @@ computingTime(x, ...) \item{...}{Ignored.} } \value{ -A list of timings, empty when none were recorded. +A \code{DataFrame}, one row per analysis that ran: + \code{analysis} (\code{xqtl_coloc}, \code{joint_gwas} or + \code{separate_gwas}), \code{nRuns} (1, or one per GWAS study for + \code{separate_gwas}) and \code{seconds}, their total wall-clock time. + No rows when none were recorded. } \description{ The wall-clock timings colocboostPipeline recorded for each diff --git a/man/credibleSetSummary.Rd b/man/credibleSetSummary.Rd index 5fc92104..f569bbbd 100644 --- a/man/credibleSetSummary.Rd +++ b/man/credibleSetSummary.Rd @@ -17,7 +17,7 @@ credibleSetSummary(x, ...) \item{coverage}{Credible-set coverage to summarise. Default 0.95.} } \value{ -A \code{tibble}: \code{cs, effect_id, coverage, n_variants, +A \code{DataFrame}: \code{cs, effect_id, coverage, n_variants, purity_min, purity_mean, V, cs_log10bf} (strongest member logBF), \code{cs_log_bf} (true per-effect single-effect log Bayes factor), \code{cs_pip} (summed member PIP = inclusion mass captured), diff --git a/man/credibleSets.Rd b/man/credibleSets.Rd index e07206b2..ae3acc99 100644 --- a/man/credibleSets.Rd +++ b/man/credibleSets.Rd @@ -13,7 +13,7 @@ credibleSets(x, ...) context = NULL, trait = NULL, method = NULL, - region = NULL, + blockId = NULL, coverage = 0.95, minPurity = NULL ) @@ -35,9 +35,8 @@ this trait; \code{NULL} matches all traits.} \item{method}{Character (length 1) or \code{NULL}. Restrict the selection to this fine-mapping / weight method; \code{NULL} matches all methods.} -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -Restrict variants to this region; \code{NULL} uses the full cis window / -all regions.} +\item{blockId}{GWAS fine-mapping results only: the \code{blockId} naming +one LD block of a fit; \code{NULL} matches every block.} \item{coverage}{Numeric in (0, 1). Credible-set coverage level. Default \code{0.95}.} @@ -46,7 +45,11 @@ all regions.} retain; \code{NULL} applies no purity filter.} } \value{ -A data.frame of credible set information. +A \code{GRanges}, one range per credible-set member, carrying the + per-variant columns in \code{mcols()}; when the selectors match more + than one entry the row-identity columns are carried there too. Narrow it + with \code{subsetByOverlaps()}; take a table with + \code{as.data.frame()}. } \description{ Extract credible set assignments at the requested coverage. diff --git a/man/ctwasPipeline.Rd b/man/ctwasPipeline.Rd index 65b497aa..500c4dd6 100644 --- a/man/ctwasPipeline.Rd +++ b/man/ctwasPipeline.Rd @@ -9,9 +9,10 @@ ctwasPipeline( twasWeights, twasZ = NULL, fineMappingResult = NULL, + fineMappingMethod = NULL, method = NULL, maxNumSingleEffects = 5L, - numThreads = 1L, + BPPARAM = SerialParam(), ctwasPriorParam = CtwasPriorParam(), variantPruningParam = VariantPruningParam(), boundaryMergeParam = BoundaryMergeParam(), @@ -22,8 +23,8 @@ ctwasPipeline( \arguments{ \item{gwasSumStats}{A \code{\link{GwasSumStats}} whose elements are LD blocks (at least two), keyed by its \code{blockId} column, with -\code{qcInfo()} non-empty. Build it with -\code{loadGwasSumStatsFromManifest(..., ldBlocks = )} and pass it +\code{qcOptions()} non-empty. Build it with +\code{loadGwasSumStatsFromManifest(..., region = )} and pass it through \code{\link{summaryStatsQc}}.} \item{twasWeights}{The per-gene weight source. Either (a) a FLAT @@ -37,33 +38,47 @@ ctwas's joint group prior estimate (the legacy whole-chromosome pattern where only a few of many LD blocks carry gene weights). A gene whose cis span straddles a block boundary is homed by its single anchor; the cross-block signal is cTWAS's boundary-gene concern -(\code{\link{mergeCtwasBoundaryRegions}}), not placement.} +(\code{\link{mergeCtwasBoundaryRegions}}), not placement. A +\code{TwasWeights} row of the run's method that carries a SuSiE fit and +was narrowed since that fit warns (condition class +\code{pecotmrFitCoverage}): the fit no longer lines up with the row's +variants, so its weights are not renormalized over the variants kept.} \item{twasZ}{Optional \code{GRanges} of TWAS Z-scores (output of \code{\link{causalInferencePipeline}}). When supplied, the per-(trait, context) Z is used as the \code{z_gene} input to \code{ctwas_sumstats} so it is not recomputed.} -\item{fineMappingResult}{Optional \code{QtlFineMappingResult} or -\code{GwasFineMappingResult} carrying the per-variant PIP and credible-set -membership data used by the CS / PIP rescue filters (\code{csMinCor} and -\code{minPipCutoff}). When \code{NULL} (default) the smart filters are -no-ops; only the magnitude filter (\code{twasWeightCutoff}) and the -per-gene cap (\code{maxNumVariants}, ordered by \code{|weight|}) apply.} +\item{fineMappingResult}{Optional \code{QtlFineMappingResult}: the genes' +own fine-mapping, whose per-variant PIP and credible-set membership the +CS / PIP rescue filters (\code{csMinCor} and \code{minPipCutoff}) read. +Each gene is looked up by its weights' \code{(study, context, trait)} in +the fits of \code{fineMappingMethod}; a gene with no fit there gets no +rescue. When \code{NULL} (default) the smart filters are no-ops; only the +magnitude filter (\code{twasWeightCutoff}) and the per-gene cap +(\code{maxNumVariants}, ordered by \code{|weight|}) apply.} -\item{method}{Optional character (length 1). Picks which TWAS method's -weights to feed into ctwas for each (study, context, trait) gene. When -\code{NULL} (default): use \code{"ensemble"} if that method is present -across the weight sources; otherwise use the sole method when only one is -present; otherwise run \strong{every} method as an independent cTWAS run -(one \code{CtwasResult} row-set per method). Passing the name explicitly -(e.g. \code{"mrash"}) restricts the run to that single method.} +\item{fineMappingMethod}{Character (length 1): the method of +\code{fineMappingResult} whose fits the rescues read, e.g. +\code{"susie"}. Required with a \code{fineMappingResult}, since the +weights' own method -- an \code{"ensemble"} or \code{"lasso"} weight -- +names no fine-mapping fit. Default \code{NULL}.} + +\item{method}{Character (length 1): which TWAS method's weights to feed +into ctwas for each (study, context, trait) gene, one method per run. +\code{NULL} (default) uses the pre-combined \code{"ensemble"} weights of +\code{TwasWeights}. Weights with no ensemble, and fine-mapping results as +the weight source, have no default: name the method (e.g. +\code{"mrash"}, or a fine-mapping method such as \code{"susie"}).} \item{maxNumSingleEffects}{Integer. Max number of single effects in cTWAS fine-mapping. Default \code{5}. Pass-through to \code{ctwas::ctwas_sumstats}.} -\item{numThreads}{Number of cores. Default \code{1}.} +\item{BPPARAM}{A \code{BiocParallelParam} whose workers number the cores +ctwas's own \code{ncore} parallelism uses when they run on this machine +(\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +core. Default \code{SerialParam()}.} \item{ctwasPriorParam}{The EM stage that estimates cTWAS's group priors, built with \code{\link{CtwasPriorParam}}: \code{thin}, @@ -85,9 +100,9 @@ boundary has its regions merged and re-fine-mapped, built with \code{maxSnp}.} \item{keepSnps}{Logical (length 1). When \code{TRUE}, retain the -context-agnostic SNP background of each run as one extra \code{CtwasResult} -row (\code{study = context = "SNP"}, mirroring cTWAS's own \code{"SNP"} -group) so the full ctwas output is reconstructable from +context-agnostic SNP background of each run as extra \code{CtwasResult} +rows, one per region (\code{study = context = "SNP"}, mirroring cTWAS's +own \code{"SNP"} group) so the full ctwas output is reconstructable from \code{\link{ctwasPosteriors}} / \code{susieAlpha}. Default \code{FALSE} -- the SNP rows are the null background and are dropped from the structured gene-level result.} @@ -97,13 +112,16 @@ with \code{\link{CtwasOptions}}. Names are checked against what the ctwas steps accept between them.} } \value{ -A \code{\link{CtwasResult}} collection: one row per \code{(gwasStudy, - study, context, method)}. A single-context run is one row per method; a - multi-context (joint) run emits per-context rows sharing the same - \code{jointContexts} set and the jointly-estimated group priors. Each row's - \code{\link{CtwasResultEntry}} payload carries that context's per-gene - fine-mapping posteriors (\code{finemap}), the run's \code{param}, and its - \code{regionInfo}. For the raw \code{ctwas::finemap_regions} list (e.g. to +A \code{\link{CtwasResult}} collection: one row per + \code{(gwasStudy, study, context, method)} run and cTWAS region. A + single-context run gives each method its own rows; a multi-context + (joint) run emits per-context rows sharing the same \code{jointContexts} + set and the jointly-estimated group priors. Each row holds that region's + per-gene fine-mapping posteriors as ranges, with the region's per-effect + susie alpha table (\code{susieAlpha}), its \code{regionInfo} and the + run's \code{groupPriors} in \code{mcols()}. Its \code{seqinfo()} names + the genome build the inputs name; inputs naming different builds are + refused. For the raw \code{ctwas::finemap_regions} list (e.g. to feed \code{\link{mergeCtwasBoundaryRegions}}), call the granular \code{\link{assembleCtwasInputs}} \eqn{\to} \code{\link{estCtwasGroupPriors}} \eqn{\to} @@ -123,7 +141,7 @@ Pipeline that hands a per-block set of \code{gwasSumStats} is ONE \code{\link{GwasSumStats}} whose elements are LD blocks, keyed by its \code{blockId} column -- build it with - \code{loadGwasSumStatsFromManifest(..., ldBlocks = )}. Per-block + \code{loadGwasSumStatsFromManifest(..., region = )}. Per-block \code{region_info}, \code{LD_map}, and \code{snp_map} entries are built automatically from the LD reference and concatenated before the call to \code{ctwas::ctwas_sumstats}. A single-block input is rejected: cTWAS's EM @@ -166,12 +184,11 @@ blocks <- GenomicRanges::GRanges("chr22", IRanges::IRanges(c(10000000, 15000001), c(15000000, 19000000)), blockId = c("chr22_1", "chr22_2")) gss <- loadGwasSumStatsFromManifest(manifest = mani, genome = "hg38", - ldReference = ldStem, region = "chr22:10000000-19000000", - ldBlocks = blocks) + ldReference = ldStem, which = blocks) gwasByRegion <- summaryStatsQc(gss, panelFilterParam = PanelFilterParam(mafCutoff = 0.0025)) ctwasPipeline(gwasSumStats = gwasByRegion, - twasWeights = list(ctwasWeightsExample), + twasWeights = list(ctwasWeightsExample), method = "susie", ctwasPriorParam = CtwasPriorParam(thin = 1, niterPrefit = 3, niter = 10, fallbackToPrefit = TRUE), methodArgs = CtwasOptions( diff --git a/man/ctwasPosteriors.Rd b/man/ctwasPosteriors.Rd index f38d1d7b..bdf8962a 100644 --- a/man/ctwasPosteriors.Rd +++ b/man/ctwasPosteriors.Rd @@ -1,17 +1,17 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/AllGenerics.R, R/CtwasResult.R, -% R/CtwasResultEntry.R +% Please edit documentation in R/AllGenerics.R, R/CtwasResultEntry.R, +% R/CtwasResult.R \name{ctwasPosteriors} \alias{ctwasPosteriors} -\alias{ctwasPosteriors,CtwasResult-method} \alias{ctwasPosteriors,CtwasResultEntry-method} +\alias{ctwasPosteriors,CtwasResult-method} \title{Get cTWAS Fine-mapping Posteriors} \usage{ ctwasPosteriors(x, ...) -\S4method{ctwasPosteriors}{CtwasResult}(x) - \S4method{ctwasPosteriors}{CtwasResultEntry}(x) + +\S4method{ctwasPosteriors}{CtwasResult}(x) } \arguments{ \item{x}{A \code{CtwasResultEntry} or \code{CtwasResult}.} @@ -19,7 +19,12 @@ ctwasPosteriors(x, ...) \item{...}{Class-specific selection arguments.} } \value{ -A \code{data.frame} of posteriors (or \code{NULL} when absent). +On a \code{CtwasResultEntry}, the stored posteriors: a + \code{GRanges} when the pipeline placed its rows (each table column in + \code{mcols()}), the table as given otherwise, or \code{NULL} when + absent. On a \code{CtwasResult}, one \code{GRanges} of every row's + posteriors with the run identity in \code{mcols()} (empty when no row + has any); a row whose payload carries no coordinates is an error. } \description{ Return the per-gene (and per-SNP) fine-mapping posterior table diff --git a/man/dentist.Rd b/man/dentist.Rd index 75cbb254..9a71d5c2 100644 --- a/man/dentist.Rd +++ b/man/dentist.Rd @@ -53,7 +53,7 @@ through \code{computeLd}. Ignored when \code{R} is provided directly.} \item{dentistParam}{The DENTIST algorithm settings, built with \code{\link{DentistParam}}: \code{pValueThreshold}, \code{propSVD}, \code{gcControl}, \code{nIter}, \code{gPvalueThreshold}, -\code{duprThreshold}, \code{numThreads}, \code{correctChenEtAlBug} +\code{duprThreshold}, \code{BPPARAM}, \code{correctChenEtAlBug} and \code{seed}. This is the same record \code{\link{ldMismatchQc}} takes as \code{method = DentistParam(...)}, so a setting means the same thing diff --git a/man/dentistSingleWindow.Rd b/man/dentistSingleWindow.Rd index 025f2400..b7760a8a 100644 --- a/man/dentistSingleWindow.Rd +++ b/man/dentistSingleWindow.Rd @@ -15,7 +15,7 @@ dentistSingleWindow( nIter = 10, gPvalueThreshold = 0.05, duprThreshold = 0.99, - numThreads = 1, + BPPARAM = SerialParam(), correctChenEtAlBug = TRUE, ldMethod = "sample", seed = NULL @@ -48,7 +48,10 @@ provided; inferred from \code{X} when \code{X} is provided.} \item{duprThreshold}{Duplicate r-squared threshold. Default is 0.99.} -\item{numThreads}{Number of CPU cores. Default is 1.} +\item{BPPARAM}{A \code{BiocParallelParam} whose workers number the +threads DENTIST's OpenMP loops use when they run on this machine +(\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +thread. Default \code{SerialParam()}.} \item{correctChenEtAlBug}{Correct the original DENTIST operator! bug. Default is TRUE.} diff --git a/man/dot-penalizedRssWeights.Rd b/man/dot-penalizedRssWeights.Rd index 44d16753..b9ba0ba1 100644 --- a/man/dot-penalizedRssWeights.Rd +++ b/man/dot-penalizedRssWeights.Rd @@ -7,32 +7,35 @@ .penalizedRssWeights( stat, ldReference, - penalty, + spec, s = c(0.2, 0.5, 0.9, 1), - gamma = NULL, - alpha = 1, - lambda0 = 0, - lambda2 = 0, selection = c("ldQuadratic", "minFbeta"), fitRetention = c("none", "slim", "full"), - methodArgs = PenalizedRssOptions() + methodArgs = PenalizedRssOptions(), + label = str_c(str_to_lower(spec$penalty), "RssWeights") ) } \arguments{ -\item{stat, ldReference, s, selection, penalty, gamma, alpha, lambda0, lambda2}{See -the public wrappers for details.} +\item{stat, ldReference, s, selection}{See the public wrappers for details.} + +\item{spec}{The penalty, built by the calling wrapper from its own +arguments (internal \code{.rssPenalty()}).} \item{fitRetention}{How much of the search is kept as the \code{"fit"} attribute; see \code{\link{scadRssWeights}}.} \item{methodArgs}{Options forwarded to \code{penalizedRss}, built with -\code{\link{PenalizedRssOptions}}.} +\code{\link{PenalizedRssOptions}}: the path only, since the penalty is +the wrapper's.} + +\item{label}{The calling wrapper's name, for its error messages.} } \value{ Numeric weight vector, one weight per variant of \code{stat}. } \description{ -Shared implementation for \code{scadRssWeights()} and \code{mcpRssWeights()}. +Shared implementation for \code{scadRssWeights()}, \code{mcpRssWeights()}, +\code{enetRssWeights()} and \code{ridgeRssWeights()}. (\code{l0learnRssWeights()} uses the lower-level \code{.rssShrinkGridWeights} scaffold directly, since it sweeps an additional \code{lambda0} path.) Searches over a shrinkage grid \code{s} (LD matrix shrinkage \code{(1-s)R + diff --git a/man/dot-regionToSnpIdx.Rd b/man/dot-regionToSnpIdx.Rd index a7f3c44e..ad579ef5 100644 --- a/man/dot-regionToSnpIdx.Rd +++ b/man/dot-regionToSnpIdx.Rd @@ -9,13 +9,13 @@ \arguments{ \item{snpInfo}{data.frame with CHR and BP columns.} -\item{region}{Character region string "chr:start-end".} +\item{region}{A \code{GRanges} window, of one range or several.} } \value{ Integer vector of matching SNP indices. } \description{ Return 1-based indices into snpInfo for SNPs within a genomic - region string. + window. } \keyword{internal} diff --git a/man/enetRssWeights.Rd b/man/enetRssWeights.Rd new file mode 100644 index 00000000..f48f5ed9 --- /dev/null +++ b/man/enetRssWeights.Rd @@ -0,0 +1,94 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/regularizedRegressionWrappers.R +\name{enetRssWeights} +\alias{enetRssWeights} +\title{Compute Elastic-Net Weights from Summary Statistics} +\usage{ +enetRssWeights( + stat, + ldReference, + alpha = 0.5, + s = c(0.2, 0.5, 0.9, 1), + selection = c("ldQuadratic", "minFbeta"), + fitRetention = c("none", "slim", "full"), + methodArgs = PenalizedRssOptions() +) +} +\arguments{ +\item{stat}{A list of summary statistics: \code{n} (per-variant sample +sizes) and the marginal effects as \code{cor} (standardized), \code{z}, +\code{b} with \code{seb}, or \code{b} alone, taken as already +standardized. The engine receives the standardized effects z / sqrt(n), +with n the median of \code{n}.} + +\item{ldReference}{The LD reference the statistics' variants are matched +to by \code{stat$variantNames}: a genotype panel (see +\code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} or an +\code{\link{LdMatrix}}. A genotype reference's LD is used through its +standardized genotypes, never formed as a matrix.} + +\item{alpha}{Elastic-net mixing in \code{[0, 1]}: the L1 share of the +penalty. Default 0.5.} + +\item{s}{Numeric vector of LD shrinkage parameters. Default: \code{c(0.2, +0.5, 0.9, 1.0)}.} + +\item{selection}{Selection strategy: \code{"ldQuadratic"} (default) or +\code{"minFbeta"}.} + +\item{fitRetention}{How much of the search is kept as the \code{"fit"} +attribute of the returned weights. \code{"none"} (default) attaches +nothing. \code{"slim"} keeps \code{path}, a table with one row per +candidate (\code{s}, \code{lambda}) giving the solver's objective +\code{fbeta}, \code{loss}, convergence flag \code{conv} and number of +non-zero coefficients \code{nparams}, with \code{selected} marking the +candidate returned. \code{"full"} also keeps \code{beta}, the +candidates' coefficients (variants x candidates, in the rows' order).} + +\item{methodArgs}{Options forwarded to the solver, +\code{\link{penalizedRss}}, built with +\code{\link{PenalizedRssOptions}}. A bare list is refused: it cannot +be checked against the engine, so a misspelled option would be +silently ignored.} +} +\value{ +A numeric vector of SNP coefficient weights. Unless + \code{fitRetention = "none"}, the search is attached as attribute + \code{"fit"}. +} +\description{ +Fits the elastic net on the RSS objective -- the lasso penalty mixed with +a ridge term, as glmnet mixes them -- searching over a shrinkage grid +\code{s} and a lambda path. Model selection uses LD-quadratic +pseudovalidation by default. +} +\details{ +\code{alpha} is the L1 share of the penalty: with \eqn{l_1 = \lambda +\alpha} and \eqn{l_2 = \lambda (1 - \alpha)} the penalty is +\eqn{2 l_1 \|\beta\|_1 + l_2 \beta^T \beta}, so \code{alpha = 1} is the +lasso and \code{alpha = 0} ridge (\code{\link{ridgeRssWeights}}). The +default lambda path is divided by \code{max(alpha, 0.001)}, as glmnet +sizes its own, so the L1 share spans the same range at any \code{alpha}. + +The LD shrinkage adds a ridge term of its own, since +\eqn{\beta^T R_s \beta = (1 - s) \beta^T R \beta + s \beta^T \beta}: every +RSS lasso is already partly a ridge, and \code{alpha} adds a second ridge +term that grows with \eqn{\lambda}. Expect the lasso and the elastic net +to differ less on summary statistics than glmnet's do on genotypes. +} +\examples{ +data(eqtlRegionExample) +X <- eqtlRegionExample$X[, 1:30] +y <- eqtlRegionExample$yRes +ss <- lapply( + seq_len(ncol(X)), function(j) coef(summary(lm(y ~ X[, j])))[2, 1:2]) +stat <- list( + b = vapply(ss, `[`, numeric(1), 1L), + seb = vapply(ss, `[`, numeric(1), 2L), + n = rep(nrow(X), ncol(X)), + variantNames = colnames(X) +) +enetRssWeights(stat, LdMatrix(cor(X))) +# A larger ridge share: +enetRssWeights(stat, LdMatrix(cor(X)), alpha = 0.2) +} diff --git a/man/enetWeights.Rd b/man/enetWeights.Rd index d983cd16..97832af9 100644 --- a/man/enetWeights.Rd +++ b/man/enetWeights.Rd @@ -2,15 +2,18 @@ % Please edit documentation in R/regularizedRegressionWrappers.R \name{enetWeights} \alias{enetWeights} -\title{Compute TWAS weights via elastic net (glmnet, alpha = 0.5)} +\title{Compute TWAS weights via elastic net (glmnet)} \usage{ -enetWeights(X, y, methodArgs = GlmnetOptions()) +enetWeights(X, y, alpha = 0.5, methodArgs = GlmnetOptions()) } \arguments{ \item{X}{Numeric genotype / design matrix (samples x variants).} \item{y}{Numeric response (phenotype) vector of length \code{nrow(X)}.} +\item{alpha}{Elastic-net mixing in \code{[0, 1]}: the L1 share of the +penalty. Default 0.5.} + \item{methodArgs}{Additional arguments forwarded to \code{glmnet::cv.glmnet}, built with \code{\link{GlmnetOptions}}. A bare list is refused, since it cannot be checked against the engine's formals.} @@ -19,11 +22,14 @@ list is refused, since it cannot be checked against the engine's formals.} Numeric vector of length \code{ncol(X)} of per-variant weights. } \description{ -Convenience wrapper for \code{\link{glmnetWeights}} with \code{alpha = 0.5}. +Convenience wrapper for \code{\link{glmnetWeights}} at a mixing between the +lasso and ridge, \code{alpha = 0.5} unless set. } \examples{ data(eqtlRegionExample) X <- eqtlRegionExample$X[, 1:30] y <- eqtlRegionExample$yRes enetWeights(X, y) +# A larger ridge share: +enetWeights(X, y, alpha = 0.2) } diff --git a/man/estCtwasGroupPriors.Rd b/man/estCtwasGroupPriors.Rd index 23b8793c..2118f587 100644 --- a/man/estCtwasGroupPriors.Rd +++ b/man/estCtwasGroupPriors.Rd @@ -7,7 +7,7 @@ estCtwasGroupPriors( inputs, ctwasPriorParam = CtwasPriorParam(), - numThreads = 1L, + BPPARAM = SerialParam(), methodArgs = CtwasOptions() ) } @@ -22,7 +22,10 @@ accurate EM iterations), \code{varStructure}, and on a degenerate input is recovered by re-running only the prefit step and returning those (typically finite) priors.} -\item{numThreads}{Number of cores.} +\item{BPPARAM}{A \code{BiocParallelParam} whose workers number the cores +ctwas's own \code{ncore} parallelism uses when they run on this machine +(\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +core. Default \code{SerialParam()}.} \item{methodArgs}{Additional arguments forwarded to ctwas, built with \code{\link{CtwasOptions}}. Names are checked against what diff --git a/man/exportToVcf.Rd b/man/exportToVcf.Rd deleted file mode 100644 index 112b90bc..00000000 --- a/man/exportToVcf.Rd +++ /dev/null @@ -1,115 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/AllGenerics.R, R/resultWriters.R -\name{exportToVcf} -\alias{exportToVcf} -\alias{exportToVcf,list-method} -\alias{exportToVcf,GwasSumStats-method} -\alias{exportToVcf,FineMappingResultBase-method} -\alias{exportToVcf,TwasWeights-method} -\title{Export a result to VCF/BCF} -\usage{ -exportToVcf(x, outputPath, sampleName = NULL, ...) - -\S4method{exportToVcf}{list}(x, outputPath, sampleName = NULL, ...) - -\S4method{exportToVcf}{GwasSumStats}(x, outputPath, sampleName = NULL, studyName = NULL) - -\S4method{exportToVcf}{FineMappingResultBase}( - x, - outputPath, - sampleName = NULL, - studyName = NULL, - context = NULL, - trait = NULL, - method = NULL, - splitByContext = FALSE, - splitByTrait = FALSE -) - -\S4method{exportToVcf}{TwasWeights}( - x, - outputPath, - sampleName = NULL, - studyName = NULL, - context = NULL, - trait = NULL, - method = NULL -) -} -\arguments{ -\item{x}{A \code{GwasSumStats}, \code{QtlFineMappingResult}, -\code{GwasFineMappingResult} or \code{TwasWeights} object, or a -\code{list} of fine-mapping results or of \code{TwasWeights} objects to -combine first.} - -\item{outputPath}{File path for output. Extension determines format: -\code{.vcf.gz} or \code{.vcf.bgz} for bgzipped VCF, \code{.bcf} for BCF, -\code{.vcf} for uncompressed VCF.} - -\item{sampleName}{Name(s) for the VCF sample column(s). Default \code{NULL} -derives them from the object's identity tuple.} - -\item{...}{Additional arguments passed to methods.} - -\item{studyName}{Character or \code{NULL}. Restrict the written records to -this study; \code{NULL} includes all studies.} - -\item{context}{Character or \code{NULL}. Restrict the written records to this -context; \code{NULL} includes all contexts.} - -\item{trait}{Character or \code{NULL}. Restrict the written records to this -trait; \code{NULL} includes all traits.} - -\item{method}{Character or \code{NULL}. Restrict the written records to this -method; \code{NULL} includes all methods.} - -\item{splitByContext}{Logical. If \code{TRUE}, write one VCF per context. -Default \code{FALSE}.} - -\item{splitByTrait}{Logical. If \code{TRUE}, write one VCF per trait. Default -\code{FALSE}.} -} -\value{ -Invisible path(s) to the written file(s). -} -\description{ -Writes GWAS summary statistics, fine-mapping results or TWAS weights to a -GWAS-VCF-style file via VariantAnnotation and Rsamtools: one record per -variant, one SAMPLE per study / fitted model, and the per-variant statistics -as FORMAT fields. Supports bgzipped VCF (.vcf.gz/.vcf.bgz); BCF (.bcf) -additionally needs a working \code{Rsamtools::asBcf()}, which recent -Rsamtools releases disable, so prefer .vcf.bgz. -} -\details{ -Which FORMAT fields are written depends on the input: -\describe{ - \item{\code{GwasSumStats}}{\code{ES} / \code{SS} / \code{AF} for one - study.} - \item{a fine-mapping result}{the marginal fields (\code{ES}, - \code{SE}, \code{LP}, \code{SS}, \code{AF}) plus the posterior ones - (\code{PIP}, \code{LBF}, \code{LFSR}, and a \code{CS}/\code{PUR} pair - per credible-set coverage present).} - \item{\code{TwasWeights}}{\code{WGT}, the prediction weight.} -} - -Every fit the selectors match becomes a SAMPLE of ONE file: the records are -the union of their variants, the FORMAT schema is the union of their fields, -and a fit that did not include a variant -- or does not report a field -- -leaves those cells empty. So two methods over a region, or a dozen weight -methods for one gene, are compared by reading one file rather than a dozen. -Each sample is described in its own \code{##SAMPLE} header line, carrying -the fit's identity tuple and how many variants it contributed. -Cross-validation results are not exported -- see \code{\link{exportToBed}} -for why -- and an export requires the full-data fit. - -\code{splitByContext} / \code{splitByTrait} opt out of that and write one -single-sample file per fit, at a path decorated with the axis value. -} -\examples{ -data(gwasSumStatsS4Example) -exportToVcf( - gwasSumStatsS4Example, outputPath = tempfile(fileext = ".vcf")) -} -\seealso{ -\code{\link{exportToBed}} -} diff --git a/man/extractCsInfo.Rd b/man/extractCsInfo.Rd index b60d67e6..0fb452fa 100644 --- a/man/extractCsInfo.Rd +++ b/man/extractCsInfo.Rd @@ -7,7 +7,7 @@ extractCsInfo(fmRow, csNames, topLociTable, ldSource) } \arguments{ -\item{fmRow}{A \code{\link{fineMappingRow}}, or a single-row +\item{fmRow}{A \code{\link{FineMappingRow}}, or a single-row fine-mapping collection as returned by \code{\link{fineMappingResult}}, carrying the SuSiE fit and variant ids.} @@ -59,7 +59,7 @@ vids <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A") fit <- list(pip = c(0.1, 0.7, 0.2), sets = list(cs = list(L_1 = c(1, 2)))) tl <- data.frame(variant_id = vids, pip = c(0.1, 0.7, 0.2), z = c(1.0, 3.5, -0.5)) -fe <- fineMappingRow(variantIds = vids, susieFit = fit, topLoci = tl) +fe <- FineMappingRow(variantIds = vids, susieFit = fit, topLoci = tl) # A single credible set has no between-CS correlation (cs_corr_* are NA), so # the ldSource is not consulted here. extractCsInfo(fe, csNames = "L_1", topLociTable = tl, diff --git a/man/extractTopPipInfo.Rd b/man/extractTopPipInfo.Rd index 09652da6..a3e09936 100644 --- a/man/extractTopPipInfo.Rd +++ b/man/extractTopPipInfo.Rd @@ -7,7 +7,7 @@ extractTopPipInfo(fmRow, sumstats) } \arguments{ -\item{fmRow}{A \code{\link{fineMappingRow}}, or a single-row +\item{fmRow}{A \code{\link{FineMappingRow}}, or a single-row fine-mapping collection as returned by \code{\link{fineMappingResult}}, carrying the SuSiE fit and variant ids.} @@ -49,7 +49,7 @@ This function is particularly useful for capturing information about vids <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A") fit <- list(pip = c(0.1, 0.7, 0.2)) tl <- data.frame(variant_id = vids, pip = c(0.1, 0.7, 0.2)) -fe <- fineMappingRow(variantIds = vids, susieFit = fit, topLoci = tl) +fe <- FineMappingRow(variantIds = vids, susieFit = fit, topLoci = tl) extractTopPipInfo(fe, sumstats = list(z = c(1.0, 3.5, -0.5))) } diff --git a/man/fillFromReference.Rd b/man/fillFromReference.Rd new file mode 100644 index 00000000..da5b41ee --- /dev/null +++ b/man/fillFromReference.Rd @@ -0,0 +1,61 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/AllClasses.R +\name{fillFromReference} +\alias{fillFromReference} +\title{Fill A Per-Variant Column From A Reference} +\usage{ +fillFromReference( + x, + reference, + column = c("AF", "MAF", "N"), + studyName = NULL, + context = NULL, + trait = NULL +) +} +\arguments{ +\item{x}{A \code{GwasSumStats} or \code{QtlSumStats} object.} + +\item{reference}{A \code{GRanges} carrying \code{A1} and \code{A2} in +\code{mcols()} plus the values: a column named like \code{column}, or +else its one column besides \code{A1}/\code{A2}.} + +\item{column}{Which column to fill: \code{"AF"} (default), \code{"MAF"} or +\code{"N"}.} + +\item{studyName, context, trait}{Selectors pinning one study (every row of a +GWAS study) or one \code{QtlSumStats} entry; \code{context} and +\code{trait} are \code{QtlSumStats}-only.} +} +\value{ +\code{x}, with the selection's column filled. +} +\description{ +Fill the \code{AF}, \code{MAF} or \code{N} column of a + \code{GwasSumStats} / \code{QtlSumStats} selection from a reference + \code{GRanges}, pairing variants on \code{(chrom, pos, A1, A2)} -- the + usual case being effect-allele frequencies the source file did not + carry, taken from a reference panel. Order does not matter. + + An allele swap sends \code{AF} to \code{1 - AF}, so a flipped match is + complemented; \code{MAF} is \code{min(af, 1 - af)} and \code{N} is a + count, both swap-invariant, so neither is. A selected variant the + reference does not name is set \code{NA} -- its value is unknown, not + unchanged -- with a warning, and so is a reference variant the selection + does not hold; no overlap at all is an error. + + Values already in \code{\link{sumStats}} order are assigned positionally + instead, with \code{af(x) <- value} (see + \code{\link{variantColumnReplace}}). +} +\examples{ +data(qtlSumStatsExample) +ref <- sumStats(qtlSumStatsExample) +S4Vectors::mcols(ref) <- S4Vectors::DataFrame( + A1 = ref$A1, + A2 = ref$A2, + AF = runif(length(ref)) +) +x <- fillFromReference(qtlSumStatsExample, ref, "AF") +head(af(x)) +} diff --git a/man/fineMappingPipeline.Rd b/man/fineMappingPipeline.Rd index 0f7b5f5f..3fe90d18 100644 --- a/man/fineMappingPipeline.Rd +++ b/man/fineMappingPipeline.Rd @@ -31,7 +31,7 @@ fineMappingPipeline(data, ...) seed = NULL, mrmashPrior = NULL, dataDrivenPriorWeightsCutoff = 1e-10, - naAction = c("drop", "impute"), + phenotypeFilterParam = PhenotypeFilterParam(), verbose = 1, fitRetention = c("slim", "full"), dataType = NULL @@ -60,7 +60,7 @@ fineMappingPipeline(data, ...) usePCA = FALSE, nPCs = 10L, seed = NULL, - naAction = c("drop", "impute"), + phenotypeFilterParam = PhenotypeFilterParam(), verbose = 1, fitRetention = c("slim", "full"), dataType = NULL @@ -71,6 +71,7 @@ fineMappingPipeline(data, ...) methods, contexts = NULL, traitId = NULL, + cisWindow = NULL, jointSpecification = NULL, initializeWithSusieInf = TRUE, credibleSetParam = CredibleSetParam(), @@ -103,7 +104,10 @@ fineMappingPipeline(data, ...) } \arguments{ \item{data}{A \code{QtlDataset}, \code{MultiStudyQtlDataset}, -\code{QtlSumStats}, or \code{GwasSumStats}.} +\code{QtlSumStats}, or \code{GwasSumStats}. Each row of a +\code{GwasSumStats} is fine-mapped as one region, so it should be an LD +block (load one block, or split the study with a \code{region}); a row +spanning more than 20 Mb, as a whole chromosome does, draws a warning.} \item{...}{Reserved for future per-method arguments.} @@ -126,9 +130,9 @@ fineMappingPipeline(data, ...) even when fitting from a susieInf chain). }} -\item{contexts}{Optional context selection; \code{NULL} (the default) uses -every context. A character vector applies to every study: a context no -study has is an error, and one only some studies lack is skipped for +\item{contexts}{Optional context selection; \code{NULL} (the default) +uses every context. A character vector applies to every study: a context +no study has is an error, and one only some studies lack is skipped for those, with a warning. A list keyed by study name picks each study's contexts separately (\code{list(A = "liver")}); studies it does not name keep all of theirs.} @@ -141,23 +145,30 @@ study's entry may itself be a list keyed by context (\code{list(A = list(brain = "ENSG1"))}). Studies and contexts the list does not name keep all of their traits. A joint fit spanning a study's contexts uses every trait selected in any of them, minus the (context, -trait) pairs a per-context entry leaves out.} +trait) pairs a per-context entry leaves out. In a MultiStudyQtlDataset +a study left with no trait selected sits out; the run is refused only +when no study or summary-statistics row has one.} \item{region}{Optional variant window for QtlDataset trait selection: a -\code{GRanges}, a \code{"chr:start-end"} string, or a one-row data.frame -with \code{chrom}/\code{start}/\code{end}. Mutually exclusive with -\code{traitId}.} +\code{GRanges}. Mutually exclusive with \code{traitId}.} \item{cisWindow}{For QtlDataset: cis-window (bp) around each trait's genomic position when extracting variants. Required when \code{traitId} is -supplied. Mutually exclusive with \code{region}.} - -\item{genotypeFilterParam}{Per-call overrides of the \code{QtlDataset}'s own -filters, built with \code{\link{GenotypeFilterParam}}. A field left unset -keeps the dataset's construct-time value, so -\code{GenotypeFilterParam(mafCutoff = 0)} pins the cutoff at zero while -\code{GenotypeFilterParam()} changes nothing. Applies to the -\code{QtlDataset} method only.} +supplied. Mutually exclusive with \code{region}. For QtlSumStats: +optional; each selected tuple is analysed over its \code{traitPos} +\eqn{\pm} \code{cisWindow}, within its \code{region}, which is then +the window its result records. Every selected tuple needs a +\code{traitPos}. A MultiStudyQtlDataset applies it to each of its +studies, individual-level or summary-statistics, as above.} + +\item{genotypeFilterParam}{Which variants and samples the run keeps, built +with \code{\link{GenotypeFilterParam}}: its \code{keepSamples} narrows +the dataset once, and its MAF, MAC, variance, missingness, +\code{keepVariants} and \code{keepIndel} settings apply to each +extracted block, against that block's samples. A field left unset +filters nothing. A \code{QtlDataset} records no filter of its own, so +this is the only one. \code{QtlDataset} and +\code{MultiStudyQtlDataset} input only.} \item{jointRegions}{For QtlDataset with a multi-range \code{region}: \code{FALSE} (default) fits each range independently and merges the @@ -213,7 +224,7 @@ present are not refit.} \item{crossValidationParam}{Cross-validation settings, built with \code{\link{CrossValidationParam}}: \code{folds} (default \code{0}, no - CV), \code{numThreads} for the per-fold refits, and \code{samplePartition} + CV), \code{BPPARAM} for the per-fold refits, and \code{samplePartition} to reuse a fixed partition across methods. When \code{folds > 1} each method is refit on every fold's training samples and used to predict the held-out ones; the partition, the out-of-fold predictions and the metrics @@ -301,8 +312,12 @@ priors. \code{NULL} uses the canonical prior instead.} which data-driven prior weights are zeroed; \code{NULL} disables the cutoff.} -\item{naAction}{Character. How to handle missing values in the extracted -phenotype/genotype data.} +\item{phenotypeFilterParam}{The run's phenotype QC, built with +\code{\link{PhenotypeFilterParam}}: how missing phenotype values are +handled (unset drops the affected samples; \code{"impute"} fills each +trait's mean; a fit cannot take \code{"keep"}) and whether outlier +samples are dropped. Every fit of the run, joint ones included, reads +its phenotypes under it.} \item{verbose}{Verbosity (0 silent, 1 default). Default \code{1}.} @@ -317,9 +332,10 @@ either way --- its per-credible-set columns are governed by \item{dataType}{Optional assay / modality label for the phenotype the fit was run on (\code{"bulk_rnaseq"}, \code{"methylation"}), recorded as a -per-row provenance column and published by \code{\link{exportToBed}} / -\code{\link{exportToVcf}}. \code{NULL} (default) omits the column. It -cannot be derived --- the input carries the values, not what they measure.} +per-row provenance column and published by \code{\link{writeBed}} / +\code{\link{writeGwasVcf}}. \code{NULL} (default) omits +the column. It cannot be derived --- the input carries the values, not +what they measure.} \item{panelFilterParam}{LD-reference-panel filters for the summary-statistics and GWAS methods, built with \code{\link{PanelFilterParam}}. See @@ -362,7 +378,8 @@ A \code{QtlFineMappingResult} keyed by \code{(study, context, Each row records the LD reference its fit used: none for individual-level (QtlDataset / all-individual-level MultiStudyQtlDataset) fits, the reference of the input row it was fitted - from for RSS-derived fits. + from for RSS-derived fits. Its \code{seqinfo()} names the genome build + the inputs name; inputs naming different builds are refused. } \description{ S4-dispatched per-region fine-mapping entry point that @@ -431,7 +448,7 @@ S4-dispatched per-region fine-mapping entry point that \section{QC contract}{ All \code{QtlSumStats} and \code{GwasSumStats} inputs must have been QC'd via \code{\link{summaryStatsQc}}; the pipeline errors - on inputs where \code{length(qcInfo(x)) == 0L}. \code{summaryStatsQc} + on inputs where \code{length(qcOptions(x)) == 0L}. \code{summaryStatsQc} also drops variants absent from the \code{ldReference}, so by the time per-entry processing runs every variant is guaranteed to be present in the LD panel and a local LD matrix can be built with @@ -475,12 +492,14 @@ deliberately not ported here: the method column on the returned collection carries the bare token (\code{"susie"}, \code{"susieInf"}, \code{"mvsusie"}, ...) only. QC - provenance is recorded on the sumstats' \code{qcInfo}. + provenance is recorded on the sumstats: \code{qcOptions()} and, + per row, \code{qcInfo()}. \item An entry that \code{summaryStatsQc(pipCutoffToSkip = ...)} screened - out (recorded as \code{qcInfo$entryAudit[[i]]$pipScreenSkipped}, and - emptied to 0 variants) is \strong{skipped}, not fit: it produces no - row and a message with the screen reason. An all-screened collection - yields a valid empty result rather than an error. + out (recorded in its row's \code{pipScreenSkipped} column of + \code{qcInfo()}, and emptied to 0 variants) is \strong{skipped}, + not fit: it produces no row and a message with the screen reason. + An all-screened collection yields a valid empty result rather than + an error. } } @@ -507,12 +526,11 @@ deliberately not ported here: Individual-level genotypes reach every fit centred and scaled to unit variance, so a posterior effect --- which is the prediction weight --- is on the standardized scale, and the published - \code{weight_standardized} records it. That scaling belongs to the - \code{QtlDataset} accessors, not to this pipeline: it is - \code{\link{residualizedGenotypes}} that applies it, governed by - \code{ResidualizationParam(scaleResiduals = )} per call with the - dataset's own \code{\link{scaleResiduals}} slot as the default. One - mechanism, one place, shared with \code{\link{twasWeightsPipeline}} and + \code{weight_standardized} records it. The residualization that applies + it (\code{\link{residualizedGenotypes}}) is governed by + \code{ResidualizationParam(scaleResiduals = )}, which defaults to + \code{TRUE}. One mechanism, one place, shared with + \code{\link{twasWeightsPipeline}} and \code{\link{colocboostPipeline}}. An RSS fit needs nothing done: its likelihood is written in standardized units already. diff --git a/man/fineMappingResult.Rd b/man/fineMappingResult.Rd index dfd8b1b0..3a71a3d3 100644 --- a/man/fineMappingResult.Rd +++ b/man/fineMappingResult.Rd @@ -5,14 +5,15 @@ \alias{fineMappingResult} \alias{fineMappingResult,GwasFineMappingResult-method} \alias{fineMappingResult,QtlFineMappingResult-method} -\title{Get a Single Fine-Mapping Entry} +\title{Get One Fine-Mapping Fit} \usage{ fineMappingResult( x, studyName = NULL, context = NULL, trait = NULL, - method = NULL + method = NULL, + blockId = NULL ) \S4method{fineMappingResult}{GwasFineMappingResult}( @@ -20,7 +21,8 @@ fineMappingResult( studyName = NULL, context = NULL, trait = NULL, - method = NULL + method = NULL, + blockId = NULL ) \S4method{fineMappingResult}{QtlFineMappingResult}( @@ -28,23 +30,31 @@ fineMappingResult( studyName = NULL, context = NULL, trait = NULL, - method = NULL + method = NULL, + blockId = NULL ) } \arguments{ \item{x}{A \code{QtlFineMappingResult} or \code{GwasFineMappingResult}.} -\item{studyName, context, trait, method}{Single character identifiers. All -required when the collection has more than one row; optional when the -collection has a single row.} +\item{studyName, context, trait, method}{Single character identifiers. +Required when the collection holds more than one fit; optional when it +holds one. \code{context} and \code{trait} are QTL-only.} + +\item{blockId}{GWAS only: the \code{blockId} of one LD block, to select +that block alone. \code{NULL} (default) selects every block of the fit.} } \value{ -A single-row collection of the same class as \code{x}. +A collection of the same class as \code{x}: one row for a QTL fit, + one row per selected block for a GWAS fit. } \description{ -Return one row of a \code{QtlFineMappingResult} or - \code{GwasFineMappingResult}, selected by its identity, as a single-row - collection of the same class. +Return the rows of one fit of a \code{QtlFineMappingResult} + or \code{GwasFineMappingResult}, selected by its identity, as a + collection of the same class. A QTL fit is one row. A GWAS study + fine-mapped block by block holds one row per LD block, so its fit is + every block of the \code{(study, method)} pair, unless \code{blockId} + names one or \code{region} narrows them. } \examples{ data(qtlFineMappingExample) diff --git a/man/fineMappingRow.Rd b/man/fineMappingRow.Rd index 070b7913..2ebbe446 100644 --- a/man/fineMappingRow.Rd +++ b/man/fineMappingRow.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/fineMappingRow.R -\name{fineMappingRow} -\alias{fineMappingRow} +\name{FineMappingRow} +\alias{FineMappingRow} \title{Build One Fine-Mapping Row} \usage{ -fineMappingRow(variantIds, susieFit, topLoci, cvResult = NULL) +FineMappingRow(variantIds, susieFit, topLoci, cvResult = NULL) } \arguments{ \item{variantIds}{Character vector of variant ids. Each must encode @@ -38,12 +38,12 @@ tl <- data.frame( variant_id = c("chr1:100:A:G", "chr1:200:C:T"), pip = c(0.9, 0.1) ) -row <- fineMappingRow(tl$variant_id, susieFit = list(), topLoci = tl) +row <- FineMappingRow(tl$variant_id, susieFit = list(), topLoci = tl) QtlFineMappingResult( studyName = "s1", context = "c1", trait = "g1", method = "susie", entry = list(row) ) } \seealso{ -\code{\link{twasWeightsRow}} +\code{\link{TwasWeightsRow}} } diff --git a/man/finemapCtwasRegions.Rd b/man/finemapCtwasRegions.Rd index d5009fdb..69557350 100644 --- a/man/finemapCtwasRegions.Rd +++ b/man/finemapCtwasRegions.Rd @@ -7,7 +7,7 @@ finemapCtwasRegions( screenResult, maxNumSingleEffects = 5L, - numThreads = 1L, + BPPARAM = SerialParam(), methodArgs = CtwasOptions() ) } @@ -16,7 +16,10 @@ finemapCtwasRegions( \item{maxNumSingleEffects}{Pass-through.} -\item{numThreads}{Number of cores.} +\item{BPPARAM}{A \code{BiocParallelParam} whose workers number the cores +ctwas's own \code{ncore} parallelism uses when they run on this machine +(\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +core. Default \code{SerialParam()}.} \item{methodArgs}{Additional arguments forwarded to ctwas, built with \code{\link{CtwasOptions}}. Names are checked against what @@ -47,12 +50,11 @@ blocks <- GenomicRanges::GRanges("chr22", IRanges::IRanges(c(10000000, 15000001), c(15000000, 19000000)), blockId = c("chr22_1", "chr22_2")) gss <- loadGwasSumStatsFromManifest(manifest = mani, genome = "hg38", - ldReference = ldStem, region = "chr22:10000000-19000000", - ldBlocks = blocks) + ldReference = ldStem, which = blocks) gwasByRegion <- summaryStatsQc(gss, panelFilterParam = PanelFilterParam(mafCutoff = 0.0025)) inp <- assembleCtwasInputs(gwasSumStats = gwasByRegion, - twasWeights = list(ctwasWeightsExample)) + twasWeights = list(ctwasWeightsExample), method = "susie") est <- estCtwasGroupPriors(inp, ctwasPriorParam = CtwasPriorParam(thin = 1, niterPrefit = 3, niter = 10, fallbackToPrefit = TRUE), diff --git a/man/flattenTupleRanges.Rd b/man/flattenTupleRanges.Rd index c933b7ba..23895c59 100644 --- a/man/flattenTupleRanges.Rd +++ b/man/flattenTupleRanges.Rd @@ -2,6 +2,7 @@ % Please edit documentation in R/RangedTupleList.R \name{flattenTupleRanges} \alias{flattenTupleRanges} +\alias{coerce,RangedTupleList,GRanges-method} \title{Flatten a tuple collection to a plain GRanges} \usage{ flattenTupleRanges(x) @@ -34,9 +35,12 @@ Non-atomic \code{mcols} columns -- the per-element \code{susieFit} / \code{cvResult} payloads -- are dropped. They describe an element, not a range, so there is no row to broadcast them onto. Use the accessors (\code{\link{susieFit}}, \code{\link{cvResult}}) for those. + +\code{as(x, "GRanges")} is the same conversion. } \examples{ data(qtlFineMappingExample) flat <- flattenTupleRanges(qtlFineMappingExample) head(names(S4Vectors::mcols(flat))) +identical(as(qtlFineMappingExample, "GRanges"), flat) } diff --git a/man/frqData.Rd b/man/frqData.Rd index b13f6806..6c68b285 100644 --- a/man/frqData.Rd +++ b/man/frqData.Rd @@ -13,7 +13,7 @@ frqData(x) \item{x}{An \code{\link{SldscData}} object.} } \value{ -A \code{data.frame} of reference-panel frequencies (SNP, MAF). +A \code{DataFrame} of reference-panel frequencies (SNP, MAF). } \description{ Get the allele-frequency table from an SldscData diff --git a/man/fsusieCredibleBand.Rd b/man/fsusieCredibleBand.Rd index dc80ec4a..6d7e1e28 100644 --- a/man/fsusieCredibleBand.Rd +++ b/man/fsusieCredibleBand.Rd @@ -15,19 +15,21 @@ fsusieCredibleBand(x, ...) \item{...}{Ignored.} } \value{ -A long \code{tibble}: \code{cs, chrom, pos, effect, lower, upper, - halfwidth} -- \code{halfwidth} being \code{(upper - lower) / 2}, the - symmetric band half-width publication tables carry (the collection method - additionally carries the entry identity columns). +A \code{GRanges}, one width-1 range per (credible set, grid + position), whose \code{mcols()} hold \code{cs, chrom, pos, effect, + lower, upper, halfwidth} -- \code{halfwidth} being + \code{(upper - lower) / 2}, the symmetric band half-width publication + tables carry (the collection method additionally carries the entry + identity columns). } \description{ For a functional-SuSiE (\code{fsusieR::susiF}) fine-mapping entry, returns the fitted effect curve and its credible band over the functional grid, one -row per (credible set, grid position). Wraps the upstream fSuSiE band +range per (credible set, grid position). Wraps the upstream fSuSiE band computation (fsusieR's internal \code{update_cal_credible_band.susiF} + \code{get_fitted_effect}). Uses saved bands in trimmed fits, or computes -them from an untrimmed fit. Returns zero rows when the functional fields -are absent. +them from an untrimmed fit. Returns an empty \code{GRanges} when the +functional fields are absent. } \examples{ data(fsusieFineMappingExample) diff --git a/man/fsusieTraitEffects.Rd b/man/fsusieTraitEffects.Rd index b3863652..5f7241c2 100644 --- a/man/fsusieTraitEffects.Rd +++ b/man/fsusieTraitEffects.Rd @@ -15,7 +15,7 @@ fsusieTraitEffects(x, ...) \item{...}{Ignored.} } \value{ -A long \code{tibble}: \code{cs, chrom, jointTrait, traitPos, +A long \code{DataFrame}: \code{cs, chrom, jointTrait, traitPos, effect} (the collection method additionally carries the entry identity columns). } diff --git a/man/genomicRegion.Rd b/man/genomicRegion.Rd index 80f8341f..85bd933a 100644 --- a/man/genomicRegion.Rd +++ b/man/genomicRegion.Rd @@ -1,16 +1,13 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/AllGenerics.R, R/AllClasses.R, R/twasWeights.R +% Please edit documentation in R/AllGenerics.R, R/RangedTupleList.R \name{genomicRegion} \alias{genomicRegion} -\alias{genomicRegion,FineMappingResultBase-method} -\alias{genomicRegion,TwasWeights-method} +\alias{genomicRegion,RangedTupleList-method} \title{Get Per-Row Analysis Windows} \usage{ genomicRegion(x, ...) -\S4method{genomicRegion}{FineMappingResultBase}(x) - -\S4method{genomicRegion}{TwasWeights}(x) +\S4method{genomicRegion}{RangedTupleList}(x) } \arguments{ \item{x}{The object.} @@ -24,10 +21,13 @@ A \code{GRanges} with one range per row of \code{x}, or an empty \description{ Return the genomic interval each row was analysed over, as a \code{GRanges} with one range per row -- the trait's own region for a - \code{TwasWeights}, and for a fine-mapping result the window the fit - was run over (the requested region, or the trait's cis-window when the fit - was driven by \code{traitId} + \code{cisWindow}). This is location - provenance (e.g. for cTWAS LD-block placement). + \code{TwasWeights}; for a fine-mapping result the window the fit was run + over (the requested region, or the trait's cis-window when the fit was + driven by \code{traitId} + \code{cisWindow}); for summary statistics the + LD block or window the row was loaded for (the \code{region} given to the + constructor or loader), else the span of its variants before QC. This is + location provenance (e.g. for cTWAS LD-block placement). One method + serves every collection. This is the window that was ANALYSED, not the span of the variants that survived into the fit: QC and screening drop variants first, so a fit over @@ -36,7 +36,7 @@ Return the genomic interval each row was analysed over, as a recovered from the object; the span can, and is simply \code{range(x)}. Being a record of what was analysed, it deliberately does NOT change under - \code{subsetRegion()} or row subsetting -- a subset of a fit's variants was + subsetting -- a subset of a fit's variants was still produced by a fit over the original window. Use \code{range(x)} when you want the current content instead. @@ -46,6 +46,8 @@ Return the genomic interval each row was analysed over, as a \examples{ data(qtlFineMappingExample) genomicRegion(qtlFineMappingExample) +data(gwasSumStatsS4Example) +genomicRegion(gwasSumStatsS4Example) } \seealso{ \code{\link{traitPosition}} for the trait's own coordinates. diff --git a/man/genotypes.Rd b/man/genotypes.Rd index 42377daf..eda3e79e 100644 --- a/man/genotypes.Rd +++ b/man/genotypes.Rd @@ -7,35 +7,21 @@ \usage{ genotypes(x, ...) -\S4method{genotypes}{QtlDataset}(x, traitId = NULL, region = NULL, cisWindow = NULL, samples = NULL) +\S4method{genotypes}{QtlDataset}(x) } \arguments{ \item{x}{The object to extract from.} -\item{...}{Class-specific selection arguments (e.g., \code{traitId}, -\code{region}, \code{cisWindow} for \code{QtlDataset}).} - -\item{traitId}{Character or \code{NULL}. Molecular trait / feature identifier -to select; \code{NULL} matches all traits in the dataset.} - -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -Restrict variants to this region; \code{NULL} uses the full cis window / -all regions.} - -\item{cisWindow}{Integer or \code{NULL}. Half-width (bp) of the cis window -around the trait; \code{NULL} uses the dataset default.} - -\item{samples}{Character vector or \code{NULL}. Restrict to these sample IDs; -\code{NULL} uses all samples.} +\item{...}{Passed on to methods.} } \value{ A numeric matrix, a list of matrices, or \code{NULL}. } \description{ Extract a genotype matrix from an object that carries genotype - data. For a \code{QtlDataset}, returns the genotype matrix for a selected - set of traits or region (see method documentation for the per-class - selection arguments). + data. For a \code{QtlDataset}, the whole dataset's dosages (samples x + variants), with no QC applied: to read part of it, narrow the dataset + first, e.g. \code{genotypes(x[window, samples, ])}. } \examples{ data(qtlDatasetExample) diff --git a/man/intersectVariants.Rd b/man/intersectVariants.Rd index 4a23b7de..df811b35 100644 --- a/man/intersectVariants.Rd +++ b/man/intersectVariants.Rd @@ -31,8 +31,8 @@ Restrict two fine-mapping collections to the variants they have variants that survive. } \details{ -\code{subsetRegion()} restricts ONE object to a window; this - intersects TWO objects against each other. Coloc needs it symmetric -- +This intersects two objects against each other. Coloc needs it + symmetric -- both sides must be scored on the same variant set -- while TWAS, MR and cTWAS need it one-sided, adjusting the QTL side to the GWAS variant set and leaving the GWAS side alone. diff --git a/man/lassosumRss.Rd b/man/lassosumRss.Rd index aa161085..d549860e 100644 --- a/man/lassosumRss.Rd +++ b/man/lassosumRss.Rd @@ -22,7 +22,7 @@ it before passing (e.g., \code{(1-s)*R + s*I}).} \item{n}{Sample size of the GWAS.} -\item{lambda}{A vector of L1 penalty values. Default: 20 values from 0.001 to +\item{lambda}{A vector of L1 penalty values. Default: 20 values from 1e-4 to 0.1 on log scale.} \item{thr}{Convergence threshold. Default: 1e-4.} @@ -47,7 +47,10 @@ where \eqn{R} is the LD matrix (pre-shrunk if desired) and \eqn{r = } \details{ Based on Mak et al (2017) "Polygenic scores via penalized regression on -summary statistics", Genetic Epidemiology 41(6):469-480. +summary statistics", Genetic Epidemiology 41(6):469-480. It runs on the +solver of \code{\link{penalizedRss}}, whose LASSO at \code{alpha = 1} is +lassosum's coordinate descent: the same updates in the same order, so the +same coefficients bit for bit. Internal: \code{\link{lassosumRssWeights}} is the public interface. It runs this over a grid of LD shrinkage values, forwards \code{lambda}, diff --git a/man/lbf.Rd b/man/lbf.Rd index 76538fc7..1086e142 100644 --- a/man/lbf.Rd +++ b/man/lbf.Rd @@ -15,12 +15,13 @@ lbf(x, ...) \item{...}{Ignored.} } \value{ -A \code{tibble}: \code{variant_id} + \code{lbf_L1..lbf_LL} (the - collection method also carries the entry identity columns). +A \code{GRanges}, one range per variant, whose \code{mcols()} + hold \code{variant_id} + \code{lbf_L1..lbf_LL} (the collection method + also carries the entry identity columns). } \description{ The variant x effect matrix of single-effect log Bayes factors -(\code{lbf_variable}, or fSuSiE's \code{lBF}) from the stored fit: one row +(\code{lbf_variable}, or fSuSiE's \code{lBF}) from the stored fit: one range per variant, one \code{lbf_L} column per effect. The per-variant scalar summary (max across effects) is the \code{logBF} column of \code{\link{topLoci}}; this accessor keeps the full per-effect breakdown. diff --git a/man/ldClumpByScore.Rd b/man/ldClumpByScore.Rd index 767a9ff6..b8e43c22 100644 --- a/man/ldClumpByScore.Rd +++ b/man/ldClumpByScore.Rd @@ -24,7 +24,7 @@ which case bigsnpr falls back to minor allele frequency computed from \code{X}.} \item{chr}{Integer or character vector of length \code{ncol(X)} giving the -chromosome for each variant.} +chromosome for each variant, in any style (\code{"chr1"} or \code{1}).} \item{pos}{Integer vector of length \code{ncol(X)} giving the base-pair position for each variant.} diff --git a/man/ldMatrix.Rd b/man/ldMatrix.Rd index 5f804144..f649cc31 100644 --- a/man/ldMatrix.Rd +++ b/man/ldMatrix.Rd @@ -3,25 +3,33 @@ \name{ldMatrix} \alias{ldMatrix} \alias{ldMatrix,LdMatrix-method} +\alias{as.matrix,LdMatrix-method} +\alias{coerce,LdMatrix,matrix-method} \title{Get LD Correlation Matrix} \usage{ ldMatrix(x) \S4method{ldMatrix}{LdMatrix}(x) + +\S4method{as.matrix}{LdMatrix}(x, ...) } \arguments{ \item{x}{An \code{LdMatrix}.} + +\item{...}{Unused.} } \value{ A correlation matrix. } \description{ Extract the LD correlation matrix an \code{\link{LdMatrix}} - holds, labelled by its variant ids. + holds, labelled by its variant ids. \code{as.matrix(x)} and + \code{as(x, "matrix")} return the same matrix. } \examples{ data(eqtlRegionExample) X <- eqtlRegionExample$X[, 1:8] ld <- LdMatrix(cor(X), nSamples = nrow(X)) ldMatrix(ld)[1:3, 1:3] +identical(as.matrix(ld), ldMatrix(ld)) } diff --git a/man/learnTwasWeights.Rd b/man/learnTwasWeights.Rd index bcfd675a..3841c7c4 100644 --- a/man/learnTwasWeights.Rd +++ b/man/learnTwasWeights.Rd @@ -11,7 +11,7 @@ learnTwasWeights( studyName = "", context = "", trait = "", - numThreads = 1, + BPPARAM = SerialParam(), fittedModels = NULL, fitRetention = c("none", "slim", "full"), weightStandardized = FALSE, @@ -44,10 +44,11 @@ weights.} \item{trait}{Character. Trait identity label recorded on the resulting weights.} -\item{numThreads}{The number of threads to use for parallel processing. If -set to -1, the function uses all available cores. If set to 0 or 1, no -parallel processing is performed. If set to 2 or more, parallel processing -is enabled with that many threads.} +\item{BPPARAM}{A \code{BiocParallelParam} the methods run on; +\code{SerialParam()} (default) runs them one at a time. Each draws from +its own random-number stream, seeded by \code{seed}, else by the param's +own \code{RNGseed}, else by one draw from the session RNG, so a run +gives the same numbers however many workers it has.} \item{fittedModels}{Named list of fitted SuSiE-family models, keyed by token (\code{susie}, \code{susieInf}, \code{mvsusie}, \code{fsusie}). @@ -77,10 +78,9 @@ messages, 1 = suppress external package messages (default), 2 = show all messages including those from external packages.} \item{seed}{Integer or \code{NULL}. When supplied, seeds the main-process -RNG and the parallel method-fitting RNG via the \code{BiocParallel} -\code{RNGseed}, for reproducibility under multi-threading. The +RNG and the streams the methods draw from (see \code{BPPARAM}). The main-process seed is scoped to the call, so the session RNG is left as it -was found. \code{NULL} (default) does not seed at all.} +was found. \code{NULL} (default) seeds neither.} } \value{ A list where each element is named after a method and contains the diff --git a/man/loadGenotypeRegion.Rd b/man/loadGenotypeRegion.Rd index fead0e4f..b961008c 100644 --- a/man/loadGenotypeRegion.Rd +++ b/man/loadGenotypeRegion.Rd @@ -6,7 +6,7 @@ \usage{ loadGenotypeRegion( genotype, - region = NULL, + which = NULL, keepIndel = TRUE, keepVariantsPath = NULL, returnVariantInfo = FALSE, @@ -17,7 +17,8 @@ loadGenotypeRegion( \arguments{ \item{genotype}{Path to the genotype data file, or a PLINK prefix.} -\item{region}{The target region in the format "chr:start-end".} +\item{which}{Optional \code{GRanges}: load only the variants that overlap +it. If NULL, loads every variant.} \item{keepIndel}{Whether to keep indel SNPs.} @@ -51,5 +52,6 @@ dosages are automatically rescaled using the stored U_MIN/U_MAX values. \examples{ stem <- sub("[.]bed$", "", system.file("extdata", "toy_ref.bed", package = "pecotmr")) -loadGenotypeRegion(genotype = stem, region = "chr22:1-100000000") +loadGenotypeRegion(genotype = stem, + which = GenomicRanges::GRanges("chr22:1-100000000")) } diff --git a/man/loadGwasSumStatsFromManifest.Rd b/man/loadGwasSumStatsFromManifest.Rd index e07345f2..49577d6c 100644 --- a/man/loadGwasSumStatsFromManifest.Rd +++ b/man/loadGwasSumStatsFromManifest.Rd @@ -8,12 +8,11 @@ loadGwasSumStatsFromManifest( manifest, genome = NULL, ldReference = NULL, - region = NULL, + which = NULL, minLdOverlapWarn = 0.5, columnMapping = NULL, sampleSelect = NULL, - formatMapping = NULL, - ldBlocks = NULL + formatMapping = NULL ) } \arguments{ @@ -27,7 +26,11 @@ chromosomes its studies cover, and stored once). When a row supplies a study-level scalar (\code{nCase} + \code{nControl}, or \code{nSample}), its sumstats file need not carry a per-variant \code{N} column; -\code{\link{summaryStatsQc}} fills \code{N} from the scalar.} +\code{\link{summaryStatsQc}} fills \code{N} from the scalar. Optional +BED-style \code{chrom}/\code{start}/\code{end} columns, with a 0-based +\code{start} as in BED, give each study its own window, read and kept as +with \code{which}; a manifest that has them cannot also be given +\code{which}.} \item{genome}{Genome build; reconciled with a \code{genome} column.} @@ -36,9 +39,17 @@ spec (path/prefix/genoMeta), used for every study; where a row also names an \code{ldReferencePath} the two must agree. Omit it to give each study the reference its \code{ldReferencePath} names.} -\item{region}{Optional \code{chr:start-end} string, GRanges, or one-row -data.frame restricting the variants read (honoured only for tabix-indexed -text and bgzipped+tabixed VCF; ignored with a warning otherwise).} +\item{which}{Optional analysis windows shared by every study, typically +LD blocks: a \code{GRanges}, or the path of a BED file, read as BED +with a 0-based start. Only the variants inside them are read, when the +file is tabix-indexed text or a bgzipped + tabixed VCF (otherwise the +whole file is read, with a warning), and each study is split into one +element per window it has variants in, each window recorded as that +element's \code{region}, as \code{\link{GwasSumStats}} does with its +\code{region}; a named \code{GRanges} names the blocks. Without +windows a genome-wide file splits +into one element per chromosome; split by LD block, it has the +granularity \code{\link{assembleCtwasInputs}} needs.} \item{minLdOverlapWarn}{Warn when the fraction of sumstats variants present in the LD reference falls below this (default 0.5).} @@ -51,22 +62,16 @@ when a row has no \code{columnMapping}.} \item{formatMapping}{Optional GWAS-VCF FORMAT tag mapping (canonical stat -> FORMAT field), overriding ES/SE/LP/SS/EAF defaults.} - -\item{ldBlocks}{Optional LD-block specification (a \code{GRanges}, a -data.frame with \code{chrom}/\code{start}/\code{end}, or a path to such -a table). Without it a genome-wide file splits into one -element per chromosome; with it, into one element per LD block, which is -the granularity \code{\link{assembleCtwasInputs}} needs.} } \value{ A \code{GwasSumStats} object. } \description{ Build a \code{\link{GwasSumStats}} from a manifest with one row - per study. No QC is run (the result carries \code{qcInfo = list()}). Each - sumstats file needs a \code{z} column, or \code{beta}+\code{se} from which - the Wald z (\code{z = beta/se}) is derived when \code{z} is absent (a - supplied \code{z} takes precedence). + per study. No QC is run (the result carries empty \code{qcOptions()}). + Each sumstats file needs a \code{z} column, or \code{beta}+\code{se} from + which the Wald z (\code{z = beta/se}) is derived when \code{z} is absent + (a supplied \code{z} takes precedence). } \examples{ gwasTsv <- system.file("extdata", "manifests", @@ -75,5 +80,6 @@ ldStem <- file.path(system.file("extdata", "ld_reference", "chr22", package = "pecotmr"), "protocol_example.LD.chr22") manifest <- data.frame(study = "g1", sumStatsPath = gwasTsv) loadGwasSumStatsFromManifest(manifest = manifest, genome = "hg38", - ldReference = ldStem, region = "chr22:10000000-19000000") + ldReference = ldStem, + which = GenomicRanges::GRanges("chr22:10000000-19000000")) } diff --git a/man/loadMultiStudyQtlDatasetFromManifest.Rd b/man/loadMultiStudyQtlDatasetFromManifest.Rd index 72863db6..917da313 100644 --- a/man/loadMultiStudyQtlDatasetFromManifest.Rd +++ b/man/loadMultiStudyQtlDatasetFromManifest.Rd @@ -9,14 +9,12 @@ loadMultiStudyQtlDatasetFromManifest( sumStatsManifest = NULL, genome = NULL, ldReference = NULL, - region = NULL, + which = NULL, minLdOverlapWarn = 0.5, columnMapping = NULL, sampleSelect = NULL, formatMapping = NULL, - transposeCovariates = FALSE, - scaleResiduals = TRUE, - genotypeFilterParam = GenotypeFilterParam() + transposeCovariates = FALSE ) } \arguments{ @@ -27,20 +25,13 @@ loadMultiStudyQtlDatasetFromManifest( \item{sumStatsManifest}{Optional QtlSumStats manifest (see \code{\link{loadQtlSumStatsFromManifest}}).} -\item{genome, ldReference, region, minLdOverlapWarn}{Passed to the QtlSumStats +\item{genome, ldReference, which, minLdOverlapWarn}{Passed to the QtlSumStats loader for \code{sumStatsManifest}.} \item{columnMapping, sampleSelect, formatMapping}{Passed to the QtlSumStats loader for \code{sumStatsManifest}.} \item{transposeCovariates}{Transpose covariate TSVs (QTLtools layout).} - -\item{scaleResiduals}{Pass-through \code{\link{QtlDataset}} argument, -applied to every study.} - -\item{genotypeFilterParam}{Pass-through \code{\link{QtlDataset}} filtering -options, built with \code{\link{GenotypeFilterParam}} and applied to -every study.} } \value{ A \code{MultiStudyQtlDataset} object. diff --git a/man/loadQtlDatasetFromManifest.Rd b/man/loadQtlDatasetFromManifest.Rd index 0283d9bb..876ff32e 100644 --- a/man/loadQtlDatasetFromManifest.Rd +++ b/man/loadQtlDatasetFromManifest.Rd @@ -9,8 +9,6 @@ loadQtlDatasetFromManifest( studyName = NULL, genotypes = NULL, genotypeCovariates = NULL, - scaleResiduals = TRUE, - genotypeFilterParam = GenotypeFilterParam(), transposeCovariates = FALSE ) } @@ -30,12 +28,6 @@ a genotype path/prefix; reconciled with a \code{genotypePath} column.} \item{genotypeCovariates}{A numeric matrix (samples x covariates) or a path to a covariate TSV; reconciled with a \code{genotypeCovariatePath} column.} -\item{scaleResiduals}{Pass-through \code{\link{QtlDataset}} argument.} - -\item{genotypeFilterParam}{Pass-through \code{\link{QtlDataset}} filtering -options, built with \code{\link{GenotypeFilterParam}} and stored as lazy -QC slots.} - \item{transposeCovariates}{Transpose covariate TSVs (QTLtools layout) before treating them as samples-as-rows.} } diff --git a/man/loadQtlSumStatsFromManifest.Rd b/man/loadQtlSumStatsFromManifest.Rd index a1f87db8..d5bfc04d 100644 --- a/man/loadQtlSumStatsFromManifest.Rd +++ b/man/loadQtlSumStatsFromManifest.Rd @@ -8,7 +8,7 @@ loadQtlSumStatsFromManifest( manifest, genome = NULL, ldReference = NULL, - region = NULL, + which = NULL, minLdOverlapWarn = 0.5, columnMapping = NULL, sampleSelect = NULL, @@ -28,7 +28,13 @@ cover, and stored once). When a row supplies \code{nSample}, its sumstats file need not carry a per-variant \code{N} column; \code{\link{summaryStatsQc}} fills \code{N} from the scalar. (Unlike the GWAS loader, there are no \code{nCase}/\code{nControl} columns: molecular -QTL traits are quantitative.)} +QTL traits are quantitative.) Optional BED-style +\code{chrom}/\code{start}/\code{end} columns, with a 0-based +\code{start} as in BED, give each tuple its own window, read and kept as +with \code{which}; a manifest that has them cannot also be given +\code{which}. Optional \code{traitStart}/\code{traitEnd} columns, on +the row's \code{chrom} and 0-based the same way, give the trait's +position (\code{traitPos}).} \item{genome}{Genome build; reconciled with a \code{genome} column.} @@ -37,14 +43,22 @@ spec, used for every row; where a row also names an \code{ldReferencePath} the two must agree. Omit it to give each row the reference its \code{ldReferencePath} names.} -\item{region, minLdOverlapWarn, columnMapping, sampleSelect, formatMapping}{As -for \code{\link{loadGwasSumStatsFromManifest}}.} +\item{which}{Optional analysis window shared by every tuple: a +\code{GRanges}, or the path of a BED file, read as BED with a 0-based +start. One window only, since a tuple has one: tuples with windows +of their own give them in the manifest's columns. Only the variants +inside it are read, when the file is tabix-indexed (otherwise the whole +file is read, with a warning), and it is each tuple's \code{region} (see +\code{\link{QtlSumStats}}).} + +\item{minLdOverlapWarn, columnMapping, sampleSelect, formatMapping}{As for +\code{\link{loadGwasSumStatsFromManifest}}.} \item{traitColumn}{Optional column of the sumstats file naming the trait of each row (e.g. \code{"molecular_trait_id"} in a cis-QTL scan, which writes every gene into one table). When set, each manifest row keeps only the rows whose \code{traitColumn} equals that row's \code{trait}. Without it -a multi-trait file loads whole, since \code{region} restriction needs a +a multi-trait file loads whole, since \code{which} restriction needs a tabix index and neighbouring cis windows overlap regardless.} \item{variantIdAlleles}{Where to find the alleles when the file has no @@ -76,5 +90,6 @@ ldStem <- file.path(system.file("extdata", "ld_reference", "chr22", manifest <- data.frame(study = "s1", context = "brain", trait = "ENSG1", sumStatsPath = tsv) loadQtlSumStatsFromManifest(manifest = manifest, genome = "hg38", - ldReference = ldStem, region = "chr22:10000000-19000000") + ldReference = ldStem, + which = GenomicRanges::GRanges("chr22:10000000-19000000")) } diff --git a/man/maf.Rd b/man/maf.Rd index 2289830d..4ba6a564 100644 --- a/man/maf.Rd +++ b/man/maf.Rd @@ -8,22 +8,15 @@ \usage{ maf(x, ...) -\S4method{maf}{SumStatsBase}( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL -) +\S4method{maf}{SumStatsBase}(x, studyName = NULL, context = NULL, trait = NULL) -\S4method{maf}{QtlDataset}(x, region = NULL, cisWindow = NULL, samples = NULL) +\S4method{maf}{QtlDataset}(x) } \arguments{ -\item{x}{A \code{GwasSumStats} or \code{QtlDataset} object.} +\item{x}{A \code{GwasSumStats}, \code{QtlSumStats} or \code{QtlDataset} +object.} -\item{...}{Class-specific selection arguments (e.g., \code{region}, -\code{cisWindow} for \code{QtlDataset}).} +\item{...}{Class-specific selection arguments.} \item{studyName}{Character (length 1) or \code{NULL}. Restrict the selection to this study; \code{NULL} matches all studies.} @@ -33,28 +26,15 @@ this context; \code{NULL} matches all contexts.} \item{trait}{Character (length 1) or \code{NULL}. Restrict the selection to this trait; \code{NULL} matches all traits.} - -\item{annotateSignificance}{Optional correction-method name passed through to -\code{\link{sumStats}} (QTL only); \code{NULL} applies none.} - -\item{ranges}{A \code{GRanges} or \code{NULL} (default). Return only the -variants overlapping these ranges; \code{NULL} returns everything.} - -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -Restrict variants to this region; \code{NULL} uses the full cis window / -all regions.} - -\item{cisWindow}{Integer or \code{NULL}. Half-width (bp) of the cis window -around the trait; \code{NULL} uses the dataset default.} - -\item{samples}{Character vector or \code{NULL}. Restrict to these sample IDs; -\code{NULL} uses all samples.} } \value{ Numeric vector of MAFs, or NULL if not available. } \description{ -Extract MAF vector from a GwasSumStats object. +Extract the minor-allele-frequency vector from one entry of + a summary-statistic collection, or from a \code{QtlDataset} over the + whole dataset (narrow it first, with \code{x[i, j, ]}, to read part of + it). } \examples{ data(qtlDatasetExample) diff --git a/man/marginalEffects.Rd b/man/marginalEffects.Rd index 18ab81e4..ae505550 100644 --- a/man/marginalEffects.Rd +++ b/man/marginalEffects.Rd @@ -5,24 +5,20 @@ \alias{marginalEffects,FineMappingResultBase-method} \title{Get Marginal Effects} \usage{ -marginalEffects(x, maxPval = NULL, ...) +marginalEffects(x, ...) \S4method{marginalEffects}{FineMappingResultBase}( x, - maxPval = NULL, studyName = NULL, context = NULL, trait = NULL, method = NULL, - region = NULL + blockId = NULL ) } \arguments{ \item{x}{A \code{QtlFineMappingResult} or \code{GwasFineMappingResult}.} -\item{maxPval}{Optional numeric (length 1). When non-\code{NULL}, filter rows -where \code{p > maxPval}. Default \code{NULL} (no filter).} - \item{...}{Class-specific selection arguments.} \item{studyName}{Character (length 1) or \code{NULL}. Restrict the selection @@ -37,19 +33,21 @@ this trait; \code{NULL} matches all traits.} \item{method}{Character (length 1) or \code{NULL}. Restrict the selection to this fine-mapping / weight method; \code{NULL} matches all methods.} -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -Restrict variants to this region; \code{NULL} uses the full cis window / -all regions.} +\item{blockId}{GWAS fine-mapping results only: the \code{blockId} naming +one LD block of a fit; \code{NULL} matches every block.} } \value{ -A \code{data.frame}. +A \code{GRanges}, one range per variant; when the selectors match + more than one entry the row-identity columns are carried in + \code{mcols()} too. } \description{ Extract per-variant marginal univariate effects from a - fine-mapping entry or result. Returns a \code{data.frame} with identity - columns (\code{variant_id, chrom, pos, A1, A2}), context (\code{N, MAF}), - and the marginal effect columns (\code{beta, se, z, p}). Populated - uniformly across the individual-level and RSS paths. + fine-mapping entry or result, one range per variant. Its \code{mcols()} + hold the identity columns (\code{variant_id, chrom, pos, A1, A2}), + context (\code{N, MAF}), and the marginal effect columns + (\code{beta, se, z, p}). Populated uniformly across the + individual-level and RSS paths. } \examples{ data(qtlFineMappingExample) diff --git a/man/mashInput.Rd b/man/mashInput.Rd index 22fbd218..dc18ac62 100644 --- a/man/mashInput.Rd +++ b/man/mashInput.Rd @@ -22,7 +22,8 @@ mashInput( fine-mapping result objects, one per region. Names disambiguate rownames across regions (defaults to \code{region1}, \code{region2}, ...). For \code{QtlSumStats} inputs \code{\link{summaryStatsQc}} must have been -run (the matrix builder rejects un-QC'd SumStats).} +run (the matrix builder rejects un-QC'd SumStats). The conditions are a +QTL object's contexts and a GWAS object's studies.} \item{nRandom, nNull}{Per-object random / null sample sizes (default 10 each).} diff --git a/man/mcpRssWeights.Rd b/man/mcpRssWeights.Rd index 12761975..6189a018 100644 --- a/man/mcpRssWeights.Rd +++ b/man/mcpRssWeights.Rd @@ -33,7 +33,9 @@ standardized genotypes, never formed as a matrix.} \item{gamma}{MCP concavity parameter. Default 3.} -\item{alpha}{Elastic-net mixing (1 = pure L1). Default 1.} +\item{alpha}{Elastic-net mixing in \code{(0, 1]}: the MCP share of +the penalty, the rest a ridge term, as \code{\link{penalizedRss}} +mixes them. Default 1, no ridge term.} \item{selection}{Selection strategy: \code{"ldQuadratic"} (default) or \code{"minFbeta"}.} diff --git a/man/mergeCtwasBoundaryRegions.Rd b/man/mergeCtwasBoundaryRegions.Rd index ef516588..b273d365 100644 --- a/man/mergeCtwasBoundaryRegions.Rd +++ b/man/mergeCtwasBoundaryRegions.Rd @@ -10,7 +10,7 @@ mergeCtwasBoundaryRegions( filterCs = FALSE, maxSNP = Inf, maxNumSingleEffects = 5L, - numThreads = 1L, + BPPARAM = SerialParam(), methodArgs = CtwasOptions() ) } @@ -36,7 +36,10 @@ to be selected (\code{select_boundary_genes} \code{filter_cs}). Default \item{maxNumSingleEffects}{Integer. Max number of single effects for the merged-region re-fine-mapping (LD path only). Default \code{5}.} -\item{numThreads}{Number of cores. Default \code{1}.} +\item{BPPARAM}{A \code{BiocParallelParam} whose workers number the cores +ctwas's own \code{ncore} parallelism uses when they run on this machine +(\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +core. Default \code{SerialParam()}.} \item{methodArgs}{Additional arguments forwarded to ctwas, built with \code{\link{CtwasOptions}}. Names are checked against what diff --git a/man/molecularTraits.Rd b/man/molecularTraits.Rd index 7cd247dc..1c80a3a4 100644 --- a/man/molecularTraits.Rd +++ b/man/molecularTraits.Rd @@ -7,49 +7,22 @@ \usage{ molecularTraits(x, ...) -\S4method{molecularTraits}{QtlDataset}( - x, - contexts, - traitId = NULL, - region = NULL, - naAction = c("keep", "drop", "impute"), - outlierAction = c("keep", "drop"), - outlierPvalThreshold = 0.001, - outlierArgs = CovMcdOptions() -) +\S4method{molecularTraits}{QtlDataset}(x, context, trait = NULL) } \arguments{ \item{x}{The object to extract from.} -\item{...}{Class-specific selection arguments (e.g., \code{contexts}, -\code{traitId}, \code{region}).} +\item{...}{Class-specific selection arguments (e.g., \code{context}, +\code{trait}).} -\item{contexts}{Character vector. Context(s) whose data to extract.} +\item{context}{Character vector. Context(s) whose data to extract.} -\item{traitId}{Character or \code{NULL}. Molecular trait / feature identifier +\item{trait}{Character or \code{NULL}. Molecular trait / feature identifier to select; \code{NULL} matches all traits in the dataset.} - -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -Restrict variants to this region; \code{NULL} uses the full cis window / -all regions.} - -\item{naAction}{Character. How to handle missing phenotype values: one of -\code{"keep"}, \code{"drop"}, or \code{"impute"}.} - -\item{outlierAction}{Character. How to handle phenotype outliers: one of -\code{"keep"} or \code{"drop"}.} - -\item{outlierPvalThreshold}{Numeric. Two-sided p-value threshold for flagging -phenotype outliers. Default \code{1e-3}.} - -\item{outlierArgs}{Extra arguments for \code{robustbase::covMcd()}, the -robust covariance estimator the outlier rule is built on, supplied with -\code{\link{CovMcdOptions}} -- \code{alpha} in particular. Only -consulted when \code{outlierAction = "drop"}.} } \value{ -A \code{SummarizedExperiment} when one context is selected, or a - named list of them for several. A \code{QtlDataset} is a +A named list of \code{SummarizedExperiment}s keyed by context, + one per selected context. A \code{QtlDataset} is a \code{MultiAssayExperiment}, so these are its experiments; take the measurement matrix itself with \code{SummarizedExperiment::assay()} rather than asking this accessor @@ -57,11 +30,12 @@ A \code{SummarizedExperiment} when one context is selected, or a } \description{ Extract molecular-trait data from an object that carries it. - For a \code{QtlDataset}, the user can optionally select specific contexts, - traits, or a region (see method documentation for the per-class selection - arguments). + For a \code{QtlDataset}, select contexts and, optionally, traits by + name. The data come back as stored: missing values and outliers are a + run's phenotype QC (\code{\link{PhenotypeFilterParam}}), applied by the + pipelines, not by this accessor. } \examples{ data(qtlDatasetExample) -molecularTraits(qtlDatasetExample, contexts = "brain") +molecularTraits(qtlDatasetExample, context = "brain") } diff --git a/man/mrmashWrapper.Rd b/man/mrmashWrapper.Rd index c27bce1d..40f88eb9 100644 --- a/man/mrmashWrapper.Rd +++ b/man/mrmashWrapper.Rd @@ -15,7 +15,7 @@ mrmashWrapper( updateV = TRUE, updateVMethod = "full", standardize = FALSE, - numThreads = 1, + BPPARAM = SerialParam(), methodArgs = MrmashOptions() ) } @@ -53,8 +53,12 @@ data. Default is FALSE. Used by the summary-statistic and initialisation steps as well as the fit, so it is set here rather than in \code{methodArgs}.} -\item{numThreads}{The number of threads to use for parallel computation. -Default is 1. Used by the same three steps as \code{standardize}.} +\item{BPPARAM}{A \code{BiocParallelParam}. The univariate glmnet fits that +initialise the coefficients run on its workers, and mr.mash's own +threads (the summary statistics and the fit) number its workers when +they run on this machine (\code{SerialParam}, \code{MulticoreParam}); +for other backends mr.mash runs on one thread. Default +\code{SerialParam()}.} \item{methodArgs}{Options forwarded to \code{mr.mashr::mr.mash} under its own names, built with \code{\link{MrmashOptions}} diff --git a/man/nSamples.Rd b/man/nSamples.Rd index 0f1fa66d..a3dbb4c1 100644 --- a/man/nSamples.Rd +++ b/man/nSamples.Rd @@ -1,59 +1,32 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/AllGenerics.R, R/LdMatrix.R, -% R/GenotypeHandle.R, R/AllClasses.R +% R/GenotypeHandle.R \name{nSamples} \alias{nSamples} \alias{nSamples,LdMatrix-method} \alias{nSamples,GenotypeHandle-method} -\alias{nSamples,SumStatsBase-method} -\title{Get Sample Sizes} +\title{Get the Number of Reference Samples} \usage{ nSamples(x, ...) \S4method{nSamples}{LdMatrix}(x, ...) \S4method{nSamples}{GenotypeHandle}(x) - -\S4method{nSamples}{SumStatsBase}( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL -) } \arguments{ -\item{x}{A \code{GwasSumStats}, \code{QtlSumStats}, \code{LdMatrix} or -\code{GenotypeHandle} object.} +\item{x}{An \code{LdMatrix} or \code{GenotypeHandle} object.} \item{...}{Class-specific selection arguments.} - -\item{studyName}{Character (length 1) or \code{NULL}. Restrict the selection -to this study; \code{NULL} matches all studies.} - -\item{context}{Character (length 1) or \code{NULL}. Restrict the selection to -this context; \code{NULL} matches all contexts.} - -\item{trait}{Character (length 1) or \code{NULL}. Restrict the selection to -this trait; \code{NULL} matches all traits.} - -\item{annotateSignificance}{Optional correction-method name passed through to -\code{\link{sumStats}} (QTL only); \code{NULL} applies none.} - -\item{ranges}{A \code{GRanges} or \code{NULL} (default). Return only the -variants overlapping these ranges; \code{NULL} returns everything.} } \value{ -Numeric vector of sample sizes for a summary-statistic entry; - integer of length 1 for a \code{GenotypeHandle} or an \code{LdMatrix} - (\code{NA} when the matrix records no size). +An integer of length 1 (\code{NA} when an \code{LdMatrix} records + no size). } \description{ -Extract sample sizes: the per-variant sample-size vector of a - \code{GwasSumStats} or \code{QtlSumStats} entry, selected by its identity - tuple, the number of samples carried by a \code{GenotypeHandle}, or the - panel size an \code{\link{LdMatrix}} records. +The number of samples an LD reference was built from: the + samples carried by a \code{GenotypeHandle}, or the panel size an + \code{\link{LdMatrix}} records. The per-variant sample size of summary + statistics is \code{\link{sampleSize}}. } \details{ The genotype handle is the seed layer behind a panel and is not @@ -61,6 +34,7 @@ The genotype handle is the seed layer behind a panel and is not \code{readGenotypes()} and ask it directly. } \examples{ -data(qtlSumStatsExample) -nSamples(qtlSumStatsExample) +data(eqtlRegionExample) +X <- eqtlRegionExample$X[, 1:8] +nSamples(LdMatrix(cor(X), nSamples = nrow(X))) } diff --git a/man/nSnps.Rd b/man/nSnps.Rd index 8eddf55f..19f208c3 100644 --- a/man/nSnps.Rd +++ b/man/nSnps.Rd @@ -8,14 +8,7 @@ \usage{ nSnps(x, ...) -\S4method{nSnps}{SumStatsBase}( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL -) +\S4method{nSnps}{SumStatsBase}(x, studyName = NULL, context = NULL, trait = NULL) \S4method{nSnps}{H2Estimate}(x) } @@ -33,12 +26,6 @@ this context; \code{NULL} matches all contexts.} \item{trait}{Character (length 1) or \code{NULL}. Restrict the selection to this trait; \code{NULL} matches all traits.} - -\item{annotateSignificance}{Optional correction-method name passed through to -\code{\link{sumStats}} (QTL only); \code{NULL} applies none.} - -\item{ranges}{A \code{GRanges} or \code{NULL} (default). Return only the -variants overlapping these ranges; \code{NULL} returns everything.} } \value{ Integer. diff --git a/man/nestTupleRanges.Rd b/man/nestTupleRanges.Rd index 54d19155..97f02e66 100644 --- a/man/nestTupleRanges.Rd +++ b/man/nestTupleRanges.Rd @@ -18,7 +18,8 @@ An object of \code{template}'s class. } \description{ The inverse of \code{\link{flattenTupleRanges}}: ranges are grouped by the -identity tuple they carry and returned to \code{template}'s elements, so the +identity tuple they carry -- and, for a tuple split across chromosomes, by +chromosome -- and returned to \code{template}'s elements, so the collection's class, its per-element payloads and its collection-level slots all survive a plyranges round trip. } diff --git a/man/normalizeVariantId.Rd b/man/normalizeVariantId.Rd index 1b11216c..1bf84b29 100644 --- a/man/normalizeVariantId.Rd +++ b/man/normalizeVariantId.Rd @@ -9,8 +9,10 @@ normalizeVariantId(ids, chrPrefix = TRUE, convention = NULL) \arguments{ \item{ids}{A character vector of variant IDs in any supported format.} -\item{chrPrefix}{Logical, whether to include "chr" prefix. Default TRUE. -Ignored if \code{convention} is provided.} +\item{chrPrefix}{Logical. \code{TRUE} (default) writes the chromosome in +UCSC style (\code{chr1}, \code{chrM}), the style pecotmr uses +throughout; \code{FALSE} writes it bare. Ignored if \code{convention} is +provided.} \item{convention}{Optional list from \code{detectVariantConvention} or \code{attr(parseVariantId(ids), "convention")}. When provided, the output diff --git a/man/overlapTopLoci.Rd b/man/overlapTopLoci.Rd index e78c0e9b..8a2ecda3 100644 --- a/man/overlapTopLoci.Rd +++ b/man/overlapTopLoci.Rd @@ -23,7 +23,9 @@ inputs. Default 0.025.} A \code{GRanges} keyed on the QTL variant (\code{variant_id, chrom, pos, A1, A2} in \code{mcols()}) with all other columns prefixed \code{qtl_} / \code{gwas_}. Zero ranges when there is no - allele-aware overlap. Take a table with \code{as.data.frame()}. + allele-aware overlap. Take a table with \code{as.data.frame()}. Its + \code{seqinfo()} names the genome build the two results name; results + naming different builds are refused. } \description{ Intersect the top-loci tables of a \code{QtlFineMappingResult} and a diff --git a/man/parseRegion.Rd b/man/parseRegion.Rd deleted file mode 100644 index b011a737..00000000 --- a/man/parseRegion.Rd +++ /dev/null @@ -1,24 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/variantId.R -\name{parseRegion} -\alias{parseRegion} -\title{Parse a region string into its components} -\usage{ -parseRegion(region) -} -\arguments{ -\item{region}{A single region string.} -} -\value{ -A vector/list with the chromosome, start and end, or the input - unchanged when it is not a scalar string. -} -\description{ -Split a region identifier (e.g. \code{"chr1:100-200"} or -\code{"chr1_100_200"}) into chromosome, start and end. Non-character or -non-scalar input is returned unchanged. -} -\examples{ -parseRegion("chr1:1000000-2000000") -parseRegion("chr1_1000000_2000000") -} diff --git a/man/parseVariantId.Rd b/man/parseVariantId.Rd index e1882c3f..fe9dc2ca 100644 --- a/man/parseVariantId.Rd +++ b/man/parseVariantId.Rd @@ -12,18 +12,19 @@ parseVariantId(ids) layout).} } \value{ -A tibble with columns "chrom" (character, normalized), "pos" +A tibble with columns "chrom" (character, UCSC style), "pos" (integer), "A2" (character), "A1" (character). The detected convention is stored as \code{attr(result, "convention")}. } \description{ Converts variant IDs from any supported string format or data.frame into a -standardized data.frame with a normalized character chrom, integer pos, and -character allele columns (A2, A1). The chrom is canonicalized (chr stripped, -uppercased, 23 -> X / 24 -> Y / M -> MT) but kept as a string so X/Y/MT -survive. Supports colon-separated ("chr1:100:A:G"), underscore-separated -("1_100_A_G"), with or without "chr" prefix, and with optional build suffix -(":b38" or "_b38"). The detected input convention is stored as an attribute. +standardized data.frame with a character chrom, integer pos, and character +allele columns (A2, A1). The chrom is spelled in UCSC style, as every +chromosome pecotmr holds is ("chr1", "chrX", "chrM"; 23 -> chrX, +24 -> chrY). Supports colon-separated ("chr1:100:A:G"), +underscore-separated ("1_100_A_G"), with or without "chr" prefix, and with +optional build suffix (":b38" or "_b38"). The detected input convention is +stored as an attribute. } \examples{ parseVariantId(c("chr1:100:A:G", "chr2:200:T:C")) diff --git a/man/pecotmr-gwas-sumstats.Rd b/man/pecotmr-gwas-sumstats.Rd index 3da781ac..a2178535 100644 --- a/man/pecotmr-gwas-sumstats.Rd +++ b/man/pecotmr-gwas-sumstats.Rd @@ -4,7 +4,8 @@ \alias{pecotmr-gwas-sumstats} \title{GWAS Summary Statistics Handling} \description{ -Constructor, accessors, and converters for \code{GwasSumStats} - (the post-refactor DFrame-subclass collection keyed by \code{study}). +Constructor, accessors, and converters for + \code{GwasSumStats}, the \code{RangedTupleList} collection of GWAS + summary statistics keyed by \code{study}. } \keyword{internal} diff --git a/man/pecotmr-qtl-sumstats.Rd b/man/pecotmr-qtl-sumstats.Rd index 47020696..07f09354 100644 --- a/man/pecotmr-qtl-sumstats.Rd +++ b/man/pecotmr-qtl-sumstats.Rd @@ -5,6 +5,7 @@ \title{QTL Summary Statistics Handling} \description{ Constructor and accessor methods for \code{QtlSumStats}, the - DFrame-subclass collection keyed by \code{(study, context, trait)}. + \code{RangedTupleList} collection keyed by \code{(study, context, + trait)}. } \keyword{internal} diff --git a/man/penalizedRss.Rd b/man/penalizedRss.Rd index 4acb4b81..cf7af3b7 100644 --- a/man/penalizedRss.Rd +++ b/man/penalizedRss.Rd @@ -9,7 +9,7 @@ penalizedRss( R, n, penalty = c("lasso", "MCP", "SCAD", "L0", "L0L1", "L0L2"), - lambda = exp(seq(log(1e-04), log(0.1), length.out = 20)), + lambda = NULL, gamma = NULL, alpha = 1, lambda0 = 0, @@ -33,13 +33,19 @@ window), as in \code{lassosumRss()}.} \item{lambda}{Numeric vector of regularization parameter values along which to trace a solution path (warm-started, largest-first). For LASSO/MCP/SCAD this is the primary penalty strength; for L0 variants it controls the L1 -component.} +component. \code{NULL} (default) is 20 values from 1e-4 to 0.1 on a log +scale, divided by \code{max(alpha, 0.001)} as glmnet sizes its path, so +the L1 share spans the same range at any \code{alpha} and a ridge path +runs from 0.1 to 100.} \item{gamma}{Concavity parameter for MCP (default 3) or SCAD (default 3.7). Ignored for LASSO and L0 variants.} -\item{alpha}{Elastic-net mixing for MCP/SCAD: \eqn{l_1 = \lambda \alpha}, -\eqn{l_2 = \lambda (1-\alpha)}. Default 1 (pure L1, no ridge).} +\item{alpha}{Elastic-net mixing for LASSO, MCP and SCAD, in \code{[0, 1]}: +\eqn{l_1 = \lambda \alpha} and \eqn{l_2 = \lambda (1-\alpha)}, so the +penalty is \eqn{2 P(\beta; l_1) + l_2 \beta^T \beta}, glmnet's mixing. +Default 1, no ridge term. For LASSO, 0.5 is the elastic net and 0 ridge; +MCP and SCAD need \code{alpha > 0}. Ignored by the L0 variants.} \item{lambda0}{L0 penalty weight (number of non-zeros). Required for L0 variants; ignored otherwise. Default 0.} @@ -67,14 +73,16 @@ A list with components: } } \description{ -Generalizes \code{lassosumRss()} to support LASSO, MCP, SCAD, L0, L0L1, -and L0L2 penalties. Uses coordinate descent on the objective +The RSS penalized-regression solver: LASSO with its elastic-net and ridge +mixtures, MCP, SCAD, L0, L0L1 and L0L2. Uses coordinate descent on the +objective \deqn{\beta^T R \beta - 2 \beta^T z + \mathrm{penalty}(\beta)} where \eqn{R} is a (possibly pre-shrunk) LD matrix and \eqn{z = \hat\beta / -\sqrt{n}}. +\sqrt{n}}. \code{lassosumRss()} is its LASSO at \code{alpha = 1}. } \details{ -Internal: \code{\link{scadRssWeights}}, \code{\link{mcpRssWeights}} and +Internal: \code{\link{enetRssWeights}}, \code{\link{ridgeRssWeights}}, +\code{\link{scadRssWeights}}, \code{\link{mcpRssWeights}} and \code{\link{l0learnRssWeights}} are the public interface, with \code{\link{lassosumRssWeights}} for the lasso. They run this over a grid of LD shrinkage values, forward its options through diff --git a/man/phenotypeCovariates.Rd b/man/phenotypeCovariates.Rd index 9b15eec0..9ef32c2d 100644 --- a/man/phenotypeCovariates.Rd +++ b/man/phenotypeCovariates.Rd @@ -5,14 +5,14 @@ \alias{phenotypeCovariates,QtlDataset-method} \title{Get Per-Context Phenotype Covariates} \usage{ -phenotypeCovariates(x, contexts) +phenotypeCovariates(x, context) -\S4method{phenotypeCovariates}{QtlDataset}(x, contexts) +\S4method{phenotypeCovariates}{QtlDataset}(x, context) } \arguments{ \item{x}{A \code{QtlDataset} object.} -\item{contexts}{Character vector of context names (subset of +\item{context}{Character vector of context names (subset of \code{names(molecularTraits(x))}).} } \value{ @@ -24,5 +24,5 @@ Return per-context phenotype covariate matrices, taken from the } \examples{ data(qtlDatasetExample) -phenotypeCovariates(qtlDatasetExample, contexts = "brain") +phenotypeCovariates(qtlDatasetExample, context = "brain") } diff --git a/man/pip.Rd b/man/pip.Rd index 64258ed8..281a245f 100644 --- a/man/pip.Rd +++ b/man/pip.Rd @@ -15,18 +15,10 @@ pip(x, ...) context = NULL, trait = NULL, method = NULL, - region = NULL, - returnList = FALSE + blockId = NULL ) -\S4method{pip}{QtlFineMappingResult}( - x, - studyName = NULL, - context = NULL, - trait = NULL, - method = NULL, - returnList = FALSE -) +\S4method{pip}{QtlFineMappingResult}(x, studyName = NULL, context = NULL, trait = NULL, method = NULL) } \arguments{ \item{x}{A \code{QtlFineMappingResult} or \code{GwasFineMappingResult}.} @@ -45,12 +37,8 @@ this trait; \code{NULL} matches all traits.} \item{method}{Character (length 1) or \code{NULL}. Restrict the selection to this fine-mapping / weight method; \code{NULL} matches all methods.} -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -Restrict variants to this region; \code{NULL} uses the full cis window / -all regions.} - -\item{returnList}{Logical. If \code{TRUE}, return a per-entry list keyed by -identity tuple instead of a single flattened vector.} +\item{blockId}{GWAS fine-mapping results only: the \code{blockId} naming +one LD block of a fit; \code{NULL} matches every block.} } \value{ A named numeric vector of PIPs. diff --git a/man/postprocessFinemappingFits.Rd b/man/postprocessFinemappingFits.Rd index c7f57c4d..87b41580 100644 --- a/man/postprocessFinemappingFits.Rd +++ b/man/postprocessFinemappingFits.Rd @@ -56,8 +56,8 @@ are governed by \code{credibleSetParam}'s \code{perCsColumns} instead.} carry on the result untouched (returned as the \code{otherQuantities} element). Default \code{NULL}.} -\item{region}{Optional \code{"chr:start-end"} string naming the region the -fits cover; recorded on the result. Default \code{NULL}.} +\item{region}{Optional \code{GRanges}: the window the fits cover, recorded +on the result. Default \code{NULL}.} \item{priorEffTol}{Numeric (length 1). Effects whose prior variance \code{V} is at or below this tolerance are dropped as unconverged before diff --git a/man/pval.Rd b/man/pval.Rd index ed61f24d..0dc89c33 100644 --- a/man/pval.Rd +++ b/man/pval.Rd @@ -7,14 +7,7 @@ \usage{ pval(x, ...) -\S4method{pval}{SumStatsBase}( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL -) +\S4method{pval}{SumStatsBase}(x, studyName = NULL, context = NULL, trait = NULL) } \arguments{ \item{x}{A \code{GwasSumStats} or \code{QtlSumStats} object.} @@ -29,12 +22,6 @@ this context; \code{NULL} matches all contexts.} \item{trait}{Character (length 1) or \code{NULL}. Restrict the selection to this trait; \code{NULL} matches all traits.} - -\item{annotateSignificance}{Optional correction-method name passed through to -\code{\link{sumStats}} (QTL only); \code{NULL} applies none.} - -\item{ranges}{A \code{GRanges} or \code{NULL} (default). Return only the -variants overlapping these ranges; \code{NULL} returns everything.} } \value{ Numeric vector of p-values, or \code{NULL} if not available. diff --git a/man/qcDiagnostics.Rd b/man/qcDiagnostics.Rd index d116c376..737d29c6 100644 --- a/man/qcDiagnostics.Rd +++ b/man/qcDiagnostics.Rd @@ -5,32 +5,30 @@ \alias{qcDiagnostics,SumStatsBase-method} \title{Get SLALOM / DENTIST Diagnostics} \usage{ -qcDiagnostics(x, entry = 1L, ...) +qcDiagnostics(x, ...) -\S4method{qcDiagnostics}{SumStatsBase}(x, entry = 1L) +\S4method{qcDiagnostics}{SumStatsBase}(x, studyName = NULL, context = NULL, trait = NULL) } \arguments{ \item{x}{A \code{GwasSumStats} or \code{QtlSumStats} object.} -\item{entry}{Integer index (default 1) of the entry whose diagnostics table -to return. When \code{NULL}, returns a named list of every entry's -diagnostics keyed by entry index.} - \item{...}{Unused.} + +\item{studyName, context, trait}{Selectors pinning one study or entry; +\code{context} and \code{trait} are \code{QtlSumStats}-only.} } \value{ -A \code{data.frame} of per-variant diagnostics (columns include - \code{variant_id} plus the SLALOM / DENTIST output columns), \code{NULL} - when no diagnostics were preserved for that entry, or a named list of such - data.frames when \code{entry = NULL}. +A \code{DataFrame} of per-variant diagnostics (columns include + \code{variant_id} plus the SLALOM / DENTIST output columns), or + \code{NULL} when no diagnostics were preserved for the selection. } \description{ -Return the per-variant LD-mismatch diagnostics table (SLALOM or - DENTIST output) attached to a sumstats entry by - \code{\link{summaryStatsQc}} when \code{ldMismatchQcMethod} was not - \code{"none"}. - Convenience accessor over - \code{qcInfo(x)$entryAudit[[entry]]$ldMismatchDiagnostics}. +Return the per-variant LD-mismatch diagnostics (SLALOM or + DENTIST output) that \code{\link{summaryStatsQc}} attached to the + selected entry when \code{ldMismatchQcMethod} was not \code{"none"}. + The selectors pin one study (every row of a GWAS study, whose rows' + tables are stacked) or one \code{QtlSumStats} entry, as for + \code{\link{sumStats}}. } \examples{ data(qtlSumStatsExample) diff --git a/man/qcInfo.Rd b/man/qcInfo.Rd index bf9b23f7..9c2003cc 100644 --- a/man/qcInfo.Rd +++ b/man/qcInfo.Rd @@ -3,7 +3,7 @@ \name{qcInfo} \alias{qcInfo} \alias{qcInfo,SumStatsBase-method} -\title{Get QC Audit Record} +\title{Get the Per-Row QC Audit} \usage{ qcInfo(x, ...) @@ -15,15 +15,17 @@ qcInfo(x, ...) \item{...}{Unused.} } \value{ -A \code{list} (possibly empty). +A \code{DataFrame}, one row per tuple. } \description{ -Return the audit record of QC steps applied to this collection. - An empty \code{list()} (default on construction) means - \code{\link{summaryStatsQc}} has not yet been run. Pipelines that require - harmonized sumstats (\code{fineMappingPipeline}, - \code{twasWeightsPipeline}, and downstream consumers) reject inputs where - \code{length(qcInfo(x)) == 0L}. +What \code{\link{summaryStatsQc}} did to each row of a + summary-statistics collection: one row per tuple, its identity columns, + then the variant counts each QC step recorded (\code{variantsIn}, + \code{variantsOut}, and so on; a nested count is named by its path, as + in \code{contentFilters.nDropped}). A step that did not run on a row is + \code{NA} there. Only the identity columns are present before QC has run. + The options the QC ran with are \code{\link{qcOptions}}; the per-variant + LD-mismatch tables are \code{\link{qcDiagnostics}}. } \examples{ data(qtlSumStatsExample) diff --git a/man/qcOptions.Rd b/man/qcOptions.Rd new file mode 100644 index 00000000..581a8220 --- /dev/null +++ b/man/qcOptions.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/AllGenerics.R, R/AllClasses.R +\name{qcOptions} +\alias{qcOptions} +\alias{qcOptions,SumStatsBase-method} +\title{Get the QC Options} +\usage{ +qcOptions(x, ...) + +\S4method{qcOptions}{SumStatsBase}(x) +} +\arguments{ +\item{x}{A \code{GwasSumStats} or \code{QtlSumStats} object.} + +\item{...}{Unused.} +} +\value{ +A \code{list}, possibly empty. +} +\description{ +The record of the QC that ran over a summary-statistics + collection: the options \code{\link{summaryStatsQc}} was called with and + when. An empty \code{list()} (the default on construction) means QC has + not run; pipelines that need harmonized summary statistics + (\code{fineMappingPipeline}, \code{twasWeightsPipeline} and others) + refuse such inputs. What QC did to each row is \code{\link{qcInfo}}. +} +\examples{ +data(qtlSumStatsExample) +qcOptions(qtlSumStatsExample) +} diff --git a/man/qtlDatasetFilters.Rd b/man/qtlDatasetFilters.Rd deleted file mode 100644 index 3f0dc114..00000000 --- a/man/qtlDatasetFilters.Rd +++ /dev/null @@ -1,65 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/AllGenerics.R, R/QtlDataset.R -\name{qtlDatasetFilters} -\alias{qtlDatasetFilters} -\alias{mafCutoff} -\alias{macCutoff} -\alias{xvarCutoff} -\alias{imissCutoff} -\alias{keepVariants} -\alias{keepIndel} -\alias{mafCutoff,QtlDataset-method} -\alias{macCutoff,QtlDataset-method} -\alias{xvarCutoff,QtlDataset-method} -\alias{imissCutoff,QtlDataset-method} -\alias{keepVariants,QtlDataset-method} -\alias{keepIndel,QtlDataset-method} -\title{QtlDataset Filter Settings} -\usage{ -mafCutoff(x, ...) - -macCutoff(x, ...) - -xvarCutoff(x, ...) - -imissCutoff(x, ...) - -keepVariants(x, ...) - -keepIndel(x, ...) - -\S4method{mafCutoff}{QtlDataset}(x) - -\S4method{macCutoff}{QtlDataset}(x) - -\S4method{xvarCutoff}{QtlDataset}(x) - -\S4method{imissCutoff}{QtlDataset}(x) - -\S4method{keepVariants}{QtlDataset}(x) - -\S4method{keepIndel}{QtlDataset}(x) -} -\arguments{ -\item{x}{A \code{QtlDataset}.} - -\item{...}{Additional arguments passed on to methods.} -} -\value{ -\code{mafCutoff()}, \code{macCutoff()}, - \code{xvarCutoff()} and \code{imissCutoff()} single numerics; - \code{keepVariants()} a character vector (empty when no restriction - was requested); \code{keepIndel()} a single logical. The sample set - is not among them: it lives in \code{colData(x)} and \code{sampleMap(x)}. -} -\description{ -The variant- and sample-filter settings a - \code{\link{QtlDataset}} was built with. They are recorded on the object - rather than reapplied per call, so reading them back is how a caller finds - out what a dataset already excludes. -} -\examples{ -data(qtlDatasetExample) -mafCutoff(qtlDatasetExample) -keepIndel(qtlDatasetExample) -} diff --git a/man/qtlDatasets.Rd b/man/qtlDatasets.Rd deleted file mode 100644 index 38ced58b..00000000 --- a/man/qtlDatasets.Rd +++ /dev/null @@ -1,25 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/AllGenerics.R, R/MultiStudyQtlDataset.R -\name{qtlDatasets} -\alias{qtlDatasets} -\alias{qtlDatasets,MultiStudyQtlDataset-method} -\title{Get the Embedded QtlDataset List} -\usage{ -qtlDatasets(x) - -\S4method{qtlDatasets}{MultiStudyQtlDataset}(x) -} -\arguments{ -\item{x}{A \code{MultiStudyQtlDataset} object.} -} -\value{ -A named list of \code{QtlDataset} objects. -} -\description{ -Return the named list of \code{QtlDataset} objects carried by a - \code{MultiStudyQtlDataset}. -} -\examples{ -data(multiStudyQtlDatasetExample) -qtlDatasets(multiStudyQtlDatasetExample) -} diff --git a/man/qtlEnrichment.Rd b/man/qtlEnrichment.Rd index 6adf6137..a9c9b1bd 100644 --- a/man/qtlEnrichment.Rd +++ b/man/qtlEnrichment.Rd @@ -14,7 +14,7 @@ qtlEnrichment( impN = 25, doubleShrinkage = FALSE, besselCorrection = TRUE, - numThreads = 1, + BPPARAM = SerialParam(), verbose = TRUE, alignNames = TRUE, seed = NULL @@ -48,8 +48,10 @@ enrichment estimate. Default \code{FALSE}.} \item{besselCorrection}{Logical. Apply Bessel's correction when estimating the sampling variance. Default \code{TRUE}.} -\item{numThreads}{Number of Simultaneous running CPU threads for multiple -imputation, default is 1.} +\item{BPPARAM}{A \code{BiocParallelParam} whose workers number the threads +the multiple imputation runs on when they run on this machine +(\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +thread. Default \code{SerialParam()}.} \item{verbose}{Logical. Print progress messages. Default \code{TRUE}.} @@ -119,11 +121,10 @@ names(susieFits) <- paste0("fit", seq_along(susieFits)) # Set other parameters impN <- 10 lambda <- 1 -numThreads <- 1 library(pecotmr) en <- qtlEnrichment( gwasPip, susieFits, lambda = lambda, impN = impN, - numThreads = numThreads) + BPPARAM = BiocParallel::SerialParam()) } \seealso{ diff --git a/man/qtlEnrichmentPipeline.Rd b/man/qtlEnrichmentPipeline.Rd index 3a9531f7..15cc4ca5 100644 --- a/man/qtlEnrichmentPipeline.Rd +++ b/man/qtlEnrichmentPipeline.Rd @@ -8,7 +8,7 @@ qtlEnrichmentPipeline( gwasFineMappingResult, qtlFineMappingResult, qtlEnrichmentParam = QtlEnrichmentParam(), - numThreads = 1L, + BPPARAM = SerialParam(), seed = NULL, verbose = TRUE ) @@ -24,8 +24,9 @@ qtlEnrichmentPipeline( \code{besselCorrection}. A bare list is refused, since it cannot be checked.} -\item{numThreads}{Number of threads used by \code{qtlEnrichment}. Default -\code{1}.} +\item{BPPARAM}{A \code{BiocParallelParam} handed to +\code{\link{qtlEnrichment}}, whose multiple-imputation threads number +its workers. Default \code{SerialParam()}.} \item{seed}{Integer or \code{NULL}. Base random seed forwarded to \code{\link{qtlEnrichment}} for reproducible multiple imputation. @@ -34,11 +35,12 @@ checked.} \item{verbose}{Logical. Print progress messages. Default \code{TRUE}.} } \value{ -A tibble with one row per (outcome trait, annotation unit) pair. +A tibble with one row per (outcome fit, annotation unit) pair. The identity columns are \code{gwasStudy}, \code{gwasContext}, - \code{gwasTrait}, \code{qtlStudy}, \code{qtlContext}; the axes a side does - not have are \code{NA} (\code{gwasContext} / \code{gwasTrait} for a GWAS - outcome, \code{qtlContext} for a GWAS annotation). Suitable as the + \code{gwasTrait}, \code{gwasMethod}, \code{qtlStudy}, \code{qtlContext}, + \code{qtlMethod}; the axes a side does not have are \code{NA} + (\code{gwasContext} / \code{gwasTrait} for a GWAS outcome, + \code{qtlContext} for a GWAS annotation). Suitable as the \code{enrichment} argument to \code{\link{colocPipeline}}, which joins on those columns. @@ -79,17 +81,22 @@ genome of outcome PIPs and the full collection of annotation fits at once. \itemize{ \item \code{gwasFineMappingResult}: the genome-wide outcome collection. Each row's stored fit (\code{\link{susieFit}}) must carry a \code{pip} - vector. One PIP vector is built per outcome trait -- keyed by - \code{study} for a GWAS collection (one trait per study) and by - (\code{study}, \code{context}, \code{trait}) for a QTL one, since a - variant's PIP differs between molecular traits and pooling them would - collide. + vector. One PIP vector is built per outcome fit, across all its LD + blocks -- keyed by (\code{study}, \code{method}) for a GWAS collection + (one trait per study) and by (\code{study}, \code{context}, + \code{trait}, \code{method}) for a QTL one, since a variant's PIP + differs between molecular traits and between fine-mapping methods, and + pooling them would collide. \item \code{qtlFineMappingResult}: the annotation collection. Each row's stored fit must carry \code{alpha}, \code{pip}, and prior-variance fields (\code{V}). Its region fits are pooled per - (\code{study}, \code{context}) -- per \code{study} alone for a GWAS - collection, which has no context axis. + (\code{study}, \code{context}, \code{method}) -- per (\code{study}, + \code{method}) for a GWAS collection, which has no context axis -- so + each method's fits make their own estimate rather than counting every + region once per method. } +Both sides' fits are read whole, so a row narrowed since its fit warns +(condition class \code{pecotmrFitCoverage}). } \section{LD reference compatibility check}{ diff --git a/man/qtlSumStatsFromBetaMatrix.Rd b/man/qtlSumStatsFromBetaMatrix.Rd index 3a0bc2d3..76af4617 100644 --- a/man/qtlSumStatsFromBetaMatrix.Rd +++ b/man/qtlSumStatsFromBetaMatrix.Rd @@ -43,7 +43,7 @@ colnames(bhat)}, \code{trait = "mash"}.} \item{a1, a2}{Placeholder alleles. Defaults \code{"A"} / \code{"G"}.} -\item{role}{Tag stored in the \code{qcInfo} record. Default \code{"mash"}.} +\item{role}{Tag stored in the \code{qcOptions()}. Default \code{"mash"}.} } \value{ A \code{\link{QtlSumStats}} with one entry per condition (column). diff --git a/man/qtlSumStatsFromZMatrix.Rd b/man/qtlSumStatsFromZMatrix.Rd index b28915e7..c8760ab2 100644 --- a/man/qtlSumStatsFromZMatrix.Rd +++ b/man/qtlSumStatsFromZMatrix.Rd @@ -44,7 +44,7 @@ are traits rather than contexts.} \item{a1, a2}{Placeholder alleles. Defaults \code{"A"} / \code{"G"}.} -\item{role}{Tag stored in the \code{qcInfo} record. Default \code{"mash"}.} +\item{role}{Tag stored in the \code{qcOptions()}. Default \code{"mash"}.} } \value{ A \code{\link{QtlSumStats}} with one entry per condition (column). @@ -60,7 +60,7 @@ Assemble a per-condition \code{\link{QtlSumStats}} from a \code{\link{parseVariantId}} (with a synthetic-position fallback for ids that do not encode coordinates); \code{A1} / \code{A2} / \code{N} are placeholders because a Z-only input carries no alleles or sample sizes - (mash reads only Z). A pass-through \code{qcInfo} record is set so the + (mash reads only Z). Pass-through \code{qcOptions()} are set so the result clears the mash QC gate. } \examples{ diff --git a/man/raiss.Rd b/man/raiss.Rd index c0f2b7e2..e1634d2a 100644 --- a/man/raiss.Rd +++ b/man/raiss.Rd @@ -20,12 +20,16 @@ raiss( \arguments{ \item{refPanel}{A data frame containing 'chrom', 'pos', 'variant_id', 'A1', and 'A2'. Optional when the LD comes as an \code{LdMatrix} or a genotype -panel, whose own variants are used; \code{knownZscores} must then label -chromosomes canonically, as character (e.g. \code{"22"}). Required -with a plain \code{ldMatrix}, whose rows and columns follow it.} +panel, whose own variants are used. Required with a plain +\code{ldMatrix}, whose rows and columns follow it.} \item{knownZscores}{A data frame containing 'chrom', 'pos', 'variant_id', -'A1', 'A2', and 'z' values.} +'A1', 'A2', and 'z' values, or a summary-statistics \code{GRanges} -- +one entry as \code{\link{sumStats}} returns it, with its \code{SNP}, +\code{A1}, \code{A2} and \code{Z} columns. Here and in \code{refPanel} +a chromosome may be labelled in any style (\code{22}, \code{"22"}, +\code{"chr22"}); both are read in UCSC style (\code{"chr22"}), which +the result uses.} \item{ldMatrix}{A square LD matrix over \code{refPanel}'s variants, in its order, or an \code{LdMatrix} covering them. Provide either diff --git a/man/readAfreq.Rd b/man/readAfreq.Rd index 87fcb0dd..80b4c4ba 100644 --- a/man/readAfreq.Rd +++ b/man/readAfreq.Rd @@ -4,10 +4,10 @@ \alias{readAfreq} \title{Read a PLINK2 allele frequency file (.afreq or .afreq.zst)} \usage{ -readAfreq(prefix) +readAfreq(path) } \arguments{ -\item{prefix}{File prefix (without .afreq extension).} +\item{path}{File prefix (without .afreq extension).} } \value{ A data.frame with columns: chrom, id, A2 (REF), A1 (ALT), alt_freq, diff --git a/man/readAnnotations.Rd b/man/readAnnotations.Rd index 54d77ace..c3425a25 100644 --- a/man/readAnnotations.Rd +++ b/man/readAnnotations.Rd @@ -5,12 +5,12 @@ \alias{readAnnotations,character-method} \title{Read Annotations} \usage{ -readAnnotations(paths, snpRanges, annotationMeta = NULL, genome = "hg19", ...) +readAnnotations(path, snpRanges, annotationMeta = NULL, genome = "hg19", ...) -\S4method{readAnnotations}{character}(paths, snpRanges, annotationMeta = NULL, genome = "hg19") +\S4method{readAnnotations}{character}(path, snpRanges, annotationMeta = NULL, genome = "hg19") } \arguments{ -\item{paths}{Named character vector of file paths, or a named list of GRanges +\item{path}{Named character vector of file paths, or a named list of GRanges objects. Names become annotation names.} \item{snpRanges}{A \code{GRanges} object defining SNP positions.} diff --git a/man/readFineMappingResult.Rd b/man/readFineMappingResult.Rd index 644c15c4..5dcbb761 100644 --- a/man/readFineMappingResult.Rd +++ b/man/readFineMappingResult.Rd @@ -6,7 +6,7 @@ \usage{ readFineMappingResult( path, - region = NULL, + which = NULL, format = c("auto", "bed", "vcf"), studyName = NULL, context = NULL, @@ -20,12 +20,12 @@ readFineMappingResult( } \arguments{ \item{path}{Path to the published file. Bgzipped and tabix-indexed files -can be read by region.} +can be read in part, with \code{which}.} -\item{region}{Optional region to restrict the read to -- a -\code{"chr:start-end"} string, a \code{GRanges}, or a one-row -\code{data.frame} with chrom/start/end. Ignored with a warning when the -file is not tabix-indexed.} +\item{which}{Optional \code{GRanges}: read only the records that overlap +it, as \code{which} does for \code{rtracklayer::import()} and +\code{VariantAnnotation::ScanVcfParam()}. Ignored with a warning when +the file is not tabix-indexed.} \item{format}{\code{"auto"} (default) reads a \code{.vcf} / \code{.bcf} path as a VCF and anything else as a published table; \code{"bed"} / @@ -57,10 +57,10 @@ A \code{QtlFineMappingResult} or \code{GwasFineMappingResult}. } \description{ Rebuild a \code{QtlFineMappingResult} or - \code{GwasFineMappingResult} from a file \code{\link{exportToBed}} or - \code{\link{exportToVcf}} wrote -- or from any file in the same - vocabulary, which is what makes this the way into pecotmr for results - produced elsewhere. + \code{GwasFineMappingResult} from a file \code{\link{writeBed}} or + \code{\link{writeGwasVcf}} wrote -- or from any file in + the same vocabulary, which is what makes this the way into pecotmr for + results produced elsewhere. A merged table holding several \code{(study, context, trait, method)} tuples reads back as a multi-row collection, one row per tuple. Which @@ -91,7 +91,7 @@ Rebuild a \code{QtlFineMappingResult} or Every published quantity comes back identical, in either format. Three things are not identities: \itemize{ - \item \code{exportToBed()} publishes the \strong{filtered} top-loci + \item \code{writeBed()} publishes the \strong{filtered} top-loci table, so a default export holds the variants that passed \code{signalCutoff} / \code{minPurity} rather than every variant of the fit. Export with \code{signalCutoff = 0} for the whole table. @@ -109,13 +109,13 @@ Rebuild a \code{QtlFineMappingResult} or \examples{ data(qtlFineMappingExample) path <- file.path(tempdir(), "top_loci.bed") -exportToBed(qtlFineMappingExample, path) +writeBed(qtlFineMappingExample, path) # This fit predates the provenance columns, so its published table does # not say which genotype scale its posterior effects are on -- the reader # will not guess. readFineMappingResult(path, weightStandardized = TRUE) } \seealso{ -\code{\link{exportToBed}}, \code{\link{exportToVcf}}, +\code{\link{writeBed}}, \code{\link{writeGwasVcf}}, \code{\link{readTwasWeights}} } diff --git a/man/readGenotypes.Rd b/man/readGenotypes.Rd index 66670574..2753ec35 100644 --- a/man/readGenotypes.Rd +++ b/man/readGenotypes.Rd @@ -21,7 +21,7 @@ readGenotypes(path, format = NULL, ...) pvar = NULL, psam = NULL, ldMeta = NULL, - region = NULL, + block = NULL, genoMeta = NULL, chroms = NULL, format = NULL, @@ -79,12 +79,12 @@ triplet, when they do not share a stem.} plink2 triplet, when they do not share a stem.} \item{ldMeta}{Path to an LD-meta TSV (columns \code{chrom}, \code{start}, -\code{end}, \code{path}). Requires \code{region}: the row covering it is +\code{end}, \code{path}). Requires \code{block}: the row covering it is resolved and the file it names is read with the matching backend.} -\item{region}{Region to resolve out of \code{ldMeta}: a -\code{"chr:start-end"} string, or a one-row data.frame with -\code{chrom}, \code{start}, \code{end}.} +\item{block}{The \code{GRanges} window whose LD block to read out of +\code{ldMeta}. It chooses a file rather than filtering records: the +panel is the whole LD block that covers it.} \item{genoMeta}{One-file-per-chromosome specification: a path to a \code{#chr,path} meta file, or a named character vector (names = @@ -92,8 +92,9 @@ chromosomes, values = payload paths / prefixes). Every file must be of one format and hold the same samples in the same order.} \item{chroms}{Optional character vector of chromosomes. Only the -\code{genoMeta} shards whose chromosome is listed are read; chromosome -labels are compared canonically. Meaningful only with \code{genoMeta}.} +\code{genoMeta} shards whose chromosome is listed are read; a label may +be in any style (\code{"chr1"} or \code{"1"}). Meaningful only with +\code{genoMeta}.} } \value{ A \code{RangedSummarizedExperiment} of variants x samples. @@ -117,7 +118,7 @@ Read genotype data (VCF, plink1, plink2, GDS or BGEN) as a \code{plink2Prefix} for a triplet stem, \code{bed}/\code{bim}/\code{fam} or \code{pgen}/\code{pvar}/\code{psam} for explicit triplet paths, \code{genoMeta} for a one-file-per-chromosome panel (optionally narrowed - with \code{chroms}), or \code{ldMeta} plus \code{region} to resolve a + with \code{chroms}), or \code{ldMeta} plus \code{block} to resolve a block out of an LD-meta table. Exactly one source may be given. } \examples{ diff --git a/man/readSldscAnnot.Rd b/man/readSldscAnnot.Rd index 5478fc33..8aaf427f 100644 --- a/man/readSldscAnnot.Rd +++ b/man/readSldscAnnot.Rd @@ -4,10 +4,10 @@ \alias{readSldscAnnot} \title{Read target annotation files (.annot.gz) into one table} \usage{ -readSldscAnnot(targetAnnoDir, annotCols = NULL) +readSldscAnnot(path, annotCols = NULL) } \arguments{ -\item{targetAnnoDir}{Character. Directory of `.annot.gz` files.} +\item{path}{Character. Directory of `.annot.gz` files.} \item{annotCols}{Character or integer vector, default NULL. Annotation columns to keep. NULL keeps all non-standard columns (auto-detected).} diff --git a/man/readSldscFrq.Rd b/man/readSldscFrq.Rd index b368a226..ab5d0121 100644 --- a/man/readSldscFrq.Rd +++ b/man/readSldscFrq.Rd @@ -4,10 +4,10 @@ \alias{readSldscFrq} \title{Read PLINK allele-frequency files (.frq) into one table} \usage{ -readSldscFrq(frqfileDir, plinkName = "ADSP_chr") +readSldscFrq(path, plinkName = "ADSP_chr") } \arguments{ -\item{frqfileDir}{Character. Directory of `.frq` files.} +\item{path}{Character. Directory of `.frq` files.} \item{plinkName}{Character. Filename prefix (files at `.frq`). Falls back to all `*.frq` in the directory when diff --git a/man/readSldscTrait.Rd b/man/readSldscTrait.Rd index c4931e8e..9fb73391 100644 --- a/man/readSldscTrait.Rd +++ b/man/readSldscTrait.Rd @@ -4,10 +4,10 @@ \alias{readSldscTrait} \title{Read S-LDSC outputs from polyfun for one trait/run} \usage{ -readSldscTrait(prefix) +readSldscTrait(path) } \arguments{ -\item{prefix}{Character. Path prefix to the polyfun outputs for one +\item{path}{Character. Path prefix to the polyfun outputs for one trait/run. The function appends `.results`, `.log`, and `.part_delete` to this prefix. Example: `"/path/to/cwd/CAD_META.filtered.sumstats.gz"`.} } diff --git a/man/readTwasWeights.Rd b/man/readTwasWeights.Rd index 54f845e8..92b9da66 100644 --- a/man/readTwasWeights.Rd +++ b/man/readTwasWeights.Rd @@ -6,7 +6,7 @@ \usage{ readTwasWeights( path, - region = NULL, + which = NULL, format = c("auto", "bed", "vcf"), studyName = NULL, context = NULL, @@ -19,12 +19,12 @@ readTwasWeights( } \arguments{ \item{path}{Path to the published file. Bgzipped and tabix-indexed files -can be read by region.} +can be read in part, with \code{which}.} -\item{region}{Optional region to restrict the read to -- a -\code{"chr:start-end"} string, a \code{GRanges}, or a one-row -\code{data.frame} with chrom/start/end. Ignored with a warning when the -file is not tabix-indexed.} +\item{which}{Optional \code{GRanges}: read only the records that overlap +it, as \code{which} does for \code{rtracklayer::import()} and +\code{VariantAnnotation::ScanVcfParam()}. Ignored with a warning when +the file is not tabix-indexed.} \item{format}{\code{"auto"} (default) reads a \code{.vcf} / \code{.bcf} path as a VCF and anything else as a published table; \code{"bed"} / @@ -49,8 +49,8 @@ A \code{TwasWeights}. } \description{ Rebuild a \code{TwasWeights} from a file - \code{\link{exportToBed}} or \code{\link{exportToVcf}} wrote, or from any - file in the same vocabulary. + \code{\link{writeBed}} or \code{\link{writeGwasVcf}} + wrote, or from any file in the same vocabulary. A merged table reads back as a multi-row collection, one row per \code{(study, context, trait, method)} tuple. A fitted model whose @@ -77,9 +77,9 @@ Rebuild a \code{TwasWeights} from a file \examples{ data(twasWeightsExample) path <- file.path(tempdir(), "weights.bed") -exportToBed(twasWeightsExample, path) +writeBed(twasWeightsExample, path) readTwasWeights(path) } \seealso{ -\code{\link{exportToBed}}, \code{\link{readFineMappingResult}} +\code{\link{writeBed}}, \code{\link{readFineMappingResult}} } diff --git a/man/refVariantInfo.Rd b/man/refVariantInfo.Rd index ec559bb7..8ae34042 100644 --- a/man/refVariantInfo.Rd +++ b/man/refVariantInfo.Rd @@ -4,13 +4,13 @@ \alias{refVariantInfo} \title{Get variant information from any LD reference source} \usage{ -refVariantInfo(source, region = NULL) +refVariantInfo(source, which = NULL) } \arguments{ \item{source}{Genotype file path/prefix or LD metadata file path.} -\item{region}{Region of interest: "chr:start-end" string or data.frame with -chrom/start/end. If NULL, returns all variants.} +\item{which}{Optional \code{GRanges}: return only the variants that +overlap it. If NULL, returns all variants.} } \value{ A data.frame with columns: chrom, id, pos, A2, A1. May also include @@ -26,5 +26,6 @@ extracts variant info. \examples{ meta <- system.file("extdata", "ld_reference", "ld_meta_file.tsv", package = "pecotmr") -refVariantInfo(meta, region = "chr22:10000000-19000000") +refVariantInfo(meta, + which = GenomicRanges::GRanges("chr22:10000000-19000000")) } diff --git a/man/regionToDf.Rd b/man/regionToDf.Rd deleted file mode 100644 index 466d0ae1..00000000 --- a/man/regionToDf.Rd +++ /dev/null @@ -1,26 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/variantId.R -\name{regionToDf} -\alias{regionToDf} -\title{Utility function to convert LD region_ids to `region of interest` dataframe} -\usage{ -regionToDf(ldRegionId, colnames = c("chrom", "start", "end")) -} -\arguments{ -\item{ldRegionId}{A string of region in the format of chrom_start_end.} - -\item{colnames}{Character vector of length 3 giving output column names for -chromosome, start and end. Default \code{c("chrom", "start", "end")}.} -} -\value{ -A tibble with one row per input region and columns named by - \code{colnames}: a normalized character chromosome plus integer start/end. -} -\description{ -The first field is treated as the chromosome and kept as a normalized string -(via \code{canonChrom}) so X/Y/MT survive; the remaining fields are genomic -positions and are returned as integers. -} -\examples{ -regionToDf(c("1_100_200", "2_300_400")) -} diff --git a/man/residualizedGenotypes.Rd b/man/residualizedGenotypes.Rd index 7e6e4a60..9d03d7c7 100644 --- a/man/residualizedGenotypes.Rd +++ b/man/residualizedGenotypes.Rd @@ -9,37 +9,16 @@ residualizedGenotypes(x, ...) \S4method{residualizedGenotypes}{QtlDataset}( x, - contexts, - traitId = NULL, - region = NULL, - cisWindow = NULL, - samples = NULL, + context, residualizationParam = ResidualizationParam() ) } \arguments{ \item{x}{A \code{QtlDataset} object.} -\item{...}{Selection arguments: \code{traitId}, \code{region}, -\code{cisWindow}, \code{phenotypeCovariatesToRemove}, -\code{genotypeCovariatesToRemove}, and \code{covariateNaAction} -(\code{"impute"}, the default, mean-imputes missing covariate cells; -\code{"drop"} removes samples with any missing covariate).} +\item{...}{Passed on to methods.} -\item{contexts}{Character vector. Context(s) whose data to extract.} - -\item{traitId}{Character or \code{NULL}. Molecular trait / feature identifier -to select; \code{NULL} matches all traits in the dataset.} - -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -Restrict variants to this region; \code{NULL} uses the full cis window / -all regions.} - -\item{cisWindow}{Integer or \code{NULL}. Half-width (bp) of the cis window -around the trait; \code{NULL} uses the dataset default.} - -\item{samples}{Character vector or \code{NULL}. Restrict to these sample IDs; -\code{NULL} uses all samples.} +\item{context}{Character vector. Context(s) whose data to extract.} \item{residualizationParam}{What the data is residualized on, built with \code{\link{ResidualizationParam}}: \code{phenotypeCovariates} and @@ -54,11 +33,11 @@ A numeric matrix (samples x variants). } \description{ Residualize the genotype matrix against the per-context - phenotype covariates and the genotype covariates, optionally subsetting - variants to those falling within a trait's cis-window or an explicit - region. + phenotype covariates and the genotype covariates, over the whole + dataset: narrow it first, with \code{x[i, j, ]}, to residualize part + of it. } \examples{ data(qtlDatasetExample) -residualizedGenotypes(qtlDatasetExample, contexts = "brain") +residualizedGenotypes(qtlDatasetExample, context = "brain") } diff --git a/man/residualizedPhenotypes.Rd b/man/residualizedPhenotypes.Rd index 28881f8b..01924223 100644 --- a/man/residualizedPhenotypes.Rd +++ b/man/residualizedPhenotypes.Rd @@ -9,48 +9,21 @@ residualizedPhenotypes(x, ...) \S4method{residualizedPhenotypes}{QtlDataset}( x, - contexts, - traitId = NULL, - region = NULL, - naAction = c("keep", "drop", "impute"), - outlierAction = c("keep", "drop"), - outlierPvalThreshold = 0.001, - outlierArgs = CovMcdOptions(), + context, + trait = NULL, residualizationParam = ResidualizationParam() ) } \arguments{ \item{x}{A \code{QtlDataset} object.} -\item{...}{Selection arguments: \code{contexts} (required), \code{traitId}, -\code{region}, \code{phenotypeCovariatesToRemove}, -\code{genotypeCovariatesToRemove}, and \code{covariateNaAction} -(\code{"impute"}, the default, mean-imputes missing covariate cells; -\code{"drop"} removes samples with any missing covariate).} +\item{...}{Passed on to methods.} -\item{contexts}{Character vector. Context(s) whose data to extract.} +\item{context}{Character vector. Context(s) whose data to extract.} -\item{traitId}{Character or \code{NULL}. Molecular trait / feature identifier +\item{trait}{Character or \code{NULL}. Molecular trait / feature identifier to select; \code{NULL} matches all traits in the dataset.} -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -Restrict variants to this region; \code{NULL} uses the full cis window / -all regions.} - -\item{naAction}{Character. How to handle missing phenotype values: one of -\code{"keep"}, \code{"drop"}, or \code{"impute"}.} - -\item{outlierAction}{Character. How to handle phenotype outliers: one of -\code{"keep"} or \code{"drop"}.} - -\item{outlierPvalThreshold}{Numeric. Two-sided p-value threshold for flagging -phenotype outliers. Default \code{1e-3}.} - -\item{outlierArgs}{Extra arguments for \code{robustbase::covMcd()}, the -robust covariance estimator the outlier rule is built on, supplied with -\code{\link{CovMcdOptions}} -- \code{alpha} in particular. Only -consulted when \code{outlierAction = "drop"}.} - \item{residualizationParam}{What the data is residualized on, built with \code{\link{ResidualizationParam}}: \code{phenotypeCovariates} and \code{genotypeCovariates} choose the covariate sets, @@ -65,9 +38,11 @@ A named list of numeric matrices keyed by context. \description{ Residualize the per-context phenotype matrices against the per-context phenotype covariates and the genotype covariates, for one or - more requested contexts. + more requested contexts. Missing values and outliers are left as they + are: they are a run's phenotype QC (\code{\link{PhenotypeFilterParam}}), + applied by the pipelines. } \examples{ data(qtlDatasetExample) -residualizedPhenotypes(qtlDatasetExample, contexts = "brain") +residualizedPhenotypes(qtlDatasetExample, context = "brain") } diff --git a/man/resolveWeights.Rd b/man/resolveWeights.Rd index 2fd92ce8..623ee00f 100644 --- a/man/resolveWeights.Rd +++ b/man/resolveWeights.Rd @@ -14,7 +14,7 @@ resolveWeights(x, ...) context = NULL, trait = NULL, method = NULL, - region = NULL + blockId = NULL ) \S4method{resolveWeights}{TwasWeights}( @@ -35,9 +35,8 @@ resolveWeights(x, ...) row of a collection, as elsewhere; each \code{NULL} (default) leaves that part of the tuple unconstrained. Ignored when \code{x} is already a row.} -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -A further selector for a fine-mapping result, whose rows also carry a -region; \code{NULL} (default) leaves it unconstrained.} +\item{blockId}{GWAS fine-mapping results only: the \code{blockId} naming +one LD block; \code{NULL} (default) leaves it unconstrained.} } \value{ A \code{list} with \code{variantIds} (character) and \code{weights} diff --git a/man/retainedMass.Rd b/man/retainedMass.Rd index 23cbdec1..9f35efef 100644 --- a/man/retainedMass.Rd +++ b/man/retainedMass.Rd @@ -15,7 +15,7 @@ retainedMass(x, ...) \item{...}{Additional arguments passed to methods.} } \value{ -A \code{data.frame}, one row per (element, effect), with the +A \code{DataFrame}, one row per (element, effect), with the element's identity columns, the effect index, and its retained mass. } \description{ diff --git a/man/ridgeRssWeights.Rd b/man/ridgeRssWeights.Rd new file mode 100644 index 00000000..daabde91 --- /dev/null +++ b/man/ridgeRssWeights.Rd @@ -0,0 +1,75 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/regularizedRegressionWrappers.R +\name{ridgeRssWeights} +\alias{ridgeRssWeights} +\title{Compute Ridge Weights from Summary Statistics} +\usage{ +ridgeRssWeights( + stat, + ldReference, + s = c(0.2, 0.5, 0.9, 1), + selection = c("ldQuadratic", "minFbeta"), + fitRetention = c("none", "slim", "full"), + methodArgs = PenalizedRssOptions() +) +} +\arguments{ +\item{stat}{A list of summary statistics: \code{n} (per-variant sample +sizes) and the marginal effects as \code{cor} (standardized), \code{z}, +\code{b} with \code{seb}, or \code{b} alone, taken as already +standardized. The engine receives the standardized effects z / sqrt(n), +with n the median of \code{n}.} + +\item{ldReference}{The LD reference the statistics' variants are matched +to by \code{stat$variantNames}: a genotype panel (see +\code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} or an +\code{\link{LdMatrix}}. A genotype reference's LD is used through its +standardized genotypes, never formed as a matrix.} + +\item{s}{Numeric vector of LD shrinkage parameters. Default: \code{c(0.2, +0.5, 0.9, 1.0)}.} + +\item{selection}{Selection strategy: \code{"ldQuadratic"} (default) or +\code{"minFbeta"}.} + +\item{fitRetention}{How much of the search is kept as the \code{"fit"} +attribute of the returned weights. \code{"none"} (default) attaches +nothing. \code{"slim"} keeps \code{path}, a table with one row per +candidate (\code{s}, \code{lambda}) giving the solver's objective +\code{fbeta}, \code{loss}, convergence flag \code{conv} and number of +non-zero coefficients \code{nparams}, with \code{selected} marking the +candidate returned. \code{"full"} also keeps \code{beta}, the +candidates' coefficients (variants x candidates, in the rows' order).} + +\item{methodArgs}{Options forwarded to the solver, +\code{\link{penalizedRss}}, built with +\code{\link{PenalizedRssOptions}}. A bare list is refused: it cannot +be checked against the engine, so a misspelled option would be +silently ignored.} +} +\value{ +A numeric vector of SNP coefficient weights. Unless + \code{fitRetention = "none"}, the search is attached as attribute + \code{"fit"}. +} +\description{ +Fits ridge regression on the RSS objective, \code{\link{enetRssWeights}} +at \code{alpha = 0}: the penalty is \eqn{\lambda \beta^T \beta}, and the +default lambda path runs from 0.1 to 100. Searches over a shrinkage grid +\code{s} as well, whose own ridge term \eqn{s \beta^T \beta} adds to it; +model selection uses LD-quadratic pseudovalidation by default. +} +\examples{ +data(eqtlRegionExample) +X <- eqtlRegionExample$X[, 1:30] +y <- eqtlRegionExample$yRes +ss <- lapply( + seq_len(ncol(X)), function(j) coef(summary(lm(y ~ X[, j])))[2, 1:2]) +stat <- list( + b = vapply(ss, `[`, numeric(1), 1L), + seb = vapply(ss, `[`, numeric(1), 2L), + n = rep(nrow(X), ncol(X)), + variantNames = colnames(X) +) +ridgeRssWeights(stat, LdMatrix(cor(X))) +} diff --git a/man/ridgeWeights.Rd b/man/ridgeWeights.Rd new file mode 100644 index 00000000..fb224292 --- /dev/null +++ b/man/ridgeWeights.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/regularizedRegressionWrappers.R +\name{ridgeWeights} +\alias{ridgeWeights} +\title{Compute TWAS weights via ridge regression (glmnet, alpha = 0)} +\usage{ +ridgeWeights(X, y, methodArgs = GlmnetOptions()) +} +\arguments{ +\item{X}{Numeric genotype / design matrix (samples x variants).} + +\item{y}{Numeric response (phenotype) vector of length \code{nrow(X)}.} + +\item{methodArgs}{Additional arguments forwarded to +\code{glmnet::cv.glmnet}, built with \code{\link{GlmnetOptions}}. A bare +list is refused, since it cannot be checked against the engine's formals.} +} +\value{ +Numeric vector of length \code{ncol(X)} of per-variant weights. +} +\description{ +Convenience wrapper for \code{\link{glmnetWeights}} with \code{alpha = 0}. +} +\examples{ +data(eqtlRegionExample) +X <- eqtlRegionExample$X[, 1:30] +y <- eqtlRegionExample$yRes +ridgeWeights(X, y) +} diff --git a/man/sampleSize.Rd b/man/sampleSize.Rd new file mode 100644 index 00000000..62ae7fdd --- /dev/null +++ b/man/sampleSize.Rd @@ -0,0 +1,40 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/AllGenerics.R, R/AllClasses.R +\name{sampleSize} +\alias{sampleSize} +\alias{sampleSize,SumStatsBase-method} +\title{Get Per-Variant Sample Sizes} +\usage{ +sampleSize(x, ...) + +\S4method{sampleSize}{SumStatsBase}(x, studyName = NULL, context = NULL, trait = NULL) +} +\arguments{ +\item{x}{A \code{GwasSumStats} or \code{QtlSumStats} object.} + +\item{...}{Class-specific selection arguments.} + +\item{studyName}{Character (length 1) or \code{NULL}. Restrict the selection +to this study; \code{NULL} matches all studies.} + +\item{context}{Character (length 1) or \code{NULL}. Restrict the selection to +this context; \code{NULL} matches all contexts.} + +\item{trait}{Character (length 1) or \code{NULL}. Restrict the selection to +this trait; \code{NULL} matches all traits.} +} +\value{ +Numeric vector of per-variant sample sizes, or \code{NULL} when the + entry carries none. +} +\description{ +Extract the per-variant sample-size vector (the \code{N} + column) of a \code{GwasSumStats} or \code{QtlSumStats} entry, selected + by its identity tuple. Part of the summary-statistic column set alongside + \code{\link{z}}, \code{\link{se}} and \code{\link{pval}}; replace it + with \code{\link[=variantColumnReplace]{sampleSize<-}}. +} +\examples{ +data(qtlSumStatsExample) +head(sampleSize(qtlSumStatsExample)) +} diff --git a/man/scadRssWeights.Rd b/man/scadRssWeights.Rd index 86734f30..bbc7966b 100644 --- a/man/scadRssWeights.Rd +++ b/man/scadRssWeights.Rd @@ -33,7 +33,9 @@ standardized genotypes, never formed as a matrix.} \item{gamma}{SCAD concavity parameter. Default 3.7.} -\item{alpha}{Elastic-net mixing (1 = pure L1). Default 1.} +\item{alpha}{Elastic-net mixing in \code{(0, 1]}: the SCAD share of +the penalty, the rest a ridge term, as \code{\link{penalizedRss}} +mixes them. Default 1, no ridge term.} \item{selection}{Selection strategy: \code{"ldQuadratic"} (default) or \code{"minFbeta"}.} diff --git a/man/scaleResiduals.Rd b/man/scaleResiduals.Rd deleted file mode 100644 index 34028a0b..00000000 --- a/man/scaleResiduals.Rd +++ /dev/null @@ -1,25 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/AllGenerics.R, R/QtlDataset.R -\name{scaleResiduals} -\alias{scaleResiduals} -\alias{scaleResiduals,QtlDataset-method} -\title{Get scaleResiduals Flag} -\usage{ -scaleResiduals(x) - -\S4method{scaleResiduals}{QtlDataset}(x) -} -\arguments{ -\item{x}{A \code{QtlDataset} object.} -} -\value{ -Logical (length 1). -} -\description{ -Whether residualization accessors scale residuals to unit - variance. -} -\examples{ -data(qtlDatasetExample) -scaleResiduals(qtlDatasetExample) -} diff --git a/man/screenCtwasRegions.Rd b/man/screenCtwasRegions.Rd index d1c2f29a..39c86e03 100644 --- a/man/screenCtwasRegions.Rd +++ b/man/screenCtwasRegions.Rd @@ -4,12 +4,19 @@ \alias{screenCtwasRegions} \title{Screen cTWAS regions} \usage{ -screenCtwasRegions(estResult, numThreads = 1L, methodArgs = CtwasOptions()) +screenCtwasRegions( + estResult, + BPPARAM = SerialParam(), + methodArgs = CtwasOptions() +) } \arguments{ \item{estResult}{A list returned by \code{\link{estCtwasGroupPriors}}.} -\item{numThreads}{Number of cores.} +\item{BPPARAM}{A \code{BiocParallelParam} whose workers number the cores +ctwas's own \code{ncore} parallelism uses when they run on this machine +(\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +core. Default \code{SerialParam()}.} \item{methodArgs}{Additional arguments forwarded to ctwas, built with \code{\link{CtwasOptions}}. Names are checked against what diff --git a/man/sdpr.Rd b/man/sdpr.Rd index 89963fa5..ba60f01e 100644 --- a/man/sdpr.Rd +++ b/man/sdpr.Rd @@ -19,7 +19,6 @@ sdpr( iter = 1000, burn = 200, thin = 5, - numThreads = 1, optLlk = 1, verbose = TRUE, seed = NULL @@ -57,8 +56,6 @@ length equal to `bhat`.} \item{thin}{Thinning interval for MCMC. Default is 5.} -\item{numThreads}{Number of threads to use. Default is 1.} - \item{optLlk}{Which likelihood to evaluate. 1 for equation 6 (slightly shrink the correlation of SNPs) and 2 for equation 5 (SNPs genotyped on different arrays in a separate cohort). Default is 1.} diff --git a/man/se.Rd b/man/se.Rd index adec8fac..e47147c5 100644 --- a/man/se.Rd +++ b/man/se.Rd @@ -7,14 +7,7 @@ \usage{ se(x, ...) -\S4method{se}{SumStatsBase}( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL -) +\S4method{se}{SumStatsBase}(x, studyName = NULL, context = NULL, trait = NULL) } \arguments{ \item{x}{A \code{GwasSumStats} or \code{QtlSumStats} object.} @@ -29,12 +22,6 @@ this context; \code{NULL} matches all contexts.} \item{trait}{Character (length 1) or \code{NULL}. Restrict the selection to this trait; \code{NULL} matches all traits.} - -\item{annotateSignificance}{Optional correction-method name passed through to -\code{\link{sumStats}} (QTL only); \code{NULL} applies none.} - -\item{ranges}{A \code{GRanges} or \code{NULL} (default). Return only the -variants overlapping these ranges; \code{NULL} returns everything.} } \value{ Numeric vector of standard errors, or \code{NULL} if not available. diff --git a/man/show-methods.Rd b/man/show-methods.Rd index adc2515f..850331b6 100644 --- a/man/show-methods.Rd +++ b/man/show-methods.Rd @@ -1,16 +1,17 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/AllGenerics.R, R/GenotypeHandle.R, % R/AnnotationMatrix.R, R/ColocResult.R, R/ColocBoostResult.R, -% R/CtwasResult.R, R/GwasFineMappingResult.R, R/H2Estimate.R, R/LdEigen.R, -% R/LdScore.R, R/MashPrior.R, R/qtlSumStats.R, R/QtlDataset.R, -% R/MultiStudyQtlDataset.R, R/QtlFineMappingResult.R, R/gwasSumStats.R, -% R/fineMappingRow.R, R/twasWeights.R, R/twasWeightsRow.R +% R/CtwasResultEntry.R, R/CtwasResult.R, R/GwasFineMappingResult.R, +% R/H2Estimate.R, R/LdEigen.R, R/LdScore.R, R/MashPrior.R, R/qtlSumStats.R, +% R/QtlDataset.R, R/MultiStudyQtlDataset.R, R/QtlFineMappingResult.R, +% R/gwasSumStats.R, R/fineMappingRow.R, R/twasWeights.R, R/twasWeightsRow.R \name{show-methods} \alias{show-methods} \alias{show,GenotypeHandle-method} \alias{show,AnnotationMatrix-method} \alias{show,ColocResult-method} \alias{show,ColocBoostResult-method} +\alias{show,CtwasResultEntry-method} \alias{show,CtwasResult-method} \alias{show,GwasFineMappingResult-method} \alias{show,H2Estimate-method} @@ -35,6 +36,8 @@ \S4method{show}{ColocBoostResult}(object) +\S4method{show}{CtwasResultEntry}(object) + \S4method{show}{CtwasResult}(object) \S4method{show}{GwasFineMappingResult}(object) diff --git a/man/sldscResults.Rd b/man/sldscResults.Rd index f4907f82..650fa495 100644 --- a/man/sldscResults.Rd +++ b/man/sldscResults.Rd @@ -7,29 +7,26 @@ \usage{ sldscResults(x, trait = NULL, ...) -\S4method{sldscResults}{SldscData}(x, trait = NULL, mode = c("single", "joint"), idx = NULL) +\S4method{sldscResults}{SldscData}(x, trait = NULL) } \arguments{ \item{x}{An \code{\link{SldscData}} object.} -\item{trait}{Character trait name, or \code{NULL} (default) to return the -named list of per-trait \code{single}/\code{joint} runs for all traits.} +\item{trait}{Character trait name(s), or \code{NULL} (default) for every +trait. A name the object does not hold is an error.} -\item{...}{Further arguments: \code{mode} (\code{"single"}/\code{"joint"}) -and \code{idx} (which single run).} - -\item{mode}{Character. Trait-run selection mode.} - -\item{idx}{Integer. Index of the trait run to select.} +\item{...}{Unused.} } \value{ -The named list of per-trait runs when \code{trait} is \code{NULL}; - otherwise a single run list, the list of single runs, or \code{NULL}. +A named list keyed by trait, each element a list with + \code{single} (a list of runs) and \code{joint} (one run, or + \code{NULL} when the trait has none). } \description{ Return the stratified LD-score regression runs held by an - \code{\link{SldscData}}: every trait's runs when \code{trait} is - \code{NULL}, otherwise the selected run(s) for that one trait. + \code{\link{SldscData}}, keyed by trait. Each trait's entry holds its + \code{single} runs (one per annotation) and its \code{joint} run, read + with \code{[[}: \code{sldscResults(x, "T")[["T"]]$joint}. } \examples{ mkRun <- function(cats) { @@ -55,5 +52,5 @@ mkTrait <- function() { } traits <- setNames(list(mkTrait(), mkTrait()), c("traitX", "traitY")) sd <- SldscData(annotData = annot, frqData = frq, traits = traits) -sldscResults(sd, "traitX") +sldscResults(sd, "traitX")[["traitX"]]$joint$categories } diff --git a/man/snpsPerBlock.Rd b/man/snpsPerBlock.Rd index 76d95d09..dd4a8255 100644 --- a/man/snpsPerBlock.Rd +++ b/man/snpsPerBlock.Rd @@ -9,7 +9,8 @@ snpsPerBlock(snpInfo, ldBlocks) \arguments{ \item{snpInfo}{A data.frame with columns CHR, BP.} -\item{ldBlocks}{A \code{GRanges} of LD block intervals.} +\item{ldBlocks}{The LD block intervals: a \code{GRanges}, or the path +of a BED file, read as BED with a 0-based start.} } \value{ A list of integer vectors, one per block. diff --git a/man/subsetChr.Rd b/man/subsetChr.Rd deleted file mode 100644 index 66742433..00000000 --- a/man/subsetChr.Rd +++ /dev/null @@ -1,26 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/AllGenerics.R, R/AllClasses.R -\name{subsetChr} -\alias{subsetChr} -\alias{subsetChr,SumStatsBase-method} -\title{Subset by Chromosome} -\usage{ -subsetChr(x, chr) - -\S4method{subsetChr}{SumStatsBase}(x, chr) -} -\arguments{ -\item{x}{A \code{GwasSumStats} object.} - -\item{chr}{Character, chromosome name (e.g., "1", "chr1").} -} -\value{ -A \code{GwasSumStats} object. -} -\description{ -Extract a chromosome-specific subset of a GwasSumStats object. -} -\examples{ -data(gwasSumStatsS4Example) -subsetChr(gwasSumStatsS4Example, "chr22") -} diff --git a/man/subsetRegion.Rd b/man/subsetRegion.Rd deleted file mode 100644 index 1fccb5fe..00000000 --- a/man/subsetRegion.Rd +++ /dev/null @@ -1,53 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/AllGenerics.R, R/RangedTupleList.R -\name{subsetRegion} -\alias{subsetRegion} -\alias{subsetRegion,RangedTupleList-method} -\title{Restrict a Collection to a Region} -\usage{ -subsetRegion(x, region, ...) - -\S4method{subsetRegion}{RangedTupleList}(x, region) -} -\arguments{ -\item{x}{A \code{RangedTupleList} collection.} - -\item{region}{A \code{GRanges}, a \code{"chr:start-end"} string, or a -one-row \code{data.frame} with \code{chrom} / \code{start} / \code{end}.} - -\item{...}{Additional arguments passed to methods. Fine-mapping collections -accept \code{adjust} to renormalize PIPs over the retained variants.} -} -\value{ -An object of the same class as \code{x}, with the collection-level - slots carried over and \code{mcols} narrowed to the surviving elements. -} -\description{ -Narrow a \code{RangedTupleList} collection to an analysis - window: elements that do not overlap it are dropped, and the survivors are - trimmed to the overlapping variants. Elements that trim to zero variants - are dropped too. -} -\details{ -This is deliberately a new verb rather than a redefinition of a - Bioconductor generic, because three genuinely different operations are in - play and all three are useful: - \describe{ - \item{\code{subsetByOverlaps(x, win)}}{selects elements, keeps them - whole.} - \item{\code{restrict(x, start, end)}}{trims elements, keeps empty ones.} - \item{\code{subsetRegion(x, win)}}{selects AND trims AND drops empties.} - } - \code{subsetChr()} is the whole-seqname special case of this verb. -} -\examples{ -data(qtlSumStatsMulticontextExample) -mc <- qtlSumStatsMulticontextExample -sum(lengths(mc)) -# Every element is narrowed to the window; the collection keeps its shape, -# so an element with nothing left stays as an empty one rather than a -# dropped row. -sub <- subsetRegion(mc, "chr22:14560203-15000000") -sum(lengths(sub)) -nrow(sub) -} diff --git a/man/sumStats-GwasSumStats-method.Rd b/man/sumStats-GwasSumStats-method.Rd index b0f47423..97364908 100644 --- a/man/sumStats-GwasSumStats-method.Rd +++ b/man/sumStats-GwasSumStats-method.Rd @@ -7,7 +7,6 @@ \S4method{sumStats}{GwasSumStats}( x, studyName = NULL, - ranges = NULL, context = NULL, trait = NULL, annotateSignificance = NULL @@ -19,9 +18,6 @@ \item{studyName}{Character (length 1) study identifier. Optional when the collection has a single row.} -\item{ranges}{Optional \code{GRanges} restricting the returned variants to -those it overlaps. \code{NULL} (default) returns the study's full set.} - \item{context, trait, annotateSignificance}{QTL-only selectors, named here so that supplying one is an error rather than a silently ignored request. A GWAS has no context or trait axis and carries no significance annotation; diff --git a/man/sumStats.Rd b/man/sumStats.Rd index d4db4bd9..959b556c 100644 --- a/man/sumStats.Rd +++ b/man/sumStats.Rd @@ -14,8 +14,7 @@ sumStats(x, ...) studyName = NULL, context = NULL, trait = NULL, - annotateSignificance = NULL, - ranges = NULL + annotateSignificance = NULL ) \S4method{sumStats}{MultiStudyQtlDataset}(x) @@ -40,16 +39,8 @@ this trait; \code{NULL} matches all traits.} \code{"bonferroni_filtered"} / \code{"qvalue"}). When set on a QtlSumStats enriched by \code{\link{qtlAssociationPostprocess}}, a logical \code{significant} mcol for that method is added to the returned entry (the -significance is derived on the fly, not stored). Flat export flattens this -full entry GRanges (all mcols) directly; note -\code{\link{as.data.frame}} is a fixed GWAS-schema view and does not -carry the association columns.} - -\item{ranges}{A \code{GRanges} or \code{NULL} (default). A selected tuple can -own several elements -- one per chromosome, since a multi-seqname entry is -split at construction -- and they are stitched back into a single -\code{GRanges}. Pass \code{ranges} to pull only the variants overlapping a -region instead of the whole span; \code{NULL} returns everything.} +significance is derived on the fly, not stored). Take a table of the +whole entry, every mcol included, with \code{as.data.frame()}.} } \value{ A \code{GRanges}, a \code{QtlSumStats}, or \code{NULL}. diff --git a/man/sumStatsDataFrame.Rd b/man/sumStatsDataFrame.Rd deleted file mode 100644 index 29fca09e..00000000 --- a/man/sumStatsDataFrame.Rd +++ /dev/null @@ -1,74 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/qtlSumStats.R, R/gwasSumStats.R -\name{as.data.frame,QtlSumStats-method} -\alias{as.data.frame,QtlSumStats-method} -\alias{as.data.frame,GwasSumStats-method} -\alias{sumStatsDataFrame} -\title{Coerce Summary Statistics to a Data Frame} -\usage{ -\S4method{as.data.frame}{QtlSumStats}( - x, - row.names = NULL, - optional = FALSE, - studyName = NULL, - context = NULL, - trait = NULL, - require = character(0), - derive = c("none", "zFromBetaSe"), - keepChrPrefix = TRUE, - ... -) - -\S4method{as.data.frame}{GwasSumStats}( - x, - row.names = NULL, - optional = FALSE, - studyName = NULL, - require = character(0), - derive = c("none", "zFromBetaSe"), - keepChrPrefix = TRUE, - ... -) -} -\arguments{ -\item{x}{A \code{GwasSumStats} or \code{QtlSumStats} object.} - -\item{row.names, optional}{Accepted for compatibility with -\code{as.data.frame} and ignored.} - -\item{studyName}{Character (length 1) or \code{NULL}. Restrict the selection -to this study; \code{NULL} matches all studies.} - -\item{context}{Character (length 1) or \code{NULL}. Restrict the selection to -this context; \code{NULL} matches all contexts (\code{QtlSumStats} only).} - -\item{trait}{Character (length 1) or \code{NULL}. Restrict the selection to -this trait; \code{NULL} matches all traits (\code{QtlSumStats} only).} - -\item{require}{Character vector. Columns that must be present (derived if -necessary) in the returned summary-statistics data frame.} - -\item{derive}{Whether to derive missing standard columns from the available -ones; \code{"zFromBetaSe"} recovers \code{z} from \code{beta}/\code{se}.} - -\item{keepChrPrefix}{Logical. If \code{TRUE}, keep the \code{chr} prefix on -chromosome names; otherwise strip it.} - -\item{...}{Unused.} -} -\value{ -A \code{data.frame}. -} -\description{ -Coerce one tuple of a \code{GwasSumStats} or - \code{QtlSumStats} collection to a per-variant \code{data.frame} in the - standardized layout \code{variant_id, chrom, pos, A1, A2, z, beta, se, N, - maf} (optional columns omitted when absent on the entry). This is the - table view of \code{\link{sumStats}}, which returns the same selection as - a \code{GRanges}; coercion rather than a return-type argument is the - Bioconductor idiom for choosing a representation. -} -\examples{ -data(qtlSumStatsExample) -head(as.data.frame(qtlSumStatsExample)) -} diff --git a/man/summaryStatsQc.Rd b/man/summaryStatsQc.Rd index d291b52b..41b2a050 100644 --- a/man/summaryStatsQc.Rd +++ b/man/summaryStatsQc.Rd @@ -49,8 +49,7 @@ disables it).} \item{keepVariants}{Optional character vector of variant IDs (SNP column) to retain prior to harmonization.} -\item{skipRegion}{Optional character vector of \code{"chr:start-end"} -strings, or a \code{GRanges}, of regions to drop.} +\item{skipRegion}{Optional \code{GRanges} of regions to drop.} \item{signalScreenParam}{Whether to skip an entry before fitting it, built with @@ -84,8 +83,9 @@ counts and an \code{N} column are present the counts win: \code{N} is overridden and the override is logged. Inputs with no counts (quantitative traits) are unchanged. The escape hatch \code{effectiveN = FALSE} restores the raw \code{N} column (or, when there is no \code{N}, the raw total -\code{nCase + nControl}) with no override. \code{qcInfo$options$effectiveN} -records the setting and each entry's \code{nSource} is one of +\code{nCase + nControl}) with no override. +\code{qcOptions(x)$options$effectiveN} records the setting and each +row's \code{nSource} (a \code{\link{qcInfo}} column) is one of \code{"effective"}, \code{"column"}, \code{"total"}, or \code{NA}.} \item{impute}{Logical (length 1). Run RAISS imputation against the @@ -99,7 +99,10 @@ records how many variants were imputed. Default \code{FALSE}.} RAISS imputation scopes its reference panel to the analysis-region window (so a per-chromosome / genome-wide \code{ldReference} does not materialize its full dosage); \code{flank} widens that window by the given number of - base pairs on each side to retain LD context for edge variants. + base pairs on each side to retain LD context for edge variants, though + never into the stretch of another row of the same study, nor past a + block range that was given: a study split into LD blocks imputes each + block once, in its own row. \code{mafCutoff}, \code{macCutoff} and \code{imissCutoff} bound which panel variants RAISS will attempt to impute. Without them every rare @@ -133,8 +136,8 @@ filter or screen. Distinct from \code{sumstatsFilterParam}, which applies quality thresholds to rows that are already well formed.} } \value{ -A new \code{QtlSumStats} / \code{GwasSumStats} with cleaned entries - and \code{qcInfo} populated. +A new \code{QtlSumStats} / \code{GwasSumStats} with cleaned entries, + \code{qcOptions} filled and each row's QC audit attached. } \description{ Applies a single QC pass to a \code{QtlSumStats} or \code{GwasSumStats} @@ -150,10 +153,12 @@ and optional RAISS imputation. No Bioconductor genome / dbSNP packages required. } \details{ -The returned collection has its \code{qcInfo} slot populated with a per-entry -audit record (variant counts, drop counts at each step, which filters fired, -etc.). Fine-mapping and TWAS-weights pipelines reject SumStats inputs where -\code{length(qcInfo(x)) == 0L}. +The returned collection records the options QC ran with in its +\code{qcOptions} slot, and what QC did to each row (variant counts, drop +counts at each step, which filters fired, etc.) in its \code{qcAudit} +column, read as a table with \code{\link{qcInfo}}. Fine-mapping and +TWAS-weights pipelines reject SumStats inputs where +\code{length(qcOptions(x)) == 0L}. Column-availability error contract: a non-zero \code{infoCutoff} requires every entry to carry an \code{INFO} column, and a non-zero \code{nCutoff} @@ -168,8 +173,8 @@ filtered against the reference panel (see below). \code{\link{twasWeightsPipeline}} measure them on the RSS path, so one number means the same thing wherever it is set. MAC is converted to a MAF equivalent and the stricter of the two applies, matching - \code{\link{QtlDataset}}. Defaults (\code{0}, \code{0}, \code{1}) filter - nothing. + \code{\link{GenotypeFilterParam}}. Defaults (\code{0}, \code{0}, + \code{1}) filter nothing. The panel is filtered once, before any entry is harmonized, so a variant the panel cannot support is absent from the LD used by kriging, diff --git a/man/susieAlpha.Rd b/man/susieAlpha.Rd index 42d89ce2..83f79f3a 100644 --- a/man/susieAlpha.Rd +++ b/man/susieAlpha.Rd @@ -1,17 +1,17 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/AllGenerics.R, R/CtwasResult.R, -% R/CtwasResultEntry.R +% Please edit documentation in R/AllGenerics.R, R/CtwasResultEntry.R, +% R/CtwasResult.R \name{susieAlpha} \alias{susieAlpha} -\alias{susieAlpha,CtwasResult-method} \alias{susieAlpha,CtwasResultEntry-method} +\alias{susieAlpha,CtwasResult-method} \title{Get cTWAS Per-effect Susie Alpha Table} \usage{ susieAlpha(x, ...) -\S4method{susieAlpha}{CtwasResult}(x) - \S4method{susieAlpha}{CtwasResultEntry}(x) + +\S4method{susieAlpha}{CtwasResult}(x) } \arguments{ \item{x}{A \code{CtwasResultEntry} or \code{CtwasResult}.} @@ -19,8 +19,11 @@ susieAlpha(x, ...) \item{...}{Class-specific selection arguments.} } \value{ -A \code{data.frame} of per-effect alphas (or \code{NULL} when - absent). +On a \code{CtwasResultEntry}, the stored alphas: a + \code{GRanges} when the pipeline placed its rows, the table as given + otherwise, or \code{NULL} when absent. On a \code{CtwasResult}, one + \code{GRanges} of every row's alphas with the run identity in + \code{mcols()} (empty when no row has any). } \description{ Return the full per-effect susie alpha table diff --git a/man/susieFit.Rd b/man/susieFit.Rd index 97736566..e32e80c2 100644 --- a/man/susieFit.Rd +++ b/man/susieFit.Rd @@ -15,7 +15,7 @@ susieFit(x, ...) context = NULL, trait = NULL, method = NULL, - region = NULL + blockId = NULL ) \S4method{susieFit}{FineMappingRow}(x) @@ -38,9 +38,8 @@ this trait; \code{NULL} matches all traits.} \item{method}{Character (length 1) or \code{NULL}. Restrict the selection to this fine-mapping / weight method; \code{NULL} matches all methods.} -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -Restrict variants to this region; \code{NULL} uses the full cis window / -all regions.} +\item{blockId}{GWAS fine-mapping results only: the \code{blockId} naming +one LD block of a fit; \code{NULL} matches every block.} } \value{ A list (the SuSiE fit object). diff --git a/man/susieResult.Rd b/man/susieResult.Rd index 7959846f..75880610 100644 --- a/man/susieResult.Rd +++ b/man/susieResult.Rd @@ -17,7 +17,9 @@ The trimmed fit (a list with \code{pip}, \code{sets}, etc.) or NULL. \description{ Returns the trimmed model fit underlying \code{conData$finemappingEntry} (a \code{FineMappingRow}, or a single-row fine-mapping result), or NULL if no -fine-mapping entry is attached. +fine-mapping entry is attached. As \code{\link{susieFit}} does, it warns +(condition class \code{pecotmrFitCoverage}) when the entry holds fewer +variants than its fit was made with. } \examples{ data(qtlFineMappingExample) diff --git a/man/topLoci.Rd b/man/topLoci.Rd index 0673afb0..014ae501 100644 --- a/man/topLoci.Rd +++ b/man/topLoci.Rd @@ -14,9 +14,8 @@ topLoci(x, signalCutoff = 0.025, ...) context = NULL, trait = NULL, method = NULL, - region = NULL, - minPurity = NULL, - raw = FALSE + blockId = NULL, + minPurity = NULL ) } \arguments{ @@ -40,17 +39,11 @@ this trait; \code{NULL} matches all traits.} \item{method}{Character (length 1) or \code{NULL}. Restrict the selection to this fine-mapping / weight method; \code{NULL} matches all methods.} -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -Restrict variants to this region; \code{NULL} uses the full cis window / -all regions.} +\item{blockId}{GWAS fine-mapping results only: the \code{blockId} naming +one LD block of a fit; \code{NULL} matches every block.} \item{minPurity}{Numeric or \code{NULL}. Minimum credible-set purity to retain; \code{NULL} applies no purity filter.} - -\item{raw}{Logical (length 1). \code{FALSE} (default) returns the posterior -view described above. \code{TRUE} hands back the stored canonical table -verbatim -- a \code{data.frame}, not a \code{GRanges} -- so neither the -projection nor \code{signalCutoff} applies.} } \value{ A \code{GRanges}, one range per retained variant, carrying the @@ -59,7 +52,7 @@ A \code{GRanges}, one range per retained variant, carrying the with \code{as.data.frame()} (which adds the standard \code{seqnames}/\code{start}/... columns) or \code{as.data.frame(S4Vectors::mcols(.))} for the per-variant columns - alone. \code{raw = TRUE} returns the stored \code{data.frame} instead. + alone. } \description{ Extract the per-variant posterior fine-mapping payload as either diff --git a/man/traitPosition.Rd b/man/traitPosition.Rd index 933a0b83..61b9bb3d 100644 --- a/man/traitPosition.Rd +++ b/man/traitPosition.Rd @@ -13,9 +13,9 @@ traitPosition(x, ...) \S4method{traitPosition}{FineMappingResultBase}(x) -\S4method{traitPosition}{QtlSumStats}(x, traitId = NULL) +\S4method{traitPosition}{QtlSumStats}(x, trait = NULL) -\S4method{traitPosition}{QtlDataset}(x, traitId = NULL) +\S4method{traitPosition}{QtlDataset}(x, trait = NULL) \S4method{traitPosition}{TwasWeights}(x) } @@ -24,12 +24,15 @@ traitPosition(x, ...) \item{...}{Reserved for future use.} -\item{traitId}{Character or \code{NULL}. Molecular trait / feature identifier +\item{trait}{Character or \code{NULL}. Molecular trait / feature identifier to select; \code{NULL} matches all traits in the dataset.} } \value{ -A \code{GRanges} with one range per row of \code{x}, or an empty - \code{GRanges} when the collection carries no trait-position provenance. +A \code{GRanges}: one range per row of a collection, or an empty + \code{GRanges} when the collection carries no trait-position provenance + (or, for a \code{QtlSumStats} with \code{trait} given, none of those + traits). For a \code{QtlDataset}, one range per requested trait, named + by trait; a trait in no context is an error. } \description{ Return the molecular feature's OWN genomic coordinates (the gene diff --git a/man/twasEngineOptions.Rd b/man/twasEngineOptions.Rd index f0e88157..ae8a85d8 100644 --- a/man/twasEngineOptions.Rd +++ b/man/twasEngineOptions.Rd @@ -61,8 +61,10 @@ Options forwarded to the engine behind a TWAS weight method, A method's individual-level and summary-statistic paths often run DIFFERENT engines, and then each takes its own constructor: \code{lassoWeights} fits with glmnet (\code{GlmnetOptions}) while - \code{lassosumRssWeights} runs pecotmr's lassosum solver - (\code{LassosumOptions}); \code{scadWeights} / \code{mcpWeights} / + \code{lassosumRssWeights} runs pecotmr's lassosum + (\code{LassosumOptions}); \code{enetWeights} / \code{ridgeWeights} fit + with glmnet too, while \code{enetRssWeights} / \code{ridgeRssWeights} + use \code{PenalizedRssOptions}; \code{scadWeights} / \code{mcpWeights} / \code{l0learnWeights} use ncvreg and L0Learn while their \code{*Rss} counterparts use \code{PenalizedRssOptions}; \code{dprGibbsWeights} uses RcppDPR and \code{sdprWeights} uses \code{SdprOptions}. Splitting them is diff --git a/man/twasPredict.Rd b/man/twasPredict.Rd index 2077a75f..7a7b4d1d 100644 --- a/man/twasPredict.Rd +++ b/man/twasPredict.Rd @@ -33,7 +33,7 @@ are derived from the names in \code{weightsList}, with "_weights" replaced by data(multiTraitData) X <- multiTraitData$X[, 1:4] colnames(X) <- sprintf("chr1:\%d:A:G", 100L * (1:4)) -twe <- twasWeightsRow(variantIds = sprintf("chr1:\%d:A:G", 100L * (1:4)), +twe <- TwasWeightsRow(variantIds = sprintf("chr1:\%d:A:G", 100L * (1:4)), weights = rep(0.1, 4), cvResult = list(rsq = 0.5), weightStandardized = FALSE) tw <- TwasWeights(studyName = "s1", context = "brain", trait = "g1", diff --git a/man/twasWeightsCv.Rd b/man/twasWeightsCv.Rd index a7d4337b..7db3ea5c 100644 --- a/man/twasWeightsCv.Rd +++ b/man/twasWeightsCv.Rd @@ -13,7 +13,7 @@ twasWeightsCv( weightMethods = NULL, maxNumVariants = NULL, variantsToKeep = NULL, - numThreads = 1, + BPPARAM = SerialParam(), verbose = 1, fitRetention = c("none", "slim", "full"), seed = NULL, @@ -49,10 +49,11 @@ maximum number of variants to use for CV purpose, to save computing time.} \item{variantsToKeep}{An optional integer to ensure that the listed variants are kept in the CV when there is a limit on the maxNumVariants to use.} -\item{numThreads}{The number of threads to use for parallel processing. If -set to -1, the function uses all available cores. If set to 0 or 1, no -parallel processing is performed. If set to 2 or more, parallel processing -is enabled with that many threads.} +\item{BPPARAM}{A \code{BiocParallelParam} the folds run on; +\code{SerialParam()} (default) runs them one at a time. Each draws from +its own random-number stream, seeded by \code{seed}, else by the param's +own \code{RNGseed}, else by one draw from the session RNG, so a run +gives the same numbers however many workers it has.} \item{verbose}{Integer controlling verbosity level: 0 = suppress all messages, 1 = suppress external package messages (default), 2 = show all @@ -66,11 +67,9 @@ for every other method the two behave alike.} \item{seed}{Integer or \code{NULL}. When supplied, seeds both the main-process RNG (fold partitioning, variant sub-sampling) and the -parallel fold-fitting RNG via the \code{BiocParallel} \code{RNGseed}, so -results are reproducible even under multi-threading. The main-process -seed is scoped to the call, so the session RNG is left as it was found. -\code{NULL} (default) does not seed at all and uses the historical -parallel default.} +streams the folds draw from (see \code{BPPARAM}). The main-process seed +is scoped to the call, so the session RNG is left as it was found. +\code{NULL} (default) seeds neither.} \item{dataDrivenPriorMatricesCv}{Optional list, one element per fold, of data-driven prior matrices for the mr.mash learner.} diff --git a/man/twasWeightsEntry.Rd b/man/twasWeightsEntry.Rd index 2f8c3d58..aafdbef8 100644 --- a/man/twasWeightsEntry.Rd +++ b/man/twasWeightsEntry.Rd @@ -24,7 +24,7 @@ Return the \code{TwasWeightsRow} for one \code{(study, context, trait, method)} row of a \code{TwasWeights} collection. } \examples{ -twe <- twasWeightsRow( +twe <- TwasWeightsRow( variantIds = sprintf("chr1:\%d:A:G", 100L * (1:4)), weights = rep(0.1, 4), cvResult = list(rsq = 0.5), weightStandardized = FALSE) tw <- TwasWeights(studyName = "s1", context = "brain", trait = "g1", diff --git a/man/twasWeightsPipeline.Rd b/man/twasWeightsPipeline.Rd index efde1f31..c0a348be 100644 --- a/man/twasWeightsPipeline.Rd +++ b/man/twasWeightsPipeline.Rd @@ -30,7 +30,7 @@ twasWeightsPipeline(data, ...) fitRetention = c("slim", "none", "full"), residualizationParam = ResidualizationParam(), weightsDataType = NULL, - naAction = c("drop", "impute"), + phenotypeFilterParam = PhenotypeFilterParam(), verbose = 1, seed = NULL ) @@ -40,6 +40,7 @@ twasWeightsPipeline(data, ...) methods = NULL, contexts = NULL, traitId = NULL, + cisWindow = NULL, jointSpecification = NULL, fineMappingResult = NULL, twasWeights = NULL, @@ -69,7 +70,7 @@ twasWeightsPipeline(data, ...) nPCs = 10L, fitRetention = c("slim", "none", "full"), weightsDataType = NULL, - naAction = c("drop", "impute"), + phenotypeFilterParam = PhenotypeFilterParam(), verbose = 1, residualizationParam = ResidualizationParam(), crossValidationParam = CrossValidationParam(), @@ -92,9 +93,9 @@ default is \code{c("lasso", "prsCs", "dprGibbs")}, which there run lassosum, PRS-CS and SDPR; the fine-mapping methods are not in it, and are requested by name together with a \code{fineMappingResult}.} -\item{contexts}{Optional context selection; \code{NULL} (the default) uses -every context. A character vector applies to every study: a context no -study has is an error, and one only some studies lack is skipped for +\item{contexts}{Optional context selection; \code{NULL} (the default) +uses every context. A character vector applies to every study: a context +no study has is an error, and one only some studies lack is skipped for those, with a warning. A list keyed by study name picks each study's contexts separately (\code{list(A = "liver")}); studies it does not name keep all of theirs.} @@ -107,23 +108,27 @@ study's entry may itself be a list keyed by context (\code{list(A = list(brain = "ENSG1"))}). Studies and contexts the list does not name keep all of their traits. A joint fit spanning a study's contexts uses every trait selected in any of them, minus the (context, -trait) pairs a per-context entry leaves out.} +trait) pairs a per-context entry leaves out. In a MultiStudyQtlDataset +a study left with no trait selected sits out; the run is refused only +when no study or summary-statistics row has one.} \item{region}{Optional variant window for QtlDataset trait selection: a -\code{GRanges}, a \code{"chr:start-end"} string, or a one-row data.frame -with \code{chrom}/\code{start}/\code{end}. Mutually exclusive with -\code{traitId}.} +\code{GRanges}. Mutually exclusive with \code{traitId}.} \item{cisWindow}{For QtlDataset: cis-window (bp) around each trait's genomic position when extracting variants. Required when \code{traitId} is -supplied. Mutually exclusive with \code{region}.} - -\item{genotypeFilterParam}{For QtlDataset: per-call genotype-filter -overrides, built with \code{\link{GenotypeFilterParam}}. Each field that is -set replaces the corresponding construct-time \code{\link{QtlDataset}} slot -for this call only (applied to a validated copy); a field left unset -leaves the stored value in place. Variant QC is a property of the data, -so these are applied identically here and in +supplied. Mutually exclusive with \code{region}. For QtlSumStats: +optional; each selected tuple is analysed over its \code{traitPos} +\eqn{\pm} \code{cisWindow}, within its \code{region}, which is then +the window its result records. Every selected tuple needs a +\code{traitPos}. A MultiStudyQtlDataset applies it to each of its +studies, individual-level or summary-statistics, as above.} + +\item{genotypeFilterParam}{For QtlDataset: which variants and samples the +run keeps, built with \code{\link{GenotypeFilterParam}}: its +\code{keepSamples} narrows the dataset once, and its other settings +apply to each extracted block. A field left unset filters nothing. +These are applied identically here and in \code{\link{fineMappingPipeline}} --- there is deliberately no TWAS-specific variant filter.} @@ -153,7 +158,9 @@ part.} its SuSiE / SuSiE-inf / SuSiE-ash trimmed fits for the matching (study, context, trait) tuples are injected into \code{learnTwasWeights} via \code{fittedModels} so SuSiE-family weight methods reuse the prior fit -instead of refitting.} +instead of refitting. Its fits and cross-validation are reused whole, +so a row narrowed since its fit warns (condition class +\code{pecotmrFitCoverage}).} \item{twasWeights}{Optional \code{\link{TwasWeights}} resume cache. For each requested \code{(study, context, trait, method)} tuple already present in @@ -217,8 +224,8 @@ components fitted per context when \code{usePCA = TRUE} (default of the returned object's contract. \code{"full"} is honoured by the mr.mash engines and, on summary - statistics, by \code{lasso}, \code{scad}, \code{mcp} and - \code{l0learn}, whose full fit also keeps every candidate's + statistics, by \code{lasso}, \code{enet}, \code{ridge}, \code{scad}, + \code{mcp} and \code{l0learn}, whose full fit also keeps every candidate's coefficients; every other method keeps its fit whole or not at all. Requesting \code{"full"} for a run where no method can honour it is an error, and a mixed run warns rather than dropping it in silence.} @@ -244,8 +251,12 @@ components fitted per context when \code{usePCA = TRUE} (default \item{weightsDataType}{Optional data-type label recorded on every \code{TwasWeightsRow$dataType} (e.g. \code{"expression"}).} -\item{naAction}{Character. How to handle missing values in the extracted -data.} +\item{phenotypeFilterParam}{The run's phenotype QC, built with +\code{\link{PhenotypeFilterParam}}: how missing phenotype values are +handled (unset drops the affected samples; \code{"impute"} fills each +trait's mean; a fit cannot take \code{"keep"}) and whether outlier +samples are dropped. Every fit of the run, joint ones included, reads +its phenotypes under it.} \item{verbose}{Verbosity (0 silent, 1 default, 2 includes external package messages).} @@ -267,6 +278,8 @@ above.} A \code{\link{TwasWeights}} collection keyed by \code{(study, context, trait, method)}. Each row's LD reference is none for individual-level fits and that of the input row(s) for RSS-derived fits. + Its \code{seqinfo()} names the genome build the inputs name; inputs + naming different builds are refused. } \description{ S4-dispatched per-region pipeline for learning TWAS prediction weights. @@ -287,11 +300,16 @@ Method-restriction rules (enforced): (require at least two traits OR at least two contexts). \item \code{prsCs} runs only on summary statistics, so it is rejected on \code{QtlDataset} input. - \item \code{enet}, \code{dprVb}, \code{dprAdaptiveGibbs} and the - Bayesian alphabet (\code{bayesA}, \code{bayesB}, \code{bayesC}, - \code{bayesL}, \code{bayesN}, \code{bayesR}, \code{bLasso}) run - only on individual-level data, so they are rejected on - \code{QtlSumStats} input. + \item \code{dprVb}, \code{dprAdaptiveGibbs} and the Bayesian alphabet + (\code{bayesA}, \code{bayesB}, \code{bayesC}, \code{bayesL}, + \code{bayesN}, \code{bayesR}, \code{bLasso}) run only on + individual-level data, so they are rejected on \code{QtlSumStats} + input. + \item \code{lasso}, \code{enet} and \code{ridge} are glmnet on + individual-level data and the penalized RSS solver on summary + statistics. \code{enet} mixes the two penalties at + \code{alpha = 0.5} unless the method's options set it, on either + input: \code{methods = list(enet = list(alpha = 0.3))}. } A \code{QtlSumStats} input must have been QC'd via @@ -337,11 +355,10 @@ same shared partition. Individual-level genotypes reach every method centred and scaled to unit variance, so all the weights are on one scale and the recorded - \code{weight_standardized} says so. The scaling belongs to the - \code{QtlDataset} accessors rather than to this pipeline: - \code{\link{residualizedGenotypes}} applies it, governed by - \code{ResidualizationParam(scaleResiduals = )} per call with the - dataset's own \code{\link{scaleResiduals}} slot as the default. + \code{weight_standardized} says so. The residualization + (\code{\link{residualizedGenotypes}}) applies it, governed by + \code{ResidualizationParam(scaleResiduals = )}, which defaults to + \code{TRUE}. It is not cosmetic: measured through pecotmr's own entry points, every method returns coefficients on the scale of the \code{X} it was given diff --git a/man/twasWeightsRow.Rd b/man/twasWeightsRow.Rd index f552e8f9..2e27d197 100644 --- a/man/twasWeightsRow.Rd +++ b/man/twasWeightsRow.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/twasWeightsRow.R -\name{twasWeightsRow} -\alias{twasWeightsRow} +\name{TwasWeightsRow} +\alias{TwasWeightsRow} \title{Build One TWAS-Weight Row} \usage{ -twasWeightsRow( +TwasWeightsRow( variantIds, weights, methodFits = NULL, @@ -38,7 +38,7 @@ Assemble a single row's payload for payload. Pass a list of these as the collection's \code{entry} argument. } \examples{ -row <- twasWeightsRow( +row <- TwasWeightsRow( variantIds = c("chr1:100:A:G", "chr1:200:C:T"), weights = c(0.4, -0.2) ) @@ -48,5 +48,5 @@ TwasWeights( ) } \seealso{ -\code{\link{fineMappingRow}} +\code{\link{FineMappingRow}} } diff --git a/man/updateObject-methods.Rd b/man/updateObject-methods.Rd index c0469e41..efea9c46 100644 --- a/man/updateObject-methods.Rd +++ b/man/updateObject-methods.Rd @@ -1,18 +1,39 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/RangedTupleList.R, R/ColocBoostResult.R +% Please edit documentation in R/RangedTupleList.R, R/AllClasses.R, +% R/ColocBoostResult.R, R/CtwasResult.R, R/QtlDataset.R, +% R/MultiStudyQtlDataset.R, R/twasWeights.R \name{updateObject-methods} \alias{updateObject-methods} \alias{updateObject,RangedTupleList-method} +\alias{updateObject,SumStatsBase-method} +\alias{updateObject,FineMappingResultBase-method} \alias{updateObject,ColocBoostResult-method} +\alias{updateObject,CtwasResult-method} +\alias{updateObject,QtlDataset-method} +\alias{updateObject,MultiStudyQtlDataset-method} +\alias{updateObject,TwasWeights-method} \title{Update an Object Saved by an Earlier pecotmr} \usage{ \S4method{updateObject}{RangedTupleList}(object, ..., verbose = FALSE) +\S4method{updateObject}{SumStatsBase}(object, ..., verbose = FALSE) + +\S4method{updateObject}{FineMappingResultBase}(object, ..., verbose = FALSE) + \S4method{updateObject}{ColocBoostResult}(object, ..., verbose = FALSE) + +\S4method{updateObject}{CtwasResult}(object, ..., verbose = FALSE) + +\S4method{updateObject}{QtlDataset}(object, ..., verbose = FALSE) + +\S4method{updateObject}{MultiStudyQtlDataset}(object, ..., verbose = FALSE) + +\S4method{updateObject}{TwasWeights}(object, ..., verbose = FALSE) } \arguments{ -\item{object}{A collection: summary statistics, fine-mapping results, TWAS -weights, or a colocalization result.} +\item{object}{A collection (summary statistics, fine-mapping results, TWAS +weights, a colocalization result), a \code{QtlDataset} or a +\code{MultiStudyQtlDataset}.} \item{...}{Passed on to the inherited method.} @@ -22,15 +43,28 @@ weights, or a colocalization result.} \code{object} in the current representation. } \description{ -Bring a collection saved by an earlier version of pecotmr up - to date. Collections now keep their LD references per row: each distinct - reference once in the \code{ldReference} slot, and an \code{ldReference} - column naming the one every row uses (in \code{outcomeInfo} for a - \code{ColocBoostResult}). An object saved when it held a single reference - for all its rows is converted by keying every row to that reference (for - a \code{ColocBoostResult}, every summary-statistic outcome), and one that - held none by marking every row LD-free. An up-to-date object is returned - unchanged. +Bring an object saved by an earlier version of pecotmr up to + date. An up-to-date object is returned unchanged. + + \itemize{ + \item Collections keep their LD references per row: each distinct + reference once in the \code{ldReference} slot, and an + \code{ldReference} column naming the one every row uses (in + \code{outcomeInfo} for a \code{ColocBoostResult}). An object saved + when it held a single reference for all its rows is converted by + keying every row to that reference (for a \code{ColocBoostResult}, + every summary-statistic outcome), and one that held none by marking + every row LD-free. + \item Collections name their elements by their identity tuple; one + saved without names gets them. + \item A \code{QtlDataset} no longer stores run settings (genotype + QC cutoffs, \code{scaleResiduals}); one saved with them has them + dropped, as the pipelines' \code{\link{GenotypeFilterParam}} and + \code{\link{ResidualizationParam}} now carry them. + \item A \code{MultiStudyQtlDataset} is now a list of its studies; one + saved when it held them in a slot is rebuilt as one, its studies + updated too. + } } \examples{ data(qtlSumStatsExample) diff --git a/man/variantColumnReplace.Rd b/man/variantColumnReplace.Rd index 9504b498..abf2180e 100644 --- a/man/variantColumnReplace.Rd +++ b/man/variantColumnReplace.Rd @@ -4,68 +4,51 @@ \alias{af<-} \alias{variantColumnReplace} \alias{maf<-} -\alias{nSamples<-} +\alias{sampleSize<-} \alias{af<-,SumStatsBase,numeric-method} -\alias{af<-,SumStatsBase,GRanges-method} \alias{maf<-,SumStatsBase,numeric-method} -\alias{maf<-,SumStatsBase,GRanges-method} -\alias{nSamples<-,SumStatsBase,numeric-method} -\alias{nSamples<-,SumStatsBase,GRanges-method} +\alias{sampleSize<-,SumStatsBase,numeric-method} \title{Replace a Per-Variant Column} \usage{ af(x, ...) <- value maf(x, ...) <- value -nSamples(x, ...) <- value +sampleSize(x, ...) <- value \S4method{af}{SumStatsBase,numeric}(x, studyName = NULL, context = NULL, trait = NULL, ...) <- value -\S4method{af}{SumStatsBase,GRanges}(x, studyName = NULL, context = NULL, trait = NULL, ...) <- value - \S4method{maf}{SumStatsBase,numeric}(x, studyName = NULL, context = NULL, trait = NULL, ...) <- value -\S4method{maf}{SumStatsBase,GRanges}(x, studyName = NULL, context = NULL, trait = NULL, ...) <- value - -\S4method{nSamples}{SumStatsBase,numeric}(x, studyName = NULL, context = NULL, trait = NULL, ...) <- value - -\S4method{nSamples}{SumStatsBase,GRanges}(x, studyName = NULL, context = NULL, trait = NULL, ...) <- value +\S4method{sampleSize}{SumStatsBase,numeric}(x, studyName = NULL, context = NULL, trait = NULL, ...) <- value } \arguments{ \item{x}{A \code{GwasSumStats} or \code{QtlSumStats} object.} \item{...}{Unused.} -\item{value}{A \code{numeric} vector (positional) or a \code{GRanges} -carrying \code{A1}/\code{A2} plus one value column (matched).} +\item{value}{A \code{numeric} vector, one value per variant in +\code{sumStats()} order.} -\item{studyName, context, trait}{Selectors pinning one entry; \code{context} -and \code{trait} are \code{QtlSumStats}-only.} +\item{studyName, context, trait}{Selectors pinning one study (every row of a +GWAS study) or one \code{QtlSumStats} entry; \code{context} and +\code{trait} are \code{QtlSumStats}-only.} } \value{ -The object, with that entry's column replaced. +The object, with the selection's column replaced. \code{sampleSize<-} + writes the per-variant \code{N}. } \description{ Supply or overwrite one per-variant column of a \code{GwasSumStats} / \code{QtlSumStats} entry after construction -- the usual case being an effect-allele frequency the source file did not - carry. Dispatch is on \code{value}: - \describe{ - \item{\code{numeric}}{positional: the vector is in the entry's own - variant order and must have exactly one value per variant. Length is - checked hard, because a recycled or truncated vector is otherwise - silently wrong.} - \item{\code{GRanges}}{matched: paired to the entry on - \code{(chrom, pos, A1, A2)} via \code{matchVariants}, so ordering - does not matter. \code{A1}/\code{A2} are \strong{required} in - \code{mcols()} so an allele swap can be detected, and exactly one - other \code{mcols} column carries the values. Entry variants the - replacement does not name are set \code{NA}.} - } - An allele swap sends \code{af} to \code{1 - af}, so \code{af<-} - complements a flipped match. \code{maf} is \code{min(af, 1 - af)} and - \code{nSamples} is a count, both swap-invariant, so neither is - complemented. + carry. The value is positional: a vector in \code{\link{sumStats}} + order for the selection -- a GWAS study split across rows is stitched, + as \code{sumStats()} returns it -- with exactly one value per variant. + Length is checked hard, because a recycled or truncated vector is + otherwise silently wrong. To take the values from a reference keyed by + variant instead, matched on \code{(chrom, pos, A1, A2)} and oriented to + the entry's alleles, use \code{\link{fillFromReference}}. } \examples{ data(qtlSumStatsExample) diff --git a/man/variantIds.Rd b/man/variantIds.Rd index 87703221..39bbb64b 100644 --- a/man/variantIds.Rd +++ b/man/variantIds.Rd @@ -25,17 +25,10 @@ variantIds(x, ...) context = NULL, trait = NULL, method = NULL, - region = NULL + blockId = NULL ) -\S4method{variantIds}{SumStatsBase}( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL -) +\S4method{variantIds}{SumStatsBase}(x, studyName = NULL, context = NULL, trait = NULL) \S4method{variantIds}{FineMappingRow}(x) @@ -60,15 +53,8 @@ this trait; \code{NULL} matches all traits.} \item{method}{Character (length 1) or \code{NULL}. Restrict the selection to this fine-mapping / weight method; \code{NULL} matches all methods.} -\item{region}{Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -Restrict variants to this region; \code{NULL} uses the full cis window / -all regions.} - -\item{annotateSignificance}{Optional correction-method name passed through to -\code{\link{sumStats}} (QTL only); \code{NULL} applies none.} - -\item{ranges}{A \code{GRanges} or \code{NULL} (default). Return only the -variants overlapping these ranges; \code{NULL} returns everything.} +\item{blockId}{GWAS fine-mapping results only: the \code{blockId} naming +one LD block of a fit; \code{NULL} matches every block.} } \value{ Character vector of variant IDs. @@ -76,7 +62,10 @@ Character vector of variant IDs. \description{ Extract variant ID vector from an object that carries one (e.g., \code{LdMatrix}, \code{FineMappingRow}, \code{TwasWeightsRow}) or from - one entry of a collection class selected by its identity tuple. + one entry of a collection class selected by its identity tuple. Every + class renders the same canonical \code{chrom:pos:A2:A1} id from each + variant's range and alleles; labels a source gave (an rsID, a file's own + spelling) stay in the \code{SNP} column of its ranges. } \examples{ data(qtlFineMappingExample) diff --git a/man/weights-methods.Rd b/man/weights-methods.Rd index d8127857..e9c1b3f9 100644 --- a/man/weights-methods.Rd +++ b/man/weights-methods.Rd @@ -42,7 +42,7 @@ Extract weights from a \code{TwasWeightsRow} or from one entry of a \code{TwasWeights} collection. } \examples{ -twe <- twasWeightsRow(variantIds = sprintf("chr1:\%d:A:G", 100L * (1:4)), +twe <- TwasWeightsRow(variantIds = sprintf("chr1:\%d:A:G", 100L * (1:4)), weights = rep(0.1, 4), cvResult = list(rsq = 0.5), weightStandardized = FALSE) weights(twe) diff --git a/man/weightsDataType.Rd b/man/weightsDataType.Rd index 93572c4b..1dc9d080 100644 --- a/man/weightsDataType.Rd +++ b/man/weightsDataType.Rd @@ -43,7 +43,7 @@ A character vector or NULL. Extract the data-type tag. } \examples{ -twe <- twasWeightsRow(variantIds = sprintf("chr1:\%d:A:G", 100L * (1:4)), +twe <- TwasWeightsRow(variantIds = sprintf("chr1:\%d:A:G", 100L * (1:4)), weights = rep(0.1, 4), cvResult = list(rsq = 0.5), weightStandardized = FALSE) weightsDataType(twe) diff --git a/man/exportToBed.Rd b/man/writeBed.Rd similarity index 76% rename from man/exportToBed.Rd rename to man/writeBed.Rd index 4f93980c..3ac5c418 100644 --- a/man/exportToBed.Rd +++ b/man/writeBed.Rd @@ -1,19 +1,19 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/AllGenerics.R, R/resultWriters.R -\name{exportToBed} -\alias{exportToBed} -\alias{exportToBed,list-method} -\alias{exportToBed,FineMappingResultBase-method} -\alias{exportToBed,TwasWeights-method} -\title{Export a result to a published BED table} +\name{writeBed} +\alias{writeBed} +\alias{writeBed,list-method} +\alias{writeBed,FineMappingResultBase-method} +\alias{writeBed,TwasWeights-method} +\title{Write a result to a published BED table} \usage{ -exportToBed(x, outputPath, ...) +writeBed(obj, filename, ...) -\S4method{exportToBed}{list}(x, outputPath, ...) +\S4method{writeBed}{list}(obj, filename, ...) -\S4method{exportToBed}{FineMappingResultBase}( - x, - outputPath, +\S4method{writeBed}{FineMappingResultBase}( + obj, + filename, schema = c("topLoci", "fsusie"), signalCutoff = 0.025, minPurity = NULL, @@ -23,19 +23,13 @@ exportToBed(x, outputPath, ...) extraColumns = NULL ) -\S4method{exportToBed}{TwasWeights}( - x, - outputPath, - coverage = NULL, - columns = NULL, - extraColumns = NULL -) +\S4method{writeBed}{TwasWeights}(obj, filename, coverage = NULL, columns = NULL, extraColumns = NULL) } \arguments{ -\item{x}{A \code{QtlFineMappingResult}, \code{GwasFineMappingResult} or +\item{obj}{A \code{QtlFineMappingResult}, \code{GwasFineMappingResult} or \code{TwasWeights} object, or a \code{list} of them, to combine first.} -\item{outputPath}{Output path. A \code{.gz} / \code{.bgz} extension selects +\item{filename}{Output path. A \code{.gz} / \code{.bgz} extension selects bgzip + tabix (via Rsamtools, so no htslib binary is needed); any other extension writes a plain table.} @@ -76,8 +70,7 @@ one. The fine-mapping views carry a long tail worth asking for (\code{grange_start} / \code{grange_end}, the legacy \code{gene} / \code{event} aliases, and whatever a custom build added); a \code{TwasWeights} element carries only its alleles and weight, so there -is nothing further to add unless the collection was built by hand. Not -accepted by the \code{"performance"} schema, which has no variant axis.} +is nothing further to add unless the collection was built by hand.} \item{extraColumns}{Optional NAMED list of trailing columns to append after the published schema. Each element is either length 1 (recycled across @@ -87,15 +80,15 @@ is the motivating case. Names that collide with a published column are an error rather than a silent overwrite.} } \value{ -\code{outputPath}, invisibly. +\code{filename}, invisibly. } \description{ Writes fine-mapping results or TWAS weights to a published FunGen-xQTL BED table, bgzipping and tabix-indexing the output when the path ends in \code{.gz} / \code{.bgz}. The tabular counterpart of -\code{\link{exportToVcf}}: the VCF is one record per variant with the models -as samples, while these tables are long-format, one row per published -observation. +\code{\link{writeGwasVcf}}: the VCF is one record per variant +with the models as samples, while these tables are long-format, one row per +published observation. } \details{ A \code{TwasWeights} writes one table, a row per (variant, weight column). @@ -113,26 +106,27 @@ Every table identifies the fit a row came from -- \code{study_ID}, \code{method} -- because these collections are keyed by that tuple and several of them are routinely folded into one output. -Cross-validation results are NOT exported, in any schema. They describe how +Cross-validation results are NOT written, in any schema. They describe how a model scored on held-out FOLDS; nothing about them is per-variant, and a published file has no data-secure way to express anything fold-level, because fold membership is sample-level information and sample names can be protected. They remain on the object, where \code{\link{cvResult}} returns -them and the caller tabulates whatever they need. For the same reason an -export REQUIRES the full-data fit: a cross-validation-only collection (what -\code{twasWeightsPipeline(fitFullData = FALSE)} produces) is refused rather -than written out empty. +them and the caller tabulates whatever they need. For the same reason +writing REQUIRES the full-data fit: a cross-validation-only collection +(what \code{twasWeightsPipeline(fitFullData = FALSE)} produces) is refused +rather than written out empty. } \examples{ data(qtlFineMappingExample) -exportToBed(qtlFineMappingExample, tempfile(fileext = ".bed")) -exportToBed( +writeBed(qtlFineMappingExample, tempfile(fileext = ".bed")) +writeBed( qtlFineMappingExample, tempfile(fileext = ".bed"), schema = "topLoci", columns = "all" ) data(twasWeightsExample) -exportToBed(twasWeightsExample, tempfile(fileext = ".bed")) +writeBed(twasWeightsExample, tempfile(fileext = ".bed")) } \seealso{ -\code{\link{exportToVcf}}, \code{\link{genomicOrder}} +\code{\link{writeGwasVcf}}, + \code{\link{readFineMappingResult}}, \code{\link{genomicOrder}} } diff --git a/man/writeGwasVcf.Rd b/man/writeGwasVcf.Rd new file mode 100644 index 00000000..83e991aa --- /dev/null +++ b/man/writeGwasVcf.Rd @@ -0,0 +1,134 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/AllGenerics.R, R/resultWriters.R +\name{writeGwasVcf} +\alias{writeGwasVcf} +\alias{writeGwasVcf,list-method} +\alias{writeGwasVcf,GwasSumStats-method} +\alias{writeGwasVcf,FineMappingResultBase-method} +\alias{writeGwasVcf,TwasWeights-method} +\title{Write a result to VCF/BCF} +\usage{ +writeGwasVcf(obj, filename, ...) + +\S4method{writeGwasVcf}{list}(obj, filename, sampleName = NULL, ...) + +\S4method{writeGwasVcf}{GwasSumStats}(obj, filename, sampleName = NULL, studyName = NULL) + +\S4method{writeGwasVcf}{FineMappingResultBase}( + obj, + filename, + sampleName = NULL, + studyName = NULL, + context = NULL, + trait = NULL, + method = NULL, + splitByContext = FALSE, + splitByTrait = FALSE, + splitByBlock = FALSE +) + +\S4method{writeGwasVcf}{TwasWeights}( + obj, + filename, + sampleName = NULL, + studyName = NULL, + context = NULL, + trait = NULL, + method = NULL +) +} +\arguments{ +\item{obj}{A \code{GwasSumStats}, \code{QtlFineMappingResult}, +\code{GwasFineMappingResult} or \code{TwasWeights} object, or a +\code{list} of fine-mapping results or of \code{TwasWeights} objects to +combine first.} + +\item{filename}{File path for output. Extension determines format: +\code{.vcf.gz} or \code{.vcf.bgz} for bgzipped VCF, \code{.bcf} for BCF, +\code{.vcf} for uncompressed VCF.} + +\item{...}{Additional arguments passed to methods.} + +\item{sampleName}{Name(s) for the VCF sample column(s). Default \code{NULL} +derives them from the object's identity tuple.} + +\item{studyName}{Character or \code{NULL}. Restrict the written records to +this study; \code{NULL} includes all studies.} + +\item{context}{Character or \code{NULL}. Restrict the written records to this +context; \code{NULL} includes all contexts.} + +\item{trait}{Character or \code{NULL}. Restrict the written records to this +trait; \code{NULL} includes all traits.} + +\item{method}{Character or \code{NULL}. Restrict the written records to this +method; \code{NULL} includes all methods.} + +\item{splitByContext}{Logical. If \code{TRUE}, write one VCF per context. +Default \code{FALSE}.} + +\item{splitByTrait}{Logical. If \code{TRUE}, write one VCF per trait. Default +\code{FALSE}.} + +\item{splitByBlock}{Logical. \code{GwasFineMappingResult} only: if +\code{TRUE}, write one VCF per LD block instead of joining a study's +blocks into one file. Default \code{FALSE}.} +} +\value{ +Invisible path(s) to the written file(s). +} +\description{ +Writes GWAS summary statistics, fine-mapping results or TWAS weights to a +GWAS-VCF-style file: one record per variant, one SAMPLE per study / fitted +model, and the per-variant statistics as FORMAT fields. The file is written +with VariantAnnotation's \code{\link[VariantAnnotation]{writeVcf}}, so that +package must be installed. +Supports bgzipped VCF (.vcf.gz/.vcf.bgz); BCF (.bcf) additionally needs a +working \code{Rsamtools::asBcf()}, which recent Rsamtools releases disable, +so prefer .vcf.bgz. +} +\details{ +Which FORMAT fields are written depends on the input: +\describe{ + \item{\code{GwasSumStats}}{\code{ES} / \code{SE} / \code{EZ} / + \code{NS} / \code{AF} / \code{MAF} for one study, whichever its + variants carry.} + \item{a fine-mapping result}{the marginal fields (\code{ES}, + \code{SE}, \code{EZ}, \code{LP}, \code{NS}), the fit's own + (\code{AF}, \code{WGT}, \code{WGTSE}, \code{THETA}) and the + posterior ones (\code{PIP}, \code{LBF}, \code{LFSR}, and a + \code{CS}/\code{PUR} pair per credible-set coverage present).} + \item{\code{TwasWeights}}{\code{WGT}, the prediction weight.} +} + +Every fit the selectors match becomes a SAMPLE of ONE file: the records are +the union of their variants, the FORMAT schema is the union of their fields, +and a fit that did not include a variant -- or does not report a field -- +leaves those cells empty. So two methods over a region, or a dozen weight +methods for one gene, are compared by reading one file rather than a dozen. +Each sample is described in its own \code{##SAMPLE} header line, carrying +the fit's identity tuple and how many variants it contributed. +Cross-validation results are not written -- see \code{\link{writeBed}} for +why -- and writing requires the full-data fit. + +A GWAS study fine-mapped block by block is ONE fit, so its blocks are +joined into one sample. A \code{BID} FORMAT field then names each +variant's LD block -- credible-set indices are numbered within a block, +so a set is the \code{(BID, CS)} pair -- and the per-block header values +(block id, analysis window and whether it was given, \code{V}, +\code{cs_index}) are packed in block order, separated by \code{|}. +\code{\link{readFineMappingResult}} splits such a sample back into its +blocks. + +\code{splitByContext} / \code{splitByTrait} opt out of that and write one +file per context / trait, at a path decorated with the axis value, holding +the fits that share it. \code{splitByBlock} writes one file per LD block +of a GWAS result, each holding every fit's part of that block. +} +\examples{ +data(gwasSumStatsS4Example) +writeGwasVcf(gwasSumStatsS4Example, tempfile(fileext = ".vcf")) +} +\seealso{ +\code{\link{writeBed}}, \code{\link{readFineMappingResult}} +} diff --git a/man/z.Rd b/man/z.Rd index 9bb1dd83..206ac7ce 100644 --- a/man/z.Rd +++ b/man/z.Rd @@ -7,14 +7,7 @@ \usage{ z(x, ...) -\S4method{z}{SumStatsBase}( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL -) +\S4method{z}{SumStatsBase}(x, studyName = NULL, context = NULL, trait = NULL) } \arguments{ \item{x}{A \code{GwasSumStats} or \code{QtlSumStats} object.} @@ -31,12 +24,6 @@ this context; \code{NULL} matches all contexts.} \item{trait}{Character (length 1) or \code{NULL}. Restrict the selection to this trait; \code{NULL} matches all traits.} - -\item{annotateSignificance}{Optional correction-method name passed through to -\code{\link{sumStats}} (QTL only); \code{NULL} applies none.} - -\item{ranges}{A \code{GRanges} or \code{NULL} (default). Return only the -variants overlapping these ranges; \code{NULL} returns everything.} } \value{ Numeric vector of z-scores. diff --git a/pixi.toml b/pixi.toml index 5b2e1acb..b287e369 100644 --- a/pixi.toml +++ b/pixi.toml @@ -11,9 +11,10 @@ platforms = [ devtools_document = "cd $GITHUB_WORKSPACE; R -e 'devtools::document()'" devtools_test = "cd $GITHUB_WORKSPACE; R -e 'devtools::test(stop_on_failure = TRUE)'" codecov = "cd $GITHUB_WORKSPACE; R -e 'covr::codecov(quiet = FALSE)'" -rcmdcheck = "cd $GITHUB_WORKSPACE; R -e 'rcmdcheck::rcmdcheck()'" -bioccheck_git_clone = "cd $GITHUB_WORKSPACE; R -e 'BiocCheck::BiocCheckGitClone()'" -bioccheck = "cd $GITHUB_WORKSPACE; R -e 'BiocCheck::BiocCheck()'" +rcmdcheck = "cd $GITHUB_WORKSPACE; R -e 'rcmdcheck::rcmdcheck(error_on = \"error\", args = c(\"--no-manual\", \"--no-build-vignettes\"))'" +bioccheck_git_clone = "cd $GITHUB_WORKSPACE; R -e 'BiocCheck::BiocCheckGitClone(\"quit-with-status\" = TRUE)'" +bioccheck = "cd $GITHUB_WORKSPACE; R -e 'BiocCheck::BiocCheck(\"quit-with-status\" = FALSE)'" +goodpractice = "cd $GITHUB_WORKSPACE; R -e 'goodpractice::gp(\".\")'" use_major_version = "cd $GITHUB_WORKSPACE; R -e 'usethis::use_version(which = \"major\", push = FALSE)'" use_minor_version = "cd $GITHUB_WORKSPACE; R -e 'usethis::use_version(which = \"minor\", push = FALSE)'" use_patch_version = "cd $GITHUB_WORKSPACE; R -e 'usethis::use_version(which = \"patch\", push = FALSE)'" diff --git a/src/cpp11.cpp b/src/cpp11.cpp index b0f643ba..e2144631 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -33,20 +33,6 @@ extern "C" SEXP _pecotmr_dentistIterativeImputeFactor(SEXP factorR, SEXP nSample return cpp11::as_sexp(dentistIterativeImputeFactor(cpp11::as_cpp&>>(factorR), cpp11::as_cpp>(nSample), cpp11::as_cpp>(zScoreR), cpp11::as_cpp>(pValueThreshold), cpp11::as_cpp>(propSVD), cpp11::as_cpp>(gcControl), cpp11::as_cpp>(nIter), cpp11::as_cpp>(gPvalueThreshold), cpp11::as_cpp>(numThreads), cpp11::as_cpp>(correctChenEtAlBug), cpp11::as_cpp>(verbose), cpp11::as_cpp>(seed))); END_CPP11 } -// lassosum_rss.cpp -cpp11::writable::list lassosumRssCpp(const doubles& zR, const list& LD, double shrink, const doubles& lambdaR, double thr, int maxiter); -extern "C" SEXP _pecotmr_lassosumRssCpp(SEXP zR, SEXP LD, SEXP shrink, SEXP lambdaR, SEXP thr, SEXP maxiter) { - BEGIN_CPP11 - return cpp11::as_sexp(lassosumRssCpp(cpp11::as_cpp>(zR), cpp11::as_cpp>(LD), cpp11::as_cpp>(shrink), cpp11::as_cpp>(lambdaR), cpp11::as_cpp>(thr), cpp11::as_cpp>(maxiter))); - END_CPP11 -} -// lassosum_rss.cpp -cpp11::writable::list lassosumRssFactorCpp(const doubles& zR, const doubles_matrix<>& factorR, double shrink, const doubles& lambdaR, double thr, int maxiter); -extern "C" SEXP _pecotmr_lassosumRssFactorCpp(SEXP zR, SEXP factorR, SEXP shrink, SEXP lambdaR, SEXP thr, SEXP maxiter) { - BEGIN_CPP11 - return cpp11::as_sexp(lassosumRssFactorCpp(cpp11::as_cpp>(zR), cpp11::as_cpp&>>(factorR), cpp11::as_cpp>(shrink), cpp11::as_cpp>(lambdaR), cpp11::as_cpp>(thr), cpp11::as_cpp>(maxiter))); - END_CPP11 -} // ld_prune.cpp cpp11::writable::integers ldThresholdComponents(const doubles_matrix<>& standardized, double threshold, int stripe); extern "C" SEXP _pecotmr_ldThresholdComponents(SEXP standardized, SEXP threshold, SEXP stripe) { @@ -117,8 +103,6 @@ static const R_CallMethodDef CallEntries[] = { {"_pecotmr_bgenSampleIdsCpp", (DL_FUNC) &_pecotmr_bgenSampleIdsCpp, 2}, {"_pecotmr_dentistIterativeImpute", (DL_FUNC) &_pecotmr_dentistIterativeImpute, 12}, {"_pecotmr_dentistIterativeImputeFactor", (DL_FUNC) &_pecotmr_dentistIterativeImputeFactor, 12}, - {"_pecotmr_lassosumRssCpp", (DL_FUNC) &_pecotmr_lassosumRssCpp, 6}, - {"_pecotmr_lassosumRssFactorCpp", (DL_FUNC) &_pecotmr_lassosumRssFactorCpp, 6}, {"_pecotmr_ldThresholdComponents", (DL_FUNC) &_pecotmr_ldThresholdComponents, 3}, {"_pecotmr_penalizedRssCpp", (DL_FUNC) &_pecotmr_penalizedRssCpp, 12}, {"_pecotmr_penalizedRssFactorCpp", (DL_FUNC) &_pecotmr_penalizedRssFactorCpp, 12}, diff --git a/src/lassosum_rss.cpp b/src/lassosum_rss.cpp deleted file mode 100644 index b5c776dc..00000000 --- a/src/lassosum_rss.cpp +++ /dev/null @@ -1,180 +0,0 @@ -// lassosum_rss.cpp — Coordinate descent for LASSO on RSS objective -// Ported from lassosum (Mak et al 2017) functions.cpp elnet()/repelnet() -// -// Objective: min_beta beta'R beta - 2 beta'z + 2 lambda ||beta||_1 -// where R is the LD matrix shrunk to R_s = (1 - s) R + s I (s = `shrink`; -// 0 for an LD matrix already shrunk) and z = bhat / sqrt(n). - -#include -#include - -#include "rss_ld.h" - -using namespace cpp11; -using namespace arma; - -// Single-block coordinate descent — mirrors lassosum elnet(). `ld` answers -// R's entries for the current beta (rss_ld.h). DenseLd tracks Rbeta = R * beta -// as a running sum (analogous to yhat = X * beta in the genotype version), -// which avoids recomputing the full dot product each iteration and matches the -// original algorithm exactly; FactorLd tracks F * beta instead. -template -static int elnet_rss(double lambda1, Ld& ld, const vec& z, double thr, vec& beta, - int maxiter) { - int p = z.n_elem; - double dlx, del, t, bj; - - int conv = 0; - for (int k = 0; k < maxiter; k++) { - dlx = 0.0; - for (int j = 0; j < p; j++) { - bj = beta(j); - double v = ld.diag(j); - // t = z(j) - sum_{k != j} R[j,k]*beta[k] - // = z(j) - ((R beta)(j) - R[j,j]*beta(j)) - t = z(j) - ld.row(j, beta) + v * bj; - // Soft-thresholding (same as lassosum line 438) - beta(j) = 0.0; - if (std::abs(t) - lambda1 > 0.0) - beta(j) = std::copysign(std::abs(t) - lambda1, t) / v; - if (beta(j) == bj) continue; - del = beta(j) - bj; - dlx = std::max(dlx, std::abs(del)); - // Update the running R * beta (analogous to yhat += del * X.col(j)) - ld.update(j, del); - } - cpp11::check_user_interrupt(); - if (dlx < thr) { - conv = 1; - break; - } - } - return conv; -} - -// The lambda path's results, in the shape both entry points return. -static cpp11::writable::list lassosum_path_result(const mat& beta_mat, const vec& lambda, - const Col& conv_vec, - const vec& loss_vec, - const vec& fbeta_vec) { - using namespace cpp11::literals; - writable::list result({ - "beta"_nm = as_doubles_matrix(beta_mat), - "lambda"_nm = as_doubles(lambda), - "conv"_nm = as_integers(conv_vec), - "loss"_nm = as_doubles(loss_vec), - "fbeta"_nm = as_doubles(fbeta_vec) - }); - return result; -} - -// `shrink` is s: each block is fitted against R_s = (1 - s) R + s I, which -// is never formed (DenseLd). -[[cpp11::register]] -cpp11::writable::list lassosumRssCpp(const doubles& zR, - const list& LD, - double shrink, - const doubles& lambdaR, - double thr, - int maxiter) { - vec z = as_Col(zR); - vec lambda = as_Col(lambdaR); - - // Cache LD blocks once (avoid re-copying from R on every lambda iteration) - int n_blocks = LD.size(); - std::vector ld_blocks(n_blocks); - std::vector block_start(n_blocks), block_end(n_blocks); - int p = 0; - for (int b = 0; b < n_blocks; b++) { - ld_blocks[b] = as_Mat(doubles_matrix<>(LD[b])); - block_start[b] = p; - p += ld_blocks[b].n_rows; - block_end[b] = p - 1; - } - - if ((int)z.n_elem != p) - cpp11::stop("Length of z must equal total rows across all LD blocks."); - - int nlambda = lambda.n_elem; - mat beta_mat(p, nlambda, fill::zeros); - Col conv_vec(nlambda, fill::zeros); - vec loss_vec(nlambda, fill::zeros); - vec fbeta_vec(nlambda, fill::zeros); - - // Working beta vector — warm-started across lambda path - vec beta(p, fill::zeros); - - for (int i = 0; i < nlambda; i++) { - // Block-wise coordinate descent — mirrors lassosum repelnet() - int out = 1; - for (int b = 0; b < n_blocks; b++) { - const mat& Rb = ld_blocks[b]; - int s = block_start[b]; - int e = block_end[b]; - vec z_blk = z.subvec(s, e); - vec beta_blk = beta.subvec(s, e); - DenseLd ld(Rb, shrink, beta_blk); - - int conv_blk = elnet_rss(lambda(i), ld, z_blk, thr, beta_blk, maxiter); - beta.subvec(s, e) = beta_blk; - out = std::min(out, conv_blk); - } - - beta_mat.col(i) = beta; - conv_vec(i) = out; - - // Compute loss = beta'R_s beta - 2 z'beta (block-wise) - double loss = -2.0 * dot(z, beta); - for (int b = 0; b < n_blocks; b++) { - const mat& Rb = ld_blocks[b]; - int s = block_start[b]; - int e = block_end[b]; - vec beta_blk = beta.subvec(s, e); - loss += (1.0 - shrink) * as_scalar(beta_blk.t() * Rb * beta_blk) - + shrink * dot(beta_blk, beta_blk); - } - loss_vec(i) = loss; - fbeta_vec(i) = loss + 2.0 * lambda(i) * sum(abs(beta)); - } - - return lassosum_path_result(beta_mat, lambda, conv_vec, loss_vec, fbeta_vec); -} - -// lassosumRssCpp() for one LD block given by a factor F of R = F'F / (m - 1) -// and shrunk to R_s = (1 - s) R + s I: the same lambda path, the same updates, -// without forming R or R_s. -[[cpp11::register]] -cpp11::writable::list lassosumRssFactorCpp(const doubles& zR, - const doubles_matrix<>& factorR, - double shrink, - const doubles& lambdaR, - double thr, - int maxiter) { - vec z = as_Col(zR); - vec lambda = as_Col(lambdaR); - mat F = as_Mat(factorR); - if (F.n_cols != z.n_elem) - cpp11::stop("The LD factor has %d columns but there are %d z-scores.", - (int)F.n_cols, (int)z.n_elem); - - int p = z.n_elem; - int nlambda = lambda.n_elem; - mat beta_mat(p, nlambda, fill::zeros); - Col conv_vec(nlambda, fill::zeros); - vec loss_vec(nlambda, fill::zeros); - vec fbeta_vec(nlambda, fill::zeros); - - // Working beta vector — warm-started across lambda path - vec beta(p, fill::zeros); - - for (int i = 0; i < nlambda; i++) { - FactorLd ld(F, shrink, beta); - conv_vec(i) = elnet_rss(lambda(i), ld, z, thr, beta, maxiter); - beta_mat.col(i) = beta; - double loss = -2.0 * dot(z, beta) + ld.quad(beta); - loss_vec(i) = loss; - fbeta_vec(i) = loss + 2.0 * lambda(i) * sum(abs(beta)); - } - - return lassosum_path_result(beta_mat, lambda, conv_vec, loss_vec, fbeta_vec); -} diff --git a/src/penalized_rss.cpp b/src/penalized_rss.cpp index cf23efb5..5bddb3e0 100644 --- a/src/penalized_rss.cpp +++ b/src/penalized_rss.cpp @@ -1,12 +1,18 @@ // penalized_rss.cpp — Coordinate descent for penalized regression on RSS objective // -// Generalizes lassosum_rss.cpp to support multiple penalties: +// The package's one RSS coordinate-descent solver, for the penalties // LASSO, MCP, SCAD, L0, L0L1, L0L2 +// lassosum (Mak et al 2017) is its LASSO at alpha = 1: the same updates in the +// same order, so the same coefficients bit for bit. // // Objective (smooth part): min_beta beta'R beta - 2 beta'z + penalty(beta) // where R is the LD matrix shrunk to R_s = (1 - s) R + s I (s = `shrink`; // 0 for an LD matrix already shrunk) and z = bhat / sqrt(n). // +// LASSO, MCP and SCAD mix in a ridge term the way glmnet and ncvreg do: +// l1 = lambda * alpha, l2 = lambda * (1 - alpha), penalty = 2 P(beta; l1) + +// l2 beta'beta. LASSO with alpha < 1 is the elastic net, alpha = 0 ridge. +// // The coordinate descent update is identical across penalties; only the // proximal/thresholding operator differs. MCP/SCAD operators are ported // from ncvreg (Breheny & Huang 2011). L0 thresholding follows L0Learn @@ -39,11 +45,17 @@ static Penalty parse_penalty(const std::string& s) { // v = R_jj (diagonal of LD matrix for coordinate j) // l1, l2 = L1 and L2 penalty weights (for elastic net: l1 = lambda*alpha, // l2 = lambda*(1-alpha)) +// +// Each operator is the exact minimizer of the one-coordinate problem +// v b^2 - 2 z b + 2 P(b; l1) + l2 b^2, whose curvature is a = v + l2. ncvreg +// writes the curvature v (1 + l2), which is the same only when v = 1: a +// correlation matrix's diagonal, but not a diagonal the shrinkage or a +// genotype factor leaves slightly off 1. static inline double lasso_thresh(double z, double l1, double l2, double v) { double az = std::abs(z); if (az <= l1) return 0.0; - return std::copysign(az - l1, z) / (v * (1.0 + l2)); + return std::copysign(az - l1, z) / (v + l2); } // MCP (minimax concave penalty) — Breheny & Huang 2011 @@ -51,10 +63,11 @@ static inline double lasso_thresh(double z, double l1, double l2, double v) { static inline double mcp_thresh(double z, double l1, double l2, double gamma, double v) { double az = std::abs(z); + double a = v + l2; if (az <= l1) return 0.0; - if (az <= gamma * l1 * (1.0 + l2)) - return std::copysign(az - l1, z) / (v * (1.0 + l2 - 1.0 / gamma)); - return z / (v * (1.0 + l2)); + if (az <= gamma * l1 * a) + return std::copysign(az - l1, z) / (a - 1.0 / gamma); + return z / a; } // SCAD (smoothly clipped absolute deviation) — Fan & Li 2001 @@ -62,13 +75,14 @@ static inline double mcp_thresh(double z, double l1, double l2, static inline double scad_thresh(double z, double l1, double l2, double gamma, double v) { double az = std::abs(z); + double a = v + l2; if (az <= l1) return 0.0; - if (az <= l1 * (2.0 + l2)) - return std::copysign(az - l1, z) / (v * (1.0 + l2)); - if (az <= gamma * l1 * (1.0 + l2)) + if (az <= l1 * (1.0 + a)) + return std::copysign(az - l1, z) / a; + if (az <= gamma * l1 * a) return std::copysign(az - gamma * l1 / (gamma - 1.0), z) / - (v * (1.0 - 1.0 / (gamma - 1.0) + l2)); - return z / (v * (1.0 + l2)); + (a - 1.0 / (gamma - 1.0)); + return z / a; } // L0 (+L1+L2) — Hazimeh & Mazumder 2020 @@ -118,28 +132,29 @@ static double scad_penalty_single(double bj, double lambda, double gamma) { return lambda * lambda * (gamma + 1.0) / 2.0; } +// The penalty the thresholding operators minimize: 2 P(beta; l1) + l2 +// beta'beta, so MCP and SCAD are evaluated at l1 = lambda * alpha, the +// threshold the operators use, not at lambda. static double compute_penalty(Penalty pen, const vec& beta, double lambda, double alpha, double gamma, double lambda0, double lambda2) { double val = 0.0; double l1 = lambda * alpha; + double l2 = lambda * (1.0 - alpha); int p = beta.n_elem; switch (pen) { case PEN_LASSO: - val = 2.0 * l1 * sum(abs(beta)); + val = 2.0 * l1 * sum(abs(beta)) + l2 * dot(beta, beta); break; case PEN_MCP: for (int j = 0; j < p; j++) - val += 2.0 * alpha * mcp_penalty_single(beta(j), lambda, gamma); - // Add ridge part - if (alpha < 1.0) - val += lambda * (1.0 - alpha) * dot(beta, beta); + val += 2.0 * mcp_penalty_single(beta(j), l1, gamma); + val += l2 * dot(beta, beta); break; case PEN_SCAD: for (int j = 0; j < p; j++) - val += 2.0 * alpha * scad_penalty_single(beta(j), lambda, gamma); - if (alpha < 1.0) - val += lambda * (1.0 - alpha) * dot(beta, beta); + val += 2.0 * scad_penalty_single(beta(j), l1, gamma); + val += l2 * dot(beta, beta); break; case PEN_L0: { int nnz = 0; diff --git a/src/rss_ld.h b/src/rss_ld.h index e6911679..b49d0247 100644 --- a/src/rss_ld.h +++ b/src/rss_ld.h @@ -1,6 +1,6 @@ // rss_ld.h -- the LD a coordinate-descent RSS solve reads. // -// The solvers in lassosum_rss.cpp and penalized_rss.cpp minimise +// The solvers in penalized_rss.cpp minimise // beta'R_s beta - 2 beta'z + penalty(beta) for R_s = (1 - s) R + s I. They // only ever ask R_s four things: a diagonal entry, one entry of R_s beta for // the current beta, the effect of changing one coordinate, and (for the L0 diff --git a/tests/testthat/helper-collectionAccessors.R b/tests/testthat/helper-collectionAccessors.R index 42df0fcd..4723aec3 100644 --- a/tests/testthat/helper-collectionAccessors.R +++ b/tests/testthat/helper-collectionAccessors.R @@ -1,5 +1,3 @@ -context("Collection-level accessors") - # =========================================================================== # Shared fixture # =========================================================================== @@ -29,7 +27,7 @@ context("Collection-level accessors") } .ca_makeFmEntry <- function(n = 3) { - fineMappingRow( + FineMappingRow( variantIds = paste0("chr1:", 100 * seq_len(n), ":A:G"), susieFit = list(payload = sprintf("fit_n=%d", n)), topLoci = .ca_makeTopLoci(n) diff --git a/tests/testthat/helper-fineMapping.R b/tests/testthat/helper-fineMapping.R new file mode 100644 index 00000000..8f9956cb --- /dev/null +++ b/tests/testthat/helper-fineMapping.R @@ -0,0 +1,146 @@ +# Fine-mapping rows and fits shared by the fine-mapping, collection, TWAS and +# result-writer tests. The fitted fixtures are promises: each is built once, +# on first use, so a test run that never reads one never pays for it. + +.makeAdjustEntry <- function(vids, maxNumSingleEffects = 2L) { + p <- length(vids) + set.seed(11L) + lbf <- matrix( + rnorm(maxNumSingleEffects * p), + nrow = maxNumSingleEffects, + ncol = p + ) + colnames(lbf) <- vids + alpha <- lbfToAlpha(lbf) + pip <- as.numeric(1 - apply(1 - alpha, 2, prod)) + FineMappingRow( + variantIds = vids, + susieFit = list( + pip = pip, + alpha = alpha, + lbf_variable = lbf, + mu = matrix(0, maxNumSingleEffects, p), + X_column_scale_factors = rep(1, p) + ), + topLoci = data.frame( + variant_id = vids, + pip = pip, + betahat = rep(0, p), + sebetahat = rep(1, p), + stringsAsFactors = FALSE + ) + ) +} + +# n = 100, p = 12 and L = 3 still give both credible sets (variants 3 and +# 10), bands and affected regions of either sign, at a fraction of the +# fitting time of a larger simulation. +.fsa_makeFit <- function(post_processing = "none") { + set.seed(1) + n <- 100L + p <- 12L + J <- 16L + X <- matrix( + rnorm(n * p), + n, + p, + dimnames = list( + paste0("s", seq_len(n)), + paste0("chr1:", seq_len(p) * 100, ":A:G") + ) + ) + b1 <- sin(seq(0, 2 * pi, length.out = J)) + b2 <- cos(seq(0, pi, length.out = J)) + Y <- X[, 3] %o% b1 + X[, 10] %o% b2 + matrix(rnorm(n * J, sd = 0.3), n, J) + colnames(Y) <- paste0("f", seq_len(J)) + suppressWarnings(fsusieR::susiF( + X = X, + Y = Y, + pos = seq_len(J), + L = 3, + post_processing = post_processing, + verbose = FALSE + )) +} + +.fsa_entry <- function(fit, purityVal = 0.85) { + vids <- names(fit$csd_X) + pipv <- if (!is.null(fit$pip)) { + as.numeric(fit$pip) + } else { + rep(0.1, length(vids)) + } + # Canonical CS labels + purity from the fit's CS membership, mirroring what + # The fsusie post-processing writes into a real FMR's topLoci + # (cs_95 / cs_95_purity). + cs95 <- rep("fsusie_0", length(vids)) + for (l in seq_along(fit$cs)) { + idx <- fit$cs[[l]] + if (is.numeric(idx)) { + idx <- as.integer(idx) + } + cs95[idx] <- paste0("fsusie_", l) + } + tl <- data.frame( + variant_id = vids, + pip = pipv, + cs_95 = cs95, + cs_95_purity = ifelse(cs95 != "fsusie_0", purityVal, 0), + stringsAsFactors = FALSE + ) + FineMappingRow(variantIds = vids, susieFit = fit, topLoci = tl) +} + +# Each fit is made once and shared: susiF() is the slow step, it is +# deterministic, and the tests only read the fits. NULL without fsusieR. +delayedAssign( + ".fsa_fits", + if ( + requireNamespace("fsusieR", quietly = TRUE) && + requireNamespace("wavethresh", quietly = TRUE) + ) { + list(none = .fsa_makeFit("none"), TI = .fsa_makeFit("TI")) + } +) + +.twcv_foldFits <- function(seed = 11, fold = 3) { + set.seed(seed) + # Loaded here, not into the global environment: this runs as a helper's + # promise, whose environment does not see what data() puts there. + data("eqtlRegionExample", package = "pecotmr", envir = environment()) + X <- eqtlRegionExample$X[, 1:40] + y <- eqtlRegionExample$yRes + Y <- matrix(y, ncol = 1, dimnames = list(rownames(X), "t1")) + cv <- pecotmr:::.fmWeightsCv( + X, + Y, + tokens = "susie", + methodArgs = list(), + fold = fold, + verbose = 0, + seed = 1 + ) + list(X = X, Y = Y, cv = cv, slice = pecotmr:::.fmSliceCv(cv, "susie")) +} + +# Built once: each build runs a susie fit per fold, and the tests only read +# it. susieR is an Import, so the build needs no skip. +delayedAssign(".twcvFixture", suppressMessages(.twcv_foldFits())) + +.thetaFit <- function(nV = 12, theta = NULL) { + set.seed(1) + alpha <- matrix(runif(2 * nV), nrow = 2) + alpha <- alpha / rowSums(alpha) + mu <- matrix(rnorm(2 * nV), nrow = 2) + fit <- list( + alpha = alpha, + mu = mu, + mu2 = mu^2 + 0.1, + pip = runif(nV), + X_column_scale_factors = rep(1, nV) + ) + if (!is.null(theta)) { + fit$theta <- theta + } + fit +} diff --git a/tests/testthat/helper-fitCoverage.R b/tests/testthat/helper-fitCoverage.R new file mode 100644 index 00000000..e3e58b61 --- /dev/null +++ b/tests/testthat/helper-fitCoverage.R @@ -0,0 +1,20 @@ +# The fit-coverage warning an expression raises, or the expression's value +# when it raises none. Every other warning is muffled: a pipeline run on test +# data warns about things these checks do not look at. +.fitCoverageCondition <- function(expr) { + suppressWarnings(tryCatch(expr, pecotmrFitCoverage = identity)) +} + +# The message of every fit-coverage warning an expression raises, run to the +# end; other warnings are muffled. +.fitCoverageMessages <- function(expr) { + msgs <- character(0) + suppressWarnings(withCallingHandlers( + expr, + pecotmrFitCoverage = function(w) { + msgs <<- c(msgs, conditionMessage(w)) + invokeRestart("muffleWarning") + } + )) + msgs +} diff --git a/tests/testthat/helper-genotypeHandle.R b/tests/testthat/helper-genotypeHandle.R index 39fcaccb..d0c71b16 100644 --- a/tests/testthat/helper-genotypeHandle.R +++ b/tests/testthat/helper-genotypeHandle.R @@ -11,3 +11,46 @@ readGenotypeHandle <- function(path, format = NULL, ...) { pecotmr:::.readGenotypeHandle(path, format = format, ...) } + +.gh_pgenHandle <- function() { + skip_if_not_installed("pgenlibr") + readGenotypeHandle(test_path("test_data", "test_variants.pgen")) +} + +.sk_panel <- function() { + readGenotypes( + test_path("test_data", "test_variants"), + format = "plink1" + ) +} + +.ssQ_makeHandle <- function(snp_n = 8L, n_samples = 60L) { + new( + "GenotypeHandle", + path = "/tmp/sketch", + format = "plink2", + snpInfo = data.frame( + SNP = paste0("rs", seq_len(snp_n)), + CHR = rep("chr1", snp_n), + BP = seq(100L, by = 100L, length.out = snp_n), + A1 = rep("A", snp_n), + A2 = rep("G", snp_n), + stringsAsFactors = FALSE + ), + nSamples = n_samples, + sampleIds = paste0("s", seq_len(n_samples)), + pgenPtr = NULL + ) +} + +# A panel whose SNP ids follow the formatVariantId convention (chr:pos:A2:A1), +# as real genotype LD sketches do, so a re-keyed entry SNP resolves against it. +.ssQ_makeHandleVid <- function(snp_n = 8L, n_samples = 60L) { + h <- .ssQ_makeHandle(snp_n, n_samples) + h@snpInfo$SNP <- paste0("chr1:", snpInfo(h)$BP, ":G:A") + h +} + +.dose <- function(panel) { + unname(as.matrix(SummarizedExperiment::assay(panel, "dosage"))) +} diff --git a/tests/testthat/helper-h2Classes.R b/tests/testthat/helper-h2Classes.R index 3c58ebe4..5150b6a9 100644 --- a/tests/testthat/helper-h2Classes.R +++ b/tests/testthat/helper-h2Classes.R @@ -1,34 +1,11 @@ -# Tests for S4 classes (h2_classes.R), GwasSumStats (h2_sumstats.R), -# and AnnotationMatrix (h2Annotations.R) +# Fixtures shared by the LD-statistic tests (LdEigen, LdScore, LdStatistic), +# the heritability tests (h2EstimationWrappers, H2Estimate) and +# test_genotypeHandle.R. # ============================================================================= # Test data helpers # ============================================================================= -makeTestGRanges <- function(n = 10) { - GenomicRanges::GRanges( - seqnames = rep("chr1", n), - ranges = IRanges::IRanges( - start = seq(1000, by = 100, length.out = n), - width = 1L - ) - ) -} - -makeTestSumstatsDf <- function(n = 50) { - set.seed(42) - data.frame( - SNP = paste0("rs", seq_len(n)), - CHR = rep("1", n), - BP = seq(1000, by = 100, length.out = n), - A1 = rep("A", n), - A2 = rep("G", n), - Z = rnorm(n), - N = rep(10000, n), - stringsAsFactors = FALSE - ) -} - makeTestLdBlocks <- function() { blocks_gr <- GenomicRanges::GRanges( seqnames = c("chr1", "chr1"), @@ -40,7 +17,7 @@ makeTestLdBlocks <- function() { makeTestSnpInfo <- function(n = 10) { data.frame( SNP = paste0("rs", seq_len(n)), - CHR = rep("1", n), + CHR = rep("chr1", n), BP = seq(1000, by = 100, length.out = n), A1 = rep("A", n), A2 = rep("G", n), @@ -48,135 +25,6 @@ makeTestSnpInfo <- function(n = 10) { ) } -makeTestAnnotationMeta <- function() { - data.frame( - name = c("base", "enhancer", "promoter"), - tier = c("baseline", "candidate", "candidate"), - type = c("binary", "binary", "continuous"), - stringsAsFactors = FALSE - ) -} - -# Bridge helper: turn the legacy per-study data.frame shape into a -# single-row GwasSumStats collection using the new API. Keeps the bulk of -# the per-accessor tests below readable. -.testGenotypeHandle <- function() { - new( - "GenotypeHandle", - path = "/tmp/test", - format = "plink2", - snpInfo = data.frame(), - nSamples = 0L, - sampleIds = character(), - pgenPtr = NULL - ) -} - -.dfToSumstatsGr <- function(df) { - chrs <- as.character(df$CHR) - if (!all(grepl("^chr", chrs))) { - chrs <- paste0("chr", sub("^chr", "", chrs)) - } - gr <- GenomicRanges::GRanges( - seqnames = chrs, - ranges = IRanges::IRanges(start = as.integer(df$BP), width = 1L) - ) - mc <- df[, setdiff(colnames(df), c("CHR", "BP")), drop = FALSE] - S4Vectors::mcols(gr) <- S4Vectors::DataFrame(mc) - gr -} - -makeGwasSumStatsFromDf <- function( - df, - traitName = "test", - genome = "hg19", - varY = NA_real_ -) { - required <- c("SNP", "A1", "A2", "Z", "N") - missingCols <- setdiff(required, colnames(df)) - if (length(missingCols) > 0L) { - stop("Missing required columns: ", paste(missingCols, collapse = ", ")) - } - keep <- stats::complete.cases(df[, required, drop = FALSE]) - if (!all(keep)) { - message(sprintf( - "Removed %d SNPs with missing required-column values.", - sum(!keep) - )) - } - df <- df[keep, , drop = FALSE] - if (is.null(varY)) { - varY <- NA_real_ - } - GwasSumStats( - studyName = traitName, - entry = list(.dfToSumstatsGr(df)), - genome = genome, - ldReference = .testGenotypeHandle(), - varY = varY - ) -} - -# A handle over a real (fake-path) variant set, so tests can build the -# per-block LD panels a block-parallel pipeline produces: same genotype source, -# each narrowed to its own variants. -.blockGenotypeHandle <- function(bp, path = "/tmp/test.pgen") { - new( - "GenotypeHandle", - path = path, - format = "plink2", - snpInfo = data.frame( - SNP = paste0("chr1:", bp, ":A:G"), - CHR = rep("1", length(bp)), - BP = as.integer(bp), - A1 = rep("G", length(bp)), - A2 = rep("A", length(bp)), - fileIdx = seq_along(bp), - stringsAsFactors = FALSE - ), - nSamples = 10L, - sampleIds = paste0("s", seq_len(10)), - pgenPtr = NULL - ) -} - -# One LD block's worth of GWAS summary statistics: `n` variants starting at -# `start`, carrying a QC record and an LD panel narrowed to just those -# variants (what a per-block pipeline step writes out). -makeGwasBlock <- function( - blockId, - start, - n = 5L, - genome = "hg19", - qcOptions = list(mafCutoff = 0.01), - ldReference = .blockGenotypeHandle(bp) -) { - bp <- seq(start, by = 100L, length.out = n) - df <- data.frame( - SNP = paste0("chr1:", bp, ":A:G"), - CHR = rep("1", n), - BP = bp, - A1 = rep("A", n), - A2 = rep("G", n), - Z = seq_len(n) / 10, - N = rep(1000L, n), - stringsAsFactors = FALSE - ) - obj <- GwasSumStats( - studyName = "trait1", - entry = list(.dfToSumstatsGr(df)), - genome = genome, - ldReference = ldReference, - blockId = blockId, - qcInfo = list( - timestamp = NA_character_, - options = qcOptions, - entryAudit = list(list(variantsIn = n, block = blockId)) - ) - ) - obj -} - # ============================================================================= # LdMatrix fixtures for buildLdEigen() / buildLdScore() @@ -241,10 +89,12 @@ makeTestLdMatrixBlocks <- function( gr <- SummarizedExperiment::rowRanges(panel) pos <- GenomicRanges::start(gr) cuts <- list(1:60, 61:200, 201:300) - blocks <- data.frame( - chrom = "chr21", - start = map_int(cuts, function(i) pos[[min(i)]]), - end = map_int(cuts, function(i) pos[[max(i)]]) + blocks <- GenomicRanges::GRanges( + "chr21", + IRanges::IRanges( + start = map_int(cuts, function(i) pos[[min(i)]]), + end = map_int(cuts, function(i) pos[[max(i)]]) + ) ) ld <- map(cuts, function(i) { LdMatrix( @@ -256,38 +106,47 @@ makeTestLdMatrixBlocks <- function( list(panel = panel, blocks = blocks, ld = ld) } -# Two baseline annotations (binary and continuous) and one candidate over the -# variants of `ref`. -.h2PanelAnnotations <- function(ref) { - set.seed(11) - p <- length(ref) - mat <- cbind( - coding = rbinom(p, 1, 0.3), - cons = runif(p), - cand = rbinom(p, 1, 0.2) - ) - AnnotationMatrix( - mat, - GenomicRanges::granges(ref, use.mcols = FALSE), +makeTestH2Estimate <- function(with_enrichment = TRUE) { + enrich <- if (with_enrichment) { data.frame( - name = colnames(mat), - tier = c("baseline", "baseline", "candidate"), - type = c("binary", "continuous", "binary") - ), - genome = "hg19" - ) -} + annotation = c("annot1", "annot2"), + tau = c(1e-7, 2e-7), + tauSe = c(5e-8, 6e-8), + enrichment = c(2.0, 3.0), + enrichmentSe = c(0.5, 0.7), + enrichmentP = c(0.01, 0.001), + propH2 = c(0.3, 0.5), + propSnps = c(0.15, 0.17), + stringsAsFactors = FALSE + ) + } else { + NULL + } -# GWAS z-scores over the fixture's blocks with heritability `h2`: -# z = sqrt(n) R beta + e, e ~ N(0, R), block by block. -.h2PanelZ <- function(ld, n, h2, seed = 3) { - set.seed(seed) - M <- sum(map_int(ld, length)) - list_c(map(ld, function(x) { - R <- ldMatrix(x) - beta <- rnorm(nrow(R), sd = sqrt(h2 / M)) - e <- eigen(R, symmetric = TRUE) - noise <- e$vectors %*% (sqrt(pmax(e$values, 0)) * rnorm(nrow(R))) - as.vector(sqrt(n) * R %*% beta + noise) - })) + set.seed(55) + annotationJackknifeCoefs <- if (with_enrichment) { + matrix( + rnorm(20), + nrow = 10, + ncol = 2, + dimnames = list(NULL, c("annot1", "annot2")) + ) + } else { + NULL + } + + new( + "H2Estimate", + estimate = 0.3, + estimateSe = 0.05, + intercept = 1.01, + interceptSe = 0.02, + localBlocks = NULL, + enrichment = enrich, + annotationJackknifeCoefs = annotationJackknifeCoefs, + scoreStats = NULL, + method = "lder", + nSnps = 100L, + traitName = "test" + ) } diff --git a/tests/testthat/helper-mash.R b/tests/testthat/helper-mash.R index ccddab06..36a10f26 100644 --- a/tests/testthat/helper-mash.R +++ b/tests/testthat/helper-mash.R @@ -44,3 +44,9 @@ mashTinyPrior <- function(k = 3L) { ) )) } + +# The fixture and one fitted model, built on first use and shared by the +# tests that only read them. Every mash() call forces three garbage +# collections (mashr times each step with system.time()), which costs far +# more than the fit itself. +delayedAssign(".mwSs", mashFixture()) diff --git a/tests/testthat/helper-resultIo.R b/tests/testthat/helper-resultIo.R new file mode 100644 index 00000000..f43e6dca --- /dev/null +++ b/tests/testthat/helper-resultIo.R @@ -0,0 +1,81 @@ +# Fine-mapping and GWAS results that the writer, reader and loader tests +# publish and read back. + +# One block's fit: three variants from `offset`, its effects' V and the +# effects that formed credible sets. +.rw_blockFit <- function(offset, V, csIndex) { + FineMappingRow( + variantIds = paste0("chr1:", offset + 100 * (1:3), ":A:G"), + susieFit = list(V = V, sets = list(cs_index = csIndex)), + topLoci = .sc_makeTopLoci(3, offset = offset) + ) +} + +.rw_blockedGwasFmr <- function( + dataType = NULL, + blockId = c("chr1_1_5000", "chr1_5001_20000") +) { + GwasFineMappingResult( + studyName = c("g1", "g1"), + method = c("susie", "susie"), + entry = list( + .rw_blockFit(0L, c(0.1, 0.2), 1L), + .rw_blockFit(10000L, c(0.3, 0.4), 2L) + ), + blockId = blockId, + region = GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(1L, 5001L), c(5000L, 20000L)) + ), + dataType = dataType + ) +} + +# The same two blocks of one fit, the first given its window and the second +# not, so its window is its variants' span. +.rw_mixedGwasFmr <- function() { + combineFineMappingResults( + GwasFineMappingResult( + studyName = "g1", + method = "susie", + entry = list(.rw_blockFit(0L, c(0.1, 0.2), 1L)), + blockId = "chr1_1_5000", + region = GenomicRanges::GRanges("chr1", IRanges::IRanges(1L, 5000L)) + ), + GwasFineMappingResult( + studyName = "g1", + method = "susie", + entry = list(.rw_blockFit(10000L, c(0.3, 0.4), 2L)), + blockId = "b2" + ) + ) +} + +.rw_sampleLines <- function(path) { + grep("^##SAMPLE", readLines(path), value = TRUE) +} + +# @noRd +.ezss <- function(supplied) { + gr <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(100L, 200L), width = 1L) + ) + cols <- S4Vectors::DataFrame( + SNP = c("chr1:100:A:G", "chr1:200:C:T"), + A1 = c("G", "T"), + A2 = c("A", "C"), + Z = c(2.5, -1.2), + N = c(1000L, 1000L), + BETA = c(0.25, -0.12), + SE = c(0.1, 0.1) + ) + if (!is.null(supplied)) { + cols$z_supplied <- rep(supplied, 2L) + } + GwasSumStats( + studyName = "s", + entry = list(S4Vectors::`mcols<-`(gr, value = cols)), + genome = "hg38" + ) +} diff --git a/tests/testthat/helper-s4Constructors.R b/tests/testthat/helper-s4Constructors.R index 2b161b10..ce94f714 100644 --- a/tests/testthat/helper-s4Constructors.R +++ b/tests/testthat/helper-s4Constructors.R @@ -1,5 +1,3 @@ -context("s4Constructors") - # =========================================================================== # Shared test helpers # =========================================================================== @@ -11,7 +9,7 @@ context("s4Constructors") format = "plink2", snpInfo = data.frame( SNP = paste0("rs", seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -49,26 +47,13 @@ context("s4Constructors") } .sc_makeFineMappingRow <- function(n = 3, offset = 0L) { - fineMappingRow( + FineMappingRow( variantIds = paste0("chr1:", offset + 100 * seq_len(n), ":A:G"), susieFit = list(fake = TRUE), topLoci = .sc_makeTopLoci(n, offset = offset) ) } -.sc_makeTwasWeightsRow <- function( - p = 5L, - weightStandardized = FALSE, - weightsDataType = "expression" -) { - twasWeightsRow( - variantIds = sprintf("chr1:%d:A:G", 100L * seq_len(p)), - weights = rnorm(p), - weightStandardized = weightStandardized, - weightsDataType = weightsDataType - ) -} - # =========================================================================== # FineMappingRow # =========================================================================== @@ -97,3 +82,176 @@ context("s4Constructors") colData = cd ) } + +.qtlMakeGenotypeHandle <- function() { + new( + "GenotypeHandle", + path = "/tmp/test", + format = "plink2", + snpInfo = data.frame(), + nSamples = 0L, + sampleIds = character(), + pgenPtr = NULL + ) +} + +.qtlMakeEntryGr <- function( + n = 5, + chr = "chr1", + start_at = 100L, + step = 100L, + with_maf = FALSE +) { + gr <- GenomicRanges::GRanges( + seqnames = rep(chr, n), + ranges = IRanges::IRanges( + start = seq(start_at, by = step, length.out = n), + width = 1L + ) + ) + mcols_list <- list( + SNP = paste0("rs", seq_len(n)), + A1 = rep("A", n), + A2 = rep("G", n), + Z = seq(1.0, by = 0.5, length.out = n), + N = rep(1000L, n) + ) + if (with_maf) { + mcols_list$MAF <- seq(0.05, by = 0.01, length.out = n) + } + S4Vectors::mcols(gr) <- S4Vectors::DataFrame(mcols_list) + gr +} + +.qtlMakeOne <- function( + studyName = "study1", + context = "Cortex", + trait = "ENSG001", + n = 5, + varY = NA_real_, + with_maf = FALSE, + qcOptions = list(), + genome = "hg19" +) { + QtlSumStats( + studyName = studyName, + context = context, + trait = trait, + entry = list(.qtlMakeEntryGr(n, with_maf = with_maf)), + genome = genome, + ldReference = .qtlMakeGenotypeHandle(), + varY = varY, + qcOptions = qcOptions + ) +} + +.cbp_makeHandle <- function(snp_n = 6L, n_samples = 30L, sample_prefix = "s") { + new( + "GenotypeHandle", + path = "/tmp/cb", + format = "plink2", + snpInfo = data.frame( + SNP = sprintf("chr1:%d:A:G", 100L * seq_len(snp_n)), + CHR = rep("chr1", snp_n), + BP = seq(100L, by = 100L, length.out = snp_n), + A1 = rep("A", snp_n), + A2 = rep("G", snp_n), + stringsAsFactors = FALSE + ), + nSamples = n_samples, + sampleIds = paste0(sample_prefix, seq_len(n_samples)), + pgenPtr = NULL + ) +} + +.afm_df <- function(freqcol, val) { + d <- data.frame( + chrom = "chr1", + pos = 100L, + variant_id = "chr1:100:A:G", + A1 = "A", + A2 = "G", + z = 2.5, + n_sample = 1000, + stringsAsFactors = FALSE + ) + d[[freqcol]] <- val + d +} + +.afm_cm <- function(...) { + c( + chrom = "chrom", + pos = "pos", + variant_id = "variant_id", + A1 = "A1", + A2 = "A2", + z = "z", + n_sample = "n_sample", + ... + ) +} + +# A deterministic per-gene QtlSumStats: one row per gene carrying the regional +# summary as row columns (p_beta / beta shapes / n_variants), each entry a +# per-variant GRanges (P / af / tss_distance / tes_distance, plus the `qvalue` +# the qvalue SNP significance query reads, with v1 tracking the gene signal). +# Deterministic so qvalue::qvalue sees a stable p-value distribution. +# emptyIdx gene indices whose entry is an empty GRanges (no p-values), for +# the "skip genes with no variants" branch; the p_beta +# distribution is unchanged, so qvalue::qvalue still estimates +# pi0 on its default path. +.qapFixture <- function(nVar = 50L, nVarFilt = 30L, emptyIdx = integer(0)) { + # 6 strong signal p_beta + a deterministic uniform null (ppoints) so + # qvalue::qvalue estimates pi0 on its default path (no fallback needed). + # 18 null genes keep its smoother well clear of failing (it does by 10). + pBeta <- c(10^(-c(8, 7, 6, 5, 4, 3)), stats::ppoints(18)) + G <- length(pBeta) + entries <- map(seq_len(G), function(i) { + if (i %in% emptyIdx) { + return(GenomicRanges::GRanges()) + } # no variants + k <- 4L + pv <- c(pBeta[i] / 5, 0.2, 0.5, 0.8) # min tracks the gene signal + gr <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges( + start = seq(1000L, by = 50L, length.out = k), + width = 1L + ) + ) + mc <- S4Vectors::DataFrame( + SNP = paste0("g", i, "_v", seq_len(k)), + A1 = "A", + A2 = "G", + P = pv, + af = c(0.30, 0.20, 0.005, 0.40), # v3 fails MAF 0.01 + tss_distance = c(0L, 500L, 900000L, 2000000L), # v4 outside 1Mb cis + tes_distance = c(0L, 500L, 900000L, 2000000L), + qvalue = c(pBeta[i] / 5, 0.30, 0.60, 0.90) + ) + S4Vectors::mcols(gr) <- mc + gr + }) + QtlSumStats( + study = rep("s", G), + context = rep("brain", G), + trait = paste0("g", seq_len(G)), + entry = entries, + genome = "hg19", + extraCols = list( + n_variants = rep(nVar, G), + n_variants_filtered = rep(nVarFilt, G), + p_beta = pBeta, + beta_shape1 = rep(1, G), + beta_shape2 = rep(200, G) + ) + ) +} + +# The default fixture is 24 genes of GRanges + mcols; building it, like every +# postprocess / significantQtls call, costs time in proportion to the gene +# count, so the tests share one instance, built on first use. S4 objects are +# copy-on-modify, so that is safe; tests needing new entries still call +# .qapFixture() with arguments. +delayedAssign(".qapDefaultFixture", .qapFixture()) diff --git a/tests/testthat/helper-showMethods.R b/tests/testthat/helper-showMethods.R index 1714e1be..5aecda74 100644 --- a/tests/testthat/helper-showMethods.R +++ b/tests/testthat/helper-showMethods.R @@ -1,5 +1,3 @@ -context("show methods") - # =========================================================================== # Shared fixtures # =========================================================================== @@ -11,7 +9,7 @@ context("show methods") format = "plink2", snpInfo = data.frame( SNP = paste0("rs", seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -44,7 +42,7 @@ context("show methods") if (with_cs) { tl$cs_95 <- paste0("susie_", c(1L, 1L, 0L)[seq_len(n)]) } - fineMappingRow( + FineMappingRow( variantIds = tl$variant_id, susieFit = list(), topLoci = tl @@ -52,7 +50,7 @@ context("show methods") } .sh_makeTwEntry <- function(p = 4, weightStandardized = FALSE) { - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * seq_len(p)), weights = rep(0.1, p), cvResult = list(rsq = 0.5), diff --git a/tests/testthat/helper-sldsc.R b/tests/testthat/helper-sldsc.R index dd6d7e93..787a46bb 100644 --- a/tests/testthat/helper-sldsc.R +++ b/tests/testthat/helper-sldsc.R @@ -1,222 +1,5 @@ -# Shared S-LDSC fixture generators for test_sldscWrapper.R (helper unit tests) -# and test_sldscPostprocessingPipeline.R (integration tests). -# -# Fixture convention: -# - 2 chromosomes (1, 2), 50 SNPs each -> 100 total -# - 2 target annotations: "annot_A" (binary), "annot_B" (continuous) -# - baseline annotations (baselineLD_0 ..) in joint run -# - 10 jackknife blocks -# - Polyfun appends "_0" to target annotation names in .results - -# Create a single .annot.gz file for one chromosome. -# Real polyfun .annot.gz files have CHR, SNP, BP, CM + annotation columns only -# (no MAF/A1/A2 -- those come from the .frq / PLINK files). -.makeAnnotGz <- function(dir, chrom, nSnps = 50) { - df <- data.frame( - CHR = chrom, - SNP = paste0("rs", (chrom - 1L) * 100L + seq_len(nSnps)), - BP = seq_len(nSnps) * 1000L, - CM = seq_len(nSnps) * 0.01, - annot_A = sample(c(0L, 1L), nSnps, replace = TRUE), - annot_B = rnorm(nSnps, 2, 0.5), - stringsAsFactors = FALSE - ) - path <- file.path(dir, sprintf("target.%d.annot.gz", chrom)) - gz <- gzfile(path, "wb") - vroom::vroom_write(df, gz, delim = "\t") - close(gz) - invisible(df) -} - -# Create a PLINK .frq file for one chromosome -.make_frq <- function(dir, chrom, plinkName = "ref_chr", nSnps = 50) { - df <- data.frame( - CHR = chrom, - SNP = paste0("rs", (chrom - 1L) * 100L + seq_len(nSnps)), - A1 = "A", - A2 = "G", - MAF = runif(nSnps, 0.01, 0.49), - NCHROBS = 200L, - stringsAsFactors = FALSE - ) - path <- file.path(dir, sprintf("%s%d.frq", plinkName, chrom)) - vroom::vroom_write(df, path, delim = "\t") - invisible(df) -} - -# Create the three polyfun output files (.results, .log, .part_delete) -# for a single-target run. Real polyfun output includes baseline categories -# even in single-target mode, so we add 2 dummy baseline categories. -.makePolyfunSingle <- function( - dir, - prefix, - target_name, - nBlocks = 10, - h2g = 0.3, - tau = 1e-7, - enrichment = 2.5, - n_baseline = 2 -) { - target_cat <- paste0(target_name, "_0") - baseline_cats <- paste0("baselineLD_", seq_len(n_baseline) - 1L) - all_cats <- c(target_cat, baseline_cats) - n_cats <- length(all_cats) - - taus_all <- c(tau, rep(1e-8, n_baseline)) - enrichments_all <- c(enrichment, rep(1.0, n_baseline)) - - results <- data.frame( - Category = all_cats, - Coefficient = taus_all, - Coefficient_std_error = abs(taus_all) * 0.3, - Enrichment = enrichments_all, - Enrichment_std_error = enrichments_all * 0.2, - Enrichment_p = rep(0.01, n_cats), - `Prop._h2` = c(0.15, rep(0.425, n_baseline)), - `Prop._SNPs` = c(0.06, rep(0.47, n_baseline)), - check.names = FALSE, - stringsAsFactors = FALSE - ) - vroom::vroom_write(results, paste0(prefix, ".results"), delim = "\t") - - writeLines( - c( - "Analysis started at 2024-01-01", - sprintf("Total Observed scale h2: %g (0.05)", h2g), - "Analysis finished" - ), - paste0(prefix, ".log") - ) - - blocks <- matrix( - rnorm( - nBlocks * n_cats, - mean = rep(taus_all, each = nBlocks), - sd = abs(rep(taus_all, each = nBlocks)) * 0.5 - ), - nrow = nBlocks, - ncol = n_cats - ) - colnames(blocks) <- all_cats - vroom::vroom_write( - as.data.frame(blocks), - paste0(prefix, ".part_delete"), - delim = "\t" - ) - invisible(NULL) -} - -# Create polyfun output files for a joint run (target + baseline annotations) -.makePolyfunJoint <- function( - dir, - prefix, - target_names, - n_baseline = 3, - nBlocks = 10, - h2g = 0.3 -) { - target_cats <- paste0(target_names, "_0") - baseline_cats <- paste0("baselineLD_", seq_len(n_baseline) - 1L) - all_cats <- c(target_cats, baseline_cats) - n_cats <- length(all_cats) - - taus <- c(rep(1e-7, length(target_cats)), rep(1e-8, n_baseline)) - enrichments <- c(rep(2.0, length(target_cats)), rep(1.0, n_baseline)) - - results <- data.frame( - Category = all_cats, - Coefficient = taus, - Coefficient_std_error = abs(taus) * 0.3, - Enrichment = enrichments, - Enrichment_std_error = enrichments * 0.2, - Enrichment_p = rep(0.05, n_cats), - `Prop._h2` = rep(1 / n_cats, n_cats), - `Prop._SNPs` = rep(1 / n_cats, n_cats), - check.names = FALSE, - stringsAsFactors = FALSE - ) - vroom::vroom_write(results, paste0(prefix, ".results"), delim = "\t") - - writeLines( - c( - "Analysis started at 2024-01-01", - sprintf("Total Observed scale h2: %g (0.05)", h2g), - "Analysis finished" - ), - paste0(prefix, ".log") - ) - - blocks <- matrix( - rnorm( - nBlocks * n_cats, - mean = rep(taus, each = nBlocks), - sd = abs(rep(taus, each = nBlocks)) * 0.5 - ), - nrow = nBlocks, - ncol = n_cats - ) - colnames(blocks) <- all_cats - vroom::vroom_write( - as.data.frame(blocks), - paste0(prefix, ".part_delete"), - delim = "\t" - ) - invisible(NULL) -} - -# Build a complete fixture directory for the full pipeline -.makeSldscFixtures <- function(envir = parent.frame()) { - base_dir <- withr::local_tempdir(.local_envir = envir) - - anno_dir <- file.path(base_dir, "annot") - frq_dir <- file.path(base_dir, "frq") - out_dir <- file.path(base_dir, "output") - dir.create(anno_dir) - dir.create(frq_dir) - dir.create(out_dir) - - plink_name <- "ref_chr" - - # Annotation + freq files for 2 chromosomes - for (chr in 1:2) { - .makeAnnotGz(anno_dir, chr) - .make_frq(frq_dir, chr, plinkName = plink_name) - } - - targets <- c("annot_A", "annot_B") - - # Single-target runs: 2 targets x 2 traits - for (trait in c("traitX", "traitY")) { - for (i in seq_along(targets)) { - pref <- file.path( - out_dir, - sprintf("%s_single_%s", trait, targets[i]) - ) - .makePolyfunSingle( - out_dir, - pref, - targets[i], - h2g = 0.3 + (i - 1) * 0.05 - ) - } - } - - # Joint runs: 1 per trait - for (trait in c("traitX", "traitY")) { - pref <- file.path(out_dir, sprintf("%s_joint", trait)) - .makePolyfunJoint(out_dir, pref, targets, h2g = 0.3) - } - - list( - base_dir = base_dir, - anno_dir = anno_dir, - frq_dir = frq_dir, - out_dir = out_dir, - plinkName = plink_name, - targets = targets, - trait_names = c("traitX", "traitY") - ) -} +# In-memory S-LDSC fixtures shared by test_SldscData.R, test_sldscWrapper.R +# and test_sldscPostprocessingPipeline.R. # ============================================================================= # In-memory builders for SldscData / compute / pipeline tests (no file I/O) diff --git a/tests/testthat/helper-vcf.R b/tests/testthat/helper-vcf.R index d3ddbb6b..1c8651fd 100644 --- a/tests/testthat/helper-vcf.R +++ b/tests/testthat/helper-vcf.R @@ -101,10 +101,6 @@ ) } -.vcfOverlapDs <- function() { - `[<-`(.vcfOverlapGt(), 1L, , value = c(0.1, 0.9, 1.8)) -} - # Keep only the GT subfield of each sample column. .vcfGtOnly <- function(records, samples = c("s1", "s2", "s3")) { gt <- lapply(records[samples], sub, pattern = ":.*$", replacement = "") diff --git a/tests/testthat/test_AllClasses.R b/tests/testthat/test_AllClasses.R index cd2c097c..c4412104 100644 --- a/tests/testthat/test_AllClasses.R +++ b/tests/testthat/test_AllClasses.R @@ -17,7 +17,7 @@ context("AllClasses (virtual base classes)") format = "plink2", snpInfo = data.frame( SNP = paste0("rs", seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -29,9 +29,9 @@ context("AllClasses (virtual base classes)") ) } -.alc_makeGr <- function(n = 3) { +.alc_makeGr <- function(n = 3, chrom = "chr1") { gr <- GenomicRanges::GRanges( - "chr1", + chrom, IRanges::IRanges( start = seq(100L, by = 100L, length.out = n), width = 1L @@ -47,13 +47,13 @@ context("AllClasses (virtual base classes)") gr } -.alc_makeGwasSumStats <- function(qcInfo = list()) { +.alc_makeGwasSumStats <- function(qcOptions = list()) { GwasSumStats( studyName = "g1", entry = list(.alc_makeGr()), genome = "hg19", ldReference = .alc_makeHandle(), - qcInfo = qcInfo + qcOptions = qcOptions ) } @@ -75,7 +75,7 @@ context("AllClasses (virtual base classes)") posterior_sd = rep(0.02, n), stringsAsFactors = FALSE ) - fineMappingRow( + FineMappingRow( variantIds = tl$variant_id, susieFit = list(), topLoci = tl @@ -86,78 +86,219 @@ context("AllClasses (virtual base classes)") # SumStatsBase: studyName (inherited by QtlSumStats / GwasSumStats) # =========================================================================== -test_that("SumStatsBase: studyName on a GwasSumStats returns unique study names", { - ss <- .alc_makeGwasSumStats() - expect_equal(studyName(ss), "g1") +test_that("SumStatsBase: studyName on a GwasSumStats names each study once", { + # g1's variants span two chromosomes, so it is split into two rows and + # the study column repeats it; studyName() names each study once. + ss <- GwasSumStats( + studyName = c("g1", "g2"), + entry = list( + .alc_makeGr(chrom = c("chr1", "chr1", "chr2")), + .alc_makeGr() + ), + genome = "hg19", + ldReference = .alc_makeHandle() + ) + expect_identical(ss$study, c("g1", "g1", "g2")) + expect_identical(studyName(ss), c("g1", "g2")) }) # =========================================================================== # SumStatsBase: qcDiagnostics — every branch # =========================================================================== -test_that("SumStatsBase: qcDiagnostics returns NULL on empty qcInfo", { - ss <- .alc_makeGwasSumStats() # qcInfo = list() by default +test_that("SumStatsBase: qcDiagnostics returns NULL without per-row audits", { + # QC options recorded but no qcAudit column -> nothing to return. + ss <- .alc_makeGwasSumStats(qcOptions = list(step1 = "ok")) expect_null(qcDiagnostics(ss)) }) -test_that("SumStatsBase: qcDiagnostics returns NULL when entryAudit slot is absent", { - # qcInfo has steps but no entryAudit -> nothing to return. - ss <- .alc_makeGwasSumStats(qcInfo = list(step1 = "ok")) - expect_null(qcDiagnostics(ss)) +# A two-study GwasSumStats carrying one QC audit per row. +.alc_twoStudyQc <- function(audits) { + x <- GwasSumStats( + studyName = c("g1", "g2"), + entry = list(.alc_makeGr(), .alc_makeGr()), + genome = "hg19", + ldReference = .alc_makeHandle(), + qcOptions = list(step1 = "ok") + ) + x$qcAudit <- S4Vectors::SimpleList(audits) + x +} + +.alc_diagQc <- function(...) { + list(...) +} + +test_that("SumStatsBase: qcDiagnostics returns the selected study's table", { + diag1 <- data.frame(SNP = "rs1", outlier = FALSE) + diag2 <- data.frame(SNP = "rs2", outlier = TRUE) + ss <- .alc_twoStudyQc(.alc_diagQc( + list(ldMismatchDiagnostics = diag1), + list(ldMismatchDiagnostics = diag2) + )) + out <- qcDiagnostics(ss, studyName = "g2") + expect_s4_class(out, "DataFrame") + expect_equal(as.data.frame(out), diag2) + expect_equal(as.data.frame(qcDiagnostics(ss, studyName = "g1")), diag1) + # Two studies and no selector: which one is meant cannot be known. + expect_error(qcDiagnostics(ss), "2 studies") }) -test_that("SumStatsBase: qcDiagnostics returns the per-entry diagnostics by index", { - diag1 <- data.frame(SNP = "rs1", outlier = FALSE, stringsAsFactors = FALSE) - diag2 <- data.frame(SNP = "rs2", outlier = TRUE, stringsAsFactors = FALSE) - qc <- list( - entryAudit = list( - list(ldMismatchDiagnostics = diag1), - list(ldMismatchDiagnostics = diag2) +test_that("SumStatsBase: qcDiagnostics is NULL for a selection without one", { + ss <- .alc_twoStudyQc(.alc_diagQc( + list(ldMismatchDiagnostics = data.frame(SNP = "rs1")), + list(other = "no diagnostics here") + )) + expect_null(qcDiagnostics(ss, studyName = "g2")) +}) + +test_that("SumStatsBase: qcDiagnostics stacks a split study's rows", { + data(gwasSumStatsS4Example) + g <- gwasSumStatsS4Example + split <- GwasSumStats( + studyName = "trait1", + entry = list(sumStats(g)), + genome = "hg19", + ldReference = ldReference(g)[[1L]], + qcOptions = list(step1 = "ok"), + region = GenomicRanges::GRanges( + "chr22", + IRanges::IRanges(c(1L, 15680321L), c(15680320L, 51304566L)) ) ) - ss <- .alc_makeGwasSumStats(qcInfo = qc) - expect_identical(qcDiagnostics(ss, entry = 1L), diag1) - expect_identical(qcDiagnostics(ss, entry = 2L), diag2) + split$qcAudit <- S4Vectors::SimpleList(.alc_diagQc( + list(ldMismatchDiagnostics = data.frame(SNP = "rs1")), + list(ldMismatchDiagnostics = data.frame(SNP = c("rs2", "rs3"))) + )) + expect_equal(nrow(split), 2L) + expect_equal(qcDiagnostics(split)$SNP, c("rs1", "rs2", "rs3")) }) -test_that("SumStatsBase: qcDiagnostics(entry = NULL) returns the populated entries only", { - diag1 <- data.frame(SNP = "rs1", outlier = FALSE, stringsAsFactors = FALSE) - # Entry 2's audit has no ldMismatchDiagnostics field; should be filtered. - qc <- list( - entryAudit = list( - list(ldMismatchDiagnostics = diag1), - list(other = "no diagnostics here") - ) +test_that("subsetting keeps each element's QC audit with it", { + # Each row's audit is a column of mcols(), so it subsets with the row: a + # subset never reports another element's diagnostics. + diag2 <- data.frame(SNP = "rs2", outlier = TRUE) + ss <- .alc_twoStudyQc(.alc_diagQc( + list(ldMismatchDiagnostics = data.frame(SNP = "rs1")), + list(ldMismatchDiagnostics = diag2) + )) + expect_equal(as.data.frame(qcDiagnostics(ss[2])), diag2) + expect_length(ss[2]$qcAudit, 1L) + expect_equal(as.data.frame(qcDiagnostics(ss[c(FALSE, TRUE)])), diag2) + expect_equal(as.data.frame(qcDiagnostics(ss[-1])), diag2) + # A collection without an audit subsets as before. + expect_null(.alc_makeGwasSumStats()[1]$qcAudit) +}) + +# =========================================================================== +# SumStatsBase: qcInfo / qcOptions, and the saved-object migration +# =========================================================================== + +test_that("qcInfo() is one row per tuple: its identity, then each count", { + ss <- .alc_twoStudyQc(.alc_diagQc( + list( + variantsIn = 10L, + contentFilters = list(nDropped = 2L), + ldMismatchDiagnostics = data.frame(SNP = "rs1") + ), + list(variantsIn = 8L) + )) + info <- qcInfo(ss) + expect_s4_class(info, "DataFrame") + expect_equal(info$study, c("g1", "g2")) + expect_equal(info$variantsIn, c(10L, 8L)) + # A nested count is named by its path; a row the step skipped is NA. + expect_equal(info$contentFilters.nDropped, c(2L, NA)) + # A per-variant table is qcDiagnostics()'s, never a column here. + expect_false(is_in("ldMismatchDiagnostics", colnames(info))) +}) + +test_that("qcInfo() before QC names the rows and records nothing", { + info <- qcInfo(.alc_makeGwasSumStats()) + expect_equal(nrow(info), 1L) + expect_equal(colnames(info), c("study", "blockId")) +}) + +test_that("an audit that is not a list contributes no counts", { + expect_equal(pecotmr:::.qcAuditScalars(NULL), list()) + expect_equal(pecotmr:::.qcAuditScalars(list()), list()) + expect_equal(pecotmr:::.qcAuditScalars(data.frame(a = 1)), list()) + # Only scalars are counts: a vector is left out. + expect_equal( + pecotmr:::.qcAuditScalars(list(a = 1L, b = 1:3)), + list(a = 1L) ) - ss <- .alc_makeGwasSumStats(qcInfo = qc) - out <- qcDiagnostics(ss, entry = NULL) - expect_type(out, "list") - expect_equal(length(out), 1L) - expect_named(out, "1") - expect_identical(out[["1"]], diag1) }) -test_that("SumStatsBase: qcDiagnostics(entry = NULL) returns NULL when no entry has diagnostics", { - qc <- list(entryAudit = list(list(other = 1), list(other = 2))) - ss <- .alc_makeGwasSumStats(qcInfo = qc) - expect_null(qcDiagnostics(ss, entry = NULL)) +test_that("qcOptions() returns the settings, separate from the audits", { + ss <- .alc_makeGwasSumStats(qcOptions = list(step1 = "ok")) + expect_equal(qcOptions(ss), list(step1 = "ok")) + expect_equal(qcOptions(.alc_makeGwasSumStats()), list()) }) -test_that("SumStatsBase: qcDiagnostics errors on out-of-range entry", { - qc <- list( - entryAudit = list(list(ldMismatchDiagnostics = data.frame(z = 1))) +test_that(".rowQcAudit reads one row's audit, NULL where there is none", { + ss <- .alc_twoStudyQc(.alc_diagQc(list(a = 1), list(a = 2))) + expect_equal(pecotmr:::.rowQcAudit(ss, 2L), list(a = 2)) + expect_null(pecotmr:::.rowQcAudit(ss, 3L)) + expect_null(pecotmr:::.rowQcAudit(.alc_makeGwasSumStats(), 1L)) +}) + +# `x` as it was saved before the per-row audits moved into mcols(): the +# whole QC record in a `qcInfo` slot, and no `qcOptions` slot. +.alc_savedWithQcInfo <- function(x, qcInfo) { + attr(x, "qcOptions") <- NULL + attr(x, "qcInfo") <- qcInfo + x +} + +test_that("updateObject() splits a saved QC record into options and audits", { + ss <- .alc_twoStudyQc(.alc_diagQc(list(), list())) + ss$qcAudit <- NULL + saved <- .alc_savedWithQcInfo( + ss, + list( + step1 = "ok", + entryAudit = list(list(variantsIn = 3L), list(variantsIn = 4L)) + ) ) - ss <- .alc_makeGwasSumStats(qcInfo = qc) - expect_error(qcDiagnostics(ss, entry = 0L), "must be a single integer") - expect_error(qcDiagnostics(ss, entry = 99L), "must be a single integer") - expect_error( - qcDiagnostics(ss, entry = c(1L, 2L)), - "must be a single integer" + up <- updateObject(saved) + expect_true(validObject(up)) + expect_null(attr(up, "qcInfo", exact = TRUE)) + expect_equal(qcOptions(up), list(step1 = "ok")) + expect_equal(qcInfo(up)$variantsIn, c(3L, 4L)) +}) + +test_that("updateObject() keeps the options of a record with no audits", { + ss <- .alc_makeGwasSumStats() + up <- updateObject(.alc_savedWithQcInfo(ss, list(step1 = "ok"))) + expect_equal(qcOptions(up), list(step1 = "ok")) + expect_null(up$qcAudit) +}) + +test_that("updateObject() drops audits it cannot match to rows, saying so", { + ss <- .alc_twoStudyQc(.alc_diagQc(list(), list())) + ss$qcAudit <- NULL + saved <- .alc_savedWithQcInfo( + ss, + list( + step1 = "ok", + entryAudit = list(list(variantsIn = 3L)) + ) ) - expect_error( - qcDiagnostics(ss, entry = "first"), - "must be a single integer" + expect_warning( + up <- updateObject(saved), + "1 row audit\\(s\\) for 2 row\\(s\\)" ) + expect_equal(qcOptions(up), list(step1 = "ok")) + expect_null(up$qcAudit) +}) + +test_that("updateObject() leaves a current summary-statistics object as is", { + ss <- .alc_makeGwasSumStats(qcOptions = list(step1 = "ok")) + up <- updateObject(ss, verbose = FALSE) + expect_equal(qcOptions(up), list(step1 = "ok")) + expect_equal(as.list(up), as.list(ss)) + expect_message(updateObject(ss, verbose = TRUE), "updateObject") }) # =========================================================================== @@ -193,47 +334,115 @@ test_that("FineMappingResultBase: adjustPips on a zero-row collection returns th ) } -test_that("topLoci(): a pinned single entry returns a GRanges", { - fmr <- .alc_makeFmr2() - gr <- topLoci( - fmr, - studyName = "Q1", +test_that("topLoci() has no type switch: the stored table stays internal", { + # `raw = TRUE` once returned the stored table, a data.frame, from the same + # accessor that otherwise returns ranges. + expect_error(topLoci(.alc_makeFmr2(), raw = TRUE), "unused argument") +}) + +test_that("QtlFineMappingResult: topLoci aggregates entries when selectors do not pin one", { + # Two entries, no selectors: the old behaviour errored ("2 entries; pass + # study/context/trait/method"). Now it stacks the per-variant tables, + # prefixed with the row identity so variants stay attributable. + e1 <- .sc_makeFineMappingRow(3) + e2 <- .sc_makeFineMappingRow(2) + res <- QtlFineMappingResult( + studyName = c("s1", "s1"), + context = c("c1", "c2"), + trait = c("t1", "t1"), + method = c("susie", "susie"), + entry = list(e1, e2) + ) + agg <- topLoci(res, signalCutoff = 0) + expect_s4_class(agg, "GRanges") + expect_equal(length(agg), 5L) + expect_true(all( + c("study", "context", "trait", "blockId", "method") %in% + names(S4Vectors::mcols(agg)) + )) + expect_equal(agg$context, c("c1", "c1", "c1", "c2", "c2")) + expect_true("variant_id" %in% names(S4Vectors::mcols(agg))) + # QTL results key on context/trait, so blockId is NA-filled. + expect_true(all(is.na(agg$blockId))) + # the added per-variant `method` must not duplicate the identity column + expect_equal(sum(names(S4Vectors::mcols(agg)) == "method"), 1L) +}) + +test_that("QtlFineMappingResult: topLoci with a full tuple keeps the bare (id-free) table", { + e1 <- .sc_makeFineMappingRow(3) + e2 <- .sc_makeFineMappingRow(2) + res <- QtlFineMappingResult( + studyName = c("s1", "s1"), + context = c("c1", "c2"), + trait = c("t1", "t1"), + method = c("susie", "susie"), + entry = list(e1, e2) + ) + tl <- topLoci( + res, + studyName = "s1", context = "c1", trait = "t1", - method = "susie" + method = "susie", + signalCutoff = 0 ) - expect_s4_class(gr, "GRanges") + expect_s4_class(tl, "GRanges") + expect_equal(length(tl), 3L) + # single-entry fast path, unchanged + expect_false(is_in("context", names(S4Vectors::mcols(tl)))) }) -test_that("topLoci(): aggregating >1 entry also returns a GRanges", { - # Converting to ranges after stacking is what makes this work: the - # row-identity columns become mcols. The old type = "GRanges" branch had - # to refuse anything but a single pinned entry. - gr <- topLoci(.alc_makeFmr2()) - expect_s4_class(gr, "GRanges") - expect_true(all( - c("study", "context", "trait", "method") %in% - names(S4Vectors::mcols(gr)) - )) +test_that("QtlFineMappingResult: topLoci aggregates only the matching subset", { + e1 <- .sc_makeFineMappingRow(3) + e2 <- .sc_makeFineMappingRow(2) + res <- QtlFineMappingResult( + studyName = c("s1", "s1"), + context = c("c1", "c2"), + trait = c("t1", "t1"), + method = c("susie", "susie"), + entry = list(e1, e2) + ) + sub <- topLoci(res, context = "c2", signalCutoff = 0) + expect_equal(length(sub), 2L) + expect_equal(unique(sub$context), "c2") }) -test_that("topLoci(raw = TRUE) stays a table", { - # The stored canonical table has no posterior projection to put on a - # range, so raw is the one form that is not a GRanges. - raw <- topLoci(.alc_makeFmr2(), raw = TRUE) - expect_true(is.data.frame(raw)) +test_that("QtlFineMappingResult: topLoci on a single-row collection still carries identity columns", { + # A no-selector call takes the aggregate path even for one row, so the PIP + # table has a uniform shape (identity columns present) whatever the row count + # -- callers don't special-case single-entry results. + row <- .sc_makeFineMappingRow(4) + res <- QtlFineMappingResult( + studyName = "s1", + context = "c1", + trait = "t1", + method = "susie", + entry = list(row) + ) + tl <- topLoci(res, signalCutoff = 0) + expect_equal(length(tl), 4L) + # The row's own (projected) table, variant for variant. + expect_equal( + tl$variant_id, + .fmrRowTopLoci(row, signalCutoff = 0)$variant_id + ) + expect_true(all( + c("study", "context", "trait", "method", "variant_id") %in% + names(S4Vectors::mcols(tl)) + )) + expect_equal(unique(tl$context), "c1") }) -test_that("FineMappingResultBase aggregate view: empty per-entry views -> 0-row frame", { +test_that("aggregate view: empty per-entry views give empty ranges", { # .alc_makeFmEntry has no credible sets, so credibleSets aggregates to nothing. - expect_equal(nrow(credibleSets(.alc_makeFmr2())), 0L) + expect_length(credibleSets(.alc_makeFmr2()), 0L) }) test_that("FineMappingResultBase aggregate view: a no-match selector re-raises the selection error", { expect_error(credibleSets(.alc_makeFmr2(), studyName = "nope"), "entries") }) -test_that("FineMappingResultBase aggregate view: an empty collection yields a 0-row frame", { +test_that("aggregate view: an empty collection gives empty ranges", { empty <- QtlFineMappingResult( studyName = character(0), context = character(0), @@ -242,10 +451,9 @@ test_that("FineMappingResultBase aggregate view: an empty collection yields a 0- entry = list(), ldReference = .alc_makeHandle() ) - expect_equal(nrow(credibleSets(empty)), 0L) + expect_length(credibleSets(empty), 0L) }) - # =========================================================================== # Variant reconciliation: intersectVariants + retainedMass # =========================================================================== @@ -266,7 +474,7 @@ test_that("FineMappingResultBase aggregate view: an empty collection yields a 0- ) alpha <- lbfToAlpha(lbf) pip <- as.numeric(1 - apply(1 - alpha, 2, prod)) - e <- fineMappingRow( + e <- FineMappingRow( vids, list( pip = pip, @@ -341,7 +549,7 @@ test_that("intersectVariants matches variants allele-aware", { expect_length(unlist(out$x, use.names = FALSE), 6L) }) -test_that("retainedMass reports per-effect surviving mass", { +test_that("retainedMass is each effect's pre-renormalization surviving mass", { x <- .rc_makeFmr(.rc_vids(1:40)) adj <- adjustPips(x, .rc_vids(1:20)) mass <- retainedMass(adj) @@ -352,17 +560,11 @@ test_that("retainedMass reports per-effect surviving mass", { expect_equal(unique(mass$nVariants), 20L) # Identity columns come along so the diagnostic is attributable. expect_true(all(c("study", "context", "trait", "method") %in% names(mass))) -}) -test_that("retainedMass is the PRE-renormalization share", { # After renormalization every effect row sums to 1, so the surviving share # is only knowable at adjustment time. A value of 1 across the board would # mean the diagnostic was reading the post-normalized alpha. - x <- .rc_makeFmr(.rc_vids(1:40)) - adj <- adjustPips(x, .rc_vids(1:20)) - mass <- retainedMass(adj) expect_false(all(abs(mass$retainedMass - 1) < 1e-9)) - fit <- susieFit(pecotmr:::.collectionEntry(adj, 1L)) expect_equal(rowSums(fit$alpha), rep(1, 3L), tolerance = 1e-10) }) @@ -389,7 +591,8 @@ test_that("retainedMass: empty result has the populated result's schema", { full <- retainedMass(both$x) expect_gt(nrow(full), 0L) expect_equal(colnames(empty), colnames(full)) - expect_equal(nrow(bind_rows(empty, full)), nrow(full)) + expect_s4_class(full, "DataFrame") + expect_equal(nrow(rbind(empty, full)), nrow(full)) }) test_that("retainedMass: identity columns follow the concrete class", { @@ -400,7 +603,6 @@ test_that("retainedMass: identity columns follow the concrete class", { expect_false(any(is_in(c("context", "trait"), cols))) }) - # --------------------------------------------------------------------------- # variantIds on SumStatsBase. # @@ -425,7 +627,10 @@ test_that("variantIds renders ids the same way the row classes do", { data(qtlSumStatsExample, envir = environment()) expect_equal( variantIds(qtlSumStatsExample), - as.data.frame(qtlSumStatsExample, require = "Z")$variant_id + pecotmr:::.entryToSumstatDf( + sumStats(qtlSumStatsExample), + require = "Z" + )$variant_id ) expect_match(variantIds(qtlSumStatsExample)[[1L]], "^chr[^:]+:\\d+:") }) @@ -449,7 +654,7 @@ test_that("variantIds defers the ambiguity error to the class", { data(qtlSumStatsMulticontextExample, envir = environment()) expect_error( variantIds(qtlSumStatsMulticontextExample), - "Pass `study`, `context`, and `trait`" + "Pass `studyName`, `context`, and `trait`" ) }) @@ -458,11 +663,138 @@ test_that("variantIds on an empty collection defers too", { expect_error(variantIds(qtlSumStatsExample[0]), "no rows") }) +# =========================================================================== +# Fit coverage: a row narrowed after its fit +# +# Narrowing a row's variants leaves its fit as it was made. Every reader of +# the fit says so, and nothing is rescaled. +# =========================================================================== + +# `x` with every row narrowed to its first `k` variants, its fits untouched. +.alc_narrowed <- function(x, k) { + endoapply(x, utils::head, k) +} + +test_that("a fine-mapping row keeps its fit's variants when narrowed", { + x <- .rc_makeFmr(.rc_vids(1:10)) + expect_equal(as.character(x$fitVariants[[1L]]), .rc_vids(1:10)) + narrowed <- .alc_narrowed(x, 4L) + expect_length(narrowed[[1L]], 4L) + expect_equal(as.character(narrowed$fitVariants[[1L]]), .rc_vids(1:10)) +}) + +test_that("reading a narrowed row's fit warns and returns it unchanged", { + x <- .rc_makeFmr(.rc_vids(1:10)) + narrowed <- .alc_narrowed(x, 4L) + expect_warning( + fit <- susieFit(narrowed), + "made with 10 variants, 6 of which this row no longer holds" + ) + expect_identical(fit, susieFit(x)) + expect_warning( + credibleSetSummary(narrowed), + "credibleSetSummary\\(\\): 1 row" + ) + # The rows that hold every variant of their fit read silently. + expect_no_warning(susieFit(x)) + expect_no_warning(lbf(x)) + expect_no_warning(credibleSetSummary(x)) +}) + +test_that("lbf() of a narrowed row keeps the held variants' values as fitted", { + x <- .rc_makeFmr(.rc_vids(1:10)) + expect_warning(out <- lbf(.alc_narrowed(x, 4L)), "lbf\\(\\): 1 row") + full <- lbf(x) + expect_equal(out$variant_id, .rc_vids(1:4)) + expect_equal( + as.data.frame(mcols(out)), + as.data.frame(mcols(full))[1:4, , drop = FALSE] + ) +}) + +test_that("the fSuSiE readers warn on a narrowed row too", { + data(fsusieFineMappingExample, envir = environment()) + narrowed <- .alc_narrowed(fsusieFineMappingExample, 3L) + expect_warning(fsusieCredibleBand(narrowed), "fsusieCredibleBand") + expect_warning(fsusieTraitEffects(narrowed), "fsusieTraitEffects") + expect_warning(fsusieAffectedRegions(narrowed), "fsusieAffectedRegions") +}) + +test_that("intersectVariants restricts a narrowed row's fit by id", { + # The route the coverage warning points to. The kept variants are found + # in the fit by id, so a row narrowed before reconciling restricts the + # fit's own columns rather than failing on the width mismatch. + x <- .rc_makeFmr(.rc_vids(1:30)) + y <- .rc_makeFmr(.rc_vids(5:50), studyName = "s2") + narrowed <- endoapply(x, utils::tail, 20L) + out <- intersectVariants(narrowed, y, oneSided = TRUE) + expect_no_warning(fit <- susieFit(out)) + expect_equal(colnames(fit$alpha), .rc_vids(11:30)) + kept <- susieFit(x)$alpha[, .rc_vids(11:30)] + expect_equal(unname(fit$alpha), unname(kept / rowSums(kept))) + expect_equal(as.character(out$fitVariants[[1L]]), .rc_vids(11:30)) +}) + +test_that("updateObject() backfills the variants each fit was made with", { + x <- .rc_makeFmr(.rc_vids(1:10)) + saved <- x + saved$fitVariants <- NULL + expect_equal( + as.character(updateObject(saved)$fitVariants[[1L]]), + .rc_vids(1:10) + ) + # A row narrowed before it was saved: its fit still names all ten. + savedNarrowed <- .alc_narrowed(x, 4L) + savedNarrowed$fitVariants <- NULL + up <- updateObject(savedNarrowed) + expect_equal(as.character(up$fitVariants[[1L]]), .rc_vids(1:10)) + expect_warning(susieFit(up), "no longer holds") + # A current collection is left as it is. + expect_identical(updateObject(x)$fitVariants, x$fitVariants) + expect_message(updateObject(x, verbose = TRUE), "updateObject") +}) + +test_that("updateObject(): an unnamed fit records its row, no fit none", { + vids <- .rc_vids(1:3) + tl <- data.frame(variant_id = vids, pip = c(0.5, 0.3, 0.2)) + saved <- QtlFineMappingResult( + studyName = c("s1", "s2"), + context = c("c1", "c1"), + trait = c("g1", "g1"), + method = c("susie", "susie"), + entry = list( + FineMappingRow(vids, list(pip = c(0.5, 0.3, 0.2)), tl), + FineMappingRow(vids, NULL, tl) + ) + ) + saved$fitVariants <- NULL + up <- updateObject(saved) + expect_equal(as.character(up$fitVariants[[1L]]), vids) + expect_equal(as.character(up$fitVariants[[2L]]), character(0)) +}) + +test_that(".fitNamedVariants reads a fit's names, never susieR's null column", { + f <- pecotmr:::.fitNamedVariants + expect_equal(f(NULL), character(0)) + expect_equal(f(list()), character(0)) + # A null_weight fit: one more effect-matrix column, named "null". + alpha <- matrix(0.5, 1L, 3L, dimnames = list(NULL, c("v1", "v2", "null"))) + expect_equal(f(list(alpha = alpha)), c("v1", "v2")) + expect_equal( + f(list(pip = c(v1 = 0.1, v2 = 0.2), alpha = alpha)), + c("v1", "v2") + ) + lbfMat <- matrix(0, 1L, 2L, dimnames = list(NULL, c("a", "b"))) + expect_equal(f(list(lbf_variable = lbfMat)), c("a", "b")) + # fSuSiE names its variables on csd_X. + expect_equal(f(list(csd_X = c(x1 = 1, x2 = 2))), c("x1", "x2")) +}) + # =========================================================================== # adjustPips: entries that share no variant with `keepVariants` # # The zero-row short-circuit is covered above and the all-overlap path by -# test_ColocResult; the two partial/disjoint branches were not. +# test_fineMappingRow.R; these are the partial and disjoint branches. # =========================================================================== # Two entries built by .rc_makeFmr (which carries a real alpha matrix, as @@ -490,7 +822,7 @@ test_that("adjustPips refuses a keepVariants set disjoint from every entry", { }) test_that("adjustPips drops non-overlapping entries and says so", { - # Matches subsetRegion's rule: an element that trims to zero variants + # As with range subsetting: an element that trims to zero variants # goes away rather than lingering unadjusted. expect_message( out <- adjustPips(.ac_twoEntry(), .rc_vids(1:5)), @@ -500,16 +832,35 @@ test_that("adjustPips drops non-overlapping entries and says so", { expect_equal(as.character(mcols(out)$study), "s1") }) +test_that("adjustPips on a FineMappingResultBase collection renormalizes each entry", { + vidsA <- paste0("chr1:", 1:6, ":A:G") + vidsB <- paste0("chr1:", 3:8, ":A:G") + entryA <- .makeAdjustEntry(vidsA) + entryB <- .makeAdjustEntry(vidsB) + fmr <- QtlFineMappingResult( + studyName = c("s1", "s1"), + context = c("c1", "c2"), + trait = c("g1", "g1"), + method = c("susie", "susie"), + entry = list(entryA, entryB) + ) + # Keep only variants shared by both entries' raw sets. + keep <- intersect(vidsA, vidsB) + adj <- adjustPips(fmr, keep) + expect_s4_class(adj, "QtlFineMappingResult") + expect_equal(nrow(adj), 2L) + expect_equal(variantIds(pecotmr:::.collectionEntry(adj, 1L)), keep) + expect_equal(variantIds(pecotmr:::.collectionEntry(adj, 2L)), keep) +}) # =========================================================================== -# .ssStitchElements()'s `ranges` filter +# .ssStitchElements()'s `window` filter # -# sumStats(x, ranges = ) is a documented argument that nothing exercised: -# every call left it NULL and returned through the early exit, so the -# chromosome test and the overlap intersection were both cold. +# The pipelines narrow a tuple to the span a pair's weights reach; the +# public sumStats() returns the whole tuple. # =========================================================================== -test_that("sumStats(ranges=) narrows the variants to the window", { +test_that(".ssStitchElements() narrows the variants to a window", { data(gwasSumStatsS4Example) full <- sumStats(gwasSumStatsS4Example) span <- range(GenomicRanges::start(full)) @@ -520,24 +871,23 @@ test_that("sumStats(ranges=) narrows the variants to the window", { span[[1L]] + (span[[2L]] - span[[1L]]) %/% 4L ) ) - sub <- sumStats(gwasSumStatsS4Example, ranges = win) + sub <- pecotmr:::.ssStitchElements(gwasSumStatsS4Example, 1L, win) expect_s4_class(sub, "GRanges") expect_lt(length(sub), length(full)) expect_gt(length(sub), 0L) expect_true(all(IRanges::overlapsAny(sub, win))) }) -test_that("sumStats(ranges=) on another chromosome returns nothing", { +test_that(".ssStitchElements() on another chromosome returns nothing", { # The chromosome test short-circuits before overlapsAny(), which would # otherwise warn about disjoint seqlevels. data(gwasSumStatsS4Example) off <- GenomicRanges::GRanges("chrZZ", IRanges::IRanges(1L, 100L)) - sub <- suppressWarnings(sumStats(gwasSumStatsS4Example, ranges = off)) + sub <- pecotmr:::.ssStitchElements(gwasSumStatsS4Example, 1L, off) expect_s4_class(sub, "GRanges") expect_equal(length(sub), 0L) }) - test_that("the genome check names a missing build and a mixed one", { f <- pecotmr:::.sumStatsCheckGenome gr <- GenomicRanges::GRanges( @@ -554,7 +904,6 @@ test_that("the genome check names a missing build and a mixed one", { expect_null(f(gr)) }) - test_that("an empty collection has no variants", { setClass( "RcEmptyKid", @@ -562,7 +911,7 @@ test_that("an empty collection has no variants", { representation( genome = "character", ldReference = "ANY", - qcInfo = "list" + qcOptions = "list" ) ) empty <- new( @@ -570,7 +919,7 @@ test_that("an empty collection has no variants", { GenomicRanges::GRangesList(), genome = "hg38", ldReference = NULL, - qcInfo = list() + qcOptions = list() ) expect_equal(nrow(empty), 0L) expect_equal(pecotmr:::.rcAllVariants(empty), character(0)) @@ -585,11 +934,11 @@ test_that("retained mass is NULL for a fit that never went through reconciliatio }) # =========================================================================== -# Variant-level replacement: af<- / maf<- / nSamples<- dispatch on `value` +# Variant-level replacement: af<- / maf<- / sampleSize<- dispatch on `value` # =========================================================================== -# A replacement GRanges over the same variants as `x`, with the alleles in -# the given orientation and one payload column. +# A fillFromReference() reference over the same variants as `x`, with the +# alleles in the given orientation and one value column. .alc_replacementGr <- function(x, swap = FALSE, k = NULL, payload = 0.3) { ids <- variantIds(x) p <- parseVariantId(ids) @@ -623,7 +972,7 @@ test_that("af<- numeric is positional and checks length hard", { expect_error(af(x) <- 0.3, "one value per variant") }) -test_that("maf<- and nSamples<- numeric are positional too", { +test_that("maf<- and sampleSize<- numeric are positional too", { data(qtlSumStatsExample) x <- qtlSumStatsExample n <- length(variantIds(x)) @@ -632,21 +981,29 @@ test_that("maf<- and nSamples<- numeric are positional too", { maf(x) <- seq(0.05, 0.2, length.out = n) expect_equal(length(maf(x)), n) expect_equal(maf(x)[[1L]], 0.05) - nSamples(x) <- rep(1234, n) - expect_equal(unique(nSamples(x)), 1234) + sampleSize(x) <- rep(1234, n) + expect_equal(unique(sampleSize(x)), 1234) expect_error(maf(x) <- c(0.1, 0.2), "one value per variant") - expect_error(nSamples(x) <- 1L, "one value per variant") + expect_error(sampleSize(x) <- 1L, "one value per variant") }) -test_that("a GRanges replacement warns about variants it could not place", { +test_that("maf returns NULL when MAF column is absent, vector when present", { + obj_no_maf <- .qtlMakeOne(with_maf = FALSE) + expect_null(maf(obj_no_maf)) + + obj_maf <- .qtlMakeOne(n = 4, with_maf = TRUE) + expect_equal(length(maf(obj_maf)), 4L) +}) + +test_that("fillFromReference warns about variants it could not place", { data(qtlSumStatsExample) x <- qtlSumStatsExample gr <- .alc_replacementGr(x, payload = 0.4) # Two variants shifted far enough to match nothing. Silently dropping - # them would hide a mis-joined replacement table, so it warns and says + # them would hide a mis-joined reference table, so it warns and says # how many were ignored. extra <- GenomicRanges::shift(gr[1:2], 10000000L) - expect_warning(af(x) <- c(gr, extra), "were ignored") + expect_warning(x <- fillFromReference(x, c(gr, extra)), "were ignored") expect_equal(unique(af(x)), 0.4) }) @@ -664,33 +1021,27 @@ test_that("the variant-level setters work on a GwasSumStats as well", { ) }) -test_that("af<- GRanges matches on (chrom, pos, A1, A2) regardless of order", { +test_that("fillFromReference matches on (chrom, pos, A1, A2) in any order", { data(qtlSumStatsExample) x <- qtlSumStatsExample gr <- .alc_replacementGr(x, payload = 0.25) - af(x) <- gr[rev(seq_along(gr))] + x <- fillFromReference(x, gr[rev(seq_along(gr))]) expect_equal(unique(af(x)), 0.25) }) -test_that("a flip complements af but leaves maf and nSamples alone", { +test_that("a flip complements AF but leaves MAF and N alone", { data(qtlSumStatsExample) x <- qtlSumStatsExample swapped <- .alc_replacementGr(x, swap = TRUE, payload = 0.3) - # An allele swap sends af -> 1 - af. maf is min(af, 1 - af) and nSamples - # is a count, so both are swap-invariant -- complementing them would - # corrupt them. - y <- x - af(y) <- swapped - expect_equal(unique(af(y)), 0.7) - z <- x - maf(z) <- swapped - expect_equal(unique(maf(z)), 0.3) - w <- x - nSamples(w) <- swapped - expect_equal(unique(nSamples(w)), 0.3) -}) - -test_that("af<- GRanges requires A1/A2 and exactly one payload column", { + # An allele swap sends af -> 1 - af. maf is min(af, 1 - af) and the + # sample size is a count, so both are swap-invariant -- complementing + # them would corrupt them. + expect_equal(unique(af(fillFromReference(x, swapped, "AF"))), 0.7) + expect_equal(unique(maf(fillFromReference(x, swapped, "MAF"))), 0.3) + expect_equal(unique(sampleSize(fillFromReference(x, swapped, "N"))), 0.3) +}) + +test_that("fillFromReference requires A1/A2 and says which column it read", { data(qtlSumStatsExample) x <- qtlSumStatsExample n <- length(variantIds(x)) @@ -702,18 +1053,35 @@ test_that("af<- GRanges requires A1/A2 and exactly one payload column", { S4Vectors::mcols(bare) <- S4Vectors::DataFrame(v = rep(0.3, n)) # Without A1/A2 a flip cannot be detected, so the value cannot be # oriented and the write is refused rather than guessed at. - expect_error(af(x) <- bare, "must carry A1 and A2") + expect_error(fillFromReference(x, bare), "must carry A1 and A2") + # Two value columns, neither named like the target: which one is meant + # cannot be known, so it is refused rather than guessed. two <- .alc_replacementGr(x) S4Vectors::mcols(two)$extra <- 1 - expect_error(af(x) <- two, "exactly one value column") + expect_error( + fillFromReference(x, two), + "has no `AF` column.*the one column besides A1/A2 \\(got 2: v, extra" + ) +}) + +test_that("fillFromReference reads the column named like the target", { + data(qtlSumStatsExample) + x <- qtlSumStatsExample + # A panel carries several per-variant columns at once; the one named + # like the target is read, whatever else rides along. + panel <- .alc_replacementGr(x, payload = 0.1) + S4Vectors::mcols(panel)$AF <- 0.6 + S4Vectors::mcols(panel)$MAF <- 0.4 + expect_equal(unique(af(fillFromReference(x, panel, "AF"))), 0.6) + expect_equal(unique(maf(fillFromReference(x, panel, "MAF"))), 0.4) }) -test_that("af<- sets NA for entry variants the replacement omits", { +test_that("fillFromReference sets NA for variants the reference omits", { data(qtlSumStatsExample) x <- qtlSumStatsExample n <- length(variantIds(x)) partial <- .alc_replacementGr(x, k = 5L, payload = 0.42) - expect_warning(af(x) <- partial, "were set NA") + expect_warning(x <- fillFromReference(x, partial), "were set NA") a <- af(x) # Unknown, not unchanged. expect_equal(sum(!is.na(a)), 5L) @@ -721,7 +1089,7 @@ test_that("af<- sets NA for entry variants the replacement omits", { expect_equal(unique(a[!is.na(a)]), 0.42) }) -test_that("af<- refuses a replacement that matches nothing", { +test_that("fillFromReference refuses a reference that matches nothing", { data(qtlSumStatsExample) x <- qtlSumStatsExample far <- GenomicRanges::GRanges( @@ -733,5 +1101,343 @@ test_that("af<- refuses a replacement that matches nothing", { A2 = rep("G", 3), v = c(0.1, 0.2, 0.3) ) - expect_error(af(x) <- far, "no variant in the replacement matches") + expect_error(fillFromReference(x, far), "no variant in `reference` matches") +}) + +test_that("fillFromReference checks what it is handed", { + data(qtlSumStatsExample) + data(gwasSumStatsS4Example) + gr <- .alc_replacementGr(qtlSumStatsExample) + expect_error(fillFromReference(sumStats(qtlSumStatsExample), gr), "x") + expect_error( + fillFromReference(qtlSumStatsExample, as.data.frame(gr)), + "reference" + ) + expect_error( + fillFromReference(qtlSumStatsExample, gr, column = "BETA"), + "must be one of" + ) + # A GWAS collection is keyed by study alone, so a QTL selector is refused + # exactly as the positional setter refuses it. + expect_error( + fillFromReference(gwasSumStatsS4Example, gr, context = "brain"), + "context" + ) +}) + +# =========================================================================== +# A GWAS study split across rows: one study, several elements +# =========================================================================== + +# gwasSumStatsS4Example's one study split into two LD blocks of 100 variants. +.alc_blockSplit <- function() { + data(gwasSumStatsS4Example) + g <- gwasSumStatsS4Example + GwasSumStats( + studyName = "trait1", + entry = list(sumStats(g)), + genome = "hg19", + ldReference = ldReference(g)[[1L]], + qcOptions = qcOptions(g), + region = GenomicRanges::GRanges( + "chr22", + IRanges::IRanges(c(1L, 15680321L), c(15680320L, 51304566L)) + ) + ) +} + +test_that("a positional setter writes across every row of a split study", { + x <- .alc_blockSplit() + expect_equal(nrow(x), 2L) + v <- seq(0.01, 0.5, length.out = 200L) + af(x, studyName = "trait1") <- v + expect_equal(nrow(x), 2L) + # sumStats() order is the rows' order, so each row takes its own piece. + expect_equal(af(x), v) + expect_equal(S4Vectors::mcols(x[[2L]])$AF, v[101:200]) + expect_error(af(x) <- v[-1L], "one value per variant \\(200") +}) + +test_that("fillFromReference places values across a split study's rows", { + x <- .alc_blockSplit() + gr <- sumStats(x) + rep <- gr + S4Vectors::mcols(rep) <- S4Vectors::DataFrame( + A1 = S4Vectors::mcols(gr)$A1, + A2 = S4Vectors::mcols(gr)$A2, + v = seq_len(200L) / 1000 + ) + # Every reference variant is in one row or the other, so neither the + # unused nor the missed warning fires. + expect_silent(x <- fillFromReference(x, rep[rev(seq_along(rep))], "MAF")) + expect_equal(maf(x), seq_len(200L) / 1000) + expect_silent(x <- fillFromReference(x, rep, "N")) + expect_equal(sampleSize(x)[c(1L, 200L)], c(0.001, 0.2)) +}) + +test_that("emptied rows of one study do not collide", { + x <- .alc_blockSplit() + # A PIP screen or filter() leaves each block an empty row; each keeps + # its own block, so two of them are not duplicates. + emptied <- combineGwasSumStats( + GwasSumStats( + studyName = "trait1", + entry = list(sumStats(x)[0L]), + genome = "hg19", + blockId = "b1" + ), + GwasSumStats( + studyName = "trait1", + entry = list(sumStats(x)[0L]), + genome = "hg19", + blockId = "b2" + ) + ) + expect_equal(unname(lengths(emptied)), c(0L, 0L)) + # The same block twice is still a duplicate. + expect_error( + combineGwasSumStats(emptied[1L], emptied[1L]), + "\\(study, range\\) must be unique" + ) + # Without a blockId, an empty row is keyed by its position; a non-empty + # one keeps its span key. + bare <- GenomicRanges::GRangesList( + GenomicRanges::GRanges(), + GenomicRanges::GRanges(), + GenomicRanges::GRanges("chr1", IRanges::IRanges(1L, 2L)) + ) + S4Vectors::mcols(bare) <- S4Vectors::DataFrame(study = rep("a", 3L)) + keys <- pecotmr:::.keyEmptyElements(bare, c("", "", "chr1:1-2")) + expect_false(anyDuplicated(keys) > 0L) + expect_identical(keys[[3L]], "chr1:1-2") +}) + +test_that("a show() line names one genome build however many chromosomes", { + gr <- GenomicRanges::GRanges( + c("chr1", "chr2"), + IRanges::IRanges(c(100L, 100L), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = c("chr1:100:A:G", "chr2:100:A:G"), + A1 = "A", + A2 = "G", + Z = c(1, 2), + N = 100L + ) + x <- GwasSumStats(studyName = "g1", entry = list(gr), genome = "hg38") + expect_identical(pecotmr:::.showGenomeBuild(x), "hg38") + expect_identical( + pecotmr:::.showGenomeBuild(GenomicRanges::GRangesList()), + "NA" + ) +}) + +test_that(".inputsBuild carries the one build the inputs name", { + hg19 <- GenomicRanges::GRanges("chr1", IRanges::IRanges(1L, width = 1L)) + GenomeInfoDb::genome(hg19) <- "hg19" + unset <- GenomicRanges::GRanges("chr2", IRanges::IRanges(1L, width = 1L)) + f <- pecotmr:::.inputsBuild + expect_identical(f(list(hg19, unset, NULL), "f"), "hg19") + expect_identical(f(list(unset, NULL), "f"), NA_character_) + # A plain list is read element by element. + expect_identical(f(list(list(unset, hg19)), "f"), "hg19") + hg38 <- GenomeInfoDb::`genome<-`(unset, value = "hg38") + expect_error( + f(list(hg19, hg38), "colocPipeline"), + "colocPipeline: the inputs name different genome builds (hg19, hg38)", + fixed = TRUE + ) +}) + +test_that(".namedBuilds reads a QtlDataset's contexts, a MultiStudy's parts", { + tagged <- .sc_makeSe() + GenomeInfoDb::genome(tagged) <- "hg38" + qd <- QtlDataset( + studyName = "s1", + genotypes = .sc_makeGenotypeHandle(), + phenotypes = list(brain = tagged) + ) + expect_identical(pecotmr:::.namedBuilds(qd), "hg38") + ms <- MultiStudyQtlDataset( + qtlDatasets = list(s1 = qd), + sumStats = qtlSumStatsExample + ) + expect_setequal(pecotmr:::.namedBuilds(ms), c("hg38", "hg19")) + # An unranged experiment places nothing, so it names no build. + bare <- SummarizedExperiment::SummarizedExperiment(list(a = matrix(1))) + expect_identical(pecotmr:::.namedBuilds(bare), character(0)) +}) + +test_that(".oneBuild and .withGenome leave an unknown build unset", { + mixed <- GenomicRanges::GRanges( + c("chr1", "chr2"), + IRanges::IRanges(1L, width = 1L) + ) + GenomeInfoDb::genome(mixed) <- c("hg19", "hg38") + expect_identical(pecotmr:::.oneBuild(mixed), NA_character_) + expect_identical(pecotmr:::.withGenome(mixed, NA_character_), mixed) + expect_null(pecotmr:::.withGenome(NULL, "hg19")) + tagged <- pecotmr:::.withGenome(mixed, "hg19") + expect_identical(unname(GenomeInfoDb::genome(tagged)), c("hg19", "hg19")) +}) + +test_that("a result's ranged views carry its genome build", { + data(qtlFineMappingExample) + data(qtlFineMappingLbfExample) + x <- GenomeInfoDb::`genome<-`(qtlFineMappingExample, value = "hg19") + build <- function(gr) unique(unname(GenomeInfoDb::genome(gr))) + expect_identical(build(topLoci(x)), "hg19") + expect_identical(build(credibleSets(x)), "hg19") + expect_identical(build(marginalEffects(x)), "hg19") + expect_identical(build(lbf(qtlFineMappingLbfExample)), NA_character_) + expect_identical( + build(lbf(GenomeInfoDb::`genome<-`( + qtlFineMappingLbfExample, + value = "hg19" + ))), + "hg19" + ) +}) + +# =========================================================================== +# Collection aggregates: lbf, credibleSetSummary and the fSuSiE accessors +# =========================================================================== + +test_that("lbf aggregates over a collection, carrying identity + NA-filling ragged effects", { + vids <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A") + mkEntry <- function(maxNumSingleEffects) { + lbf <- matrix( + seq_len(maxNumSingleEffects * length(vids)), + nrow = maxNumSingleEffects, + byrow = TRUE + ) # L x p + fit <- structure( + list(lbf_variable = lbf, pip = rep(0.3, length(vids))), + class = "susie" + ) + FineMappingRow( + variantIds = vids, + susieFit = fit, + topLoci = data.frame( + variant_id = vids, + pip = rep(0.3, length(vids)), + stringsAsFactors = FALSE + ) + ) + } + # Two entries with different effect counts (L = 2 vs 3) exercise the NA-fill of + # the ragged lbf_L columns described in the collection method's contract. + res <- QtlFineMappingResult( + studyName = c("s1", "s1"), + context = c("brain", "blood"), + trait = c("g", "g"), + method = c("susie", "susie"), + entry = list(mkEntry(2L), mkEntry(3L)) + ) + w <- lbf(res) + expect_s4_class(w, "GRanges") + expect_true(all( + c("study", "context", "trait", "method", "variant_id") %in% + names(S4Vectors::mcols(w)) + )) + expect_equal(length(w), 6L) # 2 entries x 3 variants + expect_setequal(unique(w$context), c("brain", "blood")) + expect_true("lbf_L3" %in% names(S4Vectors::mcols(w))) + expect_true(all(is.na(w$lbf_L3[w$context == "brain"]))) # L = 2 entry: no effect 3 + expect_true(all(!is.na(w$lbf_L3[w$context == "blood"]))) # L = 3 entry: present +}) + +test_that("credibleSetSummary aggregates across a collection with entry identity", { + mkEntry <- function() { + vn <- c("chr1:100:A:G", "chr1:200:C:T") + tl <- data.frame( + variant_id = vn, + pip = c(0.7, 0.2), + logBF = c(2.5, 0.3), + cs_95 = c("susie_1", "susie_1"), + cs_95_purity = c(0.9, 0.9), + stringsAsFactors = FALSE + ) + FineMappingRow(variantIds = vn, susieFit = list(x = 1), topLoci = tl) + } + res <- QtlFineMappingResult( + studyName = c("s", "s"), + context = c("brain", "blood"), + trait = c("g", "g"), + method = c("susie", "susie"), + entry = list(mkEntry(), mkEntry()) + ) + s <- credibleSetSummary(res) + expect_true(all( + c("study", "context", "trait", "method", "cs") %in% names(s) + )) + expect_equal(nrow(s), 2L) # one CS per entry + expect_setequal(unique(s$context), c("brain", "blood")) +}) + +test_that("fsusieCredibleBand on a result with no fSuSiE fit is empty ranges", { + data(qtlFineMappingExample, envir = environment()) + cb <- fsusieCredibleBand(qtlFineMappingExample) + expect_s4_class(cb, "GRanges") + expect_length(cb, 0L) +}) + +test_that("fsusieCredibleBand + fsusieAffectedRegions aggregate across a collection", { + skip_if_not_installed("fsusieR") + skip_if_not_installed("wavethresh") + fit <- .fsa_fits$none # one fit, read by both rows + res <- QtlFineMappingResult( + studyName = c("s", "s"), + context = c("brain", "blood"), + trait = c("g", "g"), + method = c("fsusie", "fsusie"), + entry = list(.fsa_entry(fit), .fsa_entry(fit)) + ) + + cb <- fsusieCredibleBand(res) + expect_true(all( + c( + "study", + "context", + "trait", + "method", + "cs", + "effect", + "lower", + "upper" + ) %in% + names(S4Vectors::mcols(cb)) + )) + expect_s4_class(cb, "GRanges") + expect_gt(length(cb), 0) + expect_setequal(unique(cb$context), c("brain", "blood")) + + gr <- fsusieAffectedRegions(res) + expect_s4_class(gr, "GRanges") + expect_gt(length(gr), 0) + expect_true(all( + c("study", "context", "trait", "cs", "purity", "direction") %in% + names(S4Vectors::mcols(gr)) + )) + expect_setequal(unique(S4Vectors::mcols(gr)$context), c("brain", "blood")) +}) + +test_that("fsusieAffectedRegions on a collection of non-fSuSiE entries is an empty GRanges", { + e <- FineMappingRow( + variantIds = "chr1:100:A:G", + susieFit = list(pip = 0.5), + topLoci = data.frame( + variant_id = "chr1:100:A:G", + pip = 0.5, + stringsAsFactors = FALSE + ) + ) + res <- QtlFineMappingResult( + studyName = "s", + context = "c", + trait = "t", + method = "susie", + entry = list(e) + ) + expect_equal(length(fsusieAffectedRegions(res)), 0L) }) diff --git a/tests/testthat/test_AllGenerics.R b/tests/testthat/test_AllGenerics.R index b1f937fd..eaaf71e1 100644 --- a/tests/testthat/test_AllGenerics.R +++ b/tests/testthat/test_AllGenerics.R @@ -16,14 +16,6 @@ ) } -# @noRd -.agIsGeneric <- function(nm) { - tryCatch( - methods::isGeneric(nm, where = asNamespace("pecotmr")), - error = function(e) FALSE - ) -} - test_that("every generic declared in AllGenerics.R has at least one method", { src <- readLines( system.file( @@ -51,18 +43,3 @@ test_that("every generic declared in AllGenerics.R has at least one method", { label = "generics with no method" ) }) - -test_that("exported generics are all reachable by name from the namespace", { - exported <- getNamespaceExports("pecotmr") - gens <- exported[map_lgl(exported, .agIsGeneric)] - expect_gt(length(gens), 50L) - # Every exported generic must resolve; a stale NAMESPACE entry pointing at - # a removed generic is the failure this catches. - for (g in gens) { - expect_true( - !is.null(getGenerics(asNamespace("pecotmr"))) && - exists(g, envir = asNamespace("pecotmr")), - label = str_c("exported generic '", g, "' resolves") - ) - } -}) diff --git a/tests/testthat/test_AnnotationMatrix.R b/tests/testthat/test_AnnotationMatrix.R index 3515d612..7e5ba75a 100644 --- a/tests/testthat/test_AnnotationMatrix.R +++ b/tests/testthat/test_AnnotationMatrix.R @@ -7,18 +7,27 @@ context("AnnotationMatrix") # The class is a RangedSummarizedExperiment, so the annotation matrix, # its per-column metadata and its ranges are read with assay(), # colData() and rowRanges() rather than through accessors of our own. -# Annotation *readers* stay in test_h2Annotations.R. Fixtures come from -# helper-h2Classes.R. - -test_that("AnnotationMatrix validates dimensions and meta", { - gr <- makeTestGRanges(10) - meta <- makeTestAnnotationMeta() - mat <- matrix(0, nrow = 10, ncol = 3) +# Annotation *readers* stay in test_h2Annotations.R. The fixtures are the +# two builders below. + +makeTestGRanges <- function(n = 10) { + GenomicRanges::GRanges( + seqnames = rep("chr1", n), + ranges = IRanges::IRanges( + start = seq(1000, by = 100, length.out = n), + width = 1L + ) + ) +} - obj <- AnnotationMatrix(mat, gr, meta) - expect_s4_class(obj, "AnnotationMatrix") - expect_true(methods::validObject(obj)) -}) +makeTestAnnotationMeta <- function() { + data.frame( + name = c("base", "enhancer", "promoter"), + tier = c("baseline", "candidate", "candidate"), + type = c("binary", "binary", "continuous"), + stringsAsFactors = FALSE + ) +} test_that("AnnotationMatrix rejects row mismatch", { gr <- makeTestGRanges(10) @@ -28,15 +37,6 @@ test_that("AnnotationMatrix rejects row mismatch", { expect_error(AnnotationMatrix(mat, gr, meta), "rows.*must match") }) -test_that("AnnotationMatrix rejects column mismatch with meta", { - gr <- makeTestGRanges(10) - meta <- makeTestAnnotationMeta() # 3 annotations - mat <- matrix(0, nrow = 10, ncol = 2) # only 2 columns - - # Constructor errors when colnames assignment fails (dimnames mismatch) - expect_error(AnnotationMatrix(mat, gr, meta)) -}) - test_that("AnnotationMatrix rejects invalid tier values", { gr <- makeTestGRanges(10) meta <- data.frame( @@ -63,20 +63,7 @@ test_that("AnnotationMatrix rejects invalid type values", { expect_error(AnnotationMatrix(mat, gr, meta), "type.*binary.*continuous") }) -test_that("AnnotationMatrix() constructor creates object from matrix", { - n <- 10 - gr <- makeTestGRanges(n) - meta <- makeTestAnnotationMeta() - mat <- matrix(runif(n * 3), nrow = n, ncol = 3) - - obj <- AnnotationMatrix(mat, gr, meta, genome = "hg38") - expect_s4_class(obj, "AnnotationMatrix") - expect_equal(nrow(assay(obj, "annotations")), n) - expect_equal(ncol(assay(obj, "annotations")), 3) - expect_equal(unname(GenomeInfoDb::genome(obj)), "hg38") -}) - -test_that("AnnotationMatrix() sets column names from annotation_meta", { +test_that("AnnotationMatrix() sets column names from annotationMeta", { n <- 10 gr <- makeTestGRanges(n) meta <- makeTestAnnotationMeta() @@ -113,6 +100,8 @@ test_that("AnnotationMatrix accessors round-trip the stored slots", { mat <- matrix(runif(n * 3), nrow = n, ncol = 3) obj <- AnnotationMatrix(mat, gr, meta, genome = "hg38") + expect_s4_class(obj, "AnnotationMatrix") + expect_true(methods::validObject(obj)) expect_equal(dim(assay(obj, "annotations")), c(n, 3L)) # colData is a DFrame keyed by the annotation names, so the plain # fixture compares as data after dropping those rownames. @@ -157,8 +146,6 @@ test_that("testedAnnotations() subsets to candidate-tier only", { expect_true(all(SummarizedExperiment::colData(cand)$tier == "candidate")) }) -# show() smoke test, moved here from test_showMethods.R so the test -# tree mirrors R/. test_that("show(AnnotationMatrix) does not error", { am <- AnnotationMatrix( matrix(0, nrow = 10, ncol = 1), diff --git a/tests/testthat/test_ColocBoostResult.R b/tests/testthat/test_ColocBoostResult.R index fbe6c5a3..76c70e16 100644 --- a/tests/testthat/test_ColocBoostResult.R +++ b/tests/testthat/test_ColocBoostResult.R @@ -13,7 +13,7 @@ test_that("ColocBoostResult: one element per confidence set", { ) expect_s4_class(x, "ColocBoostResult") expect_equal(nrow(x), 1L) - expect_equal(lengths(x), 1L) + expect_equal(unname(lengths(x)), 1L) expect_true(x$isColocalized) }) @@ -150,7 +150,10 @@ test_that("ColocBoostResult: reachable by range, not just identity", { ) win <- GenomicRanges::GRanges("chr1", IRanges::IRanges(150, 250)) expect_equal(length(IRanges::subsetByOverlaps(x, win)), 1L) - expect_equal(sum(lengths(subsetRegion(x, win))), 1L) + expect_equal( + sum(lengths(endoapply(x, IRanges::subsetByOverlaps, ranges = win))), + 1L + ) }) test_that("colocBoostOutcomes: joins each outcome to its identity", { @@ -176,31 +179,21 @@ test_that("regionVcp spans the region, not just set members", { expect_equal(sum(lengths(x)), 1L) }) -test_that("as.data.frame returns the set-level view", { +test_that("colocPairs is the set-level view; as.data.frame is standard", { x <- ColocBoostResult( list(.cbr_fake()), "xqtl_coloc", outcomeInfo = .cbr_info() ) + sets <- colocPairs(x) + expect_s4_class(sets, "DataFrame") + expect_equal(sets$cosId, "cos1:y1_y2") + expect_equal(sets$outcomes, "t1; t2") + # as.data.frame() is the inherited GRangesList coercion: one row per + # (set, variant), placed by its range. df <- as.data.frame(x) - expect_s3_class(df, "data.frame") - expect_equal(df$cosId, "cos1:y1_y2") - expect_equal(df$outcomes, "t1; t2") -}) - -test_that("separate_gwas runs are keyed by gwasStudy", { - # The three analyses are not parallel: separate_gwas is a named list one - # level deeper, so without gwasStudy its sets would be indistinguishable. - raw <- list( - xqtl_coloc = NULL, - joint_gwas = NULL, - separate_gwas = list(G1 = .cbr_fake(), G2 = .cbr_fake()), - computing_time = list() - ) - x <- .cbToResultObject(raw, .cbr_info()) - expect_equal(nrow(x), 2L) - expect_equal(x$analysis, rep("separate_gwas", 2L)) - expect_setequal(x$gwasStudy, c("G1", "G2")) + expect_true(all(c("group", "seqnames", "start") %in% names(df))) + expect_equal(nrow(df), sum(lengths(x))) }) test_that(".cbrFocalOutcome maps the no-focal sentinel to NA", { @@ -321,7 +314,7 @@ test_that("show counts colocalized and outcome-only sets separately", { # Pooled variants, and the fallbacks for a result missing its summary tables # =========================================================================== -test_that("colocVariants(pooled = TRUE) collapses to one row per variant", { +test_that("colocPooledVariants collapses to one row per variant", { # Noisy-OR only: ColocBoost's sets are not per-block slices of one signal, # so there is no mutually-exclusive sum stage the way coloc has. x <- ColocBoostResult( @@ -330,10 +323,11 @@ test_that("colocVariants(pooled = TRUE) collapses to one row per variant", { outcomeInfo = .cbr_info() ) long <- colocVariants(x) - pooled <- colocVariants(x, pooled = TRUE) - expect_lte(nrow(pooled), nrow(long)) + pooled <- colocPooledVariants(x) + expect_lte(length(pooled), length(long)) + pooledCols <- as.data.frame(S4Vectors::mcols(pooled)) expect_equal( - anyDuplicated(pooled[, c("analysis", "variant_id")]), + anyDuplicated(pooledCols[, c("analysis", "variant_id")]), 0L ) expect_true(all(pooled$vcp >= 0 & pooled$vcp <= 1)) @@ -365,7 +359,7 @@ test_that(".cbrTopVariable is NA when the id is absent from the table", { expect_true(is.na(.cbrTopVariable(NULL, "cos1"))) }) -test_that("validity names missing identity and outcomeInfo columns", { +test_that("validity names a missing identity column", { x <- ColocBoostResult( list(.cbr_fake()), "xqtl_coloc", @@ -418,6 +412,9 @@ test_that("the views answer an empty collection with empty tables", { expect_equal(length(empty), 0L) expect_equal(nrow(.cbrLongVariants(empty)), 0L) expect_equal(nrow(colocBoostOutcomes(empty)), 0L) + expect_length(colocPooledVariants(empty), 0L) + expect_s4_class(colocBoostOutcomes(empty), "DataFrame") + expect_s4_class(colocPairs(colocboostResultExample), "DataFrame") }) test_that("outcome info defaults to the empty frame and is not joined", { @@ -557,3 +554,56 @@ test_that("updateObject keys an old result's sumstat outcomes to its ref", { # A current result is left as it is. expect_identical(updateObject(x), x) }) + +# =========================================================================== +# computingTime(): one row per analysis that ran +# =========================================================================== + +test_that("computingTime() tabulates each analysis: its runs and seconds", { + timing <- list( + Analysis = list( + xqtl_coloc = as.difftime(90, units = "secs"), + joint_gwas = NULL, + separate_gwas = list( + total = as.difftime(2, units = "mins"), + n_studies = 3L + ) + ) + ) + x <- ColocBoostResult( + list(), + character(0), + outcomeInfo = .cbr_info(), + computingTime = timing + ) + tab <- computingTime(x) + expect_s4_class(tab, "DataFrame") + # An analysis that did not run is no row. + expect_equal(tab$analysis, c("xqtl_coloc", "separate_gwas")) + expect_equal(tab$nRuns, c(1L, 3L)) + expect_equal(tab$seconds, c(90, 120)) +}) + +test_that("computingTime() has no rows when nothing was timed", { + tab <- computingTime( + ColocBoostResult(list(), character(0), outcomeInfo = .cbr_info()) + ) + expect_equal(nrow(tab), 0L) + expect_equal(colnames(tab), c("analysis", "nRuns", "seconds")) +}) + +test_that("a timing as a bare number, or without a total, still reads", { + expect_equal(pecotmr:::.cbrTimingSeconds(12.5), 12.5) + expect_true(is.na(pecotmr:::.cbrTimingSeconds(list(n_studies = 2L)))) + expect_true(is.na(pecotmr:::.cbrTimingRuns(list(total = 3)))) +}) + +test_that("ColocBoostResult() keeps the caller's metadata", { + x <- ColocBoostResult( + list(), + character(0), + outcomeInfo = .cbr_info(), + metadata = list(run = "r1") + ) + expect_equal(S4Vectors::metadata(x), list(run = "r1")) +}) diff --git a/tests/testthat/test_ColocResult.R b/tests/testthat/test_ColocResult.R index 2c000ec8..91ff3885 100644 --- a/tests/testthat/test_ColocResult.R +++ b/tests/testthat/test_ColocResult.R @@ -55,7 +55,7 @@ test_that("ColocResult: stores one element per pair with its variants", { x <- ColocResult(.cr_pairs(), .cr_variants()) expect_s4_class(x, "ColocResult") expect_equal(nrow(x), 1L) - expect_equal(lengths(x), 3L) + expect_equal(unname(lengths(x)), 3L) expect_equal(x$PP.H4.abf, 0.6) }) @@ -107,14 +107,18 @@ test_that("ColocResult: variants keep their alleles, so ids round-trip", { test_that("ColocResult: is reachable by range, not just by identity", { x <- ColocResult(.cr_pairs(), .cr_variants()) win <- GenomicRanges::GRanges("chr1", IRanges::IRanges(150, 250)) - expect_equal(sum(lengths(subsetRegion(x, win))), 1L) + expect_equal( + sum(lengths(endoapply(x, IRanges::subsetByOverlaps, ranges = win))), + 1L + ) expect_equal(length(IRanges::subsetByOverlaps(x, win)), 1L) }) test_that("colocVariants: colocPp is the pair posterior times the variant", { x <- ColocResult(.cr_pairs(pp4 = 0.5), .cr_variants()) v <- colocVariants(x) - expect_equal(nrow(v), 3L) + expect_s4_class(v, "GRanges") + expect_equal(length(v), 3L) expect_equal(v$colocPp, 0.5 * c(0.6, 0.3, 0.1)) }) @@ -165,29 +169,41 @@ test_that("colocGenes: keeps distinct second-side traits apart", { expect_setequal(genes$gwasTrait, c("h1", "h2")) }) -test_that("colocVariants(pooled): pools by the same rule as genes", { +test_that("colocPooledVariants: pools by the same rule as genes", { pairs <- .cr_pairs( qtlCs = c(1L, 2L), blockId = c("b1", "b1"), pp4 = c(0.5, 0.25) ) x <- ColocResult(pairs, .cr_variants(2L)) - pooled <- colocVariants(x, pooled = TRUE) - expect_equal(nrow(pooled), 3L) + pooled <- colocPooledVariants(x) + expect_equal(length(pooled), 3L) lead <- pooled[pooled$variant_id == "chr1:100:A:G", ] expect_equal(lead$colocPp, 1 - (1 - 0.5 * 0.6) * (1 - 0.25 * 0.6)) }) test_that("colocCredibleSets: takes the smallest set reaching coverage", { x <- ColocResult(.cr_pairs(), .cr_variants()) - expect_equal(colocCredibleSets(x, coverage = 0.5)$csSize, 1L) - expect_equal(colocCredibleSets(x, coverage = 0.9)$csSize, 2L) - expect_equal(colocCredibleSets(x, coverage = 0.95)$csSize, 3L) + expect_equal(mcols(colocCredibleSets(x, coverage = 0.5))$csSize, 1L) + expect_equal(mcols(colocCredibleSets(x, coverage = 0.9))$csSize, 2L) + expect_equal(mcols(colocCredibleSets(x, coverage = 0.95))$csSize, 3L) }) -test_that("colocCredibleSets: reports the lead variant and coverage", { +test_that("colocCredibleSets: each set's members are its element", { x <- ColocResult(.cr_pairs(), .cr_variants()) cs <- colocCredibleSets(x, coverage = 0.9) + expect_s4_class(cs, "GRangesList") + expect_equal(unname(lengths(cs)), mcols(cs)$csSize) + expect_equal( + .grVariantIds(cs[[1L]]), + c("chr1:100:A:G", "chr1:200:C:T") + ) + expect_equal(mcols(cs[[1L]])$SNP.PP.H4, c(0.6, 0.3)) +}) + +test_that("colocCredibleSets: reports the lead variant and coverage", { + x <- ColocResult(.cr_pairs(), .cr_variants()) + cs <- mcols(colocCredibleSets(x, coverage = 0.9)) expect_equal(cs$leadVariant, "chr1:100:A:G") expect_equal(cs$leadPp, 0.6) expect_equal(cs$csCoverage, 0.9) @@ -196,17 +212,17 @@ test_that("colocCredibleSets: reports the lead variant and coverage", { test_that("colocCredibleSets: minPp4 drops pairs before any LD work", { pairs <- .cr_pairs(qtlCs = c(1L, 2L), pp4 = c(0.8, 0.1)) x <- ColocResult(pairs, .cr_variants(2L)) - expect_equal(nrow(colocCredibleSets(x)), 2L) - expect_equal(nrow(colocCredibleSets(x, minPp4 = 0.5)), 1L) - expect_equal(nrow(colocCredibleSets(x, minPp4 = 0.99)), 0L) + expect_length(colocCredibleSets(x), 2L) + expect_length(colocCredibleSets(x, minPp4 = 0.5), 1L) + expect_length(colocCredibleSets(x, minPp4 = 0.99), 0L) }) test_that("colocCredibleSets: requireMaxH4 keeps only H4-dominant pairs", { pairs <- .cr_pairs(qtlCs = c(1L, 2L), pp4 = c(0.8, 0.1)) x <- ColocResult(pairs, .cr_variants(2L)) cs <- colocCredibleSets(x, requireMaxH4 = TRUE) - expect_equal(nrow(cs), 1L) - expect_equal(cs$qtlCs, 1L) + expect_length(cs, 1L) + expect_equal(mcols(cs)$qtlCs, 1L) }) test_that("colocCredibleSets: purity is NA, not passing, without LD", { @@ -215,16 +231,27 @@ test_that("colocCredibleSets: purity is NA, not passing, without LD", { # to be attached. x <- ColocResult(.cr_pairs(), .cr_variants()) cs <- colocCredibleSets(x) - expect_true(is.na(cs$purity)) - expect_equal(nrow(colocCredibleSets(x, minAbsCorr = 0.99)), 1L) + expect_true(is.na(mcols(cs)$purity)) + expect_length(colocCredibleSets(x, minAbsCorr = 0.99), 1L) }) -test_that("as.data.frame returns the pair view", { +test_that("colocCredibleSets: carries the result's genome", { x <- ColocResult(.cr_pairs(), .cr_variants()) + GenomeInfoDb::genome(x) <- "hg38" + cs <- colocCredibleSets(x) + expect_equal(unique(unname(GenomeInfoDb::genome(cs))), "hg38") +}) + +test_that("colocPairs is the pair view; as.data.frame is standard", { + x <- ColocResult(.cr_pairs(), .cr_variants()) + pairs <- colocPairs(x) + expect_equal(nrow(pairs), 1L) + expect_equal(pairs$PP.H4.abf, 0.6) + # as.data.frame() is the inherited GRangesList coercion: one row per + # (pair, variant), placed by its range. df <- as.data.frame(x) - expect_s3_class(df, "data.frame") - expect_equal(nrow(df), 1L) - expect_equal(df$PP.H4.abf, 0.6) + expect_true(all(c("group", "seqnames", "start") %in% names(df))) + expect_equal(nrow(df), sum(lengths(x))) }) test_that(".crPivotColocResults: maps results column K to summary row K", { @@ -334,23 +361,36 @@ test_that("purity is NA when the panel cannot supply the members", { )) }) +# One credible-set record as .crCredibleSets() builds it: the members' +# ranges and the pair row that names its LD reference. +.cr_set <- function(ids, ldReference) { + list( + members = .variantIdsToGRanges(ids, what = "variant_id"), + row = tibble(ldReference = ldReference) + ) +} + test_that("purity is NA for every set whose pair has no LD reference", { - out <- tibble( - csVariants = list(c("a", "b"), "c"), - ldReference = NA_character_ + sets <- list( + .cr_set(c("chr1:100:A:G", "chr1:200:C:T"), NA_character_), + .cr_set("chr1:300:G:A", NA_character_) + ) + expect_equal( + map_dbl(sets, .crSetPurity, refs = list()), + c(NA_real_, NA_real_) ) - expect_equal(.crPuritiesFor(out, list()), c(NA_real_, NA_real_)) }) test_that("purity is computed per set against its own pair's reference", { # The counterpart of the no-reference case above: each set is mapped # through .crPurityOne with the reference its pair names. ids <- .cr_panelIds(3L) - out <- tibble( - csVariants = list(ids, ids[[1L]], ids), - ldReference = c("ld1", "ld1", NA_character_) + sets <- list( + .cr_set(ids, "ld1"), + .cr_set(ids[[1L]], "ld1"), + .cr_set(ids, NA_character_) ) - pur <- .crPuritiesFor(out, .cr_refs()) + pur <- map_dbl(sets, .crSetPurity, refs = .cr_refs()) expect_length(pur, 3L) expect_equal(pur[[2L]], 1) # singleton is pure by definition expect_equal( @@ -408,6 +448,20 @@ test_that("the views answer an empty collection with empty tables", { expect_equal(nrow(.crLongVariants(empty)), 0L) expect_equal(.crPairFilter(empty, 0, FALSE), integer(0)) expect_equal(nrow(colocGenes(empty)), 0L) + expect_length(colocPooledVariants(empty), 0L) + expect_s4_class(colocPooledVariants(empty), "GRanges") +}) + +test_that("the tabular views are DataFrames, the ranged ones GRanges", { + x <- ColocResult(.cr_pairs(), .cr_variants()) + expect_s4_class(colocPairs(x), "DataFrame") + expect_s4_class(colocGenes(x), "DataFrame") + expect_s4_class(colocCredibleSets(x, coverage = 0.5), "GRangesList") + expect_s4_class(mcols(colocCredibleSets(x, coverage = 0.5)), "DataFrame") + expect_s4_class(colocVariants(x), "GRanges") + expect_s4_class(colocPooledVariants(x), "GRanges") + # Column names survive the conversion as written. + expect_true("PP.H4.abf" %in% colnames(colocPairs(x))) }) test_that("pivoting a per-row column that is absent yields the empty frame", { @@ -416,9 +470,13 @@ test_that("pivoting a per-row column that is absent yields the empty frame", { }) test_that("a NULL purity cutoff leaves the credible sets untouched", { - # NULL means "do not filter", which is different from filtering at 0. - out <- tibble(a = 1, purity = NA_real_) - expect_identical(.crApplyPurityFilter(out, NULL), out) + # NULL means "do not filter": a set a cutoff would drop stays. + ids <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A") + R <- matrix(0.2, 3L, 3L, dimnames = list(ids, ids)) + diag(R) <- 1 + x <- ColocResult(.cr_pairs(), .cr_variants(), ldReference = LdMatrix(R)) + expect_equal(mcols(colocCredibleSets(x, minAbsCorr = NULL))$purity, 0.2) + expect_length(colocCredibleSets(x, minAbsCorr = 0.8), 0L) }) test_that("a pair with no variants contributes no credible set", { @@ -431,6 +489,14 @@ test_that("a pair with no variants contributes no credible set", { cr <- ColocResult(.cr_pairs(), list(noVariants)) expect_equal(length(cr[[1L]]), 0L) expect_null(.crCsForPair(1L, cr, coverage = 0.95)) - # ...and the accessor over that result is an empty table, not an error. - expect_equal(nrow(colocCredibleSets(cr)), 0L) + # ...and the accessor over that result is an empty list, not an error. + expect_length(colocCredibleSets(cr), 0L) + expect_s4_class(colocCredibleSets(cr), "GRangesList") +}) + +test_that("ColocResult() keeps the caller's metadata", { + x <- ColocResult(.cr_pairs(), .cr_variants(), metadata = list(run = "r1")) + expect_equal(S4Vectors::metadata(x), list(run = "r1")) + plain <- ColocResult(.cr_pairs(), .cr_variants()) + expect_equal(S4Vectors::metadata(plain), list()) }) diff --git a/tests/testthat/test_CtwasResult.R b/tests/testthat/test_CtwasResult.R index 0d71d5ef..279311e9 100644 --- a/tests/testthat/test_CtwasResult.R +++ b/tests/testthat/test_CtwasResult.R @@ -4,16 +4,20 @@ context("CtwasResult") # test_CtwasResultEntry.R; this file covers the CtwasResult collection. .cr_entry <- function(ids = c("g1", "g2"), pip = c(0.9, 0.1), prior = NULL) { + # Ranged, as the pipeline stores them: each id placed at a position. + at <- IRanges::IRanges(100L * seq_along(ids), width = 1L) CtwasResultEntry( - posteriors = data.frame( + posteriors = GenomicRanges::GRanges( + "chr1", + at, id = ids, - susie_pip = pip, - stringsAsFactors = FALSE + susie_pip = pip ), - susieAlpha = data.frame( + susieAlpha = GenomicRanges::GRanges( + "chr1", + at, id = ids, - susie_alpha = pip, - stringsAsFactors = FALSE + susie_alpha = pip ), groupPriors = prior, regionInfo = data.frame(region_id = "r1", stringsAsFactors = FALSE) @@ -47,11 +51,12 @@ test_that("CtwasResult: ctwasPosteriors aggregates rows tagged with run identity ) ) fm <- ctwasPosteriors(cr) + expect_s4_class(fm, "GRanges") expect_true(all( c("gwasStudy", "study", "context", "method", "id", "susie_pip") %in% - names(fm) + names(S4Vectors::mcols(fm)) )) - expect_equal(nrow(fm), 3L) # 2 + 1 gene rows + expect_equal(length(fm), 3L) # 2 + 1 gene rows expect_equal(fm$context, c("brain", "brain", "liver")) }) @@ -67,10 +72,10 @@ test_that("CtwasResult: susieAlpha aggregates the per-effect table with identity ) ) sa <- susieAlpha(cr) - expect_equal(nrow(sa), 3L) + expect_equal(length(sa), 3L) expect_true(all( c("gwasStudy", "study", "context", "method", "susie_alpha") %in% - names(sa) + names(S4Vectors::mcols(sa)) )) expect_equal(sa$context, c("brain", "brain", "liver")) }) @@ -140,7 +145,7 @@ test_that("CtwasResult: a joint column of the wrong length is rejected", { ) }) -test_that("CtwasResult: ctwasPosteriors/susieAlpha are NULL when empty or all-NULL", { +test_that("CtwasResult: the views are empty ranges when no row has a payload", { empty <- CtwasResult( gwasStudy = character(0), studyName = character(0), @@ -148,8 +153,8 @@ test_that("CtwasResult: ctwasPosteriors/susieAlpha are NULL when empty or all-NU method = character(0), entry = list() ) - expect_null(ctwasPosteriors(empty)) - expect_null(susieAlpha(empty)) + expect_length(ctwasPosteriors(empty), 0L) + expect_s4_class(susieAlpha(empty), "GRanges") nullE <- CtwasResult( gwasStudy = "D1", studyName = "Q1", @@ -157,8 +162,8 @@ test_that("CtwasResult: ctwasPosteriors/susieAlpha are NULL when empty or all-NU method = "susie", entry = list(CtwasResultEntry(posteriors = NULL, susieAlpha = NULL)) ) - expect_null(ctwasPosteriors(nullE)) - expect_null(susieAlpha(nullE)) + expect_length(ctwasPosteriors(nullE), 0L) + expect_length(susieAlpha(nullE), 0L) }) test_that("CtwasResult: show() prints a one-line-per-run summary", { @@ -176,9 +181,9 @@ test_that("CtwasResult: show() prints a one-line-per-run summary", { # =========================================================================== # Validity: the branches that name what is wrong # -# CtwasResult is a DFrame subclass, so its columns are ordinary DataFrame -# columns and a downstream edit can drop or retype one. Validity guards that, -# but every test above built a valid object. +# A CtwasResult's identity and payload columns are mcols, so a downstream edit +# can drop or retype one. Validity guards that, but every test above built a +# valid object. # =========================================================================== .ctr_res <- function() { @@ -200,32 +205,133 @@ test_that("validity names a missing required column", { ) }) -test_that("validity requires one entry payload per row", { - # Written straight into listData: `$<-` enforces the length itself, so - # the only way to reach this branch is the direct slot edit that a - # careless downstream mutation would perform. +test_that("a joint column must be character", { bad <- .ctr_res() - bad@listData$entry <- list(.cr_entry(), .cr_entry()) + S4Vectors::mcols(bad)$jointStudies <- 1L expect_error( methods::validObject(bad), - "length\\(entry\\) must equal nrow" + "'jointStudies' column must be character \\(got integer\\)" ) }) -test_that("a joint column must be character", { - bad <- .ctr_res() - bad@listData$jointStudies <- 1L + +test_that("a payload with no coordinates is refused at construction", { + # An entry built by hand from a plain table has nowhere to place its rows + # in a ranged collection, so the constructor says so instead of dropping + # them. + tableOnly <- CtwasResultEntry( + posteriors = data.frame(id = "g1", susie_pip = 0.5) + ) expect_error( - methods::validObject(bad), - "'jointStudies' column must be character \\(got integer\\)" + CtwasResult( + gwasStudy = "D1", + studyName = "Q1", + context = "brain", + method = "susie", + entry = list(tableOnly) + ), + "run 1's posteriors carry no genomic coordinates" ) + # The entry itself still reads back as given. + expect_s3_class(ctwasPosteriors(tableOnly), "data.frame") }) +# =========================================================================== +# One element per cTWAS region +# =========================================================================== + +# A run over two cTWAS regions on two chromosomes, with its region metadata. +.cr_twoRegionEntry <- function() { + regions <- c("chr1_1_1000", "chr2_1_1000") + pos <- GenomicRanges::GRanges( + c("chr1", "chr1", "chr2"), + IRanges::IRanges(c(100L, 200L, 300L), width = 1L), + id = c("g1", "g2", "g3"), + region_id = regions[c(1L, 1L, 2L)], + susie_pip = c(0.9, 0.1, 0.5) + ) + sa <- GenomicRanges::GRanges( + c("chr1", "chr2"), + IRanges::IRanges(c(100L, 300L), width = 1L), + id = c("g1", "g3"), + region_id = regions, + susie_alpha = c(0.8, 0.4) + ) + ri <- GenomicRanges::GRanges( + c("chr1", "chr2"), + IRanges::IRanges(1L, 999L), + region_id = regions + ) + CtwasResultEntry( + posteriors = pos, + susieAlpha = sa, + groupPriors = list(group_prior = c(gene = 0.01)), + regionInfo = ri + ) +} -test_that("an empty ranged payload flattens to NULL", { - expect_null(pecotmr:::.ctwasPayloadAsDf(GenomicRanges::GRanges())) - expect_null(pecotmr:::.ctwasPayloadAsDf(NULL)) - # A non-GRanges payload is passed straight through. - df <- data.frame(a = 1) - expect_equal(pecotmr:::.ctwasPayloadAsDf(df), df) +test_that("a run splits into one element per cTWAS region", { + cr <- CtwasResult( + gwasStudy = "D1", + studyName = "Q1", + context = "brain", + method = "susie", + entry = list(.cr_twoRegionEntry()) + ) + expect_s4_class(cr, "RangedTupleList") + expect_equal(length(cr), 2L) + expect_equal(cr$blockId, c("chr1_1_1000", "chr2_1_1000")) + expect_equal(unname(lengths(cr)), c(2L, 1L)) + # Each element sits on one chromosome, so the range machinery applies. + expect_equal(unname(lengths(range(cr))), c(1L, 1L)) + # The region's own payloads ride with it; the run's priors repeat. + expect_equal(cr$susieAlpha[[2L]]$id, "g3") + expect_equal(cr$regionInfo[[1L]]$region_id, "chr1_1_1000") + expect_identical(cr$groupPriors[[1L]], cr$groupPriors[[2L]]) + # Named by the run identity plus the region. + expect_equal(names(cr)[[1L]], "Q1|brain|susie|D1|chr1_1_1000") + # The stacked views put every region back together. + expect_equal(ctwasPosteriors(cr)$id, c("g1", "g2", "g3")) + expect_equal(susieAlpha(cr)$id, c("g1", "g3")) + # And a region narrows like any ranged collection. + one <- IRanges::subsetByOverlaps( + cr, + GenomicRanges::GRanges("chr2", IRanges::IRanges(1L, 1000L)) + ) + expect_equal(one$blockId, "chr2_1_1000") + expect_s4_class(one, "CtwasResult") +}) + +test_that("updateObject rebuilds a CtwasResult saved as a table of runs", { + # The earlier shape: a DFrame of whole runs, one entry per row. + old <- S4Vectors::DataFrame( + gwasStudy = "D1", + study = "Q1", + context = "brain", + method = "susie", + entry = S4Vectors::SimpleList(list(.cr_twoRegionEntry())) + ) + attr(old, "class") <- methods::getClass("CtwasResult")@className + up <- updateObject(old) + expect_s4_class(up, "CtwasResult") + expect_true(methods::validObject(up)) + expect_equal(length(up), 2L) + # A current object needs nothing. + expect_identical(updateObject(up), up) + expect_message( + updateObject(up, verbose = TRUE), + "updateObject\\(object = 'CtwasResult'\\)" + ) +}) + +test_that("CtwasResult() keeps the caller's metadata", { + cr <- CtwasResult( + gwasStudy = "D1", + studyName = "Q1", + context = "brain", + method = "susie", + entry = list(.cr_entry()), + metadata = list(run = "r1") + ) + expect_equal(S4Vectors::metadata(cr), list(run = "r1")) }) diff --git a/tests/testthat/test_CtwasResultEntry.R b/tests/testthat/test_CtwasResultEntry.R index 8f7dcedc..e00eb53b 100644 --- a/tests/testthat/test_CtwasResultEntry.R +++ b/tests/testthat/test_CtwasResultEntry.R @@ -25,6 +25,19 @@ test_that("CtwasResultEntry: constructor + accessors round-trip", { expect_equal(ctwasGroupPriors(e)$group_prior, c(brain = 0.01)) }) +test_that("as(entry, 'GRanges') gives placed posteriors only", { + placed <- GenomicRanges::GRanges("chr1:100-200", susie_pip = 0.4) + expect_identical( + as(CtwasResultEntry(posteriors = placed), "GRanges"), + placed + ) + expect_length(as(CtwasResultEntry(), "GRanges"), 0L) + expect_error( + as(CtwasResultEntry(posteriors = data.frame(id = "g1")), "GRanges"), + "not placed on the genome" + ) +}) + test_that("CtwasResultEntry: an empty entry is valid and its accessors return NULL", { e <- CtwasResultEntry() expect_s4_class(e, "CtwasResultEntry") @@ -32,3 +45,39 @@ test_that("CtwasResultEntry: an empty entry is valid and its accessors return NU expect_null(susieAlpha(e)) expect_null(ctwasGroupPriors(e)) }) + +test_that("show() counts the genes and regions an entry scores", { + e <- CtwasResultEntry( + posteriors = data.frame( + id = c("g1", "g2", "rs1", "g1"), + type = c("gene", "gene", "SNP", "gene"), + region_id = c("r1", "r1", "r1", "r2"), + susie_pip = c(0.9, 0.1, 0.2, 0.3) + ), + groupPriors = list(group_prior = c(brain = 0.01)) + ) + expect_output( + show(e), + "CtwasResultEntry: 2 gene\\(s\\) in 2 region\\(s\\); group priors set" + ) +}) + +test_that("show() reads a ranged entry, and an empty one", { + placed <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(100L, 200L), width = 1L), + id = c("g1", "g2"), + region_id = c("r1", "r1"), + susie_pip = c(0.9, 0.1) + ) + expect_output( + show(CtwasResultEntry(posteriors = placed)), + "2 gene\\(s\\) in 1 region\\(s\\); group priors not set" + ) + # No id or region column to count, and no posteriors at all. + expect_output( + show(CtwasResultEntry(posteriors = data.frame(susie_pip = 0.5))), + "0 gene\\(s\\) in 0 region\\(s\\)" + ) + expect_output(show(CtwasResultEntry()), "0 gene\\(s\\) in 0 region\\(s\\)") +}) diff --git a/tests/testthat/test_GenotypeDosageSeed.R b/tests/testthat/test_GenotypeDosageSeed.R index 5ad2ea8e..fe7687ae 100644 --- a/tests/testthat/test_GenotypeDosageSeed.R +++ b/tests/testthat/test_GenotypeDosageSeed.R @@ -5,16 +5,16 @@ context("GenotypeDosageSeed") # FORMAT/DS shapes, both SNPRelate storage orders, and SeqArray's 2-bit # planes. +.vcfOverlapDs <- function() { + `[<-`(.vcfOverlapGt(), 1L, , value = c(0.1, 0.9, 1.8)) +} + samples3 <- c("s1", "s2", "s3") .seedOf <- function(panel) { DelayedArray::seed(SummarizedExperiment::assay(panel, "dosage")) } -.dose <- function(panel) { - unname(as.matrix(SummarizedExperiment::assay(panel, "dosage"))) -} - # .vcfOverlapRecords() with one DS value per record: its first ALT allele's. .oneValueDs <- function() { recs <- .vcfOverlapRecords() diff --git a/tests/testthat/test_GenotypeMixture.R b/tests/testthat/test_GenotypeMixture.R index ea3cf3cc..00ebe0ff 100644 --- a/tests/testthat/test_GenotypeMixture.R +++ b/tests/testthat/test_GenotypeMixture.R @@ -18,10 +18,12 @@ test_that("GenotypeMixture aligns its panels to the variants they share", { expect_named(comps, c("a", "b")) expect_equal(map_int(comps, ncol), c(a = 40L, b = 60L)) expect_equal(map_int(comps, nrow), c(a = nrow(p$full), b = nrow(p$full))) + # The canonical ids the shared ranges render, not the panels' labels. expect_identical( variantIds(mix), - as.character(SummarizedExperiment::rowRanges(p$full)$SNP) + pecotmr:::.grVariantIds(SummarizedExperiment::rowRanges(p$full)) ) + expect_true(all(str_detect(variantIds(mix), "^chr21:[0-9]+:[ACGT]+:"))) # Each panel records its allele coding against the first's; these two # halves of one panel code every variant alike. expect_true(all(pecotmr:::.gmSign(mix) == 1)) @@ -354,10 +356,12 @@ test_that("an LD statistic reads a mixture's blocks as LdMatrix ones", { gr <- SummarizedExperiment::rowRanges(p$full) pos <- GenomicRanges::start(gr) cuts <- list(1:100, 101:250) - blocks <- data.frame( - chrom = "chr21", - start = c(pos[[1L]], pos[[101L]]), - end = c(pos[[100L]], pos[[250L]]) + blocks <- GenomicRanges::GRanges( + "chr21", + IRanges::IRanges( + c(pos[[1L]], pos[[101L]]), + c(pos[[100L]], pos[[250L]]) + ) ) lazy <- buildLdScore(mix, ldBlocks = blocks, genome = "hg19") expect_identical(ldReference(lazy), mix) diff --git a/tests/testthat/test_GwasFineMappingResult.R b/tests/testthat/test_GwasFineMappingResult.R index 4946b03e..cf2e1e50 100644 --- a/tests/testthat/test_GwasFineMappingResult.R +++ b/tests/testthat/test_GwasFineMappingResult.R @@ -14,34 +14,69 @@ test_that("GwasFineMappingResult: builds a collection keyed by 2-tuple", { expect_equal(nrow(res), 2L) }) -test_that("GwasFineMappingResult: region is derived from the variants", { - # genomicRegion() reports the element's REALIZED variant span, not a nominal - # window parsed out of blockId. A stored window had no correct update - # rule under subsetRegion() and would quietly go stale; the span is in - # sync by construction. +test_that("GwasFineMappingResult: a window comes from region, not blockId", { + # A blockId is a name, however it is spelled: it gives no window, so the + # rows keep their spans and nothing was given. e1 <- .sc_makeFineMappingRow(3) - e2 <- .sc_makeFineMappingRow(2) + e2 <- .sc_makeFineMappingRow(2, offset = 1000L) res <- GwasFineMappingResult( studyName = c("g1", "g1"), method = c("susie", "susie"), - blockId = c("chr1_1_500", "chr2_600_900"), + blockId = c("chr1_1_500", "b2"), entry = list(e1, e2) ) - reg <- genomicRegion(res) - expect_equal(as.character(GenomicRanges::seqnames(reg)), c("chr1", "chr1")) - expect_equal(GenomicRanges::start(reg), c(100L, 100L)) - expect_equal(GenomicRanges::end(reg), c(300L, 200L)) - # A synthetic blockId no longer produces a chrUn sentinel: with the span - # derived from the variants there is nothing to fabricate. + expect_identical(res$blockId, c("chr1_1_500", "b2")) + expect_identical( + as.character(genomicRegion(res)), + c("chr1:100-300", "chr1:1100-1200") + ) + expect_identical(res$regionGiven, c(FALSE, FALSE)) + # A window that leaves out its row's variants is not that row's window. + expect_error( + GwasFineMappingResult( + studyName = c("g1", "g1"), + method = c("susie", "susie"), + entry = list(e1, e2), + region = GenomicRanges::GRanges( + c("chr1", "chr2"), + IRanges::IRanges(c(1L, 600L), c(500L, 900L)) + ) + ), + "row 2: range chr2:600-900, variants at chr1:1100-1200", + fixed = TRUE + ) + expect_error( + GwasFineMappingResult( + studyName = "g1", + method = "susie", + entry = list(e1), + region = GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(150L, 400L) + ) + ), + "must contain the row's variants" + ) + # With no range given there is no region column: genomicRegion() reads + # the span of the variants, which cannot drift out of step with them. res2 <- GwasFineMappingResult( studyName = "g1", method = "susie", entry = list(e1) ) - expect_equal( - as.character(GenomicRanges::seqnames(genomicRegion(res2))), - "chr1" + expect_false("region" %in% colnames(S4Vectors::mcols(res2))) + expect_false(res2$regionGiven) + expect_identical(as.character(genomicRegion(res2)), "chr1:100-300") + # A `region` is given, whatever the blockId. + res3 <- GwasFineMappingResult( + studyName = "g1", + method = "susie", + entry = list(e1), + blockId = "b1", + region = GenomicRanges::GRanges("chr1", IRanges::IRanges(50L, 400L)) ) + expect_true(res3$regionGiven) + expect_identical(as.character(genomicRegion(res3)), "chr1:50-400") }) @@ -80,27 +115,6 @@ test_that("GwasFineMappingResult: errors on length mismatch", { }) -test_that("GwasFineMappingResult: same (study, method), other ranges", { - # Row identity is (study, method, range), so (study, method) may repeat as - # long as the two rows cover different genomic spans. This is the - # genome-wide-across-blocks shape that qtlEnrichmentPipeline + - # colocPipeline expect, and it now needs no label to disambiguate it. - e1 <- .sc_makeFineMappingRow(3) - e2 <- .sc_makeFineMappingRow(3, offset = 10000L) - res <- GwasFineMappingResult( - studyName = c("g1", "g1"), - method = c("susie", "susie"), - entry = list(e1, e2) - ) - expect_s4_class(res, "GwasFineMappingResult") - expect_equal(nrow(res), 2L) - # No blockId was supplied, so the column is simply absent -- nothing - # synthesises a placeholder id any more. - expect_false(is_in("blockId", colnames(res))) - expect_equal(length(unique(.rtlRangeKeys(res))), 2L) -}) - - test_that("GwasFineMappingResult: rejects two rows covering the same range", { # Same (study, method) AND the same span: these are the same block, and no # blockId label can make them distinct -- which is the point of keying on @@ -111,7 +125,7 @@ test_that("GwasFineMappingResult: rejects two rows covering the same range", { GwasFineMappingResult( studyName = c("g1", "g1"), method = c("susie", "susie"), - blockId = c("chr22_1_100", "chr22_200_300"), + blockId = c("blockA", "blockB"), entry = list(e1, e2) ), "uniqueness violated" @@ -134,20 +148,6 @@ test_that("GwasFineMappingResult: errors when blockId length mismatches", { }) -test_that("GwasFineMappingResult: show prints summary", { - e <- .sc_makeFineMappingRow(3) - res <- GwasFineMappingResult( - studyName = "g1", - method = "susie", - entry = list(e) - ) - expect_output(show(res), "GwasFineMappingResult") -}) - -# =========================================================================== -# TwasWeights collection -# =========================================================================== - # === Tests migrated from test_showMethods.R (GwasFineMappingResult) === test_that("show.GwasFineMappingResult prints (study, method) summary", { @@ -177,19 +177,6 @@ test_that("show.GwasFineMappingResult reports the ldReference source", { # === Tests migrated from test_collectionAccessors.R (GwasFineMappingResult) === -test_that("GwasFineMappingResult: pip with study/method selectors", { - e1 <- .ca_makeFmEntry(3) - e2 <- .ca_makeFmEntry(4) - res <- GwasFineMappingResult( - studyName = c("g1", "g2"), - method = c("susie", "susie"), - entry = list(e1, e2) - ) - pip <- pip(res, studyName = "g2", method = "susie") - expect_equal(length(pip), 4L) -}) - - test_that("GwasFineMappingResult: contexts/traitNames return NULL", { e <- .ca_makeFmEntry(3) res <- GwasFineMappingResult( @@ -209,7 +196,7 @@ test_that("GwasFineMappingResult: credibleSets/topLoci/susieFit/variantIds dispa method = "susie", entry = list(e) ) - expect_equal(nrow(credibleSets(res)), 2L) + expect_equal(length(credibleSets(res)), 2L) # topLoci returns the projected posterior view (filtered by default # signalCutoff = 0.025; .ca_makeTopLoci sets all pip > 0.025 so all rows # survive). Compare on the projected shape, not the slot's raw shape. @@ -225,11 +212,11 @@ test_that("GwasFineMappingResult: topLoci aggregates per-block rows genome-wide" # With no selectors topLoci now stacks both blocks, tagging each variant # with its blockId; context/trait are NA-filled (GWAS keys on region). e1 <- .sc_makeFineMappingRow(3) - e2 <- .sc_makeFineMappingRow(2) + e2 <- .sc_makeFineMappingRow(2, offset = 1000L) res <- GwasFineMappingResult( studyName = c("g1", "g1"), method = c("susie", "susie"), - blockId = c("chr1:1-100", "chr1:200-300"), + blockId = c("chr1:1-500", "chr1:501-2000"), entry = list(e1, e2) ) agg <- topLoci(res, signalCutoff = 0) @@ -237,11 +224,11 @@ test_that("GwasFineMappingResult: topLoci aggregates per-block rows genome-wide" expect_equal( agg$blockId, c( - "chr1:1-100", - "chr1:1-100", - "chr1:1-100", - "chr1:200-300", - "chr1:200-300" + "chr1:1-500", + "chr1:1-500", + "chr1:1-500", + "chr1:501-2000", + "chr1:501-2000" ) ) expect_true(all(is.na(agg$context))) @@ -249,49 +236,71 @@ test_that("GwasFineMappingResult: topLoci aggregates per-block rows genome-wide" expect_true("variant_id" %in% names(S4Vectors::mcols(agg))) }) -test_that("GwasFineMappingResult: topLoci region= selects a single block", { +test_that("GwasFineMappingResult: topLoci picks one block by name or window", { e1 <- .sc_makeFineMappingRow(3) - e2 <- .sc_makeFineMappingRow(2) + e2 <- .sc_makeFineMappingRow(2, offset = 1000L) res <- GwasFineMappingResult( studyName = c("g1", "g1"), method = c("susie", "susie"), - blockId = c("chr1:1-100", "chr1:200-300"), + blockId = c("chr1:1-500", "chr1:501-2000"), entry = list(e1, e2) ) - # region= pins one row, so this hits the single-entry fast path (bare table). + # blockId= pins one row, so this hits the single-entry fast path (bare + # table). tl <- topLoci( res, studyName = "g1", method = "susie", - region = "chr1:200-300", + blockId = "chr1:501-2000", signalCutoff = 0 ) expect_equal(length(tl), 2L) expect_false("blockId" %in% names(S4Vectors::mcols(tl))) + # A window selects rows by subsetting the collection on its rows' + # analysis windows -- here, alone, the second block, whose variants span + # chr1:1100-1200. + byWindow <- topLoci( + res[IRanges::overlapsAny( + genomicRegion(res), + GenomicRanges::GRanges("chr1:1150-1500") + )], + signalCutoff = 0 + ) + expect_identical(as.character(byWindow), as.character(tl)) + # A window over both blocks keeps both, which then aggregate. + both <- topLoci( + res[IRanges::overlapsAny( + genomicRegion(res), + GenomicRanges::GRanges("chr1:1-5000") + )], + signalCutoff = 0 + ) + expect_equal(length(both), 5L) + expect_true("blockId" %in% names(S4Vectors::mcols(both))) }) test_that("GwasFineMappingResult: credibleSets aggregates CS across blocks", { e1 <- .sc_makeFineMappingRow(3) - e2 <- .sc_makeFineMappingRow(2) + e2 <- .sc_makeFineMappingRow(2, offset = 1000L) res <- GwasFineMappingResult( studyName = c("g1", "g1"), method = c("susie", "susie"), - blockId = c("chr1:1-100", "chr1:200-300"), + blockId = c("chr1:1-500", "chr1:501-2000"), entry = list(e1, e2) ) cs <- credibleSets(res) - expect_equal(nrow(cs), 4L) # 2 CS members per block + expect_equal(length(cs), 4L) # 2 CS members per block expect_equal( cs$blockId, - c("chr1:1-100", "chr1:1-100", "chr1:200-300", "chr1:200-300") + c("chr1:1-500", "chr1:1-500", "chr1:501-2000", "chr1:501-2000") ) expect_true(all(is.na(cs$context))) - # region= pins one block -> bare table + # blockId= pins one block -> bare table bare <- credibleSets( res, studyName = "g1", method = "susie", - region = "chr1:1-100" + blockId = "chr1:1-500" ) expect_false("blockId" %in% names(bare)) }) @@ -304,7 +313,7 @@ test_that("GwasFineMappingResult: .tupleSelectRowGwasFmr requires both selectors method = c("susie", "susie"), entry = list(e, e) ) - expect_error(pip(res), "Pass `study` and `method`") + expect_error(pip(res), "Pass `studyName` and `method`") expect_error( pip(res, studyName = c("g1", "g2"), method = "susie"), "Must have length 1" @@ -339,9 +348,11 @@ test_that("GwasFineMappingResult: marginalEffects with study/method selectors", # Collection-level selection picks the g2 entry, then delegates to the # entry-level getMarginalEffects. me <- marginalEffects(res, studyName = "g2", method = "susie") - expect_s3_class(me, "data.frame") - expect_equal(nrow(me), 4L) - expect_true(all(c("variant_id", "beta", "se", "z", "p") %in% names(me))) + expect_s4_class(me, "GRanges") + expect_equal(length(me), 4L) + expect_true(all( + c("variant_id", "beta", "se", "z", "p") %in% names(S4Vectors::mcols(me)) + )) }) # =========================================================================== @@ -380,21 +391,17 @@ test_that("validity names a missing entry payload column", { ) }) -test_that("GwasFineMappingResult: pip(returnList) keys by study|method", { - # Documented as "a per-entry list keyed by identity tuple". The QTL - # method always honoured it; this one used to ignore the flag and hand - # back the flat vector, so the list branch had no test. +test_that("GwasFineMappingResult: pip() reads the row the selectors pick", { res <- GwasFineMappingResult( studyName = c("g1", "g2"), method = c("susie", "susie"), entry = list(.ca_makeFmEntry(3), .ca_makeFmEntry(4)) ) - got <- pip(res, studyName = "g2", method = "susie", returnList = TRUE) - expect_type(got, "list") - expect_named(got, "g2|susie") - expect_equal(length(got[["g2|susie"]]), 4L) - # The flat vector is still what you get without the flag. - expect_false(is.list(pip(res, studyName = "g2", method = "susie"))) + got <- pip(res, studyName = "g2", method = "susie") + expect_type(got, "double") + expect_length(got, 4L) + # One return type: the list form is gone with its switch. + expect_error(pip(res, studyName = "g2", returnList = TRUE), "unused") }) test_that("GwasFineMappingResult: context / trait selectors are refused", { @@ -442,3 +449,207 @@ test_that("GwasFineMappingResult: context / trait selectors are refused", { 3L ) }) + +# =========================================================================== +# A study fine-mapped block by block +# =========================================================================== + +# One study fine-mapped in two LD blocks with two methods, plus a second +# study in one block. +.gfr_makeBlocked <- function() { + GwasFineMappingResult( + studyName = c("g1", "g1", "g1", "g1", "g2"), + method = c("susie", "susie", "ser", "ser", "susie"), + entry = list( + .sc_makeFineMappingRow(3), + .sc_makeFineMappingRow(3, offset = 10000L), + .sc_makeFineMappingRow(3), + .sc_makeFineMappingRow(3, offset = 10000L), + .sc_makeFineMappingRow(3) + ), + blockId = c( + "chr1_1_5000", + "chr1_5001_20000", + "chr1_1_5000", + "chr1_5001_20000", + "chr1_1_5000" + ) + ) +} + +test_that("pip(GwasFineMappingResult) picks a block by name or window", { + x <- .gfr_makeBlocked() + named <- pip( + x, + studyName = "g1", + method = "susie", + blockId = "chr1_5001_20000" + ) + near <- pip( + x[IRanges::overlapsAny( + genomicRegion(x), + GenomicRanges::GRanges("chr1:10100-10150") + )], + studyName = "g1", + method = "susie" + ) + expect_identical(near, named) + expect_length(named, 3L) + expect_error( + pip(x, studyName = "g1", method = "susie"), + "pass `blockId` to disambiguate" + ) +}) + +test_that("fineMappingResult returns every block of a fit, or the one named", { + x <- .gfr_makeBlocked() + fit <- fineMappingResult(x, studyName = "g1", method = "susie") + expect_s4_class(fit, "GwasFineMappingResult") + expect_equal(nrow(fit), 2L) + expect_identical(fit$blockId, c("chr1_1_5000", "chr1_5001_20000")) + one <- fineMappingResult( + x, + studyName = "g1", + method = "susie", + blockId = "chr1_5001_20000" + ) + expect_equal(nrow(one), 1L) + expect_identical(one$blockId, "chr1_5001_20000") + # Subsetting on the rows' windows keeps the blocks a window overlaps. + near <- fineMappingResult( + x[IRanges::overlapsAny( + genomicRegion(x), + GenomicRanges::GRanges("chr1:10100-10150") + )], + studyName = "g1", + method = "susie" + ) + expect_identical(near$blockId, "chr1_5001_20000") + # Selectors left unset are fine while they still name one fit. + expect_equal(nrow(fineMappingResult(x, studyName = "g2")), 1L) + expect_error( + fineMappingResult(x, studyName = "g1"), + "holds 2 \\(study, method\\) fits matching the selection" + ) + expect_error( + fineMappingResult(x, studyName = "g1", method = "susie", blockId = "z"), + "No entry for \\(study='g1', method='susie', blockId='z'\\)" + ) + expect_error( + fineMappingResult(x, method = "lasso"), + "No entry for \\(study='', method='lasso'\\)" + ) + expect_error( + fineMappingResult(x, studyName = "g1", context = "brain"), + "no context or trait axis" + ) + expect_error( + fineMappingResult(x[0L], studyName = "g1"), + "has no rows" + ) +}) + +test_that("a fit carried by a multi-chromosome entry is refused", { + # Splitting the entry by chromosome would copy its one fit onto every + # piece, and each piece would then be read as the whole fit. + ids <- c("chr1:100:A:G", "chr2:100:A:G") + tl <- data.frame(variant_id = ids, pip = c(0.6, 0.4)) + fitted <- FineMappingRow( + variantIds = ids, + susieFit = list(pip = setNames(c(0.6, 0.4), ids)), + topLoci = tl + ) + expect_error( + GwasFineMappingResult( + studyName = "g1", + method = "susie", + entry = list(fitted) + ), + "`entry` element\\(s\\) 1 span more than one chromosome but carry" + ) + # Without a fit there is nothing to copy, and the entry splits as before. + bare <- FineMappingRow(variantIds = ids, susieFit = list(), topLoci = tl) + split <- GwasFineMappingResult( + studyName = "g1", + method = "susie", + entry = list(bare) + ) + expect_equal(nrow(split), 2L) +}) + +test_that("filtering every variant out of a fit's blocks keeps them apart", { + skip_if_not_installed("plyranges") + x <- .gfr_makeBlocked() + # Each block becomes an empty row; its blockId keeps it distinct. + emptied <- dplyr::filter(x, pip > 2) + expect_equal(unname(lengths(emptied)), rep(0L, 5L)) + expect_identical(emptied$blockId, x$blockId) +}) + +test_that("a row without a blockId is named by its own span", { + # Row identity is (study, method, range), so one (study, method) may hold + # two blocks over other spans -- the genome-wide-across-blocks shape that + # qtlEnrichmentPipeline + colocPipeline expect. The caller named neither + # row; each is named by the stretch its variants cover, the range its + # identity already keys on. + x <- GwasFineMappingResult( + studyName = c("g1", "g1"), + method = c("susie", "susie"), + entry = list( + .sc_makeFineMappingRow(3), + .sc_makeFineMappingRow(3, offset = 10000L) + ) + ) + expect_identical(x$blockId, c("chr1_100_300", "chr1_10100_10300")) + expect_identical(x$blockId, .rtlRangeKeys(x)) + # A span filled in as the id was computed, not given. + expect_identical(x$regionGiven, c(FALSE, FALSE)) + # A supplied id is kept, and an NA one filled. + y <- GwasFineMappingResult( + studyName = c("g1", "g1"), + method = c("susie", "susie"), + entry = list( + .sc_makeFineMappingRow(3), + .sc_makeFineMappingRow(3, offset = 10000L) + ), + blockId = c("blockA", NA) + ) + expect_identical(y$blockId, c("blockA", "chr1_10100_10300")) + # Each chromosome piece of a fit-less entry gets its own span. + ids <- c("chr1:100:A:G", "chr2:500:A:G") + split <- GwasFineMappingResult( + studyName = "g1", + method = "susie", + entry = list(FineMappingRow( + ids, + susieFit = list(), + topLoci = data.frame(variant_id = ids, pip = c(0.6, 0.4)) + )) + ) + expect_identical(split$blockId, c("chr1_100_100", "chr2_500_500")) +}) + +test_that("GwasFineMappingResult() keeps the caller's metadata", { + res <- GwasFineMappingResult( + studyName = "g1", + method = "susie", + entry = list(.sc_makeFineMappingRow(3)), + metadata = list(run = "r1") + ) + expect_equal(S4Vectors::metadata(res), list(run = "r1")) +}) + +test_that("a fit-less entry split across chromosomes records no fit variants", { + # Its rows hold one chromosome each; with no fit there is nothing for a + # row to have narrowed, so none of them warns. + ids <- c("chr1:100:A:G", "chr2:200:C:T") + tl <- data.frame(variant_id = ids, pip = c(0.6, 0.4)) + res <- GwasFineMappingResult( + studyName = "g1", + method = "susie", + entry = list(FineMappingRow(ids, NULL, tl)) + ) + expect_equal(nrow(res), 2L) + expect_equal(unname(lengths(res$fitVariants)), c(0L, 0L)) + expect_no_warning(lbf(res)) +}) diff --git a/tests/testthat/test_GwasSumStats.R b/tests/testthat/test_GwasSumStats.R index be4dc9e9..c1767d3c 100644 --- a/tests/testthat/test_GwasSumStats.R +++ b/tests/testthat/test_GwasSumStats.R @@ -1,87 +1,172 @@ -# Tests migrated from test_h2ClassesSumstats.R +# Tests for R/gwasSumStats.R (the GwasSumStats class). makeGwasSumStatsFromDf(), +# below, is a test helper over GwasSumStats(). + +makeTestSumstatsDf <- function(n = 50) { + set.seed(42) + data.frame( + SNP = paste0("rs", seq_len(n)), + CHR = rep("1", n), + BP = seq(1000, by = 100, length.out = n), + A1 = rep("A", n), + A2 = rep("G", n), + Z = rnorm(n), + N = rep(10000, n), + stringsAsFactors = FALSE + ) +} -# === Tests migrated from test_h2ClassesSumstats.R (GwasSumStats) === +# Bridge helper: turn the legacy per-study data.frame shape into a +# single-row GwasSumStats collection using the new API. Keeps the bulk of +# the per-accessor tests below readable. +.testGenotypeHandle <- function() { + new( + "GenotypeHandle", + path = "/tmp/test", + format = "plink2", + snpInfo = data.frame(), + nSamples = 0L, + sampleIds = character(), + pgenPtr = NULL + ) +} -test_that("GwasSumStats(df) errors when required mcols are missing", { - df <- data.frame( - SNP = "rs1", - CHR = "1", - BP = 100, - A1 = "A", - stringsAsFactors = FALSE +.dfToSumstatsGr <- function(df) { + chrs <- as.character(df$CHR) + if (!all(grepl("^chr", chrs))) { + chrs <- paste0("chr", sub("^chr", "", chrs)) + } + gr <- GenomicRanges::GRanges( + seqnames = chrs, + ranges = IRanges::IRanges(start = as.integer(df$BP), width = 1L) ) - expect_error( - makeGwasSumStatsFromDf(df), - "Missing required columns" + mc <- df[, setdiff(colnames(df), c("CHR", "BP")), drop = FALSE] + S4Vectors::mcols(gr) <- S4Vectors::DataFrame(mc) + gr +} + +makeGwasSumStatsFromDf <- function( + df, + traitName = "test", + genome = "hg19", + varY = NA_real_ +) { + if (is.null(varY)) { + varY <- NA_real_ + } + GwasSumStats( + studyName = traitName, + entry = list(.dfToSumstatsGr(df)), + genome = genome, + ldReference = .testGenotypeHandle(), + varY = varY ) -}) +} +# A handle over a real (fake-path) variant set, so tests can build the +# per-block LD panels a block-parallel pipeline produces: same genotype source, +# each narrowed to its own variants. +.blockGenotypeHandle <- function(bp, path = "/tmp/test.pgen") { + new( + "GenotypeHandle", + path = path, + format = "plink2", + snpInfo = data.frame( + SNP = paste0("chr1:", bp, ":A:G"), + CHR = rep("chr1", length(bp)), + BP = as.integer(bp), + A1 = rep("G", length(bp)), + A2 = rep("A", length(bp)), + fileIdx = seq_along(bp), + stringsAsFactors = FALSE + ), + nSamples = 10L, + sampleIds = paste0("s", seq_len(10)), + pgenPtr = NULL + ) +} -test_that("GwasSumStats valid object passes with all required mcols", { - set.seed(1) +# One LD block's worth of GWAS summary statistics: `n` variants starting at +# `start`, carrying a QC record and an LD panel narrowed to just those +# variants (what a per-block pipeline step writes out). +makeGwasBlock <- function( + blockId, + start, + n = 5L, + genome = "hg19", + qcOptions = list(mafCutoff = 0.01), + ldReference = .blockGenotypeHandle(bp) +) { + bp <- seq(start, by = 100L, length.out = n) df <- data.frame( - SNP = paste0("rs", 1:5), - CHR = rep("1", 5), - BP = 1:5, - A1 = rep("A", 5), - A2 = rep("G", 5), - Z = rnorm(5), - N = rep(1000, 5), + SNP = paste0("chr1:", bp, ":A:G"), + CHR = rep("1", n), + BP = bp, + A1 = rep("A", n), + A2 = rep("G", n), + Z = seq_len(n) / 10, + N = rep(1000L, n), stringsAsFactors = FALSE ) - obj <- makeGwasSumStatsFromDf(df) - expect_true(methods::validObject(obj)) -}) - + obj <- GwasSumStats( + studyName = "trait1", + entry = list(.dfToSumstatsGr(df)), + genome = genome, + ldReference = ldReference, + blockId = blockId, + qcOptions = list(timestamp = NA_character_, options = qcOptions) + ) + obj$qcAudit <- S4Vectors::SimpleList(list(list( + variantsIn = n, + block = blockId + ))) + obj +} -test_that("makeGwasSumStatsFromDf() constructor creates object from data.frame", { +test_that("GwasSumStats() records the study, genome build and variants", { df <- makeTestSumstatsDf(20) obj <- makeGwasSumStatsFromDf(df, traitName = "height", genome = "hg38") expect_s4_class(obj, "GwasSumStats") - expect_equal(as.character(obj$study)[[1L]], "height") + expect_true(methods::validObject(obj)) + # One chromosome, so one row, keyed on the study it was given. + expect_identical(obj$study, "height") expect_equal(unname(GenomeInfoDb::genome(obj)), "hg38") - expect_equal(length(sumStats(obj)), 20) -}) - - -test_that("makeGwasSumStatsFromDf() normalizes chr prefix", { - df <- makeTestSumstatsDf(5) - # Input has CHR = "1" (no prefix) - obj <- makeGwasSumStatsFromDf(df) - chrs <- as.character(GenomicRanges::seqnames(sumStats(obj))) - expect_true(all(startsWith(chrs, "chr"))) - - # Input already has "chr" prefix - df2 <- df - df2$CHR <- "chr1" - obj2 <- makeGwasSumStatsFromDf(df2) - chrs2 <- as.character(GenomicRanges::seqnames(sumStats(obj2))) - # Should not double-prefix - expect_true(all(chrs2 == "chr1")) - expect_false(any(grepl("^chrchr", chrs2))) -}) - - -test_that("makeGwasSumStatsFromDf() errors on missing columns", { - df <- data.frame(SNP = "rs1", CHR = "1", BP = 100) - expect_error(makeGwasSumStatsFromDf(df), "Missing required columns") + expect_identical(sumStats(obj)$SNP, df$SNP) }) -test_that("makeGwasSumStatsFromDf() removes rows with NA in required columns", { - df <- makeTestSumstatsDf(10) - df$Z[1] <- NA - df$N[3] <- NA - expect_message( - obj <- makeGwasSumStatsFromDf(df), - "Removed.*SNPs with missing" +test_that("GwasSumStats() reads an entry's chromosomes in UCSC style", { + # Built here rather than through makeGwasSumStatsFromDf(), which adds + # the "chr" prefix itself before the constructor sees the names. + gr <- GenomicRanges::GRanges( + c("1", "1", "CHR2"), + IRanges::IRanges(c(100L, 200L, 300L), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = c("rs1", "rs2", "rs3"), + A1 = "A", + A2 = "G", + Z = c(1, 2, 3), + N = 100L ) - expect_equal(length(sumStats(obj)), 8) + obj <- GwasSumStats(studyName = "t1", entry = list(gr), genome = "hg19") + expect_identical( + as.character(GenomicRanges::seqnames(sumStats(obj))), + c("chr1", "chr1", "chr2") + ) + # The per-chromosome rows are keyed on the renamed chromosomes. + expect_identical(obj$blockId, c("chr1", "chr2")) + # Names already in UCSC style are kept, not prefixed a second time. + again <- GwasSumStats( + studyName = "t1", + entry = list(sumStats(obj)), + genome = "hg19" + ) + expect_identical(GenomeInfoDb::seqlevels(again), c("chr1", "chr2")) }) -test_that("getz() returns correct Z vector", { +test_that("z() returns correct Z vector", { set.seed(99) df <- makeTestSumstatsDf(5) obj <- makeGwasSumStatsFromDf(df) @@ -91,16 +176,16 @@ test_that("getz() returns correct Z vector", { }) -test_that("getn() returns correct N vector", { +test_that("sampleSize() returns correct N vector", { df <- makeTestSumstatsDf(5) obj <- makeGwasSumStatsFromDf(df) - n <- nSamples(obj) + n <- sampleSize(obj) expect_equal(length(n), 5) expect_true(all(n == 10000)) }) -test_that("getmaf() returns MAF when present, NULL when absent", { +test_that("maf() returns MAF when present, NULL when absent", { df <- makeTestSumstatsDf(5) obj_no_maf <- makeGwasSumStatsFromDf(df) expect_null(maf(obj_no_maf)) @@ -120,23 +205,22 @@ test_that("nSnps() returns correct count", { }) -test_that("subsetchr() filters correctly", { +test_that("keepSeqlevels() narrows a GwasSumStats to a chromosome", { df <- makeTestSumstatsDf(10) df$CHR <- c(rep("1", 6), rep("2", 4)) obj <- makeGwasSumStatsFromDf(df) - chr1 <- subsetChr(obj, "1") + chr1 <- GenomeInfoDb::keepSeqlevels(obj, "chr1", pruning.mode = "coarse") + expect_s4_class(chr1, "GwasSumStats") expect_equal(nSnps(chr1), 6) - - # Also works with "chr" prefix - chr2 <- subsetChr(obj, "chr2") + chr2 <- GenomeInfoDb::keepSeqlevels(obj, "chr2", pruning.mode = "coarse") expect_equal(nSnps(chr2), 4) }) -test_that("subsetChr() preserves study-level nCase/nControl/nSample scalars", { - # Regression: the chromosome subset rebuilds the GwasSumStats and previously - # dropped the optional per-study case/control counts + total N. +test_that("keepSeqlevels() preserves study-level nCase/nControl/nSample", { + # The per-study case/control counts and total N are row columns, so a + # chromosome subset carries them with the rows it keeps. gr <- GenomicRanges::GRanges( c("chr1", "chr1", "chr2"), IRanges::IRanges(start = c(100L, 200L, 300L), width = 1L) @@ -158,7 +242,7 @@ test_that("subsetChr() preserves study-level nCase/nControl/nSample scalars", { nSample = 20000 ) - sub <- subsetChr(obj, "chr1") + sub <- GenomeInfoDb::keepSeqlevels(obj, "chr1", pruning.mode = "coarse") expect_equal(nSnps(sub), 2) expect_equal(as.numeric(sub$nCase), 5000) expect_equal(as.numeric(sub$nControl), 15000) @@ -166,7 +250,7 @@ test_that("subsetChr() preserves study-level nCase/nControl/nSample scalars", { }) -test_that("getvary() returns var_y and NULL cases", { +test_that("varY() returns var_y and NULL cases", { df <- makeTestSumstatsDf(5) obj_null <- makeGwasSumStatsFromDf(df, varY = NULL) @@ -177,15 +261,16 @@ test_that("getvary() returns var_y and NULL cases", { }) -test_that("as.data.frame() round-trips in the standardized layout", { +test_that("as.data.frame() is the standard coercion, one row per variant", { df_in <- makeTestSumstatsDf(15) obj <- makeGwasSumStatsFromDf(df_in) - df_out <- as.data.frame(obj) - - # One coercion per class: as.data.frame() is the table view of - # sumStats(), so it yields the standardized layout rather than the raw - # mcols names. The raw form is still reachable through - # as.data.frame(mcols(sumStats(obj))). + # The inherited GRangesList coercion: the element ranges plus their + # stored mcols, under the stored names. + std <- as.data.frame(obj) + expect_true(all(c("group", "seqnames", "start", "Z") %in% names(std))) + expect_equal(nrow(std), 15) + # The standardized layout the pipelines use is built internally. + df_out <- pecotmr:::.entryToSumstatDf(sumStats(obj)) expect_true(is.data.frame(df_out)) expect_true(all( c("variant_id", "chrom", "pos", "A1", "A2", "z", "N") %in% @@ -199,11 +284,9 @@ test_that("as.data.frame() round-trips in the standardized layout", { # ============================================================================= -# AnnotationMatrix (h2Annotations.R) +# show() # ============================================================================= -# === Tests migrated from test_showMethods.R (GwasSumStats) === - test_that("show.GwasSumStats prints nrow and genome build", { ss <- GwasSumStats( studyName = c("g1", "g2"), @@ -212,11 +295,34 @@ test_that("show.GwasSumStats prints nrow and genome build", { ldReference = .sh_makeGenotypeHandle() ) out <- capture.output(show(ss)) - expect_true(any(grepl("GwasSumStats: 2 studies, genome build hg19", out))) + expect_true(any(grepl( + "GwasSumStats: 2 studies in 2 rows, genome build hg19", + out + ))) expect_true(any(grepl("LD reference: plink2 @ /tmp/test", out))) }) -# === Tests migrated from test_h2ClassesSumstats.R (showMethods) === +test_that("show.GwasSumStats counts a study split across chromosomes once", { + gr <- GenomicRanges::GRanges( + c("chr1", "chr2"), + IRanges::IRanges(c(100L, 100L), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = c("chr1:100:A:G", "chr2:100:A:G"), + A1 = "A", + A2 = "G", + Z = c(1, 2), + N = 100L + ) + ss <- GwasSumStats(studyName = "g1", entry = list(gr), genome = "hg19") + expect_equal(nrow(ss), 2L) + out <- capture.output(show(ss)) + # One header line, not one per chromosome the study spans. + expect_identical( + grep("^GwasSumStats:", out, value = TRUE), + "GwasSumStats: 1 studies in 2 rows, genome build hg19" + ) +}) # ============================================================================= # GwasSumStats() constructor validation + accessor error branches @@ -345,15 +451,8 @@ test_that("GwasSumStats: a non-GenotypeHandle ldReference is rejected", { ) }) -# show() smoke test, moved here from test_showMethods.R so the test -# tree mirrors R/. -test_that("show(GwasSumStats) does not error", { - ss <- makeGwasSumStatsFromDf(makeTestSumstatsDf(10)) - expect_output(show(ss), "GwasSumStats") -}) - -# blockId + ldBlocks (§4.2). A genome-wide GWAS split by seqname gives one +# blockId + region (§4.2). A genome-wide GWAS split by seqname gives one # element per chromosome, which is too coarse for cTWAS: its EM estimates # parameters across LD blocks. `blockId` is always present so downstream code # can key regions without asking how the collection was built. @@ -372,7 +471,7 @@ test_that("show(GwasSumStats) does not error", { } # @noRd -.gss_ldBlocks <- function() { +.gss_blocks <- function() { b <- GenomicRanges::GRanges( "chr1", IRanges::IRanges(c(1L, 800L), c(500L, 1200L)) @@ -395,7 +494,7 @@ test_that("GwasSumStats splits by LD block when a manifest is supplied", { studyName = "t1", entry = list(g), genome = "hg38", - ldBlocks = .gss_ldBlocks() + region = .gss_blocks() ) # Same chromosome, so the seqname split would have left ONE element; the # manifest is what produces per-block granularity. @@ -412,7 +511,7 @@ test_that("GwasSumStats replicates the study row against each block", { entry = list(g), genome = "hg38", varY = 2, - ldBlocks = .gss_ldBlocks() + region = .gss_blocks() ) expect_equal(x$study, c("t1", "t1")) expect_equal(x$varY, c(2, 2)) @@ -425,7 +524,7 @@ test_that("GwasSumStats warns about variants outside every LD block", { studyName = "t1", entry = list(g), genome = "hg38", - ldBlocks = .gss_ldBlocks() + region = .gss_blocks() ), "1 variant" ) @@ -440,7 +539,7 @@ test_that("GwasSumStats keeps blockId aligned across two studies", { .gss_variants("chr1", 900L) ), genome = "hg38", - ldBlocks = .gss_ldBlocks() + region = .gss_blocks() ) expect_equal(x$study, c("t1", "t1", "t2")) expect_equal(x$blockId, c("b1", "b2", "b2")) @@ -451,13 +550,13 @@ test_that("GwasSumStats blockId survives subsetting", { studyName = "t1", entry = list(.gss_variants("chr1", c(100L, 900L))), genome = "hg38", - ldBlocks = .gss_ldBlocks() + region = .gss_blocks() ) expect_equal(x[2L]$blockId, "b2") }) # =========================================================================== -# Block-key resolution: ldBlocks vs blockId +# Block-key resolution: region vs blockId # # Both arguments answer "how is this entry split into elements", so supplying # both is ambiguous rather than redundant. Neither error branch had a test. @@ -486,13 +585,13 @@ test_that("GwasSumStats blockId survives subsetting", { gr } -test_that("supplying both ldBlocks and blockId is refused", { +test_that("supplying both region and blockId is refused", { expect_error( GwasSumStats( studyName = "g1", entry = list(.gss_entry()), genome = "hg19", - ldBlocks = GenomicRanges::GRanges( + region = GenomicRanges::GRanges( "chr1", IRanges::IRanges(1L, 10000L) ), @@ -556,12 +655,12 @@ test_that("combineGwasSumStats() concatenates the per-element QC audit", { b <- makeGwasBlock("chr1_1001_2000", 1100L, n = 3L) out <- combineGwasSumStats(a, b) - audit <- qcInfo(out)$entryAudit + audit <- out$qcAudit expect_length(audit, nrow(out)) # element i's audit still describes element i expect_equal(audit[[1L]]$block, "chr1_1_1000") expect_equal(audit[[2L]]$block, "chr1_1001_2000") - expect_equal(qcInfo(out)$options, qcInfo(a)$options) + expect_equal(qcOptions(out)$options, qcOptions(a)$options) }) @@ -613,7 +712,7 @@ test_that("combineGwasSumStats() rejects collection-level disagreement", { "different summaryStatsQc\\(\\) options" ) noQc <- makeGwasBlock("chr1_1001_2000", 1100L) - noQc@qcInfo <- list() + noQc@qcOptions <- list() expect_error(combineGwasSumStats(a, noQc), "carry no QC record") }) @@ -653,8 +752,9 @@ test_that("combineGwasSumStats() validates its inputs", { test_that("sumStats(GwasSumStats) refuses the QtlSumStats selectors", { # The shared SumStatsBase accessors pass the union of both classes' - # selectors, so a GWAS sees context / trait / annotateSignificance. It - # names them in order to reject them, rather than absorbing them in `...`. + # selectors, so a GWAS sees context / trait, and sumStats() also takes + # annotateSignificance. It names them in order to reject them, rather + # than absorbing them in `...`. gss <- GwasSumStats( studyName = "g1", entry = list(.gss_entry()), @@ -672,3 +772,207 @@ test_that("sumStats(GwasSumStats) refuses the QtlSumStats selectors", { expect_s4_class(sumStats(gss), "GRanges") expect_type(z(gss), "double") }) + +test_that("varY reads one value for a study split across rows", { + gr <- GenomicRanges::GRanges( + c("chr1", "chr2"), + IRanges::IRanges(c(100L, 100L), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = c("chr1:100:A:G", "chr2:100:A:G"), + A1 = "A", + A2 = "G", + Z = c(1, 2), + N = 100L + ) + ss <- GwasSumStats( + studyName = "g1", + entry = list(gr), + genome = "hg19", + varY = 4 + ) + expect_equal(nrow(ss), 2L) + expect_equal(varY(ss), 4) + # Rows of one study that disagree have no single answer. + split <- GwasSumStats( + studyName = c("g1", "g1"), + entry = list(gr[1L], gr[2L]), + genome = "hg19", + varY = c(1, 2), + blockId = c("a", "b") + ) + expect_error(varY(split), "the 2 rows of study 'g1' disagree on varY") +}) + +test_that("GwasSumStats records each row's window and its origin", { + data(gwasSumStatsS4Example) + gr <- sumStats(gwasSumStatsS4Example) + cut <- GenomicRanges::start(gr)[[100L]] + # A `region` gives each window its interval, however it is keyed. + blocks <- GenomicRanges::GRanges( + "chr22", + IRanges::IRanges(c(1L, cut + 1L), c(cut, 60000000L)) + ) + names(blocks) <- c("b1", "b2") + x <- GwasSumStats( + studyName = "s", + entry = list(gr), + genome = "hg19", + region = blocks + ) + expect_identical(x$blockId, c("b1", "b2")) + expect_identical(x$regionGiven, c(TRUE, TRUE)) + expect_identical( + as.character(x$region), + c(str_c("chr22:1-", cut), str_c("chr22:", cut + 1L, "-60000000")) + ) + # Read from a BED file, a window's start is 0-based and the fourth column + # names it. The variants past its one window are dropped, with a warning. + bedPath <- withr::local_tempfile(fileext = ".bed") + writeLines(str_c("chr22\t0\t", cut, "\tb1"), bedPath) + expect_warning( + bed <- GwasSumStats( + studyName = "s", + entry = list(gr), + genome = "hg19", + region = bedPath + ), + "100 variant(s) lie outside every `region` window", + fixed = TRUE + ) + expect_identical(bed$blockId, "b1") + expect_identical(as.character(bed$region), str_c("chr22:1-", cut)) + # Given in R, a window is a GRanges: a table is refused, not read. + expect_error( + GwasSumStats( + studyName = "s", + entry = list(gr), + genome = "hg19", + region = data.frame(chrom = "chr22", start = 1L, end = cut) + ), + "must be a GRanges or the path of a BED file" + ) + # A blockId is a name and gives no window, however it is spelled: each + # row's window is its variants' span. + y <- GwasSumStats( + studyName = c("s", "s"), + entry = list(gr[1:100], gr[101:200]), + genome = "hg19", + blockId = c("chr22_1_15700000", "b2") + ) + expect_identical(y$blockId, c("chr22_1_15700000", "b2")) + expect_identical(y$regionGiven, c(FALSE, FALSE)) + expect_identical( + as.character(y$region), + c(as.character(range(gr[1:100])), as.character(range(gr[101:200]))) + ) + # One set of windows per study, or none for a study split by chromosome. + per <- suppressWarnings(GwasSumStats( + studyName = c("s", "t"), + entry = list(gr, gr), + genome = "hg19", + region = list(blocks[1L], NULL) + )) + expect_identical(per$study, c("s", "t")) + expect_identical(per$blockId, c("b1", "chr22")) + expect_identical(per$regionGiven, c(TRUE, FALSE)) + expect_error( + GwasSumStats( + studyName = "s", + entry = list(gr), + genome = "hg19", + region = list(blocks, blocks) + ), + "one element per `entry`" + ) + # Split by chromosome, a row's window is its variants' span. + z <- GwasSumStats(studyName = "s", entry = list(gr), genome = "hg19") + expect_false(z$regionGiven) + expect_identical(as.character(z$region), "chr22:14560203-15826991") +}) + +test_that("combineGwasSumStats() carries each row's block range through", { + data(gwasSumStatsS4Example) + gr <- sumStats(gwasSumStatsS4Example) + given <- GwasSumStats( + studyName = "s", + entry = list(gr), + genome = "hg19", + region = GenomicRanges::GRanges("chr22:1-20000000") + ) + computed <- GwasSumStats(studyName = "t", entry = list(gr), genome = "hg19") + both <- combineGwasSumStats(given, computed) + expect_identical(both$regionGiven, c(TRUE, FALSE)) + expect_identical( + as.character(both$region), + c("chr22:1-20000000", "chr22:14560203-15826991") + ) +}) + +# === metadata, qcOptions and a tabular extraCols === + +test_that("GwasSumStats() takes extra columns as a DataFrame or data.frame", { + build <- function(extra) { + GwasSumStats( + studyName = c("g1", "g2"), + entry = list(.sh_makeQtlSumstatsGr(), .sh_makeQtlSumstatsGr()), + genome = "hg19", + ldReference = .sh_makeGenotypeHandle(), + extraCols = extra + ) + } + cohorts <- c("UKB", "FinnGen") + fromDf <- build(S4Vectors::DataFrame(cohort = cohorts, wave = 1:2)) + expect_equal(fromDf$cohort, cohorts) + expect_equal(fromDf$wave, 1:2) + expect_equal(build(data.frame(cohort = cohorts))$cohort, cohorts) +}) + +test_that("GwasSumStats() keeps the caller's metadata and QC options", { + obj <- GwasSumStats( + studyName = "g1", + entry = list(.sh_makeQtlSumstatsGr()), + genome = "hg19", + ldReference = .sh_makeGenotypeHandle(), + qcOptions = list(step1 = "ok"), + metadata = list(source = "unit test") + ) + expect_equal(S4Vectors::metadata(obj), list(source = "unit test")) + expect_equal(qcOptions(obj), list(step1 = "ok")) +}) + +# =========================================================================== +# nCase and nControl +# =========================================================================== + +test_that("GwasSumStats: nCase/nControl are optional columns (absent by default)", { + gr <- GenomicRanges::GRanges( + seqnames = "chr1", + ranges = IRanges::IRanges( + start = seq(100L, by = 100L, length.out = 5L), + width = 1L + ) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = sprintf("chr1:%d:A:G", 100L * (1:5)), + A1 = "A", + A2 = "G", + Z = rnorm(5), + N = rep(1000L, 5) + ) + base <- list( + study = "G1", + entry = list(gr), + genome = "hg19", + ldReference = .cbp_makeHandle(), + qcOptions = list(ok = 1) + ) + g0 <- exec(GwasSumStats, !!!base) + expect_false(any( + c("nCase", "nControl") %in% colnames(S4Vectors::mcols(g0)) + )) + g1 <- exec(GwasSumStats, !!!c(base, list(nCase = 500, nControl = 1500))) + expect_true(all(c("nCase", "nControl") %in% colnames(S4Vectors::mcols(g1)))) + expect_equal(g1$nCase, 500) + expect_equal(g1$nControl, 1500) +}) diff --git a/tests/testthat/test_H2Estimate.R b/tests/testthat/test_H2Estimate.R index c5b2685e..05cf2c73 100644 --- a/tests/testthat/test_H2Estimate.R +++ b/tests/testthat/test_H2Estimate.R @@ -1,7 +1,3 @@ -# Tests migrated from test_h2ClassesSumstats.R - -# === Tests migrated from test_h2ClassesSumstats.R (H2Estimate) === - test_that("H2Estimate constructs with all slots", { obj <- new( "H2Estimate", @@ -22,8 +18,6 @@ test_that("H2Estimate constructs with all slots", { expect_equal(methodNames(obj), "lder") }) -# show() smoke test, moved here from test_showMethods.R so the test -# tree mirrors R/. test_that("show(H2Estimate) does not error", { h2 <- new( "H2Estimate", @@ -79,3 +73,57 @@ test_that("H2Estimate types its optional slots", { 'invalid object for slot "scoreStats"' ) }) + +# =========================================================================== +# H2Estimate accessors +# =========================================================================== + +test_that("stratifiedHeritabilityEnrichment returns the enrichment slot", { + h2_obj <- makeTestH2Estimate(with_enrichment = TRUE) + result <- stratifiedHeritabilityEnrichment(h2_obj) + expect_true(is.data.frame(result)) + expect_equal(result$annotation, c("annot1", "annot2")) +}) + +test_that("scoreStats returns the scoreStats slot", { + scoreStats <- list( + z = c(1.5, -0.8), + R = diag(2), + annotationNames = c("a1", "a2") + ) + h2_obj <- new( + "H2Estimate", + estimate = 0.3, + estimateSe = 0.05, + intercept = 1.0, + interceptSe = 0.01, + localBlocks = NULL, + enrichment = NULL, + annotationJackknifeCoefs = NULL, + scoreStats = scoreStats, + method = "lder", + nSnps = 100L, + traitName = "test" + ) + expect_identical(scoreStats(h2_obj), scoreStats) +}) + +test_that("accessors return NULL when slots are NULL", { + h2_obj <- new( + "H2Estimate", + estimate = 0.3, + estimateSe = 0.05, + intercept = 1.0, + interceptSe = 0.01, + localBlocks = NULL, + enrichment = NULL, + annotationJackknifeCoefs = NULL, + scoreStats = NULL, + method = "lder", + nSnps = 100L, + traitName = "test" + ) + expect_null(localH2Blocks(h2_obj)) + expect_null(stratifiedHeritabilityEnrichment(h2_obj)) + expect_null(scoreStats(h2_obj)) +}) diff --git a/tests/testthat/test_LdBlocks.R b/tests/testthat/test_LdBlocks.R index 67451948..43c75070 100644 --- a/tests/testthat/test_LdBlocks.R +++ b/tests/testthat/test_LdBlocks.R @@ -4,7 +4,7 @@ # string; it was retired because GRanges already carries the build in # seqinfo() and its only consumer, LdStatistic, has its own genome slot. What # remains is .asLdBlockRanges(), the one place an LD-block specification -# becomes the GRanges the splitters consume. +# becomes the GRanges the splitters consume: a GRanges, or a BED file. # @noRd .ldb_blocks <- function() { @@ -16,52 +16,70 @@ b } +# @noRd +.ldb_bedFile <- function(lines) { + path <- withr::local_tempfile( + fileext = ".bed", + .local_envir = parent.frame() + ) + writeLines(lines, path) + path +} + test_that(".asLdBlockRanges passes a GRanges through unchanged", { expect_identical(.asLdBlockRanges(.ldb_blocks()), .ldb_blocks()) }) -test_that(".asLdBlockRanges builds ranges from a block table", { - df <- data.frame( - chrom = "chr1", - start = c(1L, 800L), - end = c(500L, 1200L), - stringsAsFactors = FALSE - ) - gr <- .asLdBlockRanges(df) +test_that(".asLdBlockRanges reads a BED file with BED's 0-based start", { + gr <- .asLdBlockRanges(.ldb_bedFile(c("chr1\t0\t500", "chr1\t799\t1200"))) expect_s4_class(gr, "GRanges") - expect_equal(length(gr), 2L) expect_equal(start(gr), c(1L, 800L)) + expect_equal(end(gr), c(500L, 1200L)) + expect_null(mcols(gr)$blockId) }) -test_that(".asLdBlockRanges carries blockId from the table into mcols", { +test_that(".asLdBlockRanges takes a BED file's fourth column as the names", { # Without this the splitter would fall back to coordinate keys, and the - # caller's own block names would be silently discarded. - df <- data.frame( - chrom = "chr1", - start = c(1L, 800L), - end = c(500L, 1200L), - blockId = c("a", "b"), - stringsAsFactors = FALSE + # file's own block names would be silently discarded. + path <- .ldb_bedFile(c("chr1\t0\t500\ta", "chr1\t799\t1200\tb")) + expect_equal(mcols(.asLdBlockRanges(path))$blockId, c("a", "b")) +}) + +test_that(".asLdBlockRanges passes over BED comments and a header line", { + # An LD-block file often names its columns, as LDetect's `chr start stop` + # does; BED's columns are positional, so the header line is skipped. + path <- .ldb_bedFile(c( + "track name=blocks", + "# LD blocks", + "chr\tstart\tstop", + "chr1\t0\t500", + "" + )) + expect_identical(as.character(.asLdBlockRanges(path)), "chr1:1-500") +}) + +test_that(".asLdBlockRanges refuses a file that is not BED", { + expect_error( + .asLdBlockRanges(.ldb_bedFile(c("chr1\t0\t500", "chr1 799 1200"))), + "is not a BED file" ) - expect_equal(mcols(.asLdBlockRanges(df))$blockId, c("a", "b")) + expect_error(.asLdBlockRanges(.ldb_bedFile(character(0))), "not a BED") }) -test_that(".asLdBlockRanges reads a block table from a path", { - df <- data.frame( - chrom = "chr1", - start = c(1L, 800L), - end = c(500L, 1200L), - stringsAsFactors = FALSE +test_that(".asLdBlockRanges refuses a table, which R calls give 1-based", { + # Given in R a window is a GRanges, so a table -- whose start could be + # either base -- is refused rather than read. + df <- data.frame(chrom = "chr1", start = c(1L, 800L), end = c(500L, 1200L)) + expect_error( + .asLdBlockRanges(df), + "`ldBlocks` must be a GRanges or the path of a BED file" ) - tf <- withr::local_tempfile(fileext = ".tsv") - readr::write_tsv(df, tf, progress = FALSE) - expect_equal(length(.asLdBlockRanges(tf)), 2L) }) -test_that(".asLdBlockRanges names the columns a block table is missing", { +test_that(".asLdBlockRanges names a path that does not exist", { expect_error( - .asLdBlockRanges(data.frame(chrom = "chr1", start = 1L)), - "end" + .asLdBlockRanges("chr1:1-500"), + "no file exists at 'chr1:1-500'" ) }) diff --git a/tests/testthat/test_LdMatrix.R b/tests/testthat/test_LdMatrix.R index 67efd6ab..b9189ccf 100644 --- a/tests/testthat/test_LdMatrix.R +++ b/tests/testthat/test_LdMatrix.R @@ -64,6 +64,13 @@ test_that("LdMatrix takes its variants from a table or a GRanges", { ) }) +test_that("as.matrix() and as(x, 'matrix') return the correlation matrix", { + f <- .ldmFixture() + ld <- LdMatrix(cor(f$X), nSamples = nrow(f$X)) + expect_identical(as.matrix(ld), ldMatrix(ld)) + expect_identical(as(ld, "matrix"), ldMatrix(ld)) +}) + test_that("an unlabelled matrix without variants is refused", { f <- .ldmFixture() expect_error(LdMatrix(unname(f$R)), "`variants` is required") diff --git a/tests/testthat/test_LdStatistic.R b/tests/testthat/test_LdStatistic.R index 7efc731b..444123ef 100644 --- a/tests/testthat/test_LdStatistic.R +++ b/tests/testthat/test_LdStatistic.R @@ -28,9 +28,9 @@ test_that("genome() reports the build from seqinfo (via an LdScore)", { # =========================================================================== # Overrides REPLACE the defaults rather than being appended: forwarding `...` -# alongside a fixed `nRef = 500L` makes .lds_score(nRef = 0L) fail with -# "formal argument matched by multiple actual arguments", which an -# expect_error(., "nRef") happily matches without ever reaching validity. +# alongside a fixed `nSamples = 500L` makes .lds_score(nSamples = 0L) fail +# with "formal argument matched by multiple actual arguments", which an +# expect_error(., "nSamples") happily matches without ever reaching validity. .lds_score <- function(n = 10, ...) { args <- list( ldBlocks = makeTestLdBlocks(), @@ -60,8 +60,9 @@ test_that("validity rejects an nSamples that is not a positive integer", { test_that("validity rejects an inSample that is not a single flag", { # Through new(), not LdScore(): the constructor writes # `inSample = isTRUE(inSample)`, so a multi-element or empty flag is - # collapsed before validity can see it. (`nRef = as.integer(nRef)` does - # not collapse length, which is why the nRef branch IS reachable above.) + # collapsed before validity can see it. (`nSamples = as.integer(nSamples)` + # does not collapse length, which is why the nSamples branch IS reachable + # above.) # This one guards direct new() use -- migration scripts, deserialization. gr <- as(.lds_score(), "GRanges") msg <- "Variable 'inSample': Must have length 1" @@ -166,7 +167,7 @@ test_that("nRef is taken from the LdMatrix blocks; disagreement is an error", { expect_equal(ldPanelNSamples(buildLdEigen(list(a, a))), 500L) expect_error(buildLdEigen(list(a, b)), "differing reference panel sizes") - # An explicit nRef settles it. + # An explicit nSamples settles it. expect_equal( ldPanelNSamples(buildLdEigen(list(a, b), nSamples = 700L)), 700L @@ -242,12 +243,11 @@ test_that("a genotype panel is cut into LD blocks at ldBlocks", { panel <- readGenotypes(test_path("test_data", "test_variants.bed")) pos <- GenomicRanges::start(SummarizedExperiment::rowRanges(panel)) cut <- pos[[200L]] - # The block table may name chromosomes either way; a panel's are + # The blocks may name chromosomes either way; a panel's are # chr-prefixed. Variants outside every block are left out. - blocks <- data.frame( - chrom = "21", - start = c(pos[[1L]], cut), - end = c(cut - 1L, pos[[300L]]) + blocks <- GenomicRanges::GRanges( + "21", + IRanges::IRanges(c(pos[[1L]], cut), c(cut - 1L, pos[[300L]])) ) ref <- buildLdScore(panel, ldBlocks = blocks) expect_equal(length(ref), 300L) @@ -263,10 +263,12 @@ test_that("a genotype panel is cut into LD blocks at ldBlocks", { unname(computeLd(panel, snpIdx = 200:300)) ) expect_error(buildLdScore(panel), "`ldBlocks` is required") - overlapping <- data.frame( - chrom = "chr21", - start = c(pos[[1L]], pos[[100L]]), - end = c(pos[[150L]], pos[[300L]]) + overlapping <- GenomicRanges::GRanges( + "chr21", + IRanges::IRanges( + c(pos[[1L]], pos[[100L]]), + c(pos[[150L]], pos[[300L]]) + ) ) expect_error( buildLdEigen(panel, ldBlocks = overlapping), @@ -280,10 +282,12 @@ test_that("a stochastic sketch's blocks carry its effective size", { test_path("test_data", "test_harmonize_regions.pgen") ) gr <- SummarizedExperiment::rowRanges(sketch) - blocks <- data.frame( - chrom = "chr21", - start = min(GenomicRanges::start(gr)), - end = max(GenomicRanges::start(gr)) + blocks <- GenomicRanges::GRanges( + "chr21", + IRanges::IRanges( + min(GenomicRanges::start(gr)), + max(GenomicRanges::start(gr)) + ) ) ref <- buildLdEigen(sketch, ldBlocks = blocks) # 50 real samples projected onto 100 pseudo-samples: 1 / (1/50 + 1/100). diff --git a/tests/testthat/test_MethodOptions.R b/tests/testthat/test_MethodOptions.R index f166208f..5c6f3b80 100644 --- a/tests/testthat/test_MethodOptions.R +++ b/tests/testthat/test_MethodOptions.R @@ -67,27 +67,17 @@ test_that(".newMethodOptions merges defaults under extras, dropping NULLs", { }) test_that(".newMethodOptions rejects a name the engine cannot accept", { - expect_error( + bad <- function() { pecotmr:::.newMethodOptions( "stats::var", defaults = list(), extra = list(naRM = TRUE), label = "varArgs" - ), - "unknown argument\\(s\\) naRM" - ) -}) - -test_that(".newMethodOptions names the engine's accepted arguments in the error", { - expect_error( - pecotmr:::.newMethodOptions( - "stats::var", - defaults = list(), - extra = list(nope = 1), - label = "varArgs" - ), - "stats::var. accepts:.*na\\.rm" - ) + ) + } + expect_error(bad(), "unknown argument\\(s\\) naRM") + # The error names the arguments the engine does accept. + expect_error(bad(), "stats::var. accepts:.*na\\.rm") }) test_that(".newMethodOptions skips validation when the engine takes dots", { diff --git a/tests/testthat/test_MethodParam.R b/tests/testthat/test_MethodParam.R index 4aa2908c..78e6b0bf 100644 --- a/tests/testthat/test_MethodParam.R +++ b/tests/testthat/test_MethodParam.R @@ -193,15 +193,31 @@ test_that("TwasWeightsMethodsParam shares the rules with its own registry", { ) expect_s4_class(p, "TwasWeightsMethodsParam") expect_equal(p$qtlDatasetMethods$lasso$nfolds, 5) - # The registries differ: prsCs is summary-statistics only, enet + # The registries differ: prsCs is summary-statistics only, dprVb # individual only, and both are methods a fine-mapping Param never has. expect_error( TwasWeightsMethodsParam(qtlDatasetMethods = list(prsCs = list())), "prsCs is not a method this pipeline runs on QtlDataset" ) expect_error( - TwasWeightsMethodsParam(qtlSumStatsMethods = list(enet = list())), - "enet is not a method this pipeline runs on QtlSumStats" + TwasWeightsMethodsParam(qtlSumStatsMethods = list(dprVb = list())), + "dprVb is not a method this pipeline runs on QtlSumStats" + ) + # enet and ridge run on both, glmnet's options on one path and the + # penalized RSS solver's on the other. + both <- TwasWeightsMethodsParam( + qtlDatasetMethods = list(enet = GlmnetOptions(), ridge = list()), + qtlSumStatsMethods = list( + enet = PenalizedRssOptions(thr = 1e-6), + ridge = list() + ) + ) + expect_s4_class(both, "TwasWeightsMethodsParam") + expect_error( + TwasWeightsMethodsParam( + qtlSumStatsMethods = list(enet = GlmnetOptions()) + ), + "options are for QtlDataset" ) expect_error( FineMappingMethodsParam(methods = list(lasso = list())), @@ -239,29 +255,6 @@ test_that("a pipeline resolves only the slots its input class reads", { ) }) -test_that("a pipeline refuses a Param built for the other pipeline", { - expect_error( - pecotmr:::.methodsParamFor( - TwasWeightsMethodsParam(methods = "lasso"), - "QtlDataset", - "FineMappingMethodsParam", - "fineMappingPipeline" - ), - "configures a different pipeline" - ) - # Its own family passes through untouched. - p <- FineMappingMethodsParam(methods = "susie") - expect_identical( - pecotmr:::.methodsParamFor( - p, - "QtlDataset", - "FineMappingMethodsParam", - "fineMappingPipeline" - ), - p - ) -}) - test_that("an entry must be built by that method's own constructor", { skip_if_not_installed("susieR") # The input-type check cannot see this: lasso and bayesA both run on @@ -570,6 +563,15 @@ test_that("show counts an unnamed list slot and names a named one", { expect_true(any(str_detect(named, "susie"))) }) +test_that("show names a BPPARAM by its backend and worker count", { + out <- capture.output(show(CrossValidationParam())) + expect_true(any(str_detect(out, fixed("SerialParam (1 worker)")))) + two <- capture.output(show(CrossValidationParam( + BPPARAM = BiocParallel::MulticoreParam(2) + ))) + expect_true(any(str_detect(two, fixed("MulticoreParam (2 workers)")))) +}) + test_that(".paramNestedText reports a nested Param that is empty", { expect_match( as.character(pecotmr:::.paramNestedText(MashComponentParam())), @@ -587,7 +589,72 @@ test_that("$ and [[ refuse names and positions a Param does not have", { expect_error(cs[[NA_integer_]], "subscript out of bounds") }) -test_that(".assetMethodParam names the record it was handed", { +# --------------------------------------------------------------------------- +# $<- +# --------------------------------------------------------------------------- + +# Every concrete MethodParam class whose constructor builds with defaults. +.mp_defaultParams <- function() { + ns <- asNamespace("pecotmr") + classes <- names(methods::getClass("MethodParam")@subclasses) + concrete <- Filter(function(cl) !methods::getClass(cl)@virtual, classes) + built <- lapply(concrete, function(cl) { + if (!exists(cl, envir = ns, mode = "function")) { + return(NULL) + } + tryCatch(get(cl, envir = ns)(), error = function(e) NULL) + }) + names(built) <- concrete + Filter(Negate(is.null), built) +} + +test_that("$<- writing a setting back to itself changes nothing", { + # The rebuild goes through each class's own constructor, so every + # constructor must accept the values it stored -- normalised lists and + # nested records included. A round trip that is not the identity would + # mean `$<-` quietly reshapes a record. + params <- .mp_defaultParams() + expect_gt(length(params), 20L) + for (cl in names(params)) { + p <- params[[cl]] + fixed <- names(pecotmr:::.PARAM_FIXED_FIELDS[[cl]]) + for (f in setdiff(methods::slotNames(p), fixed)) { + q <- do.call(`$<-`, list(p, f, methods::slot(p, f))) + expect_identical(q, p, info = paste0(cl, "$", f)) + } + } +}) + +test_that("$<- normalises through the constructor and unsets with NULL", { + # FineMappingMethodsParam() turns a method name into its options entry; + # `$<-` stores exactly what the constructor would. + p <- FineMappingMethodsParam(methods = "susie") + p$methods <- c("susie", "susieInf") + expect_identical( + p, + FineMappingMethodsParam(methods = c("susie", "susieInf")) + ) + cs <- CredibleSetParam(medianAbsCorr = 0.5) + expect_true("medianAbsCorr" %in% names(cs)) + cs$medianAbsCorr <- NULL + expect_null(cs$medianAbsCorr) + expect_false("medianAbsCorr" %in% names(cs)) +}) + +test_that("$<- refuses unknown and fixed settings, naming why", { + cs <- CredibleSetParam() + expect_error(cs$nosuch <- 1, "is not a setting of CredibleSetParam") + expect_error( + cs$maxNumSingleEffects <- 3L, + "needs a refit. Build a new CredibleSetParam\\(\\) instead" + ) + mc <- MashComponentParam() + expect_error(mc$components <- list(), "assembles it from") + pv <- PvalMethodsParam(aspu = AspuOptions(n.perm = 5000)) + expect_error(pv$methods <- list(), "one argument per method") +}) + +test_that(".assertMethodParam names the record it was handed", { # A Param of the wrong class reports its own class, not "a bare list". expect_error( pecotmr:::.assertMethodParam( @@ -770,10 +837,18 @@ test_that(".methodsParamFor and ...ForMulti route each input shape", { .mpIsNsFunction <- function(n, ns) is.function(get(n, envir = ns)) .mpShadowedValues <- function(f, label, own) { - hit <- intersect( - intersect(.mpFunValueSymbols(body(f)), names(formals(f))), - own - ) + shadowing <- intersect(names(formals(f)), own) + if (length(shadowing) == 0L) { + return(NULL) + } + # A formal is passed as a value only through one of the .mpFunSlot + # helpers, and only if it appears in the body at all; all.names() rules + # out most closures before their call tree is walked. + syms <- all.names(body(f)) + if (!any(is_in(shadowing, syms)) || !any(is_in(names(.mpFunSlot), syms))) { + return(NULL) + } + hit <- intersect(.mpFunValueSymbols(body(f)), shadowing) if (length(hit)) hit else NULL } diff --git a/tests/testthat/test_MultiStudyQtlDataset.R b/tests/testthat/test_MultiStudyQtlDataset.R index c8790032..0a8e24b3 100644 --- a/tests/testthat/test_MultiStudyQtlDataset.R +++ b/tests/testthat/test_MultiStudyQtlDataset.R @@ -1,7 +1,5 @@ # Tests for R/MultiStudyQtlDataset.R -# === Tests migrated from test_s4Constructors.R (MultiStudyQtlDataset) === - test_that("MultiStudyQtlDataset: combines two QtlDatasets", { qd1 <- QtlDataset( studyName = "s1", @@ -45,6 +43,18 @@ test_that("MultiStudyQtlDataset: rejects unnamed qtlDatasets list", { }) +test_that("MultiStudyQtlDataset: rejects non-QtlDataset entries", { + qd <- QtlDataset( + studyName = "s1", + genotypes = .sc_makeGenotypeHandle(), + phenotypes = list(brain = .sc_makeSe()) + ) + expect_error( + MultiStudyQtlDataset(qtlDatasets = list(s1 = qd, s2 = "not a dataset")), + "must be a QtlDataset" + ) +}) + test_that("MultiStudyQtlDataset: rejects a trait at two positions", { se1 <- .sc_makeSe(traits = "ENSG1") # Build se2 from scratch (see note in the QtlDataset trait-conflict test). @@ -161,9 +171,6 @@ test_that("sumStats(MultiStudyQtlDataset) rejects selection arguments", { # =========================================================================== # Validity branches -# -# Every construction above builds a VALID object, so the message-returning -# arms of the checks were never reached. # =========================================================================== test_that("MultiStudyQtlDataset: rejects an empty qtlDatasets list", { @@ -204,8 +211,6 @@ test_that("MultiStudyQtlDataset: rejects a non-QtlSumStats sumStats", { test_that("studyName unions the individual-level and summary-only studies", { - # The sumStats arm was never taken: every collection built above carries - # only QtlDatasets, so studyName() only ever read their names. data(qtlSumStatsExample) qd <- QtlDataset( studyName = "s1", @@ -229,3 +234,76 @@ test_that("MultiStudyQtlDataset: qtlDatasets guard fires on a non-list", { test_that(".msqdConcat answers an empty list for no pieces", { expect_identical(pecotmr:::.msqdConcat(list()), list()) }) + +test_that("updateObject rebuilds a MultiStudyQtlDataset from its studies", { + data(multiStudyQtlDatasetExample) + ms <- multiStudyQtlDatasetExample + expect_equal(updateObject(ms), ms) + # A study set with no summary statistics keeps none: the NULL slot is + # read through slot(), not as the placeholder attr() would return. + expect_null(pecotmr:::.msqdSavedSumStats(ms)) + expect_null(sumStats(updateObject(ms))) + noSlot <- ms + attr(noSlot, "sumStats") <- NULL + expect_null(pecotmr:::.msqdSavedSumStats(noSlot)) + expect_message( + updateObject(ms, verbose = TRUE), + "updateObject\\(object = 'MultiStudyQtlDataset'\\)" + ) + # Saved before it became a SimpleList, the studies sat in a + # `qtlDatasets` slot, which the object still carries as an attribute. + old <- ms + attr(old, "qtlDatasets") <- rev(as.list(ms)) + expect_identical(names(updateObject(old)), rev(names(ms))) + # Its summary-statistic studies are updated along with it. + qd <- QtlDataset( + studyName = "s1", + genotypes = .sc_makeGenotypeHandle(), + phenotypes = list(brain = .sc_makeSe()) + ) + withSs <- MultiStudyQtlDataset( + qtlDatasets = list(s1 = qd), + sumStats = qtlSumStatsExample + ) + expect_s4_class(sumStats(updateObject(withSs)), "QtlSumStats") +}) + +test_that("subsetting a MultiStudyQtlDataset re-checks what is left", { + data(multiStudyQtlDatasetExample) + ms <- multiStudyQtlDatasetExample + swapped <- ms[rev(names(ms))] + expect_s4_class(swapped, "MultiStudyQtlDataset") + expect_identical(names(swapped), rev(names(ms))) + expect_error(ms[1L], "at least 2 studies") +}) + +# =========================================================================== +# show() +# =========================================================================== + +test_that("show.MultiStudyQtlDataset reports per-source study counts", { + qd1 <- .sh_makeQtlDataset(studyName = "s1") + qd2 <- .sh_makeQtlDataset(studyName = "s2") + mt <- MultiStudyQtlDataset(qtlDatasets = list(s1 = qd1, s2 = qd2)) + out <- capture.output(show(mt)) + expect_true(any(grepl( + "MultiStudyQtlDataset: 2 individual-level \\+ 0 sumstats", + out + ))) + expect_true(any(grepl("Individual-level studies: s1, s2", out))) +}) + +test_that("show.MultiStudyQtlDataset reports sumstats studies when present", { + qd <- .sh_makeQtlDataset(studyName = "s1") + ss <- QtlSumStats( + studyName = "s2", + context = "c1", + trait = "t1", + entry = list(.sh_makeQtlSumstatsGr()), + genome = "hg19", + ldReference = .sh_makeGenotypeHandle() + ) + mt <- MultiStudyQtlDataset(qtlDatasets = list(s1 = qd), sumStats = ss) + out <- capture.output(show(mt)) + expect_true(any(grepl("Sumstats studies: s2", out))) +}) diff --git a/tests/testthat/test_QtlDataset.R b/tests/testthat/test_QtlDataset.R index 27990402..b8cb6869 100644 --- a/tests/testthat/test_QtlDataset.R +++ b/tests/testthat/test_QtlDataset.R @@ -1,5 +1,8 @@ context("QtlDataset internal helpers") +# The bundled genotype files the tests that read real panels open. +test_data_dir <- test_path("test_data") + # =========================================================================== # Fixture builder: a QtlDataset whose GenotypeHandle is a stub. extraction # functions are stubbed in individual tests via local_mocked_bindings. @@ -19,7 +22,7 @@ context("QtlDataset internal helpers") format = "plink2", snpInfo = data.frame( SNP = paste0("rs", seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = a1, A2 = a2, @@ -70,16 +73,14 @@ context("QtlDataset internal helpers") ) } -# `...` reaches QtlDataset(): mafCutoff / keepIndel / keepVariants and the -# other filters are constructor arguments, so a test configures them there -# instead of assigning into the built object's slots. +# The dataset holds data only: a test that filters passes the filter to the +# extraction (.qh_filter()), as a pipeline does. .qh_makeDataset <- function( contexts = c("brain", "liver"), n_samples = 12L, geno_cov = NULL, a1 = rep("A", 6L), - a2 = rep("G", 6L), - ... + a2 = rep("G", 6L) ) { gh <- .qh_makeHandle(n_samples = n_samples, a1 = a1, a2 = a2) pheno <- setNames( @@ -89,17 +90,19 @@ context("QtlDataset internal helpers") if (is.null(geno_cov)) { geno_cov <- matrix(numeric(0), nrow = 0, ncol = 0) } - # `...` is the genotype filter now: every caller passes only filter - # fields (mafCutoff / xvarCutoff / imissCutoff / keepVariants). QtlDataset( studyName = "study1", genotypes = gh, phenotypes = pheno, - genotypeCovariates = geno_cov, - genotypeFilterParam = GenotypeFilterParam(...) + genotypeCovariates = geno_cov ) } +# A resolved genotype filter, the form a pipeline threads to each extraction. +.qh_filter <- function(...) { + pecotmr:::.qtlResolveFilter(GenotypeFilterParam(...)) +} + # =========================================================================== # .qtlResidualizeQr — pure linear algebra # =========================================================================== @@ -271,7 +274,7 @@ test_that(".qtlResolveVariantRegion: region must be a GRanges; multi-range is al qd <- .qh_makeDataset() expect_error( pecotmr:::.qtlResolveVariantRegion(qd, region = "chr1:100-200"), - "Must inherit from class 'GRanges'" + "`region` must be a GRanges" ) expect_error( pecotmr:::.qtlResolveVariantRegion( @@ -320,13 +323,15 @@ test_that(".qtlVariantIndices: filters by chromosome and BP range", { expect_equal(idx, c(2L, 3L)) }) -test_that(".qtlVariantIndices: accepts chr-prefixed and bare chromosome names", { +test_that(".qtlVariantIndices: a bare-named region is read as UCSC", { qd <- .qh_makeDataset() r1 <- GenomicRanges::GRanges("chr1", IRanges::IRanges(50, 250)) r2 <- GenomicRanges::GRanges("1", IRanges::IRanges(50, 250)) + idx <- pecotmr:::.qtlVariantIndices(qd, r1) + expect_gt(length(idx), 0L) expect_equal( - pecotmr:::.qtlVariantIndices(qd, r1), - pecotmr:::.qtlVariantIndices(qd, r2) + pecotmr:::.qtlVariantIndices(qd, pecotmr:::.qtlLiteralRegion(r2, NULL)), + idx ) }) @@ -352,16 +357,19 @@ test_that("traitPosition returns each trait's union genomic span across contexts expect_equal(GenomicRanges::end(gr["ENSG1"]), 1499L) # start 1000 + width 500 - 1 expect_equal(GenomicRanges::start(gr["ENSG2"]), 2000L) # single-trait selection routes through the traitId branch of the method - one <- traitPosition(qd, traitId = "ENSG2") + one <- traitPosition(qd, trait = "ENSG2") expect_equal(names(one), "ENSG2") expect_equal(GenomicRanges::start(one), 2000L) }) -test_that("traitPosition emits a chrUn sentinel for a trait absent from every context", { +test_that("traitPosition refuses a trait absent from every context", { + # No placeholder range: an unknown name is an error, as it is for + # rowRanges(), naming every trait that is missing. qd <- .qh_makeDataset(contexts = "brain") - gr <- traitPosition(qd, traitId = "NOPE") - expect_equal(names(gr), "NOPE") - expect_equal(as.character(GenomicRanges::seqnames(gr)), "chrUn") + expect_error( + traitPosition(qd, trait = c("NOPE", "ALSO")), + "in no context of this QtlDataset: NOPE, ALSO" + ) }) # (QtlDataset validity requires a trait's rowRanges to be identical across @@ -369,39 +377,40 @@ test_that("traitPosition emits a chrUn sentinel for a trait absent from every co # matching ranges; the two-context fixture above already exercises that loop.) # =========================================================================== -# .qtlApplyFilterOverrides +# .qtlResolveFilter: a run's genotype filter # =========================================================================== -test_that(".qtlApplyFilterOverrides replaces every supplied slot on a validated copy", { +test_that(".qtlResolveFilter carries every set field; keepSamples narrows", { qd <- .qh_makeDataset(contexts = "brain") - out <- pecotmr:::.qtlApplyFilterOverrides( - qd, - GenotypeFilterParam( - mafCutoff = 0.05, - macCutoff = 10, - xvarCutoff = 0.01, - imissCutoff = 0.1, - keepIndel = FALSE, - keepSamples = c("s1", "s2"), - keepVariants = c("rs1", "rs2") - ) - ) - expect_equal(out@mafCutoff, 0.05) - expect_equal(out@macCutoff, 10) - expect_equal(out@xvarCutoff, 0.01) - expect_equal(out@imissCutoff, 0.1) - expect_false(out@keepIndel) + filt <- .qh_filter( + mafCutoff = 0.05, + macCutoff = 10, + xvarCutoff = 0.01, + imissCutoff = 0.1, + keepIndel = FALSE, + keepSamples = c("s1", "s2"), + keepVariants = c("rs1", "rs2") + ) + expect_equal(filt$mafCutoff, 0.05) + expect_equal(filt$macCutoff, 10) + expect_equal(filt$xvarCutoff, 0.01) + expect_equal(filt$imissCutoff, 0.1) + expect_false(filt$keepIndel) + expect_equal(filt$keepVariants, c("rs1", "rs2")) + out <- pecotmr:::.qtlRestrictSamples(qd, filt$keepSamples) expect_setequal( rownames(MultiAssayExperiment::colData(out)), c("s1", "s2") ) - expect_equal(out@keepVariants, c("rs1", "rs2")) }) -test_that(".qtlApplyFilterOverrides leaves stored slots untouched when args are NULL", { +test_that("an unset filter filters nothing and leaves the dataset whole", { qd <- .qh_makeDataset(contexts = "brain") + filt <- .qh_filter() + expect_equal(filt$mafCutoff, 0) + expect_true(filt$keepIndel) expect_identical( - pecotmr:::.qtlApplyFilterOverrides(qd, GenotypeFilterParam()), + pecotmr:::.qtlRestrictSamples(qd, filt$keepSamples), qd ) }) @@ -476,7 +485,7 @@ test_that(".qtlResolvePhenoSelection: list with extra keys errors", { contexts = "brain", toResidualize = list(brain = "age", ghost = "sex") ), - "list key.*not in `contexts`" + "list key.*not in `context`" ) }) @@ -714,6 +723,24 @@ test_that(".qtlBuildResidualizationDesign: intersects sample sets across blocks" } } +test_that(".qtlExtractBlock refuses a missing filter rather than skip it", { + # A pipeline threads its resolved filter to every extraction; NULL means + # a call site dropped it, which must not pass for "no filter". + qd <- .qh_makeDataset() + expect_error( + pecotmr:::.qtlExtractBlock(qd, filter = NULL), + "No resolved genotype filter" + ) +}) + +test_that("a NULL residualization bundle scales, as an unset field does", { + expect_true(pecotmr:::.qtlScaleResiduals(NULL)) + expect_true(pecotmr:::.qtlScaleResiduals(ResidualizationParam())) + expect_false(pecotmr:::.qtlScaleResiduals( + ResidualizationParam(scaleResiduals = FALSE) + )) +}) + test_that(".qtlExtractBlock: returns dosage matrix with kept variants and samples", { qd <- .qh_makeDataset() local_mocked_bindings( @@ -731,27 +758,27 @@ test_that(".qtlExtractBlock: returns dosage matrix with kept variants and sample test_that(".qtlExtractBlock: empty snpIdx returns a zero-column block", { qd <- .qh_makeDataset() region <- GenomicRanges::GRanges("chr2", IRanges::IRanges(1, 1000)) - blk <- pecotmr:::.qtlExtractBlock(qd, region = region) + blk <- pecotmr:::.qtlExtractBlock(qd, window = region) expect_equal(ncol(blk$geno), 0L) expect_equal(blk$variantIds, character(0)) }) test_that(".qtlExtractBlock: keepVariants restriction narrows the returned set", { - qd <- .qh_makeDataset(keepVariants = c("rs2", "rs4")) + qd <- .qh_makeDataset() local_mocked_bindings( extractBlockGenotypes = .qh_mockExtractor(), .package = "pecotmr" ) - blk <- pecotmr:::.qtlExtractBlock(qd) + blk <- pecotmr:::.qtlExtractBlock( + qd, + filter = .qh_filter(keepVariants = c("rs2", "rs4")) + ) expect_setequal(blk$variantIds, c("rs2", "rs4")) }) test_that(".qtlExtractBlock: keepSamples restriction narrows the returned set", { qd <- .qh_makeDataset() - qd <- pecotmr:::.qtlApplyFilterOverrides( - qd, - GenotypeFilterParam(keepSamples = paste0("s", 1:6)) - ) + qd <- pecotmr:::.qtlRestrictSamples(qd, paste0("s", 1:6)) local_mocked_bindings( extractBlockGenotypes = .qh_mockExtractor(), .package = "pecotmr" @@ -762,10 +789,7 @@ test_that(".qtlExtractBlock: keepSamples restriction narrows the returned set", test_that(".qtlExtractBlock: per-call samples arg further narrows the sample set", { qd <- .qh_makeDataset() - qd <- pecotmr:::.qtlApplyFilterOverrides( - qd, - GenotypeFilterParam(keepSamples = paste0("s", 1:6)) - ) + qd <- pecotmr:::.qtlRestrictSamples(qd, paste0("s", 1:6)) local_mocked_bindings( extractBlockGenotypes = .qh_mockExtractor(), .package = "pecotmr" @@ -775,12 +799,15 @@ test_that(".qtlExtractBlock: per-call samples arg further narrows the sample set }) test_that(".qtlExtractBlock: keepVariants with empty intersection returns empty block", { - qd <- .qh_makeDataset(keepVariants = c("rsGHOST")) + qd <- .qh_makeDataset() local_mocked_bindings( extractBlockGenotypes = .qh_mockExtractor(), .package = "pecotmr" ) - blk <- pecotmr:::.qtlExtractBlock(qd) + blk <- pecotmr:::.qtlExtractBlock( + qd, + filter = .qh_filter(keepVariants = "rsGHOST") + ) expect_equal(ncol(blk$geno), 0L) expect_equal(nrow(blk$geno), 0L) }) @@ -789,20 +816,21 @@ test_that(".qtlExtractBlock: keepIndel = FALSE drops multi-base (indel) variants # rs2 an insertion, rs4 a deletion; the rest stay SNPs. qd <- .qh_makeDataset( a1 = replace(rep("A", 6L), 2L, "AT"), - a2 = replace(rep("G", 6L), 4L, "GC"), - keepIndel = FALSE + a2 = replace(rep("G", 6L), 4L, "GC") ) local_mocked_bindings( extractBlockGenotypes = .qh_mockExtractor(), .package = "pecotmr" ) - blk <- pecotmr:::.qtlExtractBlock(qd) + blk <- pecotmr:::.qtlExtractBlock( + qd, + filter = .qh_filter(keepIndel = FALSE) + ) expect_equal(blk$variantIds, c("rs1", "rs3", "rs5", "rs6")) }) test_that(".qtlExtractBlock: keepIndel = TRUE (default) keeps indel variants", { qd <- .qh_makeDataset(a1 = replace(rep("A", 6L), 2L, "AT")) - expect_true(qd@keepIndel) # default local_mocked_bindings( extractBlockGenotypes = .qh_mockExtractor(), .package = "pecotmr" @@ -811,35 +839,33 @@ test_that(".qtlExtractBlock: keepIndel = TRUE (default) keeps indel variants", { expect_equal(length(blk$variantIds), 6L) }) -test_that("QtlDataset: keepIndel defaults to TRUE; validity rejects non-scalar", { - qd <- .qh_makeDataset() - expect_true(qd@keepIndel) - # The constructor coerces via isTRUE(); validity guards direct new()/slot sets. - qd@keepIndel <- c(TRUE, FALSE) - expect_error(validObject(qd), "Variable 'keepIndel'") +test_that("keepIndel resolves to TRUE and must be a flag", { + expect_true(.qh_filter()$keepIndel) + expect_error(GenotypeFilterParam(keepIndel = c(TRUE, FALSE)), "keepIndel") + expect_error(GenotypeFilterParam(keepIndel = NA), "keepIndel") }) test_that(".qtlExtractBlock: mafCutoff drops low-MAF variants", { # The mocked extractor returns binomial(0.3) dosages: realized MAFs hover # around 0.3-0.5 (small sample noise). Cutoff above the realized maximum # drops everything. - qd <- .qh_makeDataset(mafCutoff = 0.51) + qd <- .qh_makeDataset() local_mocked_bindings( extractBlockGenotypes = .qh_mockExtractor(), .package = "pecotmr" ) - blk <- pecotmr:::.qtlExtractBlock(qd) + blk <- pecotmr:::.qtlExtractBlock(qd, filter = .qh_filter(mafCutoff = 0.51)) expect_equal(ncol(blk$geno), 0L) }) test_that(".qtlExtractBlock: mafCutoff retains variants above the threshold", { # realized MAFs include 0.458 and 0.5 - qd <- .qh_makeDataset(mafCutoff = 0.4) + qd <- .qh_makeDataset() local_mocked_bindings( extractBlockGenotypes = .qh_mockExtractor(), .package = "pecotmr" ) - blk <- pecotmr:::.qtlExtractBlock(qd) + blk <- pecotmr:::.qtlExtractBlock(qd, filter = .qh_filter(mafCutoff = 0.4)) expect_true(ncol(blk$geno) >= 1L) expect_true(all(blk$maf >= 0.4)) }) @@ -927,8 +953,8 @@ test_that("maf stays folded while af is directional (they fold into each other)" context("QtlDataset residualization methods") # =========================================================================== -# Fixture: mirrors test_qtlDatasetHelpers.R so we can mock extractBlockGenotypes -# the same way. +# Fixture: mirrors the .qh_* builders above so extractBlockGenotypes can be +# mocked the same way. # =========================================================================== .qr_makeHandle <- function(snp_n = 6L, n_samples = 12L) { @@ -938,7 +964,7 @@ context("QtlDataset residualization methods") format = "plink2", snpInfo = data.frame( SNP = paste0("rs", seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -988,8 +1014,7 @@ context("QtlDataset residualization methods") .qr_makeDataset <- function( contexts = c("brain", "liver"), n_samples = 12L, - geno_cov = NULL, - scaleResiduals = TRUE + geno_cov = NULL ) { gh <- .qr_makeHandle(n_samples = n_samples) pheno <- setNames( @@ -1003,8 +1028,7 @@ context("QtlDataset residualization methods") studyName = "study1", genotypes = gh, phenotypes = pheno, - genotypeCovariates = geno_cov, - scaleResiduals = scaleResiduals + genotypeCovariates = geno_cov ) } @@ -1045,15 +1069,12 @@ context("QtlDataset residualization methods") } } -# =========================================================================== # =========================================================================== # Residualization flags (NULL = unset) +# +# ResidualizationParam() defaults each flag to NULL, so "not given" is +# representable apart from FALSE and the accessors just read the field. # =========================================================================== -# .qtlResolveResidualizationFlag and its two `*Flags` callers are gone: the -# convenience/precise pair of booleans plus a missing() companion for each -# existed only because a flat formal defaulting to TRUE cannot tell FALSE -# from "not given". ResidualizationParam() defaults them to NULL, so -# absence is representable and the accessors just read the field. test_that("an unset residualization flag means the side is residualized", { cfg <- ResidualizationParam() @@ -1134,21 +1155,21 @@ test_that(".qtlHandleCovariateNa: drop removes any sample with a missing covaria test_that("residualizedGenotypes: requires contexts", { qd <- .qr_makeDataset() - expect_error(residualizedGenotypes(qd), "`contexts` is required") + expect_error(residualizedGenotypes(qd), "`context` is required") expect_error( - residualizedGenotypes(qd, contexts = NULL), - "`contexts` is required" + residualizedGenotypes(qd, context = NULL), + "`context` is required" ) expect_error( - residualizedGenotypes(qd, contexts = character(0)), - "`contexts` is required" + residualizedGenotypes(qd, context = character(0)), + "`context` is required" ) }) test_that("residualizedGenotypes: unknown context errors", { qd <- .qr_makeDataset() expect_error( - residualizedGenotypes(qd, contexts = "ghost"), + residualizedGenotypes(qd, context = "ghost"), "Unknown context" ) }) @@ -1161,7 +1182,11 @@ test_that("residualizedGenotypes: empty genotype block short-circuits to G", { ) # region with no SNPs in the panel. region <- GenomicRanges::GRanges("chr2", IRanges::IRanges(1, 1000)) - G <- residualizedGenotypes(qd, contexts = "brain", region = region) + G <- pecotmr:::.qtlResidualizedGenotypes( + qd, + contexts = "brain", + window = region + ) expect_equal(ncol(G), 0L) }) @@ -1171,7 +1196,7 @@ test_that("residualizedGenotypes: produces residualized matrix shape", { extractBlockGenotypes = .qr_mockExtractor(), .package = "pecotmr" ) - G <- residualizedGenotypes(qd, contexts = "brain") + G <- residualizedGenotypes(qd, context = "brain") expect_equal(nrow(G), 12L) expect_equal(ncol(G), 6L) # When scaleResiduals = TRUE (the default), kept columns should have unit sd @@ -1189,7 +1214,7 @@ test_that("residualizedGenotypes: residualizes only against selected pheno covar ) G <- residualizedGenotypes( qd, - contexts = "brain", + context = "brain", residualizationParam = ResidualizationParam(phenotypeCovariates = "age") ) expect_equal(nrow(G), 12L) @@ -1210,7 +1235,7 @@ test_that("residualizedGenotypes: respects residualizePhenotype = FALSE", { # is just the centered (and scaled) raw block. G1 <- residualizedGenotypes( qd, - contexts = "brain", + context = "brain", residualizationParam = ResidualizationParam( residualizePhenotype = FALSE ) @@ -1219,41 +1244,12 @@ test_that("residualizedGenotypes: respects residualizePhenotype = FALSE", { expect_equal(ncol(G1), 6L) }) -test_that("residualizedGenotypes: precise-name kwarg routes correctly", { - qd <- .qr_makeDataset(contexts = "brain") - local_mocked_bindings( - extractBlockGenotypes = .qr_mockExtractor(), - .package = "pecotmr" - ) - G_precise <- residualizedGenotypes( - qd, - contexts = "brain", - residualizationParam = ResidualizationParam( - residualizePhenotype = FALSE - ) - ) - G_conv <- residualizedGenotypes( - qd, - contexts = "brain", - residualizationParam = ResidualizationParam( - residualizePhenotype = FALSE - ) - ) - expect_equal(G_precise, G_conv) -}) - -# The convenience/precise conflict test is gone with the duality itself: -# residualizePhenotypeCovariates and its FromGenotypes twin were two -# spellings of one -# boolean, needing a conflict check between them. ResidualizationParam() -# has one field, so there is nothing left to conflict. - test_that("residualizedGenotypes refuses a bare list for the bundle", { qd <- .qr_makeDataset(contexts = "brain") expect_error( residualizedGenotypes( qd, - contexts = "brain", + context = "brain", residualizationParam = list(residualizePhenotype = FALSE) ), "ResidualizationParam" @@ -1266,7 +1262,7 @@ test_that("residualizedGenotypes: joint-context mode intersects samples", { extractBlockGenotypes = .qr_mockExtractor(), .package = "pecotmr" ) - G <- residualizedGenotypes(qd, contexts = c("brain", "liver")) + G <- residualizedGenotypes(qd, context = c("brain", "liver")) expect_equal(nrow(G), 12L) expect_setequal(rownames(G), paste0("s", 1:12)) }) @@ -1285,7 +1281,7 @@ test_that("residualizedGenotypes: includes genotype covariates when supplied", { ) G <- residualizedGenotypes( qd, - contexts = "brain", + context = "brain", residualizationParam = ResidualizationParam( genotypeCovariates = c("pc1", "pc2") ) @@ -1313,7 +1309,7 @@ test_that("residualizedGenotypes: mean-imputes missing covariates by default", { # Default covariateNaAction = "impute": no error, all 12 samples retained. G <- residualizedGenotypes( qd, - contexts = "brain", + context = "brain", residualizationParam = ResidualizationParam( genotypeCovariates = c("pc1", "pc2") ) @@ -1337,7 +1333,7 @@ test_that("residualizedGenotypes: covariateNaAction='drop' removes samples with ) G <- residualizedGenotypes( qd, - contexts = "brain", + context = "brain", residualizationParam = ResidualizationParam( genotypeCovariates = c("pc1", "pc2"), covariateNaAction = "drop" @@ -1353,33 +1349,45 @@ test_that("residualizedGenotypes: covariateNaAction='drop' removes samples with test_that("residualizedPhenotypes: requires contexts", { qd <- .qr_makeDataset() - expect_error(residualizedPhenotypes(qd), "`contexts` is required") + expect_error(residualizedPhenotypes(qd), "`context` is required") }) test_that("residualizedPhenotypes: unknown context errors", { qd <- .qr_makeDataset() expect_error( - residualizedPhenotypes(qd, contexts = "ghost"), + residualizedPhenotypes(qd, context = "ghost"), "Unknown context" ) }) test_that("residualizedPhenotypes: returns one matrix per context", { qd <- .qr_makeDataset(contexts = c("brain", "liver")) - res <- residualizedPhenotypes(qd, contexts = c("brain", "liver")) + res <- residualizedPhenotypes(qd, context = c("brain", "liver")) expect_equal(names(res), c("brain", "liver")) expect_equal(nrow(res$brain), 12L) expect_equal(ncol(res$brain), 2L) expect_equal(nrow(res$liver), 12L) }) +test_that("residualizedPhenotypes: an absent trait gives zero columns", { + # The trait filter keeps none of brain's traits; residualizing that empty + # selection answers an empty matrix rather than failing inside lm.fit(). + qd <- .qr_makeDataset() + expect_warning( + res <- residualizedPhenotypes(qd, context = "brain", trait = "absent"), + "context 'brain' is missing trait(s): absent", + fixed = TRUE + ) + expect_equal(dim(res$brain), c(12L, 0L)) +}) + test_that("residualizedPhenotypes: residualizes against age covariate", { qd <- .qr_makeDataset(contexts = "brain") Y <- residualizedPhenotypes( qd, - contexts = "brain", + context = "brain", residualizationParam = ResidualizationParam(phenotypeCovariates = "age") - ) + )[["brain"]] age <- seq_len(12) for (j in seq_len(ncol(Y))) { expect_lt(abs(cor(Y[, j], age)), 1e-6) @@ -1390,53 +1398,50 @@ test_that("residualizedPhenotypes: respects residualizePhenotype = FALSE", { qd <- .qr_makeDataset(contexts = "brain") Y <- residualizedPhenotypes( qd, - contexts = "brain", + context = "brain", residualizationParam = ResidualizationParam( residualizePhenotype = FALSE ) - ) + )[["brain"]] expect_equal(nrow(Y), 12L) expect_equal(ncol(Y), 2L) }) -test_that("residualizedPhenotypes: precise-name kwarg routes correctly", { - qd <- .qr_makeDataset(contexts = "brain") - Y_precise <- residualizedPhenotypes( - qd, - contexts = "brain", - residualizationParam = ResidualizationParam( - residualizePhenotype = FALSE - ) - ) - Y_conv <- residualizedPhenotypes( - qd, - contexts = "brain", - residualizationParam = ResidualizationParam( - residualizePhenotype = FALSE - ) - ) - expect_equal(Y_precise, Y_conv) -}) - -test_that("residualizedPhenotypes: traitId subsets to requested traits", { +test_that("residualizedPhenotypes: trait subsets to requested traits", { qd <- .qr_makeDataset(contexts = "brain") - Y <- residualizedPhenotypes(qd, contexts = "brain", traitId = "ENSG1") + Y <- residualizedPhenotypes(qd, context = "brain", trait = "ENSG1")[[ + "brain" + ]] expect_equal(ncol(Y), 1L) expect_equal(colnames(Y), "ENSG1") }) test_that("residualizedPhenotypes: scaleResiduals = FALSE skips the rescale step", { - qd <- .qr_makeDataset(contexts = "brain", scaleResiduals = FALSE) - Y <- residualizedPhenotypes(qd, contexts = "brain") + qd <- .qr_makeDataset(contexts = "brain") + Y <- residualizedPhenotypes( + qd, + context = "brain", + residualizationParam = ResidualizationParam(scaleResiduals = FALSE) + )[["brain"]] # Without scaling the residual columns generally won't have sd = 1. sds <- apply(Y, 2L, sd) expect_false(any(abs(sds - 1) < 1e-6)) }) # =========================================================================== -# molecularTraits/residualizedPhenotypes naAction +# Phenotype QC (PhenotypeFilterParam) applied by the extraction workers # =========================================================================== +# The run's resolved phenotype QC, as a pipeline hands it to the workers. +.qr_pheno <- function(...) { + pecotmr:::.qtlResolvePhenotypeFilter( + PhenotypeFilterParam(...), + naDefault = "keep", + naAllowed = c("keep", "drop", "impute"), + caller = "test" + ) +} + # Helper to build a single-context SE with controlled NA placement. .qr_makeSeWithNa <- function(n_samples = 8L, na_idx = c(2L, 5L)) { traits <- c("ENSG1", "ENSG2") @@ -1465,7 +1470,7 @@ test_that("residualizedPhenotypes: scaleResiduals = FALSE skips the rescale step ) } -test_that("molecularTraits naAction='drop' drops samples with any NA in selected traits", { +test_that("naAction = 'drop' drops samples with an NA in a selected trait", { gh <- .qr_makeHandle(n_samples = 8L) se <- .qr_makeSeWithNa(n_samples = 8L, na_idx = c(2L, 5L)) qd <- QtlDataset( @@ -1474,13 +1479,17 @@ test_that("molecularTraits naAction='drop' drops samples with any NA in selected phenotypes = list(brain = se), genotypeCovariates = matrix(numeric(0), 0L, 0L) ) - out <- molecularTraits(qd, contexts = "brain", naAction = "drop") + out <- pecotmr:::.qtlMolecularTraits( + qd, + "brain", + phenotypeFilter = .qr_pheno(naAction = "drop") + )[["brain"]] expect_s4_class(out, "SummarizedExperiment") expect_equal(ncol(out), 6L) expect_false(any(is.na(SummarizedExperiment::assay(out)))) }) -test_that("molecularTraits naAction='impute' mean-imputes NAs per trait", { +test_that("naAction = 'impute' mean-imputes NAs per trait", { gh <- .qr_makeHandle(n_samples = 8L) se <- .qr_makeSeWithNa(n_samples = 8L, na_idx = c(2L, 5L)) qd <- QtlDataset( @@ -1489,7 +1498,11 @@ test_that("molecularTraits naAction='impute' mean-imputes NAs per trait", { phenotypes = list(brain = se), genotypeCovariates = matrix(numeric(0), 0L, 0L) ) - out <- molecularTraits(qd, contexts = "brain", naAction = "impute") + out <- pecotmr:::.qtlMolecularTraits( + qd, + "brain", + phenotypeFilter = .qr_pheno(naAction = "impute") + )[["brain"]] Y <- SummarizedExperiment::assay(out) expect_equal(ncol(Y), 8L) expect_false(any(is.na(Y))) @@ -1500,7 +1513,7 @@ test_that("molecularTraits naAction='impute' mean-imputes NAs per trait", { expect_equal(Y[1L, 5L], obsMean) }) -test_that("residualizedPhenotypes naAction='impute' yields NA-free residuals", { +test_that("residualizing under naAction = 'impute' yields NA-free residuals", { gh <- .qr_makeHandle(n_samples = 8L) se <- .qr_makeSeWithNa(n_samples = 8L, na_idx = c(2L, 5L)) qd <- QtlDataset( @@ -1509,13 +1522,17 @@ test_that("residualizedPhenotypes naAction='impute' yields NA-free residuals", { phenotypes = list(brain = se), genotypeCovariates = matrix(numeric(0), 0L, 0L) ) - Y <- residualizedPhenotypes(qd, contexts = "brain", naAction = "impute") + Y <- pecotmr:::.qtlResidualizedPhenotypes( + qd, + "brain", + phenotypeFilter = .qr_pheno(naAction = "impute") + )[["brain"]] expect_false(any(is.na(Y))) expect_equal(nrow(Y), 8L) }) # =========================================================================== -# molecularTraits/residualizedPhenotypes outlierAction +# Outliers: dropped under the run's QC, kept by the accessors # =========================================================================== # Build a single-context SE with a clear multivariate outlier at sample s10. @@ -1551,7 +1568,7 @@ test_that("residualizedPhenotypes naAction='impute' yields NA-free residuals", { ) } -test_that("molecularTraits outlierAction='drop' drops a clear multivariate outlier", { +test_that("outlierAction = 'drop' drops a clear multivariate outlier", { skip_if_not_installed("robustbase") gh <- .qr_makeHandle(n_samples = 30L) se <- .qr_makeSeWithOutlier(n_samples = 30L, outlier_idx = 10L) @@ -1561,13 +1578,17 @@ test_that("molecularTraits outlierAction='drop' drops a clear multivariate outli phenotypes = list(brain = se), genotypeCovariates = matrix(numeric(0), 0L, 0L) ) - out <- molecularTraits(qd, contexts = "brain", outlierAction = "drop") + out <- pecotmr:::.qtlMolecularTraits( + qd, + "brain", + phenotypeFilter = .qr_pheno(outlierAction = "drop") + )[["brain"]] expect_s4_class(out, "SummarizedExperiment") expect_lt(ncol(out), 30L) expect_false("s10" %in% colnames(out)) }) -test_that("molecularTraits outlierAction='keep' is the default and a no-op", { +test_that("the accessors apply no phenotype QC: an outlier stays", { gh <- .qr_makeHandle(n_samples = 30L) se <- .qr_makeSeWithOutlier(n_samples = 30L, outlier_idx = 10L) qd <- QtlDataset( @@ -1576,11 +1597,20 @@ test_that("molecularTraits outlierAction='keep' is the default and a no-op", { phenotypes = list(brain = se), genotypeCovariates = matrix(numeric(0), 0L, 0L) ) - out <- molecularTraits(qd, contexts = "brain") + out <- molecularTraits(qd, context = "brain")[["brain"]] expect_equal(ncol(out), 30L) + # QC belongs to the run, so the accessors take none of its settings. + expect_error( + molecularTraits(qd, context = "brain", outlierAction = "drop"), + "unused argument" + ) + expect_error( + residualizedPhenotypes(qd, context = "brain", naAction = "drop"), + "unused argument" + ) }) -test_that("residualizedPhenotypes outlierAction='drop' drops residualized outliers", { +test_that("outlierAction = 'drop' drops residualized outliers", { skip_if_not_installed("robustbase") gh <- .qr_makeHandle(n_samples = 30L) se <- .qr_makeSeWithOutlier(n_samples = 30L, outlier_idx = 10L) @@ -1590,11 +1620,11 @@ test_that("residualizedPhenotypes outlierAction='drop' drops residualized outlie phenotypes = list(brain = se), genotypeCovariates = matrix(numeric(0), 0L, 0L) ) - Y <- residualizedPhenotypes( + Y <- pecotmr:::.qtlResidualizedPhenotypes( qd, - contexts = "brain", - outlierAction = "drop" - ) + "brain", + phenotypeFilter = .qr_pheno(outlierAction = "drop") + )[["brain"]] expect_lt(nrow(Y), 30L) expect_false("s10" %in% rownames(Y)) }) @@ -1620,355 +1650,9 @@ test_that(".qtlOutlierKeepMask: returns all-TRUE when n < p + 2", { expect_true(all(keep)) }) - -# Tests for functions that consume genotype matrices or compute LD: -# computeLd, checkLd, ldPruneByCorrelation, ldClumpByScore, -# enforceDesignFullRank, filterVariantsByLdReference, -# resolveLdInput, dentistSingleWindow, dentist - -# Fixtures: 100 samples x 100 biallelic polymorphic SNPs on chr21 -test_data_dir <- test_path("test_data") -plink_prefix <- file.path(test_data_dir, "test_variants") - -# Load genotype matrix once for reuse across tests -loadTestGenotype <- function() { - loadGenotypeRegion(plink_prefix, returnVariantInfo = TRUE) -} - -# --- computeLd -------------------------------------------------------------- - -test_that("computeLd produces valid sample correlation matrix", { - skip_if_not_installed("pgenlibr") - geno <- loadTestGenotype() - R <- computeLd(geno$X, method = "sample") - expect_true(is.matrix(R)) - expect_equal(nrow(R), ncol(geno$X)) - expect_equal(ncol(R), ncol(geno$X)) - expect_true(isSymmetric(R)) - expect_true(all(abs(diag(R) - 1) < 1e-10)) - expect_false(any(is.nan(R))) - expect_true(all(R >= -1 - 1e-10 & R <= 1 + 1e-10)) -}) - -test_that("computeLd population method produces valid matrix", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - R <- computeLd(X, method = "population") - expect_true(isSymmetric(R)) - expect_true(all(abs(diag(R) - 1) < 1e-10)) - expect_false(any(is.nan(R))) -}) - -test_that("computeLd sample and population methods are similar", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - R_s <- computeLd(X, method = "sample") - R_p <- computeLd(X, method = "population") - # Should be close but not identical (N-1 vs N denominator) - expect_true(max(abs(R_s - R_p)) < 0.05) -}) - -test_that("computeLd errors on NULL input", { - expect_error(computeLd(NULL), "X must be provided") -}) - -# --- checkLd ---------------------------------------------------------------- - -test_that("checkLd diagnoses real LD matrix correctly", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - R <- computeLd(X, method = "sample") - result <- checkLd(R) - expect_true(is.list(result)) - expect_true(result$isPsd) - expect_equal(result$methodApplied, "none") - # min eigenvalue may be near-zero (numerically PSD, not strictly PD) - expect_true(result$minEigenvalue > -1e-7) - expect_true(result$nNegative == 0) - expect_true(is.finite(result$conditionNumber)) -}) - -test_that("checkLd eigenfix improves non-PSD matrix", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - R <- computeLd(X, method = "sample") - # Make a non-PSD matrix by negating a small block of off-diagonal entries - R_bad <- R - R_bad[1:3, 4:6] <- -abs(R_bad[1:3, 4:6]) - 0.5 - R_bad[4:6, 1:3] <- t(R_bad[1:3, 4:6]) - diag(R_bad) <- 1 - - result_check <- checkLd(R_bad, method = "check") - expect_false(result_check$isPsd) - expect_true(result_check$nNegative > 0) - - result_fix <- checkLd(R_bad, method = "eigenfix") - expect_equal(result_fix$methodApplied, "eigenfix") - # Eigenfix should improve (raise) minimum eigenvalue - fixed_check <- checkLd(result_fix$R) - expect_true(fixed_check$minEigenvalue > result_check$minEigenvalue) -}) - -test_that("checkLd shrink repairs perturbed LD matrix", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - R <- computeLd(X, method = "sample") - R_bad <- R - R_bad[1, 2] <- R_bad[2, 1] <- 1.5 - diag(R_bad) <- 1 - result <- checkLd(R_bad, method = "shrink", shrinkage = 0.1) - expect_equal(result$methodApplied, "shrink") -}) - -# --- ldPruneByCorrelation ------------------------------------------------- - -test_that("ldPruneByCorrelation prunes correlated variants", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - result <- ldPruneByCorrelation(X, corThres = 0.8) - expect_true(is.list(result)) - expect_true(is.matrix(result$X.new)) - expect_true(ncol(result$X.new) <= ncol(X)) - expect_true(ncol(result$X.new) > 0) - expect_equal(length(result$filter.id), ncol(result$X.new)) - # Retained columns are a subset of original - expect_true(all(result$filter.id %in% seq_len(ncol(X)))) -}) - -test_that("ldPruneByCorrelation with strict threshold prunes more", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - loose <- ldPruneByCorrelation(X, corThres = 0.95) - strict <- ldPruneByCorrelation(X, corThres = 0.5) - expect_true(ncol(strict$X.new) <= ncol(loose$X.new)) -}) - -test_that("ldPruneByCorrelation with high threshold keeps most columns", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - result <- ldPruneByCorrelation(X, corThres = 0.999) - # At threshold near 1, only near-duplicates are pruned; real data may have many - expect_true(ncol(result$X.new) >= ncol(X) * 0.4) -}) - -# --- ldClumpByScore ------------------------------------------------------- - -test_that("ldClumpByScore returns valid indices", { - skip_if_not_installed("pgenlibr") - skip_if_not_installed("bigsnpr") - skip_if_not_installed("bigstatsr") - geno <- loadTestGenotype() - set.seed(42) - score <- runif(ncol(geno$X)) - chr <- as.integer(geno$variant_info$chrom) - pos <- geno$variant_info$pos - keep <- ldClumpByScore( - geno$X, - score = score, - chr = chr, - pos = pos, - r2 = 0.2 - ) - expect_true(is.integer(keep)) - expect_true(length(keep) > 0) - expect_true(length(keep) <= ncol(geno$X)) - expect_true(all(keep %in% seq_len(ncol(geno$X)))) -}) - -# --- enforceDesignFullRank ------------------------------------------------ - -test_that("enforceDesignFullRank handles genotype matrix with covariates", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - # Create a simple covariate matrix (e.g., first 2 PCs of X) - pca <- prcomp(X, rank. = 2) - C <- pca$x - result <- enforceDesignFullRank(X, C, strategy = "correlation") - expect_true(is.matrix(result)) - expect_equal(nrow(result), nrow(X)) - # Should produce full-rank design - full_design <- cbind(1, result, C) - expect_equal(qr(full_design)$rank, ncol(full_design)) -}) - -# --- filterVariantsByLdReference ----------------------------------------- - -test_that("filterVariantsByLdReference filters against PLINK reference via metadata", { - skip_if_not_installed("pgenlibr") - geno <- loadTestGenotype() - vi <- geno$variant_info - variant_ids <- paste0(vi$chrom, ":", vi$pos, ":", vi$A2, ":", vi$A1) - fake_ids <- c("21:999999:A:G", "21:888888:C:T") - all_ids <- c(variant_ids, fake_ids) - - # Create a metadata TSV in the same directory as the PLINK files - # so the relative path resolves correctly - meta_file <- file.path(test_data_dir, "ld_meta_tmp.tsv") - on.exit(unlink(meta_file), add = TRUE) - writeLines( - paste("chrom", "start", "end", "path", sep = "\t"), - meta_file - ) - cat( - paste("21", "0", "0", "test_variants", sep = "\t"), - "\n", - file = meta_file, - append = TRUE - ) - - result <- suppressMessages( - filterVariantsByLdReference(all_ids, meta_file, keepIndel = TRUE) - ) - expect_true(is.list(result)) - expect_true(length(result$data) <= length(all_ids)) - expect_true(length(result$idx) == length(result$data)) - # Fake variants should be filtered out - expect_true(length(result$data) <= length(variant_ids)) -}) - -# --- resolveLdInput (internal) --------------------------------------------- - -test_that("resolveLdInput computes LD from genotype matrix", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - result <- pecotmr:::resolveLdInput(X = X, needNSample = TRUE) - expect_true(is.list(result)) - expect_true(is.matrix(result$R)) - expect_equal(nrow(result$R), ncol(X)) - expect_equal(result$nSample, nrow(X)) - expect_true(isSymmetric(result$R)) -}) - -test_that("resolveLdInput passes through pre-computed R", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - R <- computeLd(X, method = "sample") - result <- pecotmr:::resolveLdInput( - R = R, - nSample = 100L, - needNSample = TRUE - ) - expect_equal(result$R, R) - expect_equal(result$nSample, 100L) -}) - -test_that("resolveLdInput errors when neither R nor X provided", { - expect_error( - pecotmr:::resolveLdInput(), - "Either R .* or X .* must be provided" - ) -}) - -test_that("resolveLdInput errors when both R and X provided", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - R <- computeLd(X, method = "sample") - expect_error( - pecotmr:::resolveLdInput(R = R, X = X), - "Provide either R or X, not both" - ) -}) - -test_that("resolveLdInput errors when R given without nSample and needed", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - R <- computeLd(X, method = "sample") - expect_error( - pecotmr:::resolveLdInput(R = R, needNSample = TRUE), - "nSample is required" - ) -}) - -# --- dentistSingleWindow --------------------------------------------------- - -test_that("dentistSingleWindow works with genotype matrix X", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - set.seed(42) - z <- rnorm(ncol(X)) - result <- suppressWarnings(dentistSingleWindow(z, X = X)) - expect_true(is.data.frame(result)) - expect_equal(nrow(result), length(z)) - expect_true("original_z" %in% names(result)) - expect_true("imputed_z" %in% names(result)) - expect_true("outlier" %in% names(result)) - expect_true(is.logical(result$outlier)) -}) - -test_that("dentistSingleWindow works with pre-computed R", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - R <- computeLd(X, method = "sample") - set.seed(42) - z <- rnorm(ncol(X)) - result <- suppressWarnings(dentistSingleWindow(z, R = R, nSample = nrow(X))) - expect_true(is.data.frame(result)) - expect_equal(nrow(result), length(z)) -}) - -test_that("dentistSingleWindow detects injected outliers", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - R <- computeLd(X, method = "sample") - set.seed(42) - z <- rnorm(ncol(X)) - # Inject extreme outliers - z[1] <- 50 - z[2] <- -50 - result <- suppressWarnings(dentistSingleWindow(z, R = R, nSample = nrow(X))) - # At least one of the injected values should be flagged - expect_true(any(result$outlier)) -}) - -# --- dentist (multi-window) ------------------------------------------------- - -test_that("dentist works with genotype matrix and sum_stat data frame", { - skip_if_not_installed("pgenlibr") - geno <- loadTestGenotype() - set.seed(42) - sum_stat <- data.frame( - pos = geno$variant_info$pos, - z = rnorm(ncol(geno$X)) - ) - # Use count mode with small window since we only have 100 variants - result <- suppressWarnings( - dentist(sum_stat, X = geno$X, windowMode = "count", minDim = 50) - ) - expect_true(is.data.frame(result)) - # Window merging may add overlap rows; result should be >= input size - expect_true(nrow(result) >= nrow(sum_stat)) - expect_true(all(c("original_z", "imputed_z", "outlier") %in% names(result))) -}) - -test_that("dentist accepts zscore column name variant", { - skip_if_not_installed("pgenlibr") - geno <- loadTestGenotype() - R <- computeLd(geno$X, method = "sample") - set.seed(42) - sum_stat <- data.frame( - position = geno$variant_info$pos, - zscore = rnorm(ncol(geno$X)) - ) - result <- suppressWarnings( - dentist( - sum_stat, - R = R, - nSample = nrow(geno$X), - windowMode = "count", - minDim = 50 - ) - ) - expect_true(nrow(result) >= nrow(sum_stat)) -}) - -test_that("dentist errors when sum_stat missing required columns", { - skip_if_not_installed("pgenlibr") - X <- loadTestGenotype()$X - bad_stat <- data.frame(x = seq_len(ncol(X)), y = rnorm(ncol(X))) - expect_error(dentist(bad_stat, X = X), "missing either") -}) - -# === Tests migrated from test_s4Constructors.R (QtlDataset) === +# =========================================================================== +# QtlDataset construction and validity +# =========================================================================== test_that("QtlDataset: builds and validates with a single-context SE", { se <- .sc_makeSe() @@ -2034,17 +1718,9 @@ test_that("QtlDataset: rejects non-SE elements in phenotype list", { }) -test_that("QtlDataset: rejects negative QC cutoffs", { - se <- .sc_makeSe() - expect_error( - QtlDataset( - studyName = "s1", - genotypes = .sc_makeGenotypeHandle(), - phenotypes = list(brain = se), - genotypeFilterParam = GenotypeFilterParam(mafCutoff = -0.1) - ), - "is not >= 0" - ) +test_that("GenotypeFilterParam: rejects negative QC cutoffs", { + expect_error(GenotypeFilterParam(mafCutoff = -0.1), "is not >= 0") + expect_error(GenotypeFilterParam(imissCutoff = Inf), "imissCutoff") }) @@ -2119,23 +1795,27 @@ test_that("QtlDataset: tolerates chr-prefix-only seqname differences for a share }) # =========================================================================== -# MultiStudyQtlDataset +# updateObject # =========================================================================== -test_that("MultiStudyQtlDataset: rejects non-QtlDataset entries", { - qd <- QtlDataset( - studyName = "s1", - genotypes = .sc_makeGenotypeHandle(), - phenotypes = list(brain = .sc_makeSe()) - ) - expect_error( - MultiStudyQtlDataset(qtlDatasets = list(s1 = qd, s2 = "not a dataset")), - "must be a QtlDataset" +test_that("updateObject drops the slots a QtlDataset no longer has", { + data(qtlDatasetExample) + old <- qtlDatasetExample + attr(old, "mafCutoff") <- 0.01 + attr(old, "keepIndel") <- TRUE + up <- updateObject(old) + expect_null(attr(up, "mafCutoff")) + expect_null(attr(up, "keepIndel")) + expect_true(methods::validObject(up)) + expect_message( + updateObject(qtlDatasetExample, verbose = TRUE), + "updateObject\\(object = 'QtlDataset'\\)" ) }) - -# === Tests migrated from test_showMethods.R (QtlDataset) === +# =========================================================================== +# show() +# =========================================================================== test_that("show.QtlDataset lists context names and trait count", { qd <- .sh_makeQtlDataset() @@ -2146,35 +1826,6 @@ test_that("show.QtlDataset lists context names and trait count", { expect_true(any(grepl("Genotypes: plink2 @ /tmp/test", out))) }) - -test_that("show.MultiStudyQtlDataset reports per-source study counts", { - qd1 <- .sh_makeQtlDataset(studyName = "s1") - qd2 <- .sh_makeQtlDataset(studyName = "s2") - mt <- MultiStudyQtlDataset(qtlDatasets = list(s1 = qd1, s2 = qd2)) - out <- capture.output(show(mt)) - expect_true(any(grepl( - "MultiStudyQtlDataset: 2 individual-level \\+ 0 sumstats", - out - ))) - expect_true(any(grepl("Individual-level studies: s1, s2", out))) -}) - - -test_that("show.MultiStudyQtlDataset reports sumstats studies when present", { - qd <- .sh_makeQtlDataset(studyName = "s1") - ss <- QtlSumStats( - studyName = "s2", - context = "c1", - trait = "t1", - entry = list(.sh_makeQtlSumstatsGr()), - genome = "hg19", - ldReference = .sh_makeGenotypeHandle() - ) - mt <- MultiStudyQtlDataset(qtlDatasets = list(s1 = qd), sumStats = ss) - out <- capture.output(show(mt)) - expect_true(any(grepl("Sumstats studies: s2", out))) -}) - # =========================================================================== # Multi-region variant extraction: genotypes() with a multi-range region # (the mechanism behind jointRegions). Single-file (chr21) and sharded @@ -2201,8 +1852,12 @@ test_that("show.MultiStudyQtlDataset reports sumstats studies when present", { colData = S4Vectors::DataFrame(row.names = samples) ) } -.mr_ncol <- function(qd, region) ncol(genotypes(qd, region = region)) -.mr_vids <- function(qd, region) colnames(genotypes(qd, region = region)) +# A pipeline's extraction over an analysis window of one or more ranges. +.mr_geno <- function(qd, window) { + pecotmr:::.qtlExtractBlock(qd, window = window)$geno +} +.mr_ncol <- function(qd, window) ncol(.mr_geno(qd, window)) +.mr_vids <- function(qd, window) colnames(.mr_geno(qd, window)) test_that("multi-range region unions disjoint sub-ranges on one chromosome", { skip_if_not_installed("pgenlibr") @@ -2264,8 +1919,8 @@ test_that("multi-range region spans chromosomes on a sharded handle", { expect_gt(n22, 0L) expect_equal(.mr_ncol(qd, rBoth), n21 + n22) - gBoth <- genotypes(qd, region = rBoth) - g21 <- genotypes(qd, region = r21) + gBoth <- .mr_geno(qd, rBoth) + g21 <- .mr_geno(qd, r21) expect_equal(unname(gBoth[, seq_len(n21)]), unname(g21)) expect_true(all(grepl("_c22$", colnames(gBoth)[(n21 + 1):(n21 + n22)]))) }) @@ -2285,79 +1940,57 @@ test_that("multi-region: single-range extraction is unchanged (regression)", { expect_equal(.mr_ncol(qd, r), nrow(snpInfo(h))) }) -test_that(".qtlResolveVariantRegion rejects a non-GRanges / empty region", { - skip_if_not_installed("pgenlibr") - h <- GenotypeHandle( - plink2Prefix = file.path(test_data_dir, "test_variants") - ) - qd <- QtlDataset( - studyName = "S", - genotypes = h, - phenotypes = list(ctx = .mr_makeSE(sampleIds(h))) - ) - expect_error( - genotypes(qd, region = "chr21:1-2"), - "Must inherit from class 'GRanges'" - ) - expect_error( - genotypes(qd, region = GenomicRanges::GRanges()), - "at least one range" - ) -}) - # =========================================================================== -# Accessors: genotypeCovariates / scaleResiduals / phenotypeCovariates +# Accessors: genotypeCovariates / phenotypeCovariates # =========================================================================== -test_that("genotypeCovariates / scaleResiduals return their slots", { +test_that("genotypeCovariates returns the genotype experiment's colData", { gc <- matrix( rnorm(12 * 2), nrow = 12, ncol = 2, dimnames = list(paste0("s", 1:12), c("pc1", "pc2")) ) - qd <- .qr_makeDataset( - contexts = "brain", - geno_cov = gc, - scaleResiduals = FALSE - ) + qd <- .qr_makeDataset(contexts = "brain", geno_cov = gc) + # The covariates live on the genotype experiment's colData, one row per + # panel sample. + cd <- SummarizedExperiment::colData(pecotmr:::.qtlGenotypeSe(qd)) + expect_equal(colnames(cd), c("pc1", "pc2")) + expect_equal(rownames(cd), sampleIds(genotypeHandle(qd))) expect_identical( genotypeCovariates(qd), pecotmr:::.qtlColDataMatrix(pecotmr:::.qtlGenotypeSe(qd)) ) expect_equal(unname(genotypeCovariates(qd)), unname(gc)) - expect_false(scaleResiduals(qd)) - qd2 <- .qr_makeDataset(contexts = "brain", scaleResiduals = TRUE) - expect_true(scaleResiduals(qd2)) }) test_that("phenotypeCovariates returns per-context colData matrices", { qd <- .qr_makeDataset(contexts = c("brain", "liver")) - out <- phenotypeCovariates(qd, contexts = c("brain", "liver")) + out <- phenotypeCovariates(qd, context = c("brain", "liver")) expect_equal(names(out), c("brain", "liver")) expect_true(is.matrix(out$brain)) expect_setequal(colnames(out$brain), c("sex", "age")) expect_equal(nrow(out$brain), 12L) # Single-context request still returns a named list of length 1. - one <- phenotypeCovariates(qd, contexts = "liver") + one <- phenotypeCovariates(qd, context = "liver") expect_equal(names(one), "liver") }) test_that("phenotypeCovariates: requires contexts and rejects unknown ones", { qd <- .qr_makeDataset(contexts = "brain") - expect_error(phenotypeCovariates(qd), "`contexts` is required") + expect_error(phenotypeCovariates(qd), "`context` is required") expect_error( - phenotypeCovariates(qd, contexts = character(0)), - "`contexts` is required" + phenotypeCovariates(qd, context = character(0)), + "`context` is required" ) expect_error( - phenotypeCovariates(qd, contexts = "ghost"), + phenotypeCovariates(qd, context = "ghost"), "Unknown context" ) }) # =========================================================================== -# .qtlResolveVariantRegion: region-path cisWindow validation (line ~247) +# .qtlResolveVariantRegion: region-path cisWindow validation # =========================================================================== test_that(".qtlResolveVariantRegion: region path rejects a non-scalar/negative cisWindow", { @@ -2383,12 +2016,15 @@ test_that(".qtlResolveVariantRegion: region path rejects a non-scalar/negative c test_that(".qtlExtractBlock: keepIndel = FALSE with an all-indel panel returns an empty block", { # Every variant a multi-base allele, so the indel filter drops them all. - qd <- .qh_makeDataset(a1 = rep("AT", 6L), keepIndel = FALSE) + qd <- .qh_makeDataset(a1 = rep("AT", 6L)) local_mocked_bindings( extractBlockGenotypes = .qh_mockExtractor(), .package = "pecotmr" ) - blk <- pecotmr:::.qtlExtractBlock(qd) + blk <- pecotmr:::.qtlExtractBlock( + qd, + filter = .qh_filter(keepIndel = FALSE) + ) expect_equal(ncol(blk$geno), 0L) expect_equal(nrow(blk$geno), 0L) expect_equal(blk$variantIds, character(0)) @@ -2398,10 +2034,7 @@ test_that(".qtlExtractBlock: keepIndel = FALSE with an all-indel panel returns a test_that(".qtlExtractBlock: keepSamples disjoint from the panel returns a zero-sample block", { qd <- .qh_makeDataset() # none are panel samples - qd <- pecotmr:::.qtlApplyFilterOverrides( - qd, - GenotypeFilterParam(keepSamples = c("zzz1", "zzz2")) - ) + qd <- pecotmr:::.qtlRestrictSamples(qd, c("zzz1", "zzz2")) local_mocked_bindings( extractBlockGenotypes = .qh_mockExtractor(), .package = "pecotmr" @@ -2459,12 +2092,15 @@ test_that(".qtlExtractBlock: keepSamples disjoint from the panel returns a zero- test_that(".qtlExtractBlock: imissCutoff drops high-missingness samples and mean-imputes the rest", { # s1 (100% NA) dropped; s2 (1 NA) kept then imputed - qd <- .qh_makeDataset(imissCutoff = 0.5) + qd <- .qh_makeDataset() local_mocked_bindings( extractBlockGenotypes = .qh_naExtractor(), .package = "pecotmr" ) - blk <- pecotmr:::.qtlExtractBlock(qd) + blk <- pecotmr:::.qtlExtractBlock( + qd, + filter = .qh_filter(imissCutoff = 0.5) + ) expect_false("s1" %in% blk$sampleIds) expect_true("s2" %in% blk$sampleIds) expect_false(anyNA(blk$geno)) # scattered NA was mean-imputed @@ -2512,12 +2148,15 @@ test_that(".qtlExtractBlock: imissCutoff drops high-missingness samples and mean } test_that(".qtlExtractBlock: xvarCutoff drops near-constant (low-variance) variants", { - qd <- .qh_makeDataset(xvarCutoff = 0.01) + qd <- .qh_makeDataset() local_mocked_bindings( extractBlockGenotypes = .qh_lowVarExtractor(), .package = "pecotmr" ) - blk <- pecotmr:::.qtlExtractBlock(qd) + blk <- pecotmr:::.qtlExtractBlock( + qd, + filter = .qh_filter(xvarCutoff = 0.01) + ) expect_false("rs1" %in% blk$variantIds) # constant column dropped on variance expect_true(ncol(blk$geno) >= 1L) }) @@ -2528,36 +2167,40 @@ test_that(".qtlExtractBlock: xvarCutoff drops near-constant (low-variance) varia test_that("molecularTraits: requires contexts", { qd <- .qr_makeDataset() - expect_error(molecularTraits(qd), "`contexts` is required") + expect_error(molecularTraits(qd), "`context` is required") expect_error( - molecularTraits(qd, contexts = character(0)), - "`contexts` is required" + molecularTraits(qd, context = character(0)), + "`context` is required" ) }) test_that("molecularTraits: unknown context errors", { qd <- .qr_makeDataset() - expect_error(molecularTraits(qd, contexts = "ghost"), "Unknown context") + expect_error(molecularTraits(qd, context = "ghost"), "Unknown context") }) -test_that("molecularTraits: region keeps only overlapping traits", { +test_that("a pipeline's window keeps only the overlapping traits", { qd <- .qr_makeDataset(contexts = "brain") # brain SE: ENSG1 @ chr1:1000-1499, ENSG2 @ chr1:2000-2499. region <- GenomicRanges::GRanges("chr1", IRanges::IRanges(900, 1600)) - out <- molecularTraits(qd, contexts = "brain", region = region) + out <- pecotmr:::.qtlMolecularTraits( + qd, + contexts = "brain", + window = region + )[["brain"]] expect_s4_class(out, "SummarizedExperiment") expect_equal(rownames(out), "ENSG1") }) -test_that("molecularTraits: non-overlapping region + naAction='drop' hits the empty-Y short-circuit", { +test_that("an unmatched window under naAction = 'drop' gives an empty SE", { qd <- .qr_makeDataset(contexts = "brain") region <- GenomicRanges::GRanges("chr2", IRanges::IRanges(1, 100)) # no overlap - out <- molecularTraits( + out <- pecotmr:::.qtlMolecularTraits( qd, contexts = "brain", - region = region, - naAction = "drop" - ) + window = region, + phenotypeFilter = .qr_pheno(naAction = "drop") + )[["brain"]] expect_s4_class(out, "SummarizedExperiment") expect_equal(nrow(out), 0L) }) @@ -2585,26 +2228,12 @@ test_that(".qtlOutlierKeepMask: robustbase covMcd failure falls back to colMeans ) set.seed(8L) Y <- matrix(c(rnorm(29), 60), ncol = 1L) - keep <- pecotmr:::.qtlOutlierKeepMask(Y, pvalThreshold = 1e-3) - expect_length(keep, 30L) - expect_false(keep[[30L]]) # the planted 60 is still flagged -}) - -test_that(".qtlOutlierKeepMask: falls back with a message when robustbase is absent", { - # Force the robustbase-absent branch by mocking base::requireNamespace. - local_mocked_bindings( - requireNamespace = function(package, ...) { - if (identical(package, "robustbase")) FALSE else TRUE - }, - .package = "base" - ) - set.seed(5L) - Y <- matrix(c(rnorm(29), 50), ncol = 1L) expect_message( keep <- pecotmr:::.qtlOutlierKeepMask(Y, pvalThreshold = 1e-3), - "install 'robustbase'" + "robustbase's MCD estimator failed" ) expect_length(keep, 30L) + expect_false(keep[[30L]]) # the planted 60 is still flagged }) # =========================================================================== @@ -2720,7 +2349,7 @@ test_that(".qtlBuildResidualizationDesign: disjoint blocks error", { }) # =========================================================================== -# getResidualized{Genotypes,Phenotypes}: disjoint sample-set errors +# residualized{Genotypes,Phenotypes}: disjoint sample-set errors # =========================================================================== test_that("residualizedGenotypes: errors when genotypes and covariates share no samples", { @@ -2738,7 +2367,7 @@ test_that("residualizedGenotypes: errors when genotypes and covariates share no expect_error( residualizedGenotypes( qd, - contexts = "brain", + context = "brain", residualizationParam = ResidualizationParam( residualizePhenotype = FALSE, genotypeCovariates = c("pc1", "pc2") @@ -2759,7 +2388,7 @@ test_that("residualizedPhenotypes: errors when phenotypes and covariates share n expect_error( residualizedPhenotypes( qd, - contexts = "brain", + context = "brain", residualizationParam = ResidualizationParam( residualizePhenotype = FALSE, genotypeCovariates = c("pc1", "pc2") @@ -2769,37 +2398,6 @@ test_that("residualizedPhenotypes: errors when phenotypes and covariates share n ) }) -test_that("QtlDataset filter accessors report the construction settings", { - data(qtlDatasetExample, envir = environment()) - x <- qtlDatasetExample - expect_type(mafCutoff(x), "double") - expect_length(mafCutoff(x), 1L) - expect_length(macCutoff(x), 1L) - expect_length(xvarCutoff(x), 1L) - expect_length(imissCutoff(x), 1L) - expect_type(keepIndel(x), "logical") - expect_type(keepVariants(x), "character") -}) - -test_that("QtlDataset filter accessors round-trip what was passed in", { - data(qtlDatasetExample, envir = environment()) - x <- .qtlApplyFilterOverrides( - qtlDatasetExample, - GenotypeFilterParam( - mafCutoff = 0.05, - macCutoff = 10, - xvarCutoff = 0.01, - imissCutoff = 0.1, - keepIndel = FALSE - ) - ) - expect_equal(mafCutoff(x), 0.05) - expect_equal(macCutoff(x), 10) - expect_equal(xvarCutoff(x), 0.01) - expect_equal(imissCutoff(x), 0.1) - expect_false(keepIndel(x)) -}) - test_that("genotypeHandle returns the handle, genotypes a dosage block", { # These are different accessors on purpose: genotypes() extracts # dosages through the filter stack, genotypeHandle() hands back the @@ -2899,19 +2497,6 @@ test_that("the dosage assay is delayed and oriented variants x samples", { expect_equal(ncol(a), length(sampleIds(handle))) }) -test_that("genotype covariates live on the genotype experiment's colData", { - qd <- .qm_makeDataset() - cd <- SummarizedExperiment::colData(pecotmr:::.qtlGenotypeSe(qd)) - expect_equal(colnames(cd), c("pc1", "pc2")) - expect_equal(rownames(cd), sampleIds(genotypeHandle(qd))) - expect_equal( - genotypeCovariates(qd), - pecotmr:::.qtlColDataMatrix( - pecotmr:::.qtlGenotypeSe(qd) - ) - ) -}) - test_that("subsetting by sample keeps the class and its own slots", { qd <- .qm_makeDataset() out <- qd[, paste0("s", 1:5), ] @@ -2919,7 +2504,6 @@ test_that("subsetting by sample keeps the class and its own slots", { expect_equal(nrow(MultiAssayExperiment::colData(out)), 5L) expect_equal(studyName(out), studyName(qd)) expect_identical(genotypeHandle(out), genotypeHandle(qd)) - expect_equal(mafCutoff(out), mafCutoff(qd)) }) test_that("subsetting by context keeps the genotype experiment", { @@ -2938,36 +2522,28 @@ test_that("subsetting by context keeps the genotype experiment", { expect_true(validObject(out)) }) -test_that("subsetting by sample and context together narrows both axes", { - # `x[, j, k]`: the experiment axis is applied here, then the remaining +test_that("subsetting by context also applies feature and sample subscripts", { + # `x[i, j, k]`: the experiment axis is applied here, then the remaining # axes go back through the method with no `k` so the inherited one runs. + # With no sample subscript, every sample survives. qd <- .qm_makeDataset() - out <- suppressWarnings(suppressMessages(qd[, paste0("s", 1:5), "brain"])) - expect_s4_class(out, "QtlDataset") - expect_equal(contexts(out), "brain") - expect_equal(nrow(MultiAssayExperiment::colData(out)), 5L) - expect_true(validObject(out)) -}) - -test_that("subsetting by feature and context leaves the samples alone", { - # `x[i, , k]`: no sample subscript, so every sample survives. - qd <- .qm_makeDataset() - out <- suppressWarnings(suppressMessages(qd[1, , "brain"])) - expect_s4_class(out, "QtlDataset") - expect_equal(contexts(out), "brain") - expect_equal(nrow(MultiAssayExperiment::colData(out)), 12L) - expect_true(validObject(out)) -}) - -test_that("all three subscripts can be given at once", { - qd <- .qm_makeDataset() - out <- suppressWarnings(suppressMessages( - qd[1, paste0("s", 1:5), "brain"] - )) - expect_s4_class(out, "QtlDataset") - expect_equal(contexts(out), "brain") - expect_equal(nrow(MultiAssayExperiment::colData(out)), 5L) - expect_true(validObject(out)) + s5 <- str_c("s", 1:5) + cases <- suppressWarnings(suppressMessages(list( + `sample and context` = list(out = qd[, s5, "brain"], nSamples = 5L), + `feature and context` = list(out = qd[1, , "brain"], nSamples = 12L), + `all three` = list(out = qd[1, s5, "brain"], nSamples = 5L) + ))) + for (case in names(cases)) { + out <- cases[[case]]$out + expect_true(is(out, "QtlDataset"), info = case) + expect_equal(contexts(out), "brain", info = case) + expect_equal( + nrow(MultiAssayExperiment::colData(out)), + cases[[case]]$nSamples, + info = case + ) + expect_true(validObject(out), info = case) + } }) test_that("the experiment subscript accepts logical and numeric, not just names", { @@ -3152,13 +2728,6 @@ test_that("QtlDataset still rejects a genotype source it cannot open", { # guards were never executed. # =========================================================================== -test_that("validity rejects a non-scalar scaleResiduals", { - # The constructor coerces via isTRUE(); validity guards direct slot sets. - qd <- .qh_makeDataset() - qd@scaleResiduals <- c(TRUE, FALSE) - expect_error(validObject(qd), "Variable 'scaleResiduals'") -}) - test_that("the phenotype-list check rejects duplicated context names", { se <- .qh_makeSe() errs <- pecotmr:::.qtlCheckPhenotypeList(list(brain = se, brain = se)) @@ -3253,16 +2822,34 @@ test_that("aligning covariates with nothing to align returns NULL", { expect_null(pecotmr:::.qtlAlignCovariates(list(), NULL)) }) -test_that("outlier detection reports a singular trait covariance", { - # A singular covariance silently became a pseudo-inverse, while the - # sibling robustbase-missing branch already informed the user. +test_that("outlier detection reports a singular trait covariance once", { + skip_if_not_installed("robustbase") + # robustbase::covMcd() warns, in its own words, that the samples lie + # on a line; that warning is the one signal, so pecotmr adds none. + Y <- cbind(a = c(1, 2, 3, 4), b = c(2, 4, 6, 8)) + expect_warning( + expect_no_message( + keep <- pecotmr:::.qtlOutlierKeepMask(Y, pvalThreshold = 0.05) + ), + "covariance matrix of the data is singular" + ) + expect_length(keep, 4L) +}) + +test_that("a non-robust fallback announces its own singular covariance", { + skip_if_not_installed("robustbase") + # With no MCD there is no robustbase warning, so pecotmr says both what + # it fell back to and that it took a pseudo-inverse. + local_mocked_bindings( + covMcd = function(...) stop("forced covMcd failure"), + .package = "robustbase" + ) Y <- cbind(a = c(1, 2, 3, 4), b = c(2, 4, 6, 8)) - cnd <- rlang::catch_cnd( - pecotmr:::.qtlOutlierKeepMask(Y, pvalThreshold = 0.05), - classes = "message" + msgs <- capture_messages( + pecotmr:::.qtlOutlierKeepMask(Y, pvalThreshold = 0.05) ) - expect_match(conditionMessage(cnd), "singular") - expect_match(conditionMessage(cnd), "pseudo-inverse") + expect_true(any(str_detect(msgs, "MCD estimator failed"))) + expect_true(any(str_detect(msgs, "pseudo-inverse"))) }) test_that(".qtlConcat answers an empty list for no pieces", { @@ -3309,17 +2896,16 @@ test_that("the three filter bundles are separate on purpose", { }) test_that("an unset genotype filter field is absent, not NULL", { - # Absence is what distinguishes "pin this value" from "leave it alone": - # QtlDataset resolves an unset field to its own default, a pipeline - # leaves the dataset's construct-time slot untouched. + # The bundle reports only what was set; a run resolves an unset field to + # its default (.qtlResolveFilter()). expect_length(GenotypeFilterParam(), 0L) expect_equal(names(GenotypeFilterParam(mafCutoff = 0)), "mafCutoff") - # A pinned zero is NOT the same as unset. + # A set zero is reported; an unset field is not. expect_equal(GenotypeFilterParam(mafCutoff = 0)$mafCutoff, 0) expect_null(GenotypeFilterParam()$mafCutoff) }) -test_that("every GenotypeFilterParam field is one QtlDataset resolves", { +test_that("every GenotypeFilterParam field is one a run resolves", { expect_setequal( names(formals(GenotypeFilterParam)), names(pecotmr:::.qtlResolveFilter(GenotypeFilterParam())) @@ -3396,9 +2982,94 @@ test_that("a QtlDataset reads genotypes held in memory as from a file", { expect_null(genotypeHandle(qd)) region <- SummarizedExperiment::rowRanges(disk)[1:30] expect_equal( - genotypes(qd, region = region), - genotypes(qtlDatasetExample, region = region) + genotypes(qd[region, , ]), + genotypes(qtlDatasetExample[region, , ]) ) out <- capture.output(show(qd)) expect_true(any(grepl("held in memory", out))) }) + +# =========================================================================== +# PhenotypeFilterParam: the run's phenotype QC +# =========================================================================== + +test_that("PhenotypeFilterParam: unset fields take each pipeline's default", { + p <- PhenotypeFilterParam() + expect_length(p, 0L) + fm <- pecotmr:::.fmResolvePhenotypeFilter(p) + expect_equal(fm$naAction, "drop") + expect_equal(fm$outlierAction, "keep") + expect_equal(fm$outlierPvalThreshold, 1e-3) + expect_s4_class(fm$outlierArgs, "MethodOptions") + # colocboost takes missing phenotypes as they are. + expect_equal(pecotmr:::.cbResolvePhenotypeFilter(p)$naAction, "keep") + tw <- pecotmr:::.twasResolvePhenotypeFilter( + PhenotypeFilterParam(naAction = "impute", outlierPvalThreshold = 0.01) + ) + expect_equal(tw$naAction, "impute") + expect_equal(tw$outlierPvalThreshold, 0.01) +}) + +test_that("PhenotypeFilterParam: a fit that cannot take NAs refuses 'keep'", { + keep <- PhenotypeFilterParam(naAction = "keep") + expect_error( + pecotmr:::.fmResolvePhenotypeFilter(keep), + "fineMappingPipeline: naAction = \"keep\" is not available" + ) + expect_error( + pecotmr:::.twasResolvePhenotypeFilter(keep), + "twasWeightsPipeline: .*Use \"drop\" or \"impute\"" + ) + expect_equal(pecotmr:::.cbResolvePhenotypeFilter(keep)$naAction, "keep") +}) + +test_that("PhenotypeFilterParam: a bad value is named where it is set", { + expect_error(PhenotypeFilterParam(naAction = "zap"), "naAction") + expect_error(PhenotypeFilterParam(outlierAction = "zap"), "outlierAction") + expect_error( + PhenotypeFilterParam(outlierPvalThreshold = 2), + "outlierPvalThreshold" + ) + expect_error(PhenotypeFilterParam(outlierArgs = list()), "outlierArgs") + # A record built for another engine means nothing to the detector. + expect_error( + PhenotypeFilterParam(outlierArgs = GlmnetOptions()), + "must be built with CovMcdOptions\\(\\) \\(got a record for glmnet" + ) + expect_s4_class( + PhenotypeFilterParam(outlierArgs = CovMcdOptions(alpha = 0.9)), + "PhenotypeFilterParam" + ) + expect_error( + pecotmr:::.fmResolvePhenotypeFilter(GenotypeFilterParam()), + "PhenotypeFilterParam" + ) +}) + +test_that("molecularTraits / residualizedPhenotypes: lists for one context", { + qd <- .qr_makeDataset(contexts = "brain") + mt <- molecularTraits(qd, context = "brain") + expect_type(mt, "list") + expect_named(mt, "brain") + expect_s4_class(mt[["brain"]], "SummarizedExperiment") + rp <- residualizedPhenotypes(qd, context = "brain") + expect_named(rp, "brain") + expect_true(is.matrix(rp[["brain"]])) +}) + +# =========================================================================== +# .qtlResidualizeQr +# =========================================================================== + +test_that("a constant genotype column comes back as zeros, not NaN", { + # `.qtlResidualizeQr()` treats anything below sqrt(.Machine$double.eps) as + # constant: lm.fit residuals of a constant column are ~1e-16 rather than + # 0, and dividing the (also tiny) residuals by that amplifies roundoff to + # unit scale. The column is zeroed instead, and .dropZeroVariance() + # removes it downstream. + Y <- cbind(a = c(1, 2, 3, 4), b = c(2, 2, 2, 2)) + out <- pecotmr:::.qtlResidualizeQr(Y, NULL, scaleResiduals = TRUE) + expect_equal(unname(out[, "b"]), rep(0, 4)) + expect_equal(sd(out[, "a"]), 1) + expect_false(anyNA(out)) +}) diff --git a/tests/testthat/test_QtlFineMappingResult.R b/tests/testthat/test_QtlFineMappingResult.R index e831ac80..ab355d3e 100644 --- a/tests/testthat/test_QtlFineMappingResult.R +++ b/tests/testthat/test_QtlFineMappingResult.R @@ -162,19 +162,6 @@ test_that("QtlFineMappingResult: single-row collection allows omitting selectors }) -test_that("QtlFineMappingResult: show prints summary", { - e <- .sc_makeFineMappingRow(3) - res <- QtlFineMappingResult( - studyName = "s1", - context = "c1", - trait = "t1", - method = "susie", - entry = list(e) - ) - expect_output(show(res), "QtlFineMappingResult") -}) - - test_that("QtlFineMappingResult: joint columns absent by default", { e <- .sc_makeFineMappingRow(3) res <- QtlFineMappingResult( @@ -272,10 +259,6 @@ test_that("QtlFineMappingResult: length-mismatched joint vector errors", { ) }) -# =========================================================================== -# GwasFineMappingResult -# =========================================================================== - # === Tests migrated from test_showMethods.R (QtlFineMappingResult) === test_that("show.QtlFineMappingResult prints entry/study/context/trait/method counts", { @@ -331,7 +314,7 @@ test_that("QtlFineMappingResult: pip returns named pip vector for selected tuple }) -test_that("QtlFineMappingResult: pip(returnList = TRUE) wraps in pipe-keyed list", { +test_that("QtlFineMappingResult: pip() is one named numeric vector", { e <- .ca_makeFmEntry(3) res <- QtlFineMappingResult( studyName = "s1", @@ -340,125 +323,13 @@ test_that("QtlFineMappingResult: pip(returnList = TRUE) wraps in pipe-keyed list method = "susie", entry = list(e) ) - out <- pip(res, returnList = TRUE) - expect_true(is.list(out)) - expect_equal(names(out), "s1|c1|t1|susie") + out <- pip(res) + expect_type(out, "double") + expect_length(out, 3L) + expect_error(pip(res, returnList = TRUE), "unused") }) -test_that("QtlFineMappingResult: credibleSets filters to credible sets", { - e <- .ca_makeFmEntry(3) # cs_95 = c("susie_1", "susie_1", "susie_0") - res <- QtlFineMappingResult( - studyName = "s1", - context = "c1", - trait = "t1", - method = "susie", - entry = list(e) - ) - cs <- credibleSets(res) - expect_equal(nrow(cs), 2L) -}) - - -test_that("QtlFineMappingResult: topLoci returns the entry's topLoci (projected)", { - e <- .ca_makeFmEntry(3) - res <- QtlFineMappingResult( - studyName = "s1", - context = "c1", - trait = "t1", - method = "susie", - entry = list(e) - ) - tl <- topLoci(res, signalCutoff = 0) - expect_equal(length(tl), 3L) - expect_equal(tl$variant_id, .ca_makeTopLoci(3)$variant_id) -}) - -test_that("QtlFineMappingResult: topLoci aggregates entries when selectors do not pin one", { - # Two entries, no selectors: the old behaviour errored ("2 entries; pass - # study/context/trait/method"). Now it stacks the per-variant tables, - # prefixed with the row identity so variants stay attributable. - e1 <- .sc_makeFineMappingRow(3) - e2 <- .sc_makeFineMappingRow(2) - res <- QtlFineMappingResult( - studyName = c("s1", "s1"), - context = c("c1", "c2"), - trait = c("t1", "t1"), - method = c("susie", "susie"), - entry = list(e1, e2) - ) - agg <- topLoci(res, signalCutoff = 0) - expect_equal(length(agg), 5L) - expect_true(all( - c("study", "context", "trait", "blockId", "method") %in% - names(S4Vectors::mcols(agg)) - )) - expect_equal(agg$context, c("c1", "c1", "c1", "c2", "c2")) - expect_true("variant_id" %in% names(S4Vectors::mcols(agg))) - # QTL results key on context/trait, so blockId is NA-filled. - expect_true(all(is.na(agg$blockId))) - # the added per-variant `method` must not duplicate the identity column - expect_equal(sum(names(S4Vectors::mcols(agg)) == "method"), 1L) -}) - -test_that("QtlFineMappingResult: topLoci with a full tuple keeps the bare (id-free) table", { - e1 <- .sc_makeFineMappingRow(3) - e2 <- .sc_makeFineMappingRow(2) - res <- QtlFineMappingResult( - studyName = c("s1", "s1"), - context = c("c1", "c2"), - trait = c("t1", "t1"), - method = c("susie", "susie"), - entry = list(e1, e2) - ) - tl <- topLoci( - res, - studyName = "s1", - context = "c1", - trait = "t1", - method = "susie", - signalCutoff = 0 - ) - expect_equal(length(tl), 3L) - # single-entry fast path, unchanged - expect_false(is_in("context", names(S4Vectors::mcols(tl)))) -}) - -test_that("QtlFineMappingResult: topLoci aggregates only the matching subset", { - e1 <- .sc_makeFineMappingRow(3) - e2 <- .sc_makeFineMappingRow(2) - res <- QtlFineMappingResult( - studyName = c("s1", "s1"), - context = c("c1", "c2"), - trait = c("t1", "t1"), - method = c("susie", "susie"), - entry = list(e1, e2) - ) - sub <- topLoci(res, context = "c2", signalCutoff = 0) - expect_equal(length(sub), 2L) - expect_equal(unique(sub$context), "c2") -}) - -test_that("QtlFineMappingResult: topLoci on a single-row collection still carries identity columns", { - # A no-selector call takes the aggregate path even for one row, so the PIP - # table has a uniform shape (identity columns present) whatever the row count - # -- callers don't special-case single-entry results. - res <- QtlFineMappingResult( - studyName = "s1", - context = "c1", - trait = "t1", - method = "susie", - entry = list(.sc_makeFineMappingRow(4)) - ) - tl <- topLoci(res, signalCutoff = 0) - expect_equal(length(tl), 4L) - expect_true(all( - c("study", "context", "trait", "method", "variant_id") %in% - names(S4Vectors::mcols(tl)) - )) - expect_equal(unique(tl$context), "c1") -}) - test_that("QtlFineMappingResult: credibleSets aggregates every entry's credible sets with identity columns", { # e1 (n=3) has cs_95 = susie_1/susie_1/susie_0 -> 2 CS members; e2 (n=2) -> 2. e1 <- .sc_makeFineMappingRow(3) @@ -471,10 +342,10 @@ test_that("QtlFineMappingResult: credibleSets aggregates every entry's credible entry = list(e1, e2) ) cs <- credibleSets(res) - expect_equal(nrow(cs), 4L) + expect_equal(length(cs), 4L) expect_true(all( c("study", "context", "trait", "blockId", "method", "variant_id") %in% - names(cs) + names(S4Vectors::mcols(cs)) )) expect_equal(cs$context, c("c1", "c1", "c2", "c2")) # full tuple still returns the bare per-entry credible-set table @@ -485,8 +356,8 @@ test_that("QtlFineMappingResult: credibleSets aggregates every entry's credible trait = "t1", method = "susie" ) - expect_false("context" %in% names(bare)) - expect_equal(nrow(bare), 2L) + expect_false("context" %in% names(S4Vectors::mcols(bare))) + expect_equal(length(bare), 2L) }) test_that("QtlFineMappingResult: marginalEffects aggregates every entry with identity columns", { @@ -500,8 +371,11 @@ test_that("QtlFineMappingResult: marginalEffects aggregates every entry with ide entry = list(e1, e2) ) me <- marginalEffects(res) - expect_equal(nrow(me), 5L) # all topLoci rows (no CS filter) - expect_true(all(c("study", "context", "trait", "method") %in% names(me))) + expect_equal(length(me), 5L) # all topLoci rows (no CS filter) + expect_true(all( + c("study", "context", "trait", "method") %in% + names(S4Vectors::mcols(me)) + )) expect_equal(unique(me$context), c("c1", "c2")) }) @@ -559,7 +433,7 @@ test_that("cvResult works at the QtlFineMappingResult collection level", { prediction = list(susie_predicted = matrix(0, 1, 1)), performance = list(susie_performance = matrix(0, 1, 6)) ) - e <- fineMappingRow("chr1:100:A:G", list(), tl, cvResult = cv) + e <- FineMappingRow("chr1:100:A:G", list(), tl, cvResult = cv) fmr <- QtlFineMappingResult( studyName = "S", context = "C", @@ -599,15 +473,13 @@ test_that("QtlFineMappingResult: marginalEffects with tuple selectors", { trait = "t1", method = "susie" ) - expect_s3_class(me, "data.frame") - expect_equal(nrow(me), 4L) - expect_true(all(c("variant_id", "beta", "se", "z", "p") %in% names(me))) + expect_s4_class(me, "GRanges") + expect_equal(length(me), 4L) + expect_true(all( + c("variant_id", "beta", "se", "z", "p") %in% names(S4Vectors::mcols(me)) + )) }) -# =========================================================================== -# GwasFineMappingResult collection accessors -# =========================================================================== - # =========================================================================== # Validity: the branches that name what is wrong # @@ -655,20 +527,128 @@ test_that("a joint column must be character, not a factor or number", { ) }) -test_that("a QtlFineMappingResult refuses a region selector", { +test_that("a QtlFineMappingResult refuses a blockId", { data(qtlFineMappingExample) - # Region selection belongs to GwasFineMappingResult. The shared - # FineMappingResultBase accessors pass `region` to every selector, and - # this one used to absorb it in `...` and silently return the - # study/context/trait/method match instead. + x <- qtlFineMappingExample + # Block selection belongs to GwasFineMappingResult. The shared + # FineMappingResultBase accessors pass `blockId` to every selector, and + # this one refuses it rather than return the study/context/trait/method + # match as if it had been honoured. + expect_error(susieFit(x, blockId = "b1"), "has no LD blocks") + expect_error(variantIds(x, blockId = "b1"), "has no LD blocks") + # The supported selectors still work. + expect_type(susieFit(x, method = "susie"), "list") +}) + +test_that("fineMappingResult(QtlFineMappingResult) refuses a blockId", { + res <- QtlFineMappingResult( + studyName = "s1", + context = "c1", + trait = "t1", + method = "susie", + entry = list(.sc_makeFineMappingRow(3)) + ) + # A QTL fit is one row; `blockId` names a GWAS block, and NA is unset. + expect_equal(nrow(fineMappingResult(res, blockId = NA)), 1L) expect_error( - susieFit(qtlFineMappingExample, region = "chr22:1-2"), - "not region-indexed" + fineMappingResult(res, blockId = "chr1_1_500"), + "`blockId` names an LD block of a GWAS fit" + ) +}) + +test_that("a QTL fit across chromosomes is refused by name", { + ids <- c("chr1:100:A:G", "chr2:100:A:G") + trans <- FineMappingRow( + variantIds = ids, + susieFit = list(), + topLoci = data.frame(variant_id = ids, pip = c(0.6, 0.4)) ) expect_error( - variantIds(qtlFineMappingExample, region = "chr22:1-2"), - "not region-indexed" + QtlFineMappingResult( + studyName = c("s1", "s1"), + context = c("c1", "c1"), + trait = c("t1", "t2"), + method = c("susie", "susie"), + entry = list(.sc_makeFineMappingRow(3), trans) + ), + "`entry` element\\(s\\) 2 span more than one chromosome" + ) +}) + +test_that("QtlFineMappingResult() keeps the caller's metadata", { + res <- QtlFineMappingResult( + studyName = "s1", + context = "c1", + trait = "t1", + method = "susie", + entry = list(.sc_makeFineMappingRow(3)), + metadata = list(run = "r1") + ) + expect_equal(S4Vectors::metadata(res), list(run = "r1")) + expect_error( + QtlFineMappingResult( + studyName = "s1", + context = "c1", + trait = "t1", + method = "susie", + entry = list(.sc_makeFineMappingRow(3)), + metadata = "r1" + ), + "metadata" + ) +}) + +test_that("each row records the variants its fit was made with", { + row <- .sc_makeFineMappingRow(3) + res <- QtlFineMappingResult( + studyName = "s1", + context = "c1", + trait = "t1", + method = "susie", + entry = list(row) + ) + expect_s4_class(res$fitVariants, "CharacterList") + expect_equal( + as.character(res$fitVariants[[1L]]), + pecotmr:::.fmRowFitVariants(row) + ) +}) + +test_that("cvResult() of a narrowed row warns and returns it unchanged", { + tl <- data.frame( + variant_id = c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A"), + pip = c(0.5, 0.3, 0.2) + ) + cv <- list(prediction = list(susie = 1:4)) + res <- QtlFineMappingResult( + studyName = "s1", + context = "c1", + trait = "t1", + method = "susie", + entry = list(FineMappingRow(tl$variant_id, NULL, tl, cvResult = cv)) + ) + narrowed <- endoapply(res, utils::head, 2L) + expect_warning( + out <- cvResult(narrowed), + "cvResult\\(\\): the stored fit was made with 3 variants" + ) + expect_identical(out, cv) + expect_no_warning(cvResult(res)) +}) + +# =========================================================================== +# Constructor guards +# =========================================================================== + +test_that("QtlFineMappingResult: rejects rows that are not row payloads", { + expect_error( + QtlFineMappingResult( + studyName = "s1", + context = "c1", + trait = "t1", + method = "susie", + entry = list("not_an_entry") + ), + "must be a fine-mapping row" ) - # The supported selectors still work. - expect_type(susieFit(qtlFineMappingExample, method = "susie"), "list") }) diff --git a/tests/testthat/test_RangedTupleList.R b/tests/testthat/test_RangedTupleList.R index 6b27e4a3..e0722143 100644 --- a/tests/testthat/test_RangedTupleList.R +++ b/tests/testthat/test_RangedTupleList.R @@ -7,7 +7,11 @@ setClass( "RtlTestKid", contains = "RangedTupleList", - representation(genome = "character", ldReference = "ANY", qcInfo = "list") + representation( + genome = "character", + ldReference = "ANY", + qcOptions = "list" + ) ) .rtl_mk <- function(chr, pos, strand = "*") { @@ -28,7 +32,7 @@ setClass( ), genome = "hg38", ldReference = "SKETCH", - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) S4Vectors::mcols(x) <- S4Vectors::DataFrame( study = c("s1", "s2", "s3"), @@ -57,7 +61,7 @@ test_that("ncol is zero when the collection has no mcols", { GenomicRanges::GRangesList(a = .rtl_mk("chr1", 1:2)), genome = "hg38", ldReference = NULL, - qcInfo = list() + qcOptions = list() ) expect_equal(ncol(bare), 0L) expect_equal(nrow(bare), 1L) @@ -88,7 +92,7 @@ test_that("$<- works on a collection that had no mcols at all", { GenomicRanges::GRangesList(a = .rtl_mk("chr1", 1:2)), genome = "hg38", ldReference = NULL, - qcInfo = list() + qcOptions = list() ) bare$study <- "s1" expect_equal(bare$study, "s1") @@ -133,7 +137,7 @@ test_that("validity rejects an element spanning two seqnames", { GenomicRanges::GRangesList(a = .rtl_mk(c("chr1", "chr2"), c(1, 2))), genome = "hg38", ldReference = NULL, - qcInfo = list() + qcOptions = list() ), "span more than one" ) @@ -150,7 +154,7 @@ test_that("validity rejects an element spanning two strands", { ), genome = "hg38", ldReference = NULL, - qcInfo = list() + qcOptions = list() ), "span more than one" ) @@ -164,7 +168,7 @@ test_that("validity accepts a stranded element as long as it is consistent", { ), genome = "hg38", ldReference = NULL, - qcInfo = list() + qcOptions = list() ) expect_equal(length(x), 1L) expect_equal(length(range(x)[[1L]]), 1L) @@ -176,7 +180,7 @@ test_that("an empty collection is valid", { GenomicRanges::GRangesList(), genome = "hg38", ldReference = NULL, - qcInfo = list() + qcOptions = list() ) expect_equal(length(empty), 0L) expect_equal(nrow(empty), 0L) @@ -193,7 +197,7 @@ test_that(".rtlRebuild carries every subclass slot across a rebuild", { x <- .rtl_makeKid() expect_setequal( pecotmr:::.rtlOwnSlots(x), - c("genome", "ldReference", "qcInfo") + c("genome", "ldReference", "qcOptions") ) out <- pecotmr:::.rtlRebuild( x, @@ -203,7 +207,7 @@ test_that(".rtlRebuild carries every subclass slot across a rebuild", { expect_s4_class(out, "RtlTestKid") expect_equal(out@genome, "hg38") expect_equal(out@ldReference, "SKETCH") - expect_equal(out@qcInfo, list(step1 = "ok")) + expect_equal(out@qcOptions, list(step1 = "ok")) expect_equal(out$study, c("s1", "s3")) expect_equal(unname(lengths(out)), c(1L, 1L)) }) @@ -238,52 +242,24 @@ test_that("endoapply rejects a FUN that stops returning GRanges", { }) # =========================================================================== -# subsetRegion +# Narrowing by range with the standard verbs # =========================================================================== -test_that("subsetRegion selects, trims, and drops emptied elements", { - x <- .rtl_makeKid() - out <- subsetRegion( - x, - GenomicRanges::GRanges( - "chr1", - IRanges::IRanges(150, 1050) - ) - ) - # a: 200,300 kept (100 trimmed away); b: 1000 kept; c: chr2, dropped. - expect_equal(length(out), 2L) - expect_equal(names(out), c("a", "b")) - expect_equal(unname(lengths(out)), c(2L, 1L)) - expect_equal(out$study, c("s1", "s2")) - expect_equal(out@genome, "hg38") -}) - -test_that("subsetRegion accepts a chr:start-end string", { - x <- .rtl_makeKid() - out <- subsetRegion(x, "chr2:40-70") - expect_equal(length(out), 1L) - expect_equal(names(out), "c") - expect_equal(out$study, "s3") -}) - -test_that("subsetRegion returns an empty collection when nothing overlaps", { - x <- .rtl_makeKid() - out <- subsetRegion(x, "chr9:1-100") - expect_s4_class(out, "RtlTestKid") - expect_equal(length(out), 0L) - expect_equal(out@genome, "hg38") -}) - -test_that("subsetRegion differs from subsetByOverlaps and restrict", { - # The three operations are genuinely distinct and all three are useful. +test_that("the standard verbs narrow a collection by range", { + # subsetByOverlaps() keeps the elements that overlap, whole; endoapply() + # over it trims each element to the window and keeps the class and its + # collection-level slots. x <- .rtl_makeKid() win <- GenomicRanges::GRanges("chr1", IRanges::IRanges(150, 1050)) byOverlaps <- IRanges::subsetByOverlaps(x, win) - trimmed <- subsetRegion(x, win) - # subsetByOverlaps keeps matching elements WHOLE (a still has 3 variants). + expect_s4_class(byOverlaps, "RtlTestKid") expect_equal(unname(lengths(byOverlaps)), c(3L, 2L)) - # subsetRegion trims them (a keeps 2, b keeps 1). - expect_equal(unname(lengths(trimmed)), c(2L, 1L)) + trimmed <- endoapply(x, IRanges::subsetByOverlaps, ranges = win) + expect_s4_class(trimmed, "RtlTestKid") + # a keeps 200 and 300, b keeps 1000, c (chr2) is left empty. + expect_equal(unname(lengths(trimmed)), c(2L, 1L, 0L)) + expect_equal(trimmed@genome, "hg38") + expect_equal(unname(lengths(trimmed[lengths(trimmed) > 0L])), c(2L, 1L)) }) @@ -313,6 +289,11 @@ test_that(".rtlSplitByBlocks splits one element into per-block pieces", { # `outer.inner` mangling was an artifact, and inconsistent at that). expect_null(names(r$entry)) expect_equal(r$blockId, c("b1", "b2")) + # Each piece carries its block's interval as well as its key. + expect_identical( + as.character(r$blockRange), + c("chr1:1-500", "chr1:800-1200") + ) expect_equal(unname(lengths(r$entry)), c(2L, 1L)) # Both pieces came from the one input element, so its metadata row is # replicated twice. @@ -391,6 +372,7 @@ test_that(".rtlSplitByBlocks handles an empty entry list", { expect_length(r$entry, 0L) expect_length(r$fromIdx, 0L) expect_length(r$blockId, 0L) + expect_length(r$blockRange, 0L) }) test_that(".rtlSplitByBlocks rejects a non-GRanges element", { @@ -420,7 +402,7 @@ test_that("[[<- replaces an element and keeps class, slots and mcols", { # The collection-level slots are exactly what the setAs route would drop. expect_equal(x@genome, "hg38") expect_equal(x@ldReference, "SKETCH") - expect_equal(x@qcInfo, list(step1 = "ok")) + expect_equal(x@qcOptions, list(step1 = "ok")) }) test_that("[[<- leaves the other elements untouched", { @@ -514,6 +496,7 @@ test_that(".rtlGatherElements matches unlist(x[idx]) for every index shape", { x <- .rtl_makeKid() slow <- function(idx) unlist(x[idx], use.names = FALSE) expect_identical(.rtlGatherElements(x, 1L), slow(1L)) + expect_identical(.rtlGatherElements(x, 2L), x[[2]]) expect_identical(.rtlGatherElements(x, c(1L, 3L)), slow(c(1L, 3L))) expect_identical( .rtlGatherElements(x, seq_len(length(x))), @@ -559,13 +542,6 @@ test_that(".rtlGatherElements keeps the elements' inner mcols", { expect_identical(got, unlist(kid[c(1L, 2L)], use.names = FALSE)) }) -test_that(".rtlGatherElements does not re-validate the collection", { - # Nothing here reconstructs the subclass, so a collection whose validity - # would be expensive is not paying for it on every element read. - x <- .rtl_makeKid() - expect_identical(.rtlGatherElements(x, 2L), x[[2]]) -}) - # =========================================================================== # The plyranges bridge: the flatten / nest conversions and the dplyr verbs @@ -700,10 +676,9 @@ test_that("nestTupleRanges validates its arguments", { # --------------------------------------------------------------------------- # plyranges / dplyr verbs. # -# These call the methods directly rather than through the generic: dispatch -# needs the S3method() entries a roxygen regen writes, and the logic under test -# is the same either way. The final test checks dispatch itself, and skips -# until the registration exists. +# These call the methods directly rather than through the generic; the logic +# under test is the same either way. The final test checks dispatch through +# the dplyr generics, which the NAMESPACE's S3method() entries provide. # --------------------------------------------------------------------------- # @noRd @@ -778,18 +753,9 @@ test_that("group_by returns plyranges' own grouped representation", { test_that("the verbs are reachable through the dplyr generics", { - # Needs the S3method() entries from a roxygen regen; skips until then. - # Probed by attempting dispatch rather than by looking the function up: + # Checked by dispatching rather than by looking the function up: # getS3method() finds it in the namespace whether or not it is registered. mc <- .trv_mc() - dispatches <- tryCatch( - { - dplyr::filter(mc, Z > 2) - TRUE - }, - error = function(e) FALSE - ) - skip_if_not(dispatches, "S3 methods not yet registered (regen pending)") expect_s4_class(dplyr::filter(mc, Z > 2), "QtlSumStats") expect_s4_class(dplyr::slice(mc, 1:2), "QtlSumStats") }) @@ -834,6 +800,130 @@ test_that("range keys of an empty collection are empty", { ) }) +test_that("range keys and seqnames are read per element, NA when empty", { + grl <- GenomicRanges::GRangesList( + a = .rtl_mk("chr1", c(100, 300)), + b = GenomicRanges::GRanges(), + c = .rtl_mk("chr2", c(50, 60)) + ) + keys <- pecotmr:::.rtlRangeKeys(grl) + expect_identical(keys, c("chr1_100_300", NA, "chr2_50_60")) + # One formatter keys a single GRanges' span the same way. + expect_identical( + pecotmr:::.rtlOneRangeKey(range(grl[["a"]])), + keys[[1L]] + ) + expect_identical( + pecotmr:::.rtlElementSeqnames(grl), + c("chr1", NA, "chr2") + ) +}) + +test_that("elements bind into the object GRangesList() builds", { + # Plain elements are joined from their vectors; the result must be the + # very object GRangesList() makes, names and seqinfo included. + data( + qtlFineMappingExample, + qtlSumStatsMulticontextExample, + envir = environment() + ) + named <- .rtl_mk("chr1", c(5, 9)) + names(named) <- c("v1", "v2") + stranded <- .rtl_mk("chr3", 7, strand = "+") + GenomeInfoDb::genome(stranded) <- "hg38" + namedColumn <- .rtl_mk("chr1", c(1, 2)) + S4Vectors::mcols(namedColumn)$x <- c(p = 0.1, q = 0.2) + plainColumn <- .rtl_mk("chr2", 3) + S4Vectors::mcols(plainColumn)$x <- 0.3 + cases <- list( + columnNames = list(namedColumn, plainColumn), + fineMapping = as.list(qtlFineMappingExample), + sumStats = as.list(qtlSumStatsMulticontextExample), + withEmpty = list( + .rtl_mk("chr1", 1), + GenomicRanges::GRanges(), + .rtl_mk("chr2", 2) + ), + mixed = list(named, stranded, .rtl_mk("chr1", 3)), + outerNames = list(a = .rtl_mk("chr1", 1), b = .rtl_mk("chr2", 2)) + ) + for (nm in names(cases)) { + # The bare join is the fast path; it reports the seqinfo merge + # warnings .rtlBindElements() silences, as GRangesList() does. + joined <- suppressWarnings( + pecotmr:::.rtlJoinPlainElements(cases[[nm]]) + ) + expect_false(is.null(joined), info = nm) + expect_identical( + pecotmr:::.rtlBindElements(cases[[nm]]), + GenomicRanges::GRangesList(cases[[nm]]), + info = nm + ) + } +}) + +test_that("elements outside the plain case bind through GRangesList()", { + a <- .rtl_mk("chr1", 1) + S4Vectors::mcols(a)$x <- 1L + otherType <- .rtl_mk("chr2", 2) + S4Vectors::mcols(otherType)$x <- 2.5 + otherColumn <- .rtl_mk("chr2", 3) + S4Vectors::mcols(otherColumn)$y <- "z" + matrixColumn <- .rtl_mk("chr2", 4) + S4Vectors::mcols(matrixColumn)$x <- matrix(1:2, nrow = 1L) + withMetadata <- a + S4Vectors::metadata(withMetadata) <- list(source = "test") + cases <- list( + list(a, otherType), + list(a, otherColumn), + list(matrixColumn, matrixColumn), + list(withMetadata, a), + list() + ) + for (els in cases) { + expect_null(pecotmr:::.rtlJoinPlainElements(els)) + expect_identical( + pecotmr:::.rtlBindElements(els), + GenomicRanges::GRangesList(els) + ) + } +}) + +test_that("collections join into the GRangesList of their elements", { + data(qtlSumStatsMulticontextExample, envir = environment()) + x <- qtlSumStatsMulticontextExample + parts <- list(x[1L], x[2:3]) + expect_identical( + pecotmr:::.rtlJoinParts(parts), + GenomicRanges::GRangesList(c(as.list(parts[[1L]]), as.list(x[2:3]))) + ) +}) + +test_that("joining elements on different chromosomes says nothing", { + # Merging their seqinfo warns that the two share no seqlevel, which + # GRangesList() keeps quiet, and so do both joins. + a <- GenomicRanges::GRangesList(a = .rtl_mk("chr1", 1)) + b <- GenomicRanges::GRangesList(b = .rtl_mk("chr2", 2)) + expect_silent(joined <- pecotmr:::.rtlJoinParts(list(a, b))) + expect_identical( + joined, + GenomicRanges::GRangesList(c(as.list(a), as.list(b))) + ) + elements <- list(.rtl_mk("chr1", 1), .rtl_mk("chr2", 2)) + expect_silent(bound <- pecotmr:::.rtlBindElements(elements)) + expect_identical(bound, GenomicRanges::GRangesList(elements)) +}) + +test_that("a variant column is found on all elements or none", { + x <- .rtl_makeKid() + expect_false(pecotmr:::.rtlHasVariantColumn(x, "pip")) + withPip <- GenomicRanges::GRangesList( + a = GenomicRanges::GRanges("chr1:1-2", pip = 0.5), + b = GenomicRanges::GRanges("chr1:5-6", pip = 0.1) + ) + expect_true(pecotmr:::.rtlHasVariantColumn(withPip, "pip")) +}) + test_that("seqinfo is left alone when the source carries none", { # Nothing to restore from, so the rebuild is returned untouched. empty <- new( @@ -841,7 +931,7 @@ test_that("seqinfo is left alone when the source carries none", { GenomicRanges::GRangesList(), genome = "hg38", ldReference = NULL, - qcInfo = list() + qcOptions = list() ) grl <- GenomicRanges::GRangesList( a = GenomicRanges::GRanges("chr1", IRanges::IRanges(100L, width = 1L)) @@ -889,7 +979,7 @@ test_that("blockId reads the recorded value, not the variants' span", { variant_id = c("chr1:100:A:G", "chr1:200:C:T"), pip = c(0.9, 0.1) ) - row <- fineMappingRow(tl$variant_id, susieFit = list(), topLoci = tl) + row <- FineMappingRow(tl$variant_id, susieFit = list(), topLoci = tl) res <- GwasFineMappingResult( studyName = "s", method = "susie", @@ -945,3 +1035,170 @@ test_that("updateObject leaves a current collection as it is", { "updateObject\\(object = 'QtlSumStats'\\)" ) }) + +# =========================================================================== +# Coercion, sort / unique / trim, rebuilt names, and split tuples +# =========================================================================== + +test_that("as(x, 'GRanges') flattens a collection", { + data(qtlFineMappingExample) + expect_identical( + as(qtlFineMappingExample, "GRanges"), + flattenTupleRanges(qtlFineMappingExample) + ) +}) + +test_that("sort, unique and trim return the collection's own class", { + data(qtlSumStatsMulticontextExample) + x <- qtlSumStatsMulticontextExample + # Each element is sorted on its own; the collection keeps its slots and + # its names. + s <- sort(endoapply(x, rev)) + expect_s4_class(s, "QtlSumStats") + expect_identical(GenomicRanges::start(s[[1L]]), sort(start(x[[1L]]))) + expect_identical(ldReference(s), ldReference(x)) + expect_identical(names(s), names(x)) + expect_s4_class(unique(x), "QtlSumStats") + expect_identical(lengths(unique(x)), lengths(x)) + expect_s4_class(trim(x), "QtlSumStats") +}) + +test_that("a rebuild names an unnamed collection from its tuples", { + data(qtlSumStatsMulticontextExample) + x <- qtlSumStatsMulticontextExample + unnamed <- `names<-`(x, NULL) + expect_null(names(unnamed)) + expect_identical(names(endoapply(unnamed, identity)), names(x)) +}) + +test_that("nestTupleRanges returns a split tuple's pieces to their own rows", { + # A fit-less entry on two chromosomes, given one blockId, splits into two + # rows sharing that whole identity; only the chromosome tells their + # ranges apart. + ids <- c("chr1:100:A:G", "chr1:200:A:G", "chr2:100:A:G") + tl <- data.frame(variant_id = ids, pip = c(0.5, 0.3, 0.2)) + x <- GwasFineMappingResult( + studyName = "g1", + method = "susie", + entry = list(FineMappingRow(ids, susieFit = list(), topLoci = tl)), + blockId = "b1" + ) + expect_identical(x$blockId, c("b1", "b1")) + expect_equal(nrow(x), 2L) + back <- nestTupleRanges(flattenTupleRanges(x), x) + expect_equal(unname(lengths(back)), c(2L, 1L)) + expect_identical( + as.character(unlist(GenomicRanges::seqnames(back), use.names = FALSE)), + c("chr1", "chr1", "chr2") + ) + # An emptied piece has no chromosome, and stays empty. + flat <- flattenTupleRanges(x) + kept <- flat[as.character(GenomicRanges::seqnames(flat)) == "chr1"] + expect_equal(unname(lengths(nestTupleRanges(kept, x))), c(2L, 0L)) +}) + +# =========================================================================== +# Identity columns are character; metadata; genomicRegion() +# =========================================================================== + +test_that("an identity column must be character, and may hold NA", { + # A bare GRangesList takes any table; building the collection from it + # runs validity. + grl <- GenomicRanges::GRangesList(a = .rtl_mk("chr1", 1:2)) + S4Vectors::mcols(grl)$study <- 1L + expect_error( + new( + "RtlTestKid", + grl, + genome = "hg38", + ldReference = NULL, + qcOptions = list() + ), + "the `study` column must be character \\(got integer\\)" + ) + withNa <- .rtl_makeKid() + S4Vectors::mcols(withNa)$gwasContext <- c("c1", NA, "c3") + expect_true(validObject(withNa)) +}) + +test_that("mcols<- and its older spellings refuse a wrong-typed identity", { + x <- .rtl_makeKid() + expect_error( + S4Vectors::mcols(x)$study <- 1:3, + "the `study` column must be character \\(got integer\\)" + ) + expect_error( + S4Vectors::mcols(x) <- S4Vectors::DataFrame(blockId = c(1, 2, 3)), + "the `blockId` column must be character \\(got numeric\\)" + ) + expect_error( + S4Vectors::values(x)$trait <- c(TRUE, FALSE, TRUE), + "the `trait` column must be character \\(got logical\\)" + ) + expect_error( + S4Vectors::elementMetadata(x)$method <- factor(c("a", "b", "c")), + "the `method` column must be character \\(got factor\\)" + ) + # The refused assignments left the collection as it was. + expect_identical(x, .rtl_makeKid()) + # Character identity values, and any other column, are stored. + S4Vectors::mcols(x)$study <- c("a", "b", "c") + S4Vectors::mcols(x)$n <- c(1.5, 2.5, 3.5) + expect_equal(x$study, c("a", "b", "c")) + expect_equal(x$n, c(1.5, 2.5, 3.5)) + expect_s4_class(x, "RtlTestKid") + # Dropping the table leaves no identity column to check. + S4Vectors::mcols(x) <- NULL + expect_equal(ncol(x), 0L) +}) + +test_that("the per-variant metadata level is passed through untouched", { + x <- .rtl_makeKid() + perVariant <- S4Vectors::splitAsList( + S4Vectors::DataFrame(score = seq_len(sum(lengths(x)))), + factor(rep(names(x), lengths(x)), levels = names(x)) + ) + S4Vectors::mcols(x, level = "within") <- perVariant + expect_equal(S4Vectors::mcols(x[[2L]])$score, 4:5) + expect_equal(x$study, c("s1", "s2", "s3")) +}) + +test_that("$<- refuses an identity column of the wrong type", { + x <- .rtl_makeKid() + expect_error( + x$study <- 1:3, + "the `study` column must be character \\(got integer\\)" + ) + expect_error( + x$gwasTrait <- c(1, 2, 3), + "the `gwasTrait` column must be character \\(got numeric\\)" + ) + # Character identity values, and any other column, are taken as given. + x$n <- c(1L, 2L, 3L) + x$study <- c("a", "b", "c") + expect_equal(x$study, c("a", "b", "c")) + expect_equal(x$n, 1:3) +}) + +test_that(".withMetadata attaches a list as the collection's metadata", { + x <- .rtl_makeKid() + out <- pecotmr:::.withMetadata(x, list(source = "unit test")) + expect_equal(S4Vectors::metadata(out), list(source = "unit test")) + expect_identical(pecotmr:::.withMetadata(x, list()), x) + expect_error(pecotmr:::.withMetadata(x, "not a list"), "metadata") +}) + +test_that("genomicRegion() is each row's span unless a region was stored", { + x <- .rtl_makeKid() + expect_equal( + as.character(genomicRegion(x)), + c("chr1:100-300", "chr1:1000-1100", "chr2:50-60") + ) + stored <- GenomicRanges::GRanges( + c("chr1", "chr1", "chr2"), + IRanges::IRanges(c(1L, 901L, 1L), c(500L, 1500L, 100L)) + ) + x$region <- stored + expect_identical(genomicRegion(x), stored) + expect_length(genomicRegion(x[0]), 0L) +}) diff --git a/tests/testthat/test_SldscData.R b/tests/testthat/test_SldscData.R index 7cb3230b..79f9bc25 100644 --- a/tests/testthat/test_SldscData.R +++ b/tests/testthat/test_SldscData.R @@ -68,7 +68,8 @@ test_that("validity rejects a trait without a `single` element", { test_that("annotData / frqData return the stored frames", { sd <- .sldscMkData() - expect_s3_class(annotData(sd), "data.frame") + expect_s4_class(annotData(sd), "DataFrame") + expect_s4_class(frqData(sd), "DataFrame") expect_equal(nrow(annotData(sd)), 6L) expect_equal(nrow(frqData(sd)), 6L) }) @@ -84,25 +85,43 @@ test_that("sldscResults / traitNames expose the traits list", { expect_named(sldscResults(sd), c("traitX", "traitY")) }) -test_that("sldscResults retrieves single (by idx), joint, and NULL cases", { +test_that("sldscResults is one trait-keyed list, whatever is selected", { sd <- .sldscMkData() - single1 <- sldscResults(sd, "traitX", "single", 1L) + one <- sldscResults(sd, "traitX") + expect_named(one, "traitX") + expect_equal( + one[["traitX"]]$joint$categories, + c("annot_A_0", "annot_B_0", "baselineLD_0") + ) + expect_length(one[["traitX"]]$single, 2L) + expect_named(sldscResults(sd, c("traitY", "traitX")), c("traitY", "traitX")) + expect_error( + sldscResults(sd, "no_such_trait"), + "no trait no_such_trait.*It has: traitX, traitY" + ) + expect_error(sldscResults(sd, "traitX", "joint"), "unused argument") +}) + +test_that(".sldscRun retrieves single (by idx), joint, and NULL cases", { + sd <- .sldscMkData() + single1 <- .sldscRun(sd, "traitX", "single", 1L) expect_equal(single1$categories, c("annot_A_0", "baselineLD_0")) expect_equal( - sldscResults(sd, "traitX", "joint")$categories, + .sldscRun(sd, "traitX", "joint")$categories, c("annot_A_0", "annot_B_0", "baselineLD_0") ) # whole single list when idx is NULL - expect_length(sldscResults(sd, "traitX", "single"), 2L) + expect_length(.sldscRun(sd, "traitX", "single"), 2L) # out-of-range idx -> NULL - expect_null(sldscResults(sd, "traitX", "single", 5L)) + expect_null(.sldscRun(sd, "traitX", "single", 5L)) # unknown trait -> NULL - expect_null(sldscResults(sd, "no_such_trait", "joint")) + expect_null(.sldscRun(sd, "no_such_trait", "joint")) }) -test_that("sldscResults returns NULL joint when a trait has none", { +test_that(".sldscRun returns NULL joint when a trait has none", { sd <- .sldscMkData(withJoint = FALSE) - expect_null(sldscResults(sd, "traitX", "joint")) + expect_null(.sldscRun(sd, "traitX", "joint")) + expect_null(sldscResults(sd, "traitX")[["traitX"]]$joint) }) test_that("show prints a compact summary", { diff --git a/tests/testthat/test_causalInferencePipeline.R b/tests/testthat/test_causalInferencePipeline.R index b5147fc5..91e2f497 100644 --- a/tests/testthat/test_causalInferencePipeline.R +++ b/tests/testthat/test_causalInferencePipeline.R @@ -13,7 +13,7 @@ context("causalInferencePipeline") format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -83,7 +83,7 @@ context("causalInferencePipeline") entry = list(gr), genome = "hg19", ldReference = .cip_makeHandle(), - qcInfo = if (qc) list(step1 = "ok") else list() + qcOptions = if (qc) list(step1 = "ok") else list() ) } @@ -91,7 +91,7 @@ context("causalInferencePipeline") method = "susie", variant_ids = sprintf("chr1:%d:A:G", 100L * (1:5)) ) { - entry <- twasWeightsRow( + entry <- TwasWeightsRow( variantIds = variant_ids, weights = c(0.1, 0.05, -0.2, 0.3, 0.0) ) @@ -119,7 +119,7 @@ context("causalInferencePipeline") posterior_sd = rep(0.05, n), stringsAsFactors = FALSE ) - e <- fineMappingRow( + e <- FineMappingRow( variantIds = variant_ids, susieFit = list(), topLoci = tl @@ -173,7 +173,7 @@ test_that("causalInferencePipeline: rejects non-TwasWeights twasWeights arg", { }) test_that("causalInferencePipeline: rejects GwasFineMappingResult for the QTL slot", { - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(), topLoci = data.frame( @@ -207,7 +207,7 @@ test_that(".cipRequireMatchingLdRefs: NULL twas-side ldReference is allowed", { context = "c1", trait = "t1", method = "lasso", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), weights = rep(0.1, 5) )), @@ -231,7 +231,7 @@ test_that(".cipRequireMatchingLdRefs: sample set mismatch errors", { context = "c1", trait = "t1", method = "lasso", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), weights = rep(0.1, 5) )), @@ -275,7 +275,7 @@ test_that(".cipRequireMatchingLdRefs: rows that never meet may differ", { context = "c1", trait = "t1", method = "lasso", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = sprintf("chr2:%d:A:G", 100L * (1:5)), weights = rep(0.1, 5) )), @@ -367,11 +367,11 @@ test_that("causalInferencePipeline: combineMethods appends combined rows", { trait = c("t1", "t1"), method = c("lasso", "enet"), entry = list( - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), weights = rep(0.1, 5) ), - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), weights = rep(0.05, 5) ) @@ -409,7 +409,7 @@ test_that(".cipZToSe: falls back to vector of 1 when maf/n are NA", { test_that(".cipFilterEligibleMethods: rsq+pval gating, drop sub-cutoff groups, SS-TWAS keeps all", { mkEntry <- function(rsq, pval = 0.01) { - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), weights = rep(0.1, 3), cvResult = list(metrics = c(corr = 0.1, rsq = rsq, pval = pval)) @@ -467,11 +467,11 @@ test_that(".cipFilterEligibleMethods: rsq+pval gating, drop sub-cutoff groups, S trait = rep("G", 2), method = c("susie", "lasso"), entry = list( - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), weights = rep(0.1, 3) ), - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), weights = rep(0.1, 3) ) @@ -522,12 +522,12 @@ test_that("causalInferencePipeline: rsqCutoff selects the max-rsq method per gro trait = rep("t1", 2), method = c("susie", "lasso"), entry = list( - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), weights = c(0.1, 0.05, -0.2, 0.3, 0.0), cvResult = list(metrics = c(rsq = 0.2, pval = 0.001)) ), - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), weights = c(0.2, 0.1, -0.1, 0.2, 0.1), cvResult = list(metrics = c(rsq = 0.5, pval = 0.001)) @@ -555,12 +555,12 @@ test_that("causalInferencePipeline: NA/Inf TWAS-Z triggers method re-selection", method = c("susie", "lasso"), entry = list( # top rsq but all-zero weights -> wᵀRw = 0 -> twasZ NaN - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), weights = rep(0, 5), cvResult = list(metrics = c(rsq = 0.9, pval = 0.001)) ), - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), weights = c(0.2, 0.1, -0.1, 0.2, 0.1), cvResult = list(metrics = c(rsq = 0.5, pval = 0.001)) @@ -588,12 +588,12 @@ test_that("causalInferencePipeline: rsqPvalCutoff gates out high-CV-pval methods trait = rep("t1", 2), method = c("susie", "lasso"), entry = list( - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), weights = c(0.2, 0.1, -0.1, 0.2, 0.1), cvResult = list(metrics = c(rsq = 0.9, pval = 0.5)) ), - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), weights = c(0.2, 0.1, -0.1, 0.2, 0.1), cvResult = list(metrics = c(rsq = 0.5, pval = 0.001)) @@ -617,7 +617,7 @@ test_that("causalInferencePipeline: rsqPvalCutoff gates out high-CV-pval methods }) -context("twas: twasZ and harmonize deprecated wrappers") +context("twasZ") # =========================================================================== # Fixture builder: a small genotype + LD matrix. @@ -850,28 +850,48 @@ test_that("twasZ: combineMethods K>=2 forwards to combinePValues with correlatio expect_equal(res$combined$input$nValid, 2L) }) # =========================================================================== -# Tests migrated from test_twas.R (twasZ behaviour) +# twasZ: hand-computed values on the R path (positional alignment) # =========================================================================== -test_that("twasZ errors when weights and z lengths differ", { - expect_error(twasZ(c(1, 2), c(1, 2, 3)), "Must have exactly 3 rows") -}) - - -test_that("twasZ: single weight and single z-score returns valid result", { - weights <- 0.7 - z <- 2.5 - R <- matrix(1, nrow = 1, ncol = 1) - result <- twasZ(weights, z, R = R) - expect_true(is.list(result)) - expect_equal(colnames(result$Z), c("Z", "pval")) - # With single variant: stat = 0.7 * 2.5 = 1.75, denom = 0.7 * 1 * 0.7 = 0.49 - # zscore = 1.75 / sqrt(0.49) = 1.75 / 0.7 = 2.5 - expect_equal(as.numeric(result$Z[, "Z"]), 2.5, tolerance = 1e-10) - expect_true(result$Z[, "pval"] > 0 && result$Z[, "pval"] < 1) +test_that("twasZ: R path gives w'z / sqrt(w'Rw) on hand-computed cases", { + # Each case: weights, z, R and the Z worked out by hand. + cases <- list( + # 0.7 * 2.5 / sqrt(0.7^2) = 2.5 + singleVariant = list(0.7, 2.5, matrix(1), 2.5), + # 5 * 3 / sqrt(5) + equalWeights = list(rep(1, 5), rep(3, 5), diag(5), 15 / sqrt(5)), + # (-1 - 0.3) / sqrt(0.25 + 0.09): the sign follows the weights. + negativeWeights = list( + c(-0.5, -0.3), + c(2, 1), + diag(2), + -1.3 / sqrt(0.34) + ), + # w'Rw = sum(w)^2 = 1 when every pair is perfectly correlated. + perfectlyCorrelated = list(rep(0.25, 4), rep(2, 4), matrix(1, 4, 4), 2), + # A single non-zero weight reads that variant's z alone. + sparseWeights = list(c(0, 0, 1, 0, 0), 1:5, diag(5), 3), + # 1e6 * 1e-6 / sqrt(1e12) + largeWeightTinyZ = list(c(1e6, 0, 0), c(1e-6, 5, 5), diag(3), 1e-6), + # Z = 0, so the p-value is 1. + zeroZ = list(c(0.5, 0.3, 0.2), c(0, 0, 0), diag(3), 0), + # Z = 2e6 / sqrt(2), so the p-value underflows to 0. + largeZ = list(c(1, 1), c(1e6, 1e6), diag(2), 2e6 / sqrt(2)) + ) + for (nm in names(cases)) { + cs <- cases[[nm]] + res <- twasZ(cs[[1L]], cs[[2L]], R = cs[[3L]])$Z + expect_equal(colnames(res), c("Z", "pval"), info = nm) + expect_equal(unname(res[, "Z"]), cs[[4L]], tolerance = 1e-10, info = nm) + expect_equal( + unname(res[, "pval"]), + 2 * pnorm(-abs(cs[[4L]])), + tolerance = 1e-10, + info = nm + ) + } }) - test_that("twasZ: all-zero weights produce NaN z-score", { weights <- c(0, 0, 0) z <- c(1.5, -0.5, 2.0) @@ -882,68 +902,6 @@ test_that("twasZ: all-zero weights produce NaN z-score", { }) -test_that("twasZ: very large z-scores still produce finite results", { - set.seed(42) - p <- 5 - weights <- rnorm(p) - z <- rep(1e6, p) - R <- diag(p) - result <- twasZ(weights, z, R = R) - expect_true(is.finite(as.numeric(result$Z[, "Z"]))) - # p-value should be extremely small for large z - expect_true(result$Z[, "pval"] < 1e-10 || result$Z[, "pval"] == 0) -}) - - -test_that("twasZ: identical z-scores with equal weights gives proportional result", { - p <- 5 - weights <- rep(1, p) - z <- rep(3.0, p) - R <- diag(p) - result <- twasZ(weights, z, R = R) - # stat = sum(weights * z) = 5 * 3 = 15 - # denom = t(w) %*% I %*% w = 5 - # zscore = 15 / sqrt(5) = 6.7082... - expect_equal(as.numeric(result$Z[, "Z"]), 15 / sqrt(5), tolerance = 1e-10) -}) - - -test_that("twasZ: negative weights flip the sign of the z-score", { - weights_pos <- c(0.5, 0.3) - weights_neg <- c(-0.5, -0.3) - z <- c(2.0, 1.0) - R <- diag(2) - result_pos <- twasZ(weights_pos, z, R = R) - result_neg <- twasZ(weights_neg, z, R = R) - # z-score should have opposite sign but same p-value - expect_equal( - as.numeric(result_pos$Z[, "Z"]), - -as.numeric(result_neg$Z[, "Z"]), - tolerance = 1e-10 - ) - expect_equal( - as.numeric(result_pos$Z[, "pval"]), - as.numeric(result_neg$Z[, "pval"]), - tolerance = 1e-10 - ) -}) - - -test_that("twasZ: off-diagonal correlation in R changes the result", { - weights <- c(0.5, 0.5) - z <- c(2.0, 2.0) - R_identity <- diag(2) - R_correlated <- matrix(c(1, 0.8, 0.8, 1), nrow = 2) - result_identity <- twasZ(weights, z, R = R_identity) - result_correlated <- twasZ(weights, z, R = R_correlated) - # Same stat but different denominators, so different z-scores - expect_false(isTRUE(all.equal( - as.numeric(result_identity$Z[, "Z"]), - as.numeric(result_correlated$Z[, "Z"]) - ))) -}) - - test_that("twasZ: computing R from X matches providing R directly", { set.seed(123) n <- 20 @@ -967,102 +925,6 @@ test_that("twasZ: computing R from X matches providing R directly", { ) }) - -test_that("twasZ: p-value is always between 0 and 1 for random inputs", { - set.seed(999) - for (i in 1:5) { - p <- sample(2:10, 1) - weights <- rnorm(p) - z <- rnorm(p) - R <- diag(p) # use identity to avoid singularity - result <- twasZ(weights, z, R = R) - pval <- as.numeric(result$Z[, "pval"]) - expect_true( - pval >= 0 && pval <= 1, - info = paste("Iteration", i, "p-value out of range:", pval) - ) - } -}) - - -test_that("twasZ: single very large weight with tiny z gives moderate result", { - weights <- c(1e6, 0, 0) - z <- c(1e-6, 5.0, 5.0) - R <- diag(3) - result <- twasZ(weights, z, R = R) - # stat = 1e6 * 1e-6 + 0 + 0 = 1.0 - # denom = (1e6)^2 * 1 = 1e12 - # zscore = 1 / sqrt(1e12) = 1e-6 - expect_equal(as.numeric(result$Z[, "Z"]), 1e-6, tolerance = 1e-10) -}) - -# =========================================================================== -# twasZ: more mathematical edge cases -# =========================================================================== - -test_that("twasZ: perfectly correlated R matrix (all ones off-diagonal)", { - p <- 4 - R <- matrix(1, nrow = p, ncol = p) # perfectly correlated - weights <- c(0.25, 0.25, 0.25, 0.25) - z <- c(2, 2, 2, 2) - result <- twasZ(weights, z, R = R) - # stat = sum(0.25 * 2) = 2 - # denom = t(w) %*% ones_matrix %*% w = (sum(w))^2 = 1 - # zscore = 2 / sqrt(1) = 2 - expect_equal(as.numeric(result$Z[, "Z"]), 2.0, tolerance = 1e-10) -}) - - -test_that("twasZ: sparse weights (only one non-zero) extracts single SNP signal", { - p <- 5 - weights <- c(0, 0, 1, 0, 0) - z <- c(1, 2, 3, 4, 5) - R <- diag(p) - result <- twasZ(weights, z, R = R) - # With identity R and sparse weight: zscore = w3 * z3 / sqrt(w3^2) = 3 - expect_equal(as.numeric(result$Z[, "Z"]), 3.0, tolerance = 1e-10) -}) - - -test_that("twasZ: z-scores of zero give zero TWAS z-score", { - weights <- c(0.5, 0.3, 0.2) - z <- c(0, 0, 0) - R <- diag(3) - result <- twasZ(weights, z, R = R) - expect_equal(as.numeric(result$Z[, "Z"]), 0.0, tolerance = 1e-10) - # p-value for z=0 should be 1 - expect_equal(as.numeric(result$Z[, "pval"]), 1.0, tolerance = 1e-10) -}) - -# =========================================================================== -# twasZ: edge case with near-singular R matrix -# =========================================================================== - -test_that("twasZ: near-singular R matrix still produces a result", { - set.seed(777) - p <- 3 - # Create a nearly singular R by making two rows almost identical - R <- matrix(c(1, 0.999, 0.999, 0.999, 1, 0.999, 0.999, 0.999, 1), nrow = 3) - weights <- c(0.3, 0.4, 0.3) - z <- c(2.0, 2.5, 1.8) - result <- twasZ(weights, z, R = R) - expect_true(is.list(result)) - expect_true(is.finite(as.numeric(result$Z[, "Z"]))) -}) - - -test_that("twasZ: length-one input vectors produce correct scalar output", { - result <- twasZ(1.0, 3.0, R = matrix(1, 1, 1)) - expect_equal(as.numeric(result$Z[, "Z"]), 3.0, tolerance = 1e-10) - expect_true(result$Z[, "pval"] > 0 && result$Z[, "pval"] < 1) -}) - - -test_that("twasZ: R=NULL and X=NULL still errors consistently", { - # When neither R nor X is provided, twasZ should error - expect_error(twasZ(c(1, 2), c(3, 4))) -}) - # =========================================================================== # twasZ: matrix weights path -- multiple methods/conditions # =========================================================================== @@ -1086,140 +948,40 @@ test_that("twasZ: matrix weights produce one Z row per column", { }) -test_that("twasZ: combineMethods returns combined p-value summary", { - set.seed(11) - p <- 4 - k <- 2 - weights <- matrix( - rnorm(p * k), - nrow = p, - ncol = k, - dimnames = list(paste0("SNP", seq_len(p)), paste0("Cond", seq_len(k))) - ) - z <- rnorm(p) - R <- diag(p) - rownames(R) <- colnames(R) <- paste0("SNP", seq_len(p)) - result <- twasZ(weights, z, R = R, combineMethods = "acat") - expect_false(is.null(result$combined)) -}) - -# =========================================================================== -# Tests from test_twas_predict.R # =========================================================================== - -# ---- twasPredict ---- - +# twasZ: the SVD path agrees with the R path # =========================================================================== -# Tests migrated from test_twasSketch.R (twasZ SVD path) -# =========================================================================== - -test_that("twasZ: SVD path matches R path for full-rank genotype matrix", { - set.seed(42) - n <- 100 # samples (sketch size) - p <- 20 # variants - - # Generate genotype-like matrix (dosages 0/1/2) - X <- matrix(rbinom(n * p, 2, runif(p, 0.1, 0.9)), nrow = n, ncol = p) - - # HWE-based standardization - af <- colMeans(X) / 2 - X_std <- sweep(X, 2, 2 * af) - X_std <- sweep(X_std, 2, sqrt(2 * af * (1 - af)), "/") - - # Compute R from standardized X - R <- crossprod(X_std) / (n - 1) - - # SVD of standardized X - svd_result <- svd(X_std) - - # Random weights and z-scores - weights <- rnorm(p) - z <- rnorm(p) - - # R path - result_R <- pecotmr:::twasZ(weights, z, R = R) - - # SVD path - result_SVD <- pecotmr:::twasZ( - weights, - z, - V = svd_result$v, - D = svd_result$d, - nSketch = n - ) - - expect_equal( - as.numeric(result_SVD$z), - as.numeric(result_R$z), - tolerance = 1e-10 - ) - expect_equal( - as.numeric(result_SVD$pval), - as.numeric(result_R$pval), - tolerance = 1e-10 - ) -}) - -test_that("twasZ: SVD path matches R path for rank-deficient matrix (n < p)", { - set.seed(123) - n <- 15 # fewer samples than variants - - p <- 30 - - X <- matrix(rbinom(n * p, 2, runif(p, 0.15, 0.85)), nrow = n, ncol = p) - - af <- colMeans(X) / 2 - # Remove monomorphic columns - keep <- af > 0 & af < 1 - X <- X[, keep, drop = FALSE] - af <- af[keep] - p <- ncol(X) - - X_std <- sweep(X, 2, 2 * af) - X_std <- sweep(X_std, 2, sqrt(2 * af * (1 - af)), "/") - - R <- crossprod(X_std) / (n - 1) - svd_result <- svd(X_std) - - weights <- rnorm(p) - z <- rnorm(p) - - result_R <- pecotmr:::twasZ(weights, z, R = R) - result_SVD <- pecotmr:::twasZ( - weights, - z, - V = svd_result$v, - D = svd_result$d, - nSketch = n - ) - - expect_equal( - as.numeric(result_SVD$z), - as.numeric(result_R$z), - tolerance = 1e-10 - ) - expect_equal( - as.numeric(result_SVD$pval), - as.numeric(result_R$pval), - tolerance = 1e-10 - ) +test_that("twasZ: SVD path matches R path, full rank and n < p", { + # Sketch sizes (samples, variants, seed): full rank, and fewer samples + # than variants. + shapes <- list(fullRank = c(100, 20, 42), rankDeficient = c(15, 30, 123)) + for (nm in names(shapes)) { + n <- shapes[[nm]][[1L]] + p <- shapes[[nm]][[2L]] + set.seed(shapes[[nm]][[3L]]) + X <- matrix(rbinom(n * p, 2, runif(p, 0.15, 0.85)), nrow = n, ncol = p) + af <- colMeans(X) / 2 + # A monomorphic column has no standardized dosage. + keep <- af > 0 & af < 1 + X <- X[, keep, drop = FALSE] + af <- af[keep] + Xstd <- sweep(X, 2, 2 * af) + Xstd <- sweep(Xstd, 2, sqrt(2 * af * (1 - af)), "/") + R <- crossprod(Xstd) / (n - 1) + s <- svd(Xstd) + weights <- rnorm(ncol(X)) + z <- rnorm(ncol(X)) + expect_equal( + twasZ(weights, z, V = s$v, D = s$d, nSketch = n)$Z, + twasZ(weights, z, R = R)$Z, + tolerance = 1e-10, + info = nm + ) + } }) -test_that("twasZ: error when weights and z have different lengths", { - expect_error( - pecotmr:::twasZ( - rnorm(5), - rnorm(3), - V = matrix(1, 5, 2), - D = c(1, 1), - nSketch = 10 - ), - "weights.*Must have exactly 3 rows" - ) -}) - # =========================================================================== # Direct unit tests for the MR / metric helpers (mock topLoci to feed # controlled topLoci frames; gwasDf is a plain data.frame as produced by @@ -1826,8 +1588,7 @@ test_that(".cipComputeTwasZ: below 2 matches warns instead of silent NULL", { expect_null(out) }) -test_that(".cipComputeTwasZ: full overlap is silent", { - ids <- paste0("chr1:", 100 * (1:3), ":A:G") +test_that(".cipWarnVariantDrop: a full overlap is silent", { expect_silent( pecotmr:::.cipWarnVariantDrop(3L, 3L, "test pair") ) @@ -2005,7 +1766,7 @@ test_that(".cipRun errors when no tuple produced a result", { selectionActive = FALSE ) }, - .cipScoreQtlTuple = function(qi, ...) list(), + .cipTupleInputs = function(...) NULL, .package = "pecotmr" ) expect_error( @@ -2022,25 +1783,68 @@ test_that(".cipRun errors when no tuple produced a result", { ) }) -test_that(".cipScoreQtlTuple skips a tuple with no weights", { +test_that(".cipTupleInputs skips a tuple with no weights", { local_mocked_bindings( .cipExtractWeights = function(...) NULL, .package = "pecotmr" ) - p <- list( - qtlRows = data.frame( - qtlStudy = "s", - context = "c", - trait = "t", - method = "m", - useFmrForWeights = FALSE, - stringsAsFactors = FALSE + qtlRows <- data.frame( + qtlStudy = "s", + context = "c", + trait = "t", + method = "m", + useFmrForWeights = FALSE, + stringsAsFactors = FALSE + ) + expect_null(pecotmr:::.cipTupleInputs(1L, qtlRows, NULL, NULL)) +}) + +test_that("causalInferencePipeline refuses a tuple past given blocks", { + # The block window ends before chr1:500, which a weight sits on. + gws <- suppressWarnings(GwasSumStats( + studyName = "G1", + entry = list(sumStats(.cip_makeGwasSumstats())), + genome = "hg19", + ldReference = .cip_makeHandle(), + qcOptions = list(step1 = "ok"), + region = GenomicRanges::GRanges("chr1:1-450") + )) + expect_error( + causalInferencePipeline( + gwasSumStats = gws, + twasWeights = .cip_makeTwasWeights() + ), + "1 variant(s) past the end of block chr1:1-450 of GWAS study 'G1'", + fixed = TRUE + ) +}) + +test_that(".cipCheckBlockReach warns of a tuple running past computed spans", { + gws <- GwasSumStats( + studyName = "G1", + entry = list(sumStats(.cip_makeGwasSumstats())[1:3]), + genome = "hg19" + ) + tuple <- list( + tuple = list( + qStudy = "Q1", + qContext = "c1", + qTrait = "t1", + qMethod = "m" + ), + variants = GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(100L * (1:5), width = 1L) + ) + ) + expect_warning( + pecotmr:::.cipCheckBlockReach(list(tuple), gws), + str_c( + "QTL (study='Q1', context='c1', trait='t1', method='m'): ", + "2 variant(s) past the end of block chr1 (chr1:100-300)" ), - twasWeights = NULL, - fineMappingResult = NULL + fixed = TRUE ) - # An empty list contributes no rows once flattened. - expect_identical(pecotmr:::.cipScoreQtlTuple(1L, p), list()) }) test_that(".cipScoreGwasPair skips a pair with no TWAS z", { @@ -2086,23 +1890,95 @@ test_that(".cipRunMr routes to the CS-aware estimator when asked", { expect_true(isTRUE(out$SENTINEL)) }) -test_that(".cipCvMetric reads metrics wrapped or bare, NA when absent", { - local_mocked_bindings( - cvResult = function(...) list(rsq = 0.42, pval = 0.01), - .package = "pecotmr" +# One-row weights for (Q1, c1, t1, susie) whose cross-validation is `cv`. +.cip_cvWeights <- function(cv) { + TwasWeights( + studyName = "Q1", + context = "c1", + trait = "t1", + method = "susie", + entry = list(TwasWeightsRow( + variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), + weights = c(0.1, 0.05, -0.2, 0.3, 0.0), + cvResult = cv + )) ) +} + +test_that(".cipCvMetric reads metrics wrapped or bare, NA when absent", { # A bare metrics list (no $metrics wrapper) is read directly. - expect_equal(pecotmr:::.cipCvMetric(NULL, "s", "c", "t", "m", "rsq"), 0.42) - expect_true(is.na(pecotmr:::.cipCvMetric(NULL, "s", "c", "t", "m", "zzz"))) + bare <- .cip_cvWeights(list(rsq = 0.42, pval = 0.01)) + expect_equal( + pecotmr:::.cipCvMetric(bare, "Q1", "c1", "t1", "susie", "rsq"), + 0.42 + ) + expect_true(is.na( + pecotmr:::.cipCvMetric(bare, "Q1", "c1", "t1", "susie", "zzz") + )) + wrapped <- .cip_cvWeights(list(metrics = c(rsq = 0.3, pval = 0.02))) + expect_equal( + pecotmr:::.cipCvMetric(wrapped, "Q1", "c1", "t1", "susie", "pval"), + 0.02 + ) }) test_that(".cipCvMetric returns NA when the CV result cannot be read", { + # No row for the tuple; and a row without a CV record. + tw <- .cip_cvWeights(list(rsq = 0.42)) + expect_true( + is.na(pecotmr:::.cipCvMetric(tw, "Q9", "c1", "t1", "susie", "rsq")) + ) + expect_true(is.na( + pecotmr:::.cipCvMetric( + .cip_cvWeights(NULL), + "Q1", + "c1", + "t1", + "susie", + "rsq" + ) + )) +}) + +test_that("CV selection warns once about narrowed weights; scoring does not", { + tw <- TwasWeights( + studyName = rep("Q1", 2), + context = rep("c1", 2), + trait = rep("t1", 2), + method = c("susie", "lasso"), + entry = list( + TwasWeightsRow( + variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), + weights = c(0.1, 0.05, -0.2, 0.3, 0.0), + cvResult = list(metrics = c(rsq = 0.2, pval = 0.001)) + ), + TwasWeightsRow( + variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), + weights = c(0.2, 0.1, -0.1, 0.2, 0.1), + cvResult = list(metrics = c(rsq = 0.5, pval = 0.001)) + ) + ), + ldReference = .cip_makeHandle() + ) + narrowed <- endoapply(tw, utils::head, 4L) local_mocked_bindings( - cvResult = function(...) stop("nope"), + extractBlockGenotypes = .cip_mockExtractor(), .package = "pecotmr" ) - expect_true( - is.na(pecotmr:::.cipCvMetric(NULL, "s", "c", "t", "m", "rsq")) + selected <- .fitCoverageMessages(causalInferencePipeline( + gwasSumStats = .cip_makeGwasSumstats(), + twasWeights = narrowed, + weightSelectionParam = WeightSelectionParam(cutoff = 0.1) + )) + expect_length(selected, 1L) + expect_match(selected, "causalInferencePipeline\\(\\): 2 row\\(s\\)") + # Without selection only the weights are read, which the row holds. + expect_length( + .fitCoverageMessages(causalInferencePipeline( + gwasSumStats = .cip_makeGwasSumstats(), + twasWeights = narrowed + )), + 0L ) }) @@ -2186,7 +2062,7 @@ test_that(".cipRowsLdRef refuses overlapped rows on two references", { .cip_makeHandle(sample_prefix = "z") ), blockId = c("b1", "b2"), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) expect_error( pecotmr:::.cipRowsLdRef(two, 1:2, "G1"), @@ -2232,14 +2108,14 @@ test_that("a gene is scored once per GWAS study, over the rows it overlaps", { genome = "hg19", ldReference = list(chr1, chr1, ldm(ids2)), blockId = c("blockA", "blockB", "chr2"), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) tw <- TwasWeights( studyName = "Q1", context = "c1", trait = "gene1", method = "lasso", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = idsA, weights = c(0.3, 0.2, 0.1, 0.05, 0) )), diff --git a/tests/testthat/test_colocPipeline.R b/tests/testthat/test_colocPipeline.R index dc92129b..948c878f 100644 --- a/tests/testthat/test_colocPipeline.R +++ b/tests/testthat/test_colocPipeline.R @@ -14,7 +14,7 @@ context("colocPipeline") format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -68,7 +68,7 @@ context("colocPipeline") dimnames = list(NULL, variant_ids) ) } - fineMappingRow(variantIds = variant_ids, susieFit = fit, topLoci = tl) + FineMappingRow(variantIds = variant_ids, susieFit = fit, topLoci = tl) } .cp_makeQtlFmr <- function( @@ -133,7 +133,7 @@ context("colocPipeline") entry = list(gr), genome = "hg19", ldReference = .cp_makeHandle(), - qcInfo = if (qc) list(step1 = "ok") else list() + qcOptions = if (qc) list(step1 = "ok") else list() ) } @@ -159,7 +159,7 @@ context("colocPipeline") entry = list(gr), genome = "hg19", ldReference = .cp_makeHandle(), - qcInfo = if (qc) list(step1 = "ok") else list() + qcOptions = if (qc) list(step1 = "ok") else list() ) } @@ -300,6 +300,43 @@ test_that("colocPipeline: returns one row per (QTL tuple, GWAS tuple) pair", { expect_setequal(out$gwasStudy, c("G1", "G2")) }) +test_that("colocPipeline carries the sides' genome build and refuses two", { + qfmr <- .cp_makeQtlFmr() + gfmr <- GenomeInfoDb::`genome<-`(.cp_makeGwasFmr(), value = "hg38") + # Per-variant results too, so the pair holds variants for seqinfo to + # describe: a collection of empty elements has no sequence to name a + # build for. + summaryOnly <- .cp_mockColocBfBf() + local_mocked_bindings( + coloc.bf_bf = function(qLbf, gLbf, ...) { + res <- summaryOnly(qLbf, gLbf, ...) + # The LBF matrices carry a `null` column beside the variants. + ids <- colnames(qLbf)[str_detect(colnames(qLbf), ":")] + res$results <- data.frame( + snp = ids, + SNP.PP.H4.row1 = 1 / length(ids) + ) + res + }, + .package = "coloc" + ) + out <- suppressWarnings(colocPipeline( + qtlFineMappingResult = qfmr, + gwasInput = gfmr + )) + expect_gt(sum(lengths(out)), 0L) + expect_identical(unique(unname(GenomeInfoDb::genome(out))), "hg38") + expect_identical( + unique(unname(GenomeInfoDb::genome(colocVariants(out)))), + "hg38" + ) + hg19 <- GenomeInfoDb::`genome<-`(qfmr, value = "hg19") + expect_error( + colocPipeline(qtlFineMappingResult = hg19, gwasInput = gfmr), + "colocPipeline: the inputs name different genome builds" + ) +}) + # =========================================================================== # Either side may be a QTL or a GWAS fine-mapping result # =========================================================================== @@ -392,8 +429,14 @@ test_that("colocPipeline: resolves GwasSumStats via fineMappingPipeline (mocked) qfmr <- .cp_makeQtlFmr() gss <- .cp_makeGwasSumstats() local_mocked_bindings(coloc.bf_bf = .cp_mockColocBfBf(), .package = "coloc") + # Like the real pipeline, the stand-in keeps each row's block name, which + # is what the pairing finds a region's fit by. local_mocked_bindings( - fineMappingPipeline = function(data, methods, ...) .cp_makeGwasFmr(), + fineMappingPipeline = function(data, methods, ...) { + fmr <- .cp_makeGwasFmr() + fmr$blockId <- as.character(data$blockId) + fmr + }, .package = "pecotmr" ) out <- suppressWarnings(colocPipeline( @@ -465,7 +508,7 @@ test_that("colocPipeline: empty result has the documented schema", { V = 0, lbf_variable = matrix(NA_real_, 1, 1) ) - e <- fineMappingRow( + e <- FineMappingRow( variantIds = shared, susieFit = emptyFit, topLoci = data.frame( @@ -517,8 +560,8 @@ test_that("colocPipeline: empty result has the documented schema", { # Internal helpers # =========================================================================== -test_that(".colocExtractLbfFromEntry: entry without trimmedFit returns NULL with warning", { - e <- fineMappingRow( +test_that(".colocExtractLbfFromEntry: refuses an entry with no retained fit", { + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = NULL, topLoci = data.frame( @@ -558,7 +601,7 @@ test_that(".colocExtractLbfFromEntry: filterLbfCs subsets by cs_index", { ), sets = list(cs_index = c(1L, 3L)) ) # keep effects 1 and 3 - e <- fineMappingRow( + e <- FineMappingRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), susieFit = fit, topLoci = data.frame( @@ -622,21 +665,8 @@ test_that(".colocStandardiseRow: fills in missing PP columns with NA", { )) }) - -context("encoloc") - -# The file-path colocalization / enrichment wrappers (colocWrapper, -# xqtlEnrichmentWrapper, colocPostProcessor) and their helpers -# (filterAndOrderColocResults, calculateCumsum, calculate_purity, -# processColocResults, extract_ld_for_variants) have been removed in -# favor of the S4 colocPipeline / qtlEnrichmentPipeline / enlocPipeline -# entry points. The previous tests against the file-path wrappers no -# longer apply; they relied on mocking rssAnalysisPipeline (also -# removed). New tests for colocPipeline / qtlEnrichmentPipeline / -# enlocPipeline live alongside their pipeline implementations. - # =========================================================================== -# .colocLookupEnrichment (formerly .enlocLookupEnrichment, now shared) +# .colocLookupEnrichment # =========================================================================== test_that(".colocLookupEnrichment: returns the value for a (gwasStudy, qtlStudy, qtlContext) hit", { @@ -681,7 +711,7 @@ test_that(".colocLookupEnrichment: returns NA when no row matches", { }) # =========================================================================== -# .colocEmptyResult(enriched = TRUE) — formerly .enlocEmptyResult +# .colocEmptyResult(enriched = TRUE) # =========================================================================== test_that(".colocEmptyResult(enriched=TRUE): includes enrichment + p12Used schema", { @@ -740,7 +770,7 @@ test_that("colocPipeline: rejects enrichment missing required columns", { # --- enrichment end-to-end (lookup + p12 scaling + output columns) ---------- -test_that("colocPipeline: enrichment mode takes its priors from the table", { +test_that("colocPipeline: enrichment takes table priors and reports RCP/LCP", { qfmr <- .cp_makeQtlFmr() # Q1 / c1 / t1 / susie gfmr <- .cp_makeGwasFmr() # G1 / susie enr <- data.frame( @@ -770,26 +800,7 @@ test_that("colocPipeline: enrichment mode takes its priors from the table", { # qtlEnrichmentPipeline derives p12 = P_eqtl * expit(a0 + a1) the way # fastenloc does; the pipeline uses that, rather than scaling a default. expect_equal(unique(out$p12Used), 2.5e-5) -}) - -test_that("enrichment mode reports RCP and LCP alongside the hypotheses", { - qfmr <- .cp_makeQtlFmr() - gfmr <- .cp_makeGwasFmr() - enr <- data.frame( - gwasStudy = "G1", - qtlStudy = "Q1", - qtlContext = "c1", - enrichment = 2.0, - colocP1 = 3e-4, - colocP2 = 7e-4, - colocP12 = 2.5e-5, - stringsAsFactors = FALSE - ) - out <- suppressWarnings(colocPipeline( - qtlFineMappingResult = qfmr, - gwasInput = gfmr, - enrichment = enr - )) + # RCP and LCP are reported alongside the hypotheses. pairs <- colocPairs(out) expect_true(all(c("RCP", "LCP") %in% colnames(pairs))) # The two names for the same quantities: fastenloc's RCP is the posterior @@ -911,7 +922,7 @@ test_that("colocPipeline: an enrichment miss warns and drops to plain priors", { expect_equal(unique(out$p12Used), 5e-6) }) -# --- returnGwasFineMapping attached on the empty-pair early return (~205) ---- +# --- returnGwasFineMapping attached on the empty-pair early return ---------- test_that("colocPipeline: attaches gwasFineMapping when no pairs survive", { qfmr <- .cp_makeQtlFmr() @@ -924,7 +935,7 @@ test_that("colocPipeline: attaches gwasFineMapping when no pairs survive", { V = 0, lbf_variable = matrix(NA_real_, 1, 1) ) - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = emptyFit, topLoci = .cp_tl("chr1:100:A:G", pip = 0) @@ -952,7 +963,7 @@ test_that("colocPipeline: attaches gwasFineMapping when no pairs survive", { expect_identical(attr(out, "gwasFineMapping"), resolved) }) -# --- per-pair loop skips: no usable QTL LBF (~223) and no overlap (~233) ----- +# --- per-pair loop skips: no usable QTL LBF and no overlap ------------------- test_that("colocPipeline: skips a QTL entry with no usable LBF", { badFit <- list( @@ -961,7 +972,7 @@ test_that("colocPipeline: skips a QTL entry with no usable LBF", { V = 0, lbf_variable = matrix(NA_real_, 1, 1) ) - badEntry <- fineMappingRow( + badEntry <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = badFit, topLoci = .cp_tl("chr1:100:A:G", pip = 0) @@ -1008,7 +1019,7 @@ test_that("colocPipeline: skips a pair with no shared variants", { expect_equal(nrow(out), 0L) }) -# --- .colocFilterCsByConcentration (~324-331) ------------------------------- +# --- .colocFilterCsByConcentration ----------------------------------------- test_that(".colocFilterCsByConcentration: keeps narrow CS, drops diffuse ones", { fit <- list(alpha = matrix(0.1, nrow = 3, ncol = 10)) # 10 variants @@ -1049,7 +1060,7 @@ test_that(".colocExtractLbfFromEntry: stacks fSuSiE lBF list into a matrix", { dimnames = list(NULL, sprintf("chr1:%d:A:G", 100L * (1:4))) ) fit <- list(fsusie_result = list(lBF = list(m1, m2))) - e <- fineMappingRow( + e <- FineMappingRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), susieFit = fit, topLoci = .cp_tl(sprintf("chr1:%d:A:G", 100L * (1:4))) @@ -1074,7 +1085,7 @@ test_that(".colocExtractLbfFromEntry: stacks nested fSuSiE lBF (fit[[1]] path)", dimnames = list(NULL, sprintf("chr1:%d:A:G", 100L * (1:4))) ) fit <- list(list(fsusie_result = list(lBF = list(m1)))) - e <- fineMappingRow( + e <- FineMappingRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), susieFit = fit, topLoci = .cp_tl(sprintf("chr1:%d:A:G", 100L * (1:4))) @@ -1092,7 +1103,7 @@ test_that(".colocExtractLbfFromEntry: stacks nested fSuSiE lBF (fit[[1]] path)", test_that(".colocExtractLbfFromEntry: refuses a fit carrying no LBF slot", { fit <- list(notLbf = list(a = 1)) - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = fit, topLoci = .cp_tl("chr1:100:A:G") @@ -1132,7 +1143,7 @@ test_that(".colocExtractLbfFromEntry: refuses an empty LBF matrix", { dimnames = list(NULL, sprintf("chr1:%d:A:G", 100L * (1:3))) ) ) - e <- fineMappingRow( + e <- FineMappingRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), susieFit = fit, topLoci = .cp_tl(sprintf("chr1:%d:A:G", 100L * (1:3))) @@ -1160,7 +1171,7 @@ test_that(".colocExtractLbfFromEntry: secondary CS filter subsets rows", { ), alpha = matrix(0.25, 3, 4) ) - e <- fineMappingRow( + e <- FineMappingRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), susieFit = fit, topLoci = .cp_tl(sprintf("chr1:%d:A:G", 100L * (1:4))) @@ -1185,7 +1196,7 @@ test_that(".colocExtractLbfFromEntry: secondary CS filter subsets rows", { test_that(".colocExtractLbfFromEntry: assigns colnames from variantIds when fit lacks them", { fit <- list(lbf_variable = matrix(1:8, 2, 4)) # no dimnames - e <- fineMappingRow( + e <- FineMappingRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), susieFit = fit, topLoci = .cp_tl(sprintf("chr1:%d:A:G", 100L * (1:4))) @@ -1212,7 +1223,7 @@ test_that(".colocExtractLbfFromEntry: NULL when every variant column is NA-named ) # variantIds length (1) != ncol (4) so colnames are NOT back-filled, and the # NA-named columns are dropped, leaving a 0-column matrix. - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = fit, topLoci = .cp_tl("chr1:100:A:G") @@ -1228,7 +1239,7 @@ test_that(".colocExtractLbfFromEntry: NULL when every variant column is NA-named expect_null(out) }) -# --- .colocAlignLbf no-overlap branch (~479) -------------------------------- +# --- .colocAlignLbf no-overlap branch -------------------------------------- test_that(".colocAlignLbf: returns NULL when there are no shared variants", { q <- matrix( @@ -1508,17 +1519,13 @@ test_that("priors and enrichment cannot both be given", { ), "cannot both be given" ) - # Either alone is fine. + # Either alone is fine; the same table alone is the enrichment-mode run + # tested above. expect_no_error(suppressWarnings(colocPipeline( qtlFineMappingResult = qfmr, gwasInput = gfmr, priors = ColocPriorParam(p12 = 1e-5) ))) - expect_no_error(suppressWarnings(colocPipeline( - qtlFineMappingResult = qfmr, - gwasInput = gfmr, - enrichment = enr - ))) }) test_that("GwasFineMappingParam carries only what the inline fit can use", { @@ -1590,28 +1597,27 @@ test_that("GwasFineMappingParam accessors round-trip a nested bundle", { expect_equal(fineMappingMethods(g), "susie") expect_s4_class(credibleSetParam(g), "CredibleSetParam") - # Why this class has accessors at all: once CredibleSetParam is - # settable, the container must let the edited record back in, or the - # nested settings would be readable but not writable. + # The container must let an edited nested record back in, or the nested + # settings would be readable but not writable. g2 <- g - cs <- credibleSetParam(g2) - csCoverage(cs) <- 0.8 - credibleSetParam(g2) <- cs + cs <- g2$credibleSetParam + cs$coverage <- 0.8 + g2$credibleSetParam <- cs expect_equal(csCoverage(credibleSetParam(g2)), 0.8) expect_equal(csCoverage(credibleSetParam(g)), 0.95) # The nested slots are typed, so the wrong Param is refused rather than # surfacing as a missing field somewhere downstream. expect_error( - susieRssParam(g) <- CredibleSetParam(), - "not valid for @.+susieRssParam" + g$susieRssParam <- CredibleSetParam(), + "susieRssParam" ) g3 <- g - susieRssParam(g3) <- SusieRssParam(serFallback = TRUE) + g3$susieRssParam <- SusieRssParam(serFallback = TRUE) expect_s4_class(g3, "GwasFineMappingParam") }) -test_that("GwasFineMappingParam accessors read and replace every field", { +test_that("GwasFineMappingParam fields read and replace, each one", { # Dispatching each accessor is what exercises the generics declared in # AllGenerics.R; the constructor alone never reaches them. p <- GwasFineMappingParam() @@ -1624,10 +1630,10 @@ test_that("GwasFineMappingParam accessors read and replace every field", { # Replacement edits a copy and leaves the original alone. edited <- p - fineMappingMethods(edited) <- "susieInf" - initializeWithSusieInf(edited) <- FALSE - fitRetention(edited) <- "full" - panelFilterParam(edited) <- PanelFilterParam() + edited$methods <- "susieInf" + edited$initializeWithSusieInf <- FALSE + edited$fitRetention <- "full" + edited$panelFilterParam <- PanelFilterParam() expect_equal(fineMappingMethods(edited), "susieInf") expect_false(initializeWithSusieInf(edited)) expect_equal(fitRetention(edited), "full") @@ -1666,3 +1672,522 @@ test_that("coloc lets rows that never pair sit on different references", { ) expect_null(pecotmr:::.colocRequireMatchingLdRefs(qfmr, gfmr)) }) + +# =========================================================================== +# A QTL region over several GWAS LD blocks is one colocalization +# =========================================================================== + +# One GWAS study fine-mapped in two LD blocks: chr1:100-500 in block +# chr1_1_550 and chr1:600-1000 in block chr1_551_2000, two effects each. +.cp_blockIds <- c("chr1_1_550", "chr1_551_2000") +.cp_blockWindows <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(1L, 551L), c(550L, 2000L)) +) + +.cp_makeBlockedGwasFmr <- function( + blockId = .cp_blockIds, + method = "susie", + region = .cp_blockWindows +) { + GwasFineMappingResult( + studyName = rep("G1", 2L), + method = rep(method, 2L), + entry = list( + .cp_makeFmEntry(paste0("chr1:", 100 * (1:5), ":A:G")), + .cp_makeFmEntry(paste0("chr1:", 100 * (6:10), ":A:G")) + ), + blockId = blockId, + region = region, + ldReference = .cp_makeHandle(snp_n = 10L) + ) +} + +# A QTL fit over `positions` (multiples of 100 on chr1). +.cp_makeQtlOver <- function(positions, trait = "t1") { + QtlFineMappingResult( + studyName = "Q1", + context = "c1", + trait = trait, + method = "susie", + entry = list(.cp_makeFmEntry(paste0("chr1:", positions, ":A:G"))), + ldReference = .cp_makeHandle(snp_n = 10L) + ) +} + +test_that(".colocCollapseBlocks stacks blocks, each confined to its own", { + recs <- pecotmr:::.colocPreextractGwasLbf( + .cp_makeBlockedGwasFmr(), + ColocLbfFilterParam() + ) + expect_length(recs, 2L) + one <- pecotmr:::.colocCollapseBlocks(recs[1L]) + expect_identical(one, recs[[1L]]) + merged <- pecotmr:::.colocCollapseBlocks(recs) + blockA <- paste0("chr1:", 100 * (1:5), ":A:G") + blockB <- paste0("chr1:", 100 * (6:10), ":A:G") + expect_identical(colnames(merged$lbf), c(blockA, blockB)) + # Block A's effects carry no evidence about block B's variants, and the + # reverse. + expect_true(all(merged$lbf[1:2, blockB] == -Inf)) + expect_true(all(merged$lbf[3:4, blockA] == -Inf)) + expect_equal(merged$lbf[1:2, blockA], recs[[1L]]$lbf) + # Block B's effects are numbered on from block A's two. + expect_identical(merged$effect, 1:4) + expect_identical(merged$nEffects, 4L) + # The blockIds spell coordinates, so the merged block is their union. + expect_identical(merged$blockId, "chr1_1_2000") + expect_match(merged$label, "chr1_1_2000") +}) + +test_that(".colocMergedBlockId names the stretch a fit's blocks cover", { + blocks <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(1L, 551L), c(550L, 2000L)) + ) + spans <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(100L, 600L), c(500L, 1000L)) + ) + # The stretch comes from the blocks' windows, whatever the ids say. + expect_identical( + pecotmr:::.colocMergedBlockId(.cp_blockIds, blocks), + "chr1_1_2000" + ) + expect_identical( + pecotmr:::.colocMergedBlockId(c("blockA", "blockB"), spans), + "chr1_100_1000" + ) + # One block keeps its own id, whatever it is. + expect_identical( + pecotmr:::.colocMergedBlockId("blockA", blocks[1L]), + "blockA" + ) + expect_identical(pecotmr:::.colocMergedBlockId("chr1", spans[1L]), "chr1") +}) + +test_that(".colocMergedLdRef keeps a shared reference and drops a split one", { + ref <- .cp_makeHandle() + same <- list( + list(ldKey = "ld1", ldReference = ref), + list(ldKey = "ld1", ldReference = ref) + ) + expect_identical(pecotmr:::.colocMergedLdRef(same), ref) + split <- list( + list(ldKey = "ld1", ldReference = ref), + list(ldKey = "ld2", ldReference = ref) + ) + expect_null(pecotmr:::.colocMergedLdRef(split)) +}) + +test_that("colocPipeline scores a region over two blocks as one fit", { + skip_if_not_installed("coloc") + set.seed(3) + res <- suppressWarnings(colocPipeline( + .cp_makeQtlOver(100 * (1:10)), + gwasInput = .cp_makeBlockedGwasFmr(), + adjustPips = FALSE + )) + pairs <- colocPairs(res) + expect_identical(unique(pairs$blockId), "chr1_1_2000") + # Every QTL effect is scored over its whole region, against all four GWAS + # effects of the one collapsed fit. + expect_true(all(pairs$nSnps == 10L)) + expect_setequal(pairs$gwasCs, 1:4) + pp <- as.matrix(pairs[, str_c("PP.H", 0:4, ".abf")]) + expect_false(anyNA(pp)) + expect_equal(unname(rowSums(pp)), rep(1, nrow(pairs))) + # A region inside one block reads that block alone, under its own id. + inside <- suppressWarnings(colocPipeline( + .cp_makeQtlOver(100 * (1:5)), + gwasInput = .cp_makeBlockedGwasFmr(), + adjustPips = FALSE + )) + expect_identical(unique(colocPairs(inside)$blockId), "chr1_1_550") + expect_true(all(colocPairs(inside)$nSnps == 5L)) +}) + +test_that("colocPipeline keeps two methods' block fits apart", { + skip_if_not_installed("coloc") + set.seed(4) + gfmr <- combineFineMappingResults( + .cp_makeBlockedGwasFmr(method = "susie"), + .cp_makeBlockedGwasFmr(method = "ser") + ) + res <- suppressWarnings(colocPipeline( + .cp_makeQtlOver(100 * (1:10)), + gwasInput = gfmr, + adjustPips = FALSE + )) + pairs <- colocPairs(res) + byMethod <- split(pairs$gwasCs, pairs$gwasMethod) + expect_setequal(names(byMethod), c("susie", "ser")) + expect_setequal(byMethod$susie, 1:4) + expect_setequal(byMethod$ser, 1:4) +}) + +# A GwasSumStats split into the two blocks above, and a fineMappingPipeline +# stand-in that records what it was given and fits each row it was handed. +.cp_makeBlockedGwasSumstats <- function() { + gr <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(100L * (1:10), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = sprintf("chr1:%d:A:G", 100L * (1:10)), + A1 = "A", + A2 = "G", + Z = seq_len(10L) / 10, + N = 1000L + ) + GwasSumStats( + studyName = "G1", + entry = list(gr), + genome = "hg19", + ldReference = .cp_makeHandle(snp_n = 10L), + qcOptions = list(step1 = "ok"), + region = GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(1L, 551L), c(550L, 2000L)) + ) + ) +} + +.cp_recordingFineMapper <- function(seen) { + function(data, methods, ...) { + seen$data <- data + GwasFineMappingResult( + studyName = as.character(data$study), + method = rep("susie", nrow(data)), + entry = map( + as.list(data), + function(gr) .cp_makeFmEntry(S4Vectors::mcols(gr)$SNP) + ), + blockId = as.character(data$blockId), + ldReference = .cp_makeHandle(snp_n = 10L) + ) + } +} + +test_that("colocPipeline fine-maps each set of blocks a region reaches once", { + seen <- new.env() + scored <- new.env() + scored$gwas <- character(0) + local_mocked_bindings( + fineMappingPipeline = .cp_recordingFineMapper(seen), + .package = "pecotmr" + ) + local_mocked_bindings( + coloc.bf_bf = function(qLbf, gLbf, p1, p2, p12, ...) { + scored$gwas <- c(scored$gwas, str_flatten(colnames(gLbf), ",")) + .cp_mockColocBfBf()(qLbf, gLbf, p1, p2, p12) + }, + .package = "coloc" + ) + # The first region reaches no GWAS row, so the PIP reconciliation drops + # it, and the regions after it move up a row; each must still find its + # own fit. + elsewhere <- QtlFineMappingResult( + studyName = "Q1", + context = "c1", + trait = "elsewhere", + method = "susie", + entry = list(.cp_makeFmEntry(paste0("chr2:", 100 * (1:5), ":A:G"))) + ) + qtl <- combineFineMappingResults( + elsewhere, + .cp_makeQtlOver(100 * (1:5), trait = "inside"), + .cp_makeQtlOver(100 * (4:8), trait = "across") + ) + res <- suppressMessages(suppressWarnings(colocPipeline( + qtl, + gwasInput = .cp_makeBlockedGwasSumstats(), + returnGwasFineMapping = TRUE + ))) + # Two sets: block A alone, and both blocks stitched together. + expect_identical( + as.character(seen$data$blockId), + c("chr1_1_550", "chr1_1_2000") + ) + expect_identical(unname(lengths(seen$data)), c(5L, 10L)) + # Each set's range is the stretch its blocks' given ranges cover. + expect_identical( + as.character(seen$data$region), + c("chr1:1-550", "chr1:1-2000") + ) + expect_identical(seen$data$regionGiven, c(TRUE, TRUE)) + # Each region is scored against its own set's fit and no other. + pairs <- colocPairs(res) + expect_identical( + pairs$blockId[match(c("inside", "across"), pairs$trait)], + c("chr1_1_550", "chr1_1_2000") + ) + expect_length(scored$gwas, 2L) + expect_identical( + S4Vectors::mcols(attr(res, "gwasFineMapping"))$blockId, + c("chr1_1_550", "chr1_1_2000") + ) +}) + +test_that("colocPipeline needs one LD reference across stitched blocks", { + gws <- pecotmr:::.withRowLdRefs( + .cp_makeBlockedGwasSumstats(), + list(.cp_ldm(0.2), .cp_ldm(0.5)) + ) + expect_error( + pecotmr:::.colocResolveGwasFmr( + gws, + GwasFineMappingParam(), + .cp_makeQtlOver(100 * (4:8)) + ), + "the rows of GWAS study 'G1' a QTL region reaches use 2" + ) +}) + +test_that("colocPipeline fine-maps nothing when no region reaches the GWAS", { + resolved <- pecotmr:::.colocResolveGwasFmr( + .cp_makeBlockedGwasSumstats(), + GwasFineMappingParam(), + QtlFineMappingResult( + studyName = "Q1", + context = "c1", + trait = "t1", + method = "susie", + entry = list(.cp_makeFmEntry(paste0("chr2:", 100 * (1:5), ":A:G"))) + ) + ) + expect_equal(nrow(resolved$fmr), 0L) + expect_equal(nrow(resolved$pairing), 0L) +}) + +test_that(".colocWithNull adds coloc's null column at log BF 0", { + m <- matrix(c(1, -Inf), 1L, dimnames = list(NULL, c("a", "b"))) + expect_identical( + pecotmr:::.colocWithNull(m), + cbind(m, null = 0) + ) +}) + +test_that("enloc reads SuSiE's natural-log Bayes factors as such", { + # With a flat GWAS effect the colocalization mass follows the QTL PIPs, + # which must be SuSiE's softmax over natural-log Bayes factors. + lbf <- c(2, 1, 0) + aligned <- list( + qtl = matrix(lbf, 1L, dimnames = list(NULL, c("a", "b", "c"))), + gwas = matrix(0, 1L, 3L, dimnames = list(NULL, c("a", "b", "c"))) + ) + out <- pecotmr:::.colocEnlocOneEffectPair( + 1L, + 1L, + aligned, + list(p1 = 1e-4, p2 = 1e-4, p12 = 5e-6) + ) + expect_equal( + unname(out$scp / sum(out$scp)), + exp(lbf) / sum(exp(lbf)) + ) +}) + +test_that("the enrichment lookup matches on method when the table has it", { + enr <- data.frame( + gwasStudy = "G1", + gwasMethod = c("susie", "ser"), + qtlStudy = "Q1", + qtlContext = "c1", + qtlMethod = "susie", + enrichment = c(1, 2) + ) + expect_null(pecotmr:::.colocValidateEnrichmentKeys(enr)) + q <- list(study = "Q1", context = "c1", trait = "t1", method = "susie") + gwas <- function(m) { + list(study = "G1", context = NA, trait = NA, method = m) + } + expect_identical( + pecotmr:::.colocLookupEnrichment(enr, gwas("ser"), q), + 2L + ) + expect_identical( + pecotmr:::.colocLookupEnrichment(enr, gwas("susie"), q), + 1L + ) + expect_true(is.na( + pecotmr:::.colocLookupEnrichment(enr, gwas("susieInf"), q) + )) +}) + +test_that("a stitched set of blocks keeps its case and control counts", { + gws <- .cp_makeBlockedGwasSumstats() + withCounts <- GwasSumStats( + studyName = "G1", + entry = list(sumStats(gws)), + genome = "hg19", + ldReference = .cp_makeHandle(snp_n = 10L), + nCase = 100, + nControl = 200, + qcOptions = list(step1 = "ok"), + region = GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(1L, 551L), c(550L, 2000L)) + ) + ) + sets <- pecotmr:::.colocQtlRowSets( + withCounts, + .cp_makeQtlOver(100 * (4:8)) + ) + u <- pecotmr:::.colocUnionSumStats(withCounts, sets) + expect_equal(nrow(u), 1L) + expect_equal(u$nCase, 100) + expect_equal(u$nControl, 200) + expect_false("nSample" %in% colnames(S4Vectors::mcols(u))) +}) + +test_that("a stitched set is given its range only when every block was", { + gws <- .cp_makeBlockedGwasSumstats() + sets <- pecotmr:::.colocQtlRowSets(gws, .cp_makeQtlOver(100 * (4:8))) + given <- pecotmr:::.colocUnionSumStats(gws, sets) + expect_identical(as.character(given$region), "chr1:1-2000") + expect_true(given$regionGiven) + # The same blocks with their ranges computed: the set's range is the + # stretch their spans cover, and it is computed too. + computed <- GwasSumStats( + studyName = c("G1", "G1"), + entry = as.list(gws), + genome = "hg19", + ldReference = .cp_makeHandle(snp_n = 10L), + qcOptions = list(step1 = "ok"), + blockId = c("bA", "bB") + ) + u <- pecotmr:::.colocUnionSumStats( + computed, + pecotmr:::.colocQtlRowSets(computed, .cp_makeQtlOver(100 * (4:8))) + ) + expect_identical(u$blockId, "chr1_100_1000") + expect_identical(as.character(u$region), "chr1:100-1000") + expect_false(u$regionGiven) +}) + +# =========================================================================== +# A region reaching past the GWAS blocks that were loaded +# =========================================================================== + +test_that("colocPipeline refuses a region reaching past given blocks", { + skip_if_not_installed("coloc") + # The blocks' ids spell their ranges, so chr1:2100 lies in a block that + # was not loaded. + expect_error( + colocPipeline( + .cp_makeQtlOver(c(100 * (1:10), 2100)), + gwasInput = .cp_makeBlockedGwasFmr(), + adjustPips = FALSE + ), + "1 variant(s) past the end of block chr1:551-2000 of GWAS study", + fixed = TRUE + ) + # Statistics are checked before any block is fine-mapped. + expect_error( + colocPipeline( + .cp_makeQtlOver(c(100 * (4:8), 2100)), + gwasInput = .cp_makeBlockedGwasSumstats() + ), + "lie in blocks that were not loaded" + ) +}) + +test_that("colocPipeline warns of a region running past computed blocks", { + # Labels rather than coordinates: the blocks' ranges are the spans of + # their variants, chr1:100-500 and chr1:600-1000. + gfmr <- .cp_makeBlockedGwasFmr(blockId = c("bA", "bB"), region = NULL) + expect_warning( + pecotmr:::.colocCheckBlockReach(.cp_makeQtlOver(100 * (1:12)), gfmr), + "2 variant\\(s\\) past the end of block bB \\(chr1:600-1000\\)" + ) + # One variant past a computed range may only be one the GWAS lacks. + expect_no_warning( + pecotmr:::.colocCheckBlockReach(.cp_makeQtlOver(100 * (1:11)), gfmr) + ) + # A region meeting no block of the study is not checked against it. + expect_no_warning( + pecotmr:::.colocCheckBlockReach(.cp_makeQtlOver(100 * (30:35)), gfmr) + ) + # Nor is a second side that has no blocks. + expect_null( + pecotmr:::.colocCheckBlockReach( + .cp_makeQtlOver(100 * (1:12)), + .cp_makeQtlOver(100 * (1:5)) + ) + ) +}) + +# =========================================================================== +# LBF column names come from the fit's own variants +# =========================================================================== + +test_that("an unnamed LBF matrix is named by the variants of its fit", { + vids <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A") + tl <- data.frame(variant_id = vids, pip = c(0.5, 0.3, 0.2)) + res <- QtlFineMappingResult( + studyName = "s1", + context = "c1", + trait = "g1", + method = "susie", + entry = list(FineMappingRow(vids, list(pip = tl$pip), tl)) + ) + # The row holds two of the three variants the fit's columns are. + parts <- pecotmr:::.fmrRowParts(endoapply(res, utils::head, 2L), 1L) + named <- pecotmr:::.colocLbfNamesFrom(matrix(c(1, 2, 3), 1L), parts) + expect_equal(colnames(named), vids) + # A matrix that names its own columns keeps them; one matching no + # variant list stays unnamed. + own <- matrix(1:3, 1L, dimnames = list(NULL, c("a", "b", "c"))) + expect_identical(pecotmr:::.colocLbfNamesFrom(own, parts), own) + expect_null( + colnames(pecotmr:::.colocLbfNamesFrom(matrix(1:2, 1L), parts)) + ) +}) + +# =========================================================================== +# Narrowed rows: a fit scored whole warns +# =========================================================================== + +test_that("fits scored as supplied warn about narrowed rows on both sides", { + data(qtlFineMappingExample, gwasFineMappingExample) + qtl <- endoapply(qtlFineMappingExample, utils::head, 2000L) + gwas <- endoapply(gwasFineMappingExample, utils::head, 2000L) + cnd <- tryCatch( + pecotmr:::.colocMaybeAdjustPips( + adjustPips = FALSE, + qtlFineMappingResult = qtl, + gwasFmr = gwas + ), + warning = identity + ) + expect_s3_class(cnd, "pecotmrFitCoverage") + expect_match(conditionMessage(cnd), "colocPipeline\\(\\): 2 row\\(s\\)") + # An empty side scores nothing, so nothing is read. + expect_no_warning(pecotmr:::.colocMaybeAdjustPips( + adjustPips = FALSE, + qtlFineMappingResult = qtl[0], + gwasFmr = gwas + )) +}) + +test_that("colocPipeline warns about narrowed fits only when not adjusting", { + skip_if_not_installed("coloc") + data(qtlFineMappingLbfExample, gwasFineMappingLbfExample) + narrowed <- endoapply(qtlFineMappingLbfExample, utils::head, 150L) + asSupplied <- .fitCoverageMessages(colocPipeline( + narrowed, + gwasInput = gwasFineMappingLbfExample, + adjustPips = FALSE + )) + expect_length(asSupplied, 1L) + expect_match(asSupplied, "colocPipeline\\(\\): 2 row\\(s\\)") + # The adjustment restricts each fit to the variants its row keeps. + expect_length( + .fitCoverageMessages(colocPipeline( + narrowed, + gwasInput = gwasFineMappingLbfExample + )), + 0L + ) +}) diff --git a/tests/testthat/test_colocboostPipeline.R b/tests/testthat/test_colocboostPipeline.R index 38aa76b2..8647c76f 100644 --- a/tests/testthat/test_colocboostPipeline.R +++ b/tests/testthat/test_colocboostPipeline.R @@ -1,77 +1,5 @@ context("colocboostPipeline") -# ============================================================================ -# Legacy colocboostPipeline tests removed for the post-S4-refactor API. -# ============================================================================ -# -# This file previously contained ~100 test_that blocks targeting the legacy -# colocboost pipeline API (rssData/ldData list-shape inputs, RegionalData -# fixtures, qcRegionalData driver, colocboostAnalysis adapters, etc.). Every -# block exercised functions and classes that no longer exist in pecotmr: -# -# Functions removed: -# - colocboostAnalysis() (direct colocboost adapter) -# - qcRegionalData() (legacy QC driver) -# - regionDataToIndInput() (now a .Deprecated() no-op) -# - regionDataToRssInput() (now a .Deprecated() no-op) -# - regionDataToColocboostInput() -# - rssAnalysisPipeline() (replaced by fineMappingPipeline) -# - rssBasicQc() (folded into summaryStatsQc) -# - loadRssData() (replaced by SumStats constructors) -# - getrssinput(), getlddata(), getoutliernumber() -# - colocWrapper(), xqtlEnrichmentWrapper(), colocPostProcessor() -# (now .Deprecated() no-ops returning NULL) -# - .runColocboost() (replaced by internal .cbRun(label, args)) -# - buildLdArgs() (replaced by internal .cbBuildLdArgs()) -# -# Classes removed: -# - RegionalData, MultivariateRegionalData -# - QcResult, AlleleQcResult -# -# The replacement API has a fundamentally different contract: -# -# colocboostPipeline() is now an S4 generic dispatching on the QTL input -# class. Signatures live in R/colocboostPipeline.R: -# -# setMethod("colocboostPipeline", "QtlDataset", ...) -# setMethod("colocboostPipeline", "QtlSumStats", ...) -# setMethod("colocboostPipeline", "MultiStudyQtlDataset", ...) -# -# - QTL data is supplied as a QtlDataset / QtlSumStats / MultiStudyQtlDataset -# (DFrame-based S4 objects with an ldReference slot for sumstats inputs and -# residualizedGenotypes() / residualizedPhenotypes() accessors for -# individual-level inputs). -# - GWAS is supplied separately via the gwasSumStats = GwasSumStats(...) -# argument. -# - Individual-level QC (MAF / X-variance / sample missingness / event -# selection) lives on the QtlDataset constructor and is applied lazily -# by its accessors. There is no separate qcRegionalData() pass. -# - All summary-statistic QC lives in summaryStatsQc(). The pipeline -# rejects QtlSumStats / GwasSumStats whose qcInfo() is empty. -# -# Rewriting the legacy tests in place would require fabricating new -# QtlDataset / QtlSumStats / GwasSumStats / MultiStudyQtlDataset fixtures -# and asserting against a different result shape -- i.e. inventing new -# coverage rather than porting existing coverage. That is out of scope -# for this legacy-cleanup pass. -# -# New tests for the S4 colocboostPipeline() methods, summaryStatsQc(), and -# the QtlDataset / QtlSumStats / GwasSumStats / MultiStudyQtlDataset -# constructors should be added in dedicated files alongside this one -# (e.g. test_colocboost_pipeline_qtl_dataset.R, -# test_colocboost_pipeline_qtl_sumstats.R, -# test_colocboost_pipeline_multitask.R). See: -# -# - R/colocboostPipeline.R (the new S4 generic + methods) -# - R/allClasses.R (QtlDataset, QtlSumStats, GwasSumStats, -# MultiStudyQtlDataset, FineMappingRow) -# - R/allMethods.R (constructors) -# - R/sumstatsQc.R (summaryStatsQc, which is now the only -# summary-statistic QC entry point) -# - tests/testthat/test_sumstatsQc.R (existing QC coverage) -# ============================================================================ - -# Sentinel test so the testthat context is non-empty. test_that("colocboostPipeline is exported as an S4 generic", { expect_true("colocboostPipeline" %in% getNamespaceExports("pecotmr")) expect_true(methods::isGeneric("colocboostPipeline")) @@ -89,25 +17,6 @@ context("colocboostPipeline (S4 dispatch)") # are exercised directly. # =========================================================================== -.cbp_makeHandle <- function(snp_n = 6L, n_samples = 30L, sample_prefix = "s") { - new( - "GenotypeHandle", - path = "/tmp/cb", - format = "plink2", - snpInfo = data.frame( - SNP = sprintf("chr1:%d:A:G", 100L * seq_len(snp_n)), - CHR = rep("1", snp_n), - BP = seq(100L, by = 100L, length.out = snp_n), - A1 = rep("A", snp_n), - A2 = rep("G", snp_n), - stringsAsFactors = FALSE - ), - nSamples = n_samples, - sampleIds = paste0(sample_prefix, seq_len(n_samples)), - pgenPtr = NULL - ) -} - .cbp_mockExtractor <- function(seed = 11, n_samples = 30L) { function(handle, snpIdx, meanImpute = TRUE) { set.seed(seed) @@ -212,7 +121,7 @@ context("colocboostPipeline (S4 dispatch)") entry = list(gr), genome = "hg19", ldReference = .cbp_makeHandle(), - qcInfo = if (qc) list(step1 = "ok") else list() + qcOptions = if (qc) list(step1 = "ok") else list() ) } @@ -236,7 +145,7 @@ context("colocboostPipeline (S4 dispatch)") entry = list(gr), genome = "hg19", ldReference = ldReference, - qcInfo = if (qc) list(step1 = "ok") else list() + qcOptions = if (qc) list(step1 = "ok") else list() ) } @@ -273,44 +182,21 @@ test_that(".cbBuildLdArgs: empty list returns empty list", { expect_equal(pecotmr:::.cbBuildLdArgs(list()), list()) }) -test_that("SignalScreenParam enforces one metric and threads the right spec", { - expect_error( - SignalScreenParam(pip = 0.5, absZ = 5), - "only one screening metric" - ) - expect_equal( - pecotmr:::.screenResolve(SignalScreenParam(absZ = 5)), - list(metric = "absZ", cutoff = 5) - ) - expect_equal( - pecotmr:::.screenResolve(SignalScreenParam(bf = 100)), - list(metric = "bf", cutoff = 100) +test_that(".cbResidualizedY skips a context whose residualization fails", { + # A failing context is skipped with a message naming it, so one bad + # context does not end the whole run. + local_mocked_bindings( + .qtlResidualizedPhenotypes = function(...) { + stop("no samples shared") + }, + .package = "pecotmr" ) - # legacy pip scalar passes through as a bare numeric - expect_equal(pecotmr:::.screenResolve(SignalScreenParam(pip = 0.3)), 0.3) - expect_equal( - pecotmr:::.screenResolve(SignalScreenParam(pip = c(brain = 0.3))), - c(brain = 0.3) - ) # context-named pass-through - expect_null(pecotmr:::.screenResolve(SignalScreenParam())) -}) - -test_that(".cbResolveCutoff passes a screen object through uniformly", { - sc <- list(metric = "absZ", cutoff = 5) - expect_identical(pecotmr:::.cbResolveCutoff(sc, "brain"), sc) - expect_identical(pecotmr:::.cbResolveCutoff(sc, "blood"), sc) - expect_equal(pecotmr:::.cbResolveCutoff(c(brain = 0.3), "brain"), 0.3) - expect_equal(pecotmr:::.cbResolveCutoff(c(brain = 0.3), "blood"), 0) # unlisted ctx - expect_equal(pecotmr:::.cbResolveCutoff(0.5, "any"), 0.5) -}) - -test_that("enabling two screen metrics errors where it is written", { - # The constructor enforces it, so this fails at the call that builds the - # bundle -- before any pipeline runs. - expect_error( - SignalScreenParam(pip = 0.5, bf = 100), - "only one screening metric" + expect_message( + out <- pecotmr:::.cbResidualizedY(NULL, "brain", NULL, NULL), + "skipping context 'brain' (residualized phenotypes unavailable)", + fixed = TRUE ) + expect_null(out) }) test_that(".cbRequireSumStatsQc: un-QCd input errors", { @@ -416,7 +302,7 @@ test_that("colocboostPipeline(QtlDataset): runs xqtl-only ColocBoost with mocked # ran" is read off the recorded timing rather than off a retained raw # object -- the timing is written whether or not the run produced sets. expect_s4_class(out, "ColocBoostResult") - expect_true(is_in("xqtl_coloc", names(computingTime(out)$Analysis))) + expect_true(is_in("xqtl_coloc", computingTime(out)$analysis)) expect_true("X" %in% names(capturedArgs)) }) @@ -426,17 +312,35 @@ test_that("colocboostPipeline(QtlDataset): no QTL bundle and no GWAS returns emp extractBlockGenotypes = .cbp_mockExtractor(), .package = "pecotmr" ) - # An impossible traitId narrows the phenotype matrix to zero columns; - # the bundle ends up NULL and the driver short-circuits. + # A signal screen no outcome clears skips every context; the bundle + # ends up NULL and the driver short-circuits. out <- suppressMessages(suppressWarnings( colocboostPipeline( qd, contexts = "brain", - traitId = "ENSG_DOES_NOT_EXIST", + signalScreenParam = SignalScreenParam(absZ = 1e6), xqtlColoc = TRUE ) )) - expect_null(out$xqtl_coloc) + # No confidence set, and no analysis ran to be timed. + expect_s4_class(out, "ColocBoostResult") + expect_length(out, 0L) + expect_equal(nrow(computingTime(out)), 0L) +}) + +test_that("colocboostPipeline refuses a trait selection that matches nothing", { + # As fineMappingPipeline and twasWeightsPipeline do, rather than + # returning an empty result. + expect_error( + colocboostPipeline(.cbp_makeQtlDataset(), traitId = "nope"), + "colocboostPipeline(QtlDataset): no traits selected.", + fixed = TRUE + ) + expect_error( + colocboostPipeline(.cbp_makeQtlSumStats(), traitId = "nope"), + "colocboostPipeline(QtlSumStats): no entries matched the ", + fixed = TRUE + ) }) # =========================================================================== @@ -491,7 +395,7 @@ test_that("colocboostPipeline: jointGwas merges qtl + gwas sumstats and runs onc separateGwas = FALSE ) ) - expect_true(is_in("joint_gwas", names(computingTime(out)$Analysis))) + expect_true(is_in("joint_gwas", computingTime(out)$analysis)) }) test_that("colocboostPipeline: separateGwas runs once per GWAS study", { @@ -532,7 +436,7 @@ test_that("colocboostPipeline: separateGwas runs once per GWAS study", { # The QTL side's LD travels with it, so the dict covers both sumstats. expect_equal(nrow(call$dict_sumstatLD), 2L) expect_true( - is_in("separate_gwas", names(computingTime(out)$Analysis)) + is_in("separate_gwas", computingTime(out)$analysis) ) }) @@ -704,38 +608,6 @@ test_that(".cbResultLdRefs keys each outcome to its pair's reference", { # GWAS case/control: optional nCase/nControl columns + effective-N wiring # =========================================================================== -test_that("GwasSumStats: nCase/nControl are optional columns (absent by default)", { - gr <- GenomicRanges::GRanges( - seqnames = "chr1", - ranges = IRanges::IRanges( - start = seq(100L, by = 100L, length.out = 5L), - width = 1L - ) - ) - S4Vectors::mcols(gr) <- S4Vectors::DataFrame( - SNP = sprintf("chr1:%d:A:G", 100L * (1:5)), - A1 = "A", - A2 = "G", - Z = rnorm(5), - N = rep(1000L, 5) - ) - base <- list( - study = "G1", - entry = list(gr), - genome = "hg19", - ldReference = .cbp_makeHandle(), - qcInfo = list(ok = 1) - ) - g0 <- exec(GwasSumStats, !!!base) - expect_false(any( - c("nCase", "nControl") %in% colnames(S4Vectors::mcols(g0)) - )) - g1 <- exec(GwasSumStats, !!!c(base, list(nCase = 500, nControl = 1500))) - expect_true(all(c("nCase", "nControl") %in% colnames(S4Vectors::mcols(g1)))) - expect_equal(g1$nCase, 500) - expect_equal(g1$nControl, 1500) -}) - test_that("colocboost GWAS bundle: effective N for case/control, per-variant N otherwise", { gr <- GenomicRanges::GRanges( seqnames = "chr1", @@ -756,7 +628,7 @@ test_that("colocboost GWAS bundle: effective N for case/control, per-variant N o entry = list(gr), genome = "hg19", ldReference = .cbp_makeHandle(), - qcInfo = list(ok = 1) + qcOptions = list(ok = 1) ) local_mocked_bindings( extractBlockGenotypes = .cbp_mockExtractor(), @@ -803,7 +675,11 @@ test_that(".cbPipSkipOutcomes: keeps signal outcomes, drops noise, honours cutof expect_null(pecotmr:::.cbPipSkipOutcomes(X, Yn, 0.5)) }) -test_that(".cbResolveCutoff: scalar applies to all; named vector is per-context", { +test_that(".cbResolveCutoff: screen/scalar uniform, named vector per context", { + # A resolved screen object applies to every context alike. + sc <- list(metric = "absZ", cutoff = 5) + expect_identical(pecotmr:::.cbResolveCutoff(sc, "brain"), sc) + expect_identical(pecotmr:::.cbResolveCutoff(sc, "blood"), sc) expect_equal(pecotmr:::.cbResolveCutoff(0.5, "brain"), 0.5) expect_equal( pecotmr:::.cbResolveCutoff(c(brain = 0.3, blood = 0.7), "blood"), @@ -827,6 +703,47 @@ test_that(".cbResolveCutoff: scalar applies to all; named vector is per-context" ) } +test_that("colocboostPipeline(MultiStudy) refuses a trait no study carries", { + expect_error( + colocboostPipeline(.cbp_makeMultiStudy(), traitId = "nope"), + "colocboostPipeline(MultiStudyQtlDataset): no traits selected.", + fixed = TRUE + ) + # A trait only the embedded sumstats carry still selects something. + expect_silent(pecotmr:::.cbMsAssertTraitsSelected( + .cbp_makeMultiStudy(), + NULL, + "t1" + )) +}) + +test_that("colocboostPipeline(MultiStudy): context selection skips a study", { + # As in fineMappingPipeline: a context only some studies have is skipped + # for the others, with a warning, and one no study has is refused. + local_mocked_bindings( + extractBlockGenotypes = .cbp_mockExtractor(), + .package = "pecotmr" + ) + local_mocked_bindings( + colocboost = function(...) list(stub = TRUE), + .package = "colocboost" + ) + expect_warning( + out <- suppressMessages(colocboostPipeline( + .cbp_makeMultiStudy(), + contexts = "c1", + xqtlColoc = TRUE + )), + "study 'study1' is missing requested context\\(s\\): c1" + ) + # Only the summary statistics' outcome reached colocboost. + expect_identical(out@outcomeInfo$name, "Q1:c1:t1") + expect_error( + colocboostPipeline(.cbp_makeMultiStudy(), contexts = "ghost"), + "no study has: ghost" + ) +}) + test_that("colocboostPipeline(MultiStudyQtlDataset): combines per-study bundles + embedded sumstats", { mt <- .cbp_makeMultiStudy() capturedArgs <- NULL @@ -848,7 +765,7 @@ test_that("colocboostPipeline(MultiStudyQtlDataset): combines per-study bundles separateGwas = FALSE )) expect_s4_class(out, "ColocBoostResult") - expect_true(is_in("xqtl_coloc", names(computingTime(out)$Analysis))) + expect_true(is_in("xqtl_coloc", computingTime(out)$analysis)) # The individual study's outcome is prefixed "study1:" in the combined bundle. expect_true(any(grepl("study1:", names(capturedArgs$Y)))) }) @@ -863,11 +780,16 @@ test_that(".cbRun: an engine failure is caught -> message + NULL", { colocboost = function(...) stop("engine boom"), .package = "colocboost" ) - out <- suppressMessages(colocboostPipeline(qd, xqtlColoc = TRUE)) - expect_null(out$xqtl_coloc) # .cbRun caught (123-124) + expect_message( + out <- colocboostPipeline(qd, xqtlColoc = TRUE), + "xQTL-only ColocBoost failed" + ) + # The run was attempted and timed, and contributes no confidence set. + expect_true(is_in("xqtl_coloc", computingTime(out)$analysis)) + expect_length(out, 0L) }) -test_that(".cbIndividualBundle: multi-context bundle names + prefixes outcomes", { +test_that(".cbIndividualBundle: multi-context outcomes get context prefixes", { qd <- .cbp_makeQtlDataset(contexts = c("brain", "liver"), traits = "ENSG_A") capturedArgs <- NULL local_mocked_bindings( @@ -882,9 +804,21 @@ test_that(".cbIndividualBundle: multi-context bundle names + prefixes outcomes", .package = "colocboost" ) out <- suppressMessages(colocboostPipeline(qd, xqtlColoc = TRUE)) - expect_true(is_in("xqtl_coloc", names(computingTime(out)$Analysis))) - # Two contexts -> two context-prefixed outcomes (covers the xMatch + naming). - expect_gte(length(capturedArgs$Y), 2L) + expect_true(is_in("xqtl_coloc", computingTime(out)$analysis)) + # ENSG_A is in both contexts, so each outcome is prefixed with its context + # to tell the two apart, and colocboost is handed those names. + prefixed <- c("brain_ENSG_A", "liver_ENSG_A") + expect_identical(names(capturedArgs$Y), prefixed) + expect_identical(capturedArgs$outcome_names, prefixed) + # The contexts share genotypes and samples, so their X deduplicates to the + # first context's, and dict_YX maps both outcomes to it (the xMatch). + expect_identical(names(capturedArgs$X), "brain") + expect_identical(capturedArgs$dict_YX, cbind(Y = 1:2, X = c(1L, 1L))) + # Each prefixed name still resolves to the context and trait behind it. + info <- out@outcomeInfo + expect_identical(info$name, prefixed) + expect_identical(info$context, c("brain", "liver")) + expect_identical(info$trait, c("ENSG_A", "ENSG_A")) }) test_that("colocboostPipeline(QtlDataset): unknown context errors", { @@ -896,7 +830,7 @@ test_that("colocboostPipeline(QtlDataset): unknown context errors", { expect_error( colocboostPipeline(qd, contexts = "ghost", xqtlColoc = TRUE), "Unknown context" - ) # 209 + ) }) test_that("colocboostPipeline(QtlDataset): pipCutoffToSkip dropping every outcome -> empty", { @@ -912,7 +846,9 @@ test_that("colocboostPipeline(QtlDataset): pipCutoffToSkip dropping every outcom signalScreenParam = SignalScreenParam(pip = 0.9999) ) )) - expect_null(out$xqtl_coloc) # 249-253 skip -> empty + # The screen leaves no outcome, so nothing runs and no set is reported. + expect_length(out, 0L) + expect_equal(nrow(computingTime(out)), 0L) }) test_that(".cbPipSkipOutcomes: an outcome with < 2 observations is skipped", { @@ -925,11 +861,11 @@ test_that(".cbPipSkipOutcomes: an outcome with < 2 observations is skipped", { ) Y <- cbind(a = c(1, rep(NA, 29)), b = rnorm(30)) # col a: 1 obs (< 2) res <- pecotmr:::.cbPipSkipOutcomes(X, Y, 0.5) - expect_true(is.null(res) || is.matrix(res)) # col a -> next (180) + expect_false(is_in("a", colnames(res))) }) test_that(".cbSumstatPair: NULL / empty df -> NULL", { - expect_null(pecotmr:::.cbSumstatPair(NULL, .cbp_makeHandle())) # 317 + expect_null(pecotmr:::.cbSumstatPair(NULL, .cbp_makeHandle())) expect_null(pecotmr:::.cbSumstatPair(data.frame(), .cbp_makeHandle())) }) @@ -939,14 +875,14 @@ test_that(".cbQtlSumStatsBundle: NULL / context / trait filters and empty result extractBlockGenotypes = .cbp_mockExtractor(), .package = "pecotmr" ) - expect_equal(pecotmr:::.cbQtlSumStatsBundle(NULL), list()) # 359 - expect_length(pecotmr:::.cbQtlSumStatsBundle(ss, contexts = "c1"), 1L) # 363 - expect_length(pecotmr:::.cbQtlSumStatsBundle(ss, traitId = "t1"), 1L) # 366 - expect_equal(pecotmr:::.cbQtlSumStatsBundle(ss, contexts = "ghost"), list()) # 368 + expect_equal(pecotmr:::.cbQtlSumStatsBundle(NULL), list()) + expect_length(pecotmr:::.cbQtlSumStatsBundle(ss, contexts = "c1"), 1L) + expect_length(pecotmr:::.cbQtlSumStatsBundle(ss, traitId = "t1"), 1L) + expect_equal(pecotmr:::.cbQtlSumStatsBundle(ss, contexts = "ghost"), list()) }) test_that(".cbGwasSumStatsBundle: NULL -> empty list", { - expect_equal(pecotmr:::.cbGwasSumStatsBundle(NULL), list()) # 390 + expect_equal(pecotmr:::.cbGwasSumStatsBundle(NULL), list()) }) test_that(".cbSumstatPair: varY attaches var_y; NA variant ids fall back to chr:pos", { @@ -962,9 +898,9 @@ test_that(".cbSumstatPair: varY attaches var_y; NA variant ids fall back to chr: stringsAsFactors = FALSE ) pair <- pecotmr:::.cbSumstatPair(df, h, varY = 0.7) - expect_true("var_y" %in% names(pair$sumstat)) # 350 + expect_true("var_y" %in% names(pair$sumstat)) expect_equal(unique(pair$sumstat$var_y), 0.7) - # NA variant_id -> formatVariantId fallback (322-323); no panel overlap -> NULL (330) + # NA variant_id -> formatVariantId fallback; no panel overlap -> NULL dfNA <- data.frame( variant_id = NA_character_, chrom = "chr1", @@ -1071,22 +1007,45 @@ test_that(".cbHarmonizeAlleles aligns opposite-coded sumstats to one canonical ( expect_equal(h$pairs$B$sumstat$z, -3) # B flipped to match }) -test_that("colocboostPipeline(MultiStudyQtlDataset): a study with no usable bundle is skipped", { +test_that("colocboostPipeline(MultiStudy): a study with no bundle is skipped", { mt <- .cbp_makeMultiStudy() # qd (study1, ENSG_A) + ss (Q1, t1) + seen <- list() local_mocked_bindings( extractBlockGenotypes = .cbp_mockExtractor(), .package = "pecotmr" ) local_mocked_bindings( - colocboost = function(...) list(stub = TRUE), + colocboost = function(...) { + seen[[length(seen) + 1L]] <<- list(...) + list(stub = TRUE) + }, .package = "colocboost" ) # traitId="t1" matches the embedded sumstats but not the QtlDataset -> its - # per-study bundle is NULL and skipped (684); the sumstat side still runs. + # per-study bundle is NULL and skipped; the sumstat side still runs. out <- suppressMessages(suppressWarnings( colocboostPipeline(mt, traitId = "t1", xqtlColoc = TRUE) )) - expect_s4_class(out, "ColocBoostResult") + # One xQTL-only run over the summary statistics alone: no individual-level + # data reached colocboost, and no "study1:" outcome was named. + expect_length(seen, 1L) + call <- seen[[1L]] + expect_false(any(is_in(c("X", "Y", "dict_YX"), names(call)))) + expect_identical(call$outcome_names, "Q1:c1:t1") + expect_identical(names(call$sumstat), "Q1:c1:t1") + # The result times that run and records only the summary-level outcome, + # keyed to the embedded sumstats' LD reference. + expect_identical(computingTime(out)$analysis, "xqtl_coloc") + expect_length(out, 0L) + info <- out@outcomeInfo + expect_identical(info$name, "Q1:c1:t1") + expect_identical(info$study, "Q1") + expect_identical(info$dataForm, "sumstats") + expect_length(ldReference(out), 1L) + expect_identical( + ldReference(out)[[info$ldReference]], + ldReference(sumStats(mt))[[1L]] + ) }) @@ -1098,11 +1057,11 @@ test_that("colocboostPipeline(MultiStudyQtlDataset): a study with no usable bund # reference panel, on both the QTL and the GWAS sumstat sides. # --------------------------------------------------------------------------- -# @noRd -.cbf_qcd <- function() { +# summaryStatsQc() of the bundled example, run once for the tests below. +.cbf_ss <- local({ data(qtlSumStatsExample, envir = environment()) suppressMessages(summaryStatsQc(qtlSumStatsExample)) -} +}) # @noRd .cbf_n <- function(ss, ...) { @@ -1114,12 +1073,12 @@ test_that("colocboostPipeline(MultiStudyQtlDataset): a study with no usable bund } test_that("colocboost sumstat bundle filters nothing by default", { - ss <- .cbf_qcd() + ss <- .cbf_ss expect_equal(.cbf_n(ss), sum(lengths(ss))) }) test_that("colocboost sumstat bundle drops panel-rare variants", { - ss <- .cbf_qcd() + ss <- .cbf_ss full <- .cbf_n(ss) loose <- .cbf_n(ss, mafCutoff = 0.05) tight <- .cbf_n(ss, mafCutoff = 0.2) @@ -1128,9 +1087,9 @@ test_that("colocboost sumstat bundle drops panel-rare variants", { }) test_that("colocboost RSS cutoffs match .panelVariantFilter", { - ss <- .cbf_qcd() + ss <- .cbf_ss ids <- normalizeVariantId( - as.data.frame( + .sumStatsDf( ss, studyName = ss$study[[1L]], context = ss$context[[1L]], @@ -1152,7 +1111,7 @@ test_that("colocboost RSS cutoffs match .panelVariantFilter", { }) test_that("colocboost RSS treats MAC as a MAF equivalent", { - ss <- .cbf_qcd() + ss <- .cbf_ss nSamp <- ncol(ldReference(ss)[[1L]]) expect_equal( .cbf_n(ss, macCutoff = 0.1 * 2 * nSamp), @@ -1161,7 +1120,7 @@ test_that("colocboost RSS treats MAC as a MAF equivalent", { }) test_that("colocboost RSS honours a missingness cutoff", { - ss <- .cbf_qcd() + ss <- .cbf_ss expect_lt(.cbf_n(ss, imissCutoff = 0), sum(lengths(ss))) expect_equal(.cbf_n(ss, imissCutoff = 1), sum(lengths(ss))) }) @@ -1170,8 +1129,8 @@ test_that(".cbSumstatPair keeps sumstat rows aligned to the LD matrix", { # The row filter indexes df by the FULL-length variant id vector, so the # filtered set has to be passed to the LD build separately rather than by # shrinking that vector. - ss <- .cbf_qcd() - df <- as.data.frame( + ss <- .cbf_ss + df <- .sumStatsDf( ss, studyName = ss$study[[1L]], context = ss$context[[1L]], @@ -1213,7 +1172,7 @@ test_that("colocboost reads a panel's factor and its LdMatrix alike", { unname(computeLd(panel)), variants = SummarizedExperiment::rowRanges(panel) ), - qcInfo = qcInfo(ss) + qcOptions = qcOptions(ss) ) set.seed(1) viaPanel <- suppressWarnings(suppressMessages(colocboostPipeline(ss))) @@ -1224,8 +1183,8 @@ test_that("colocboost reads a panel's factor and its LdMatrix alike", { }) test_that(".cbSumstatPair returns NULL when a cutoff removes everything", { - ss <- .cbf_qcd() - df <- as.data.frame( + ss <- .cbf_ss + df <- .sumStatsDf( ss, studyName = ss$study[[1L]], context = ss$context[[1L]], @@ -1300,7 +1259,8 @@ test_that("a MultiStudyQtlDataset with no embedded sumstats yields no pairs", { out <- pecotmr:::.cbMultiStudySumstats( multiStudyQtlDatasetExample, contexts = NULL, - traitId = NULL + traitId = NULL, + cisWindow = NULL ) expect_equal(out$qtlPairs, list()) expect_null(out$qtlLdReference) @@ -1357,21 +1317,37 @@ test_that(".cbBuildContextXY skips a context with no shared samples", { test_that(".cbResidualizedX reports why genotypes were unavailable", { local_mocked_bindings( - residualizedGenotypes = function(...) stop("kaboom"), + .qtlResidualizedGenotypes = function(...) stop("kaboom"), .package = "pecotmr" ) # The cause is chained via `parent`, not flattened into the text, so the # rendered message still shows it AND it stays reachable as a condition. # catch_cnd() rather than expect_message(), which returns NULL. cnd <- rlang::catch_cnd( - pecotmr:::.cbResidualizedX(NULL, "c1", NULL, NULL, NULL, NULL), + pecotmr:::.cbResidualizedX( + NULL, + "c1", + NULL, + NULL, + NULL, + NULL, + genotypeFilter = pecotmr:::.qtlResolveFilter() + ), classes = "message" ) expect_match(conditionMessage(cnd), "residualized genotypes unavailable") expect_match(conditionMessage(cnd), "kaboom") expect_match(conditionMessage(cnd$parent), "kaboom") expect_null(suppressMessages( - pecotmr:::.cbResidualizedX(NULL, "c1", NULL, NULL, NULL, NULL) + pecotmr:::.cbResidualizedX( + NULL, + "c1", + NULL, + NULL, + NULL, + NULL, + genotypeFilter = pecotmr:::.qtlResolveFilter() + ) )) }) @@ -1454,7 +1430,7 @@ test_that(".cbRunXqtlOnly runs on a summary-level QTL side alone", { expect_null(captured$dict_YX) expect_equal(names(captured$sumstat), c("qtlA", "qtlB")) expect_equal(captured$outcome_names, c("qtlA", "qtlB")) - # focalTrait is honored on the summary-level side too. + # A focal outcome is honored on the summary-level side too. expect_equal(captured$focal_outcome_idx, 2L) # Identical LD matrices dedupe to one, so the dict points both at it. expect_equal(unname(captured$dict_sumstatLD[, "LD"]), c(1L, 1L)) @@ -1508,12 +1484,12 @@ test_that(".cbRunVariants: xqtlColoc runs on a QTL-only sumstat bundle", { xqtlColoc = TRUE, jointGwas = FALSE, separateGwas = FALSE, - focalTrait = NULL, + focal = NULL, methodArgs = ColocboostOptions(), qtlSumstatBundle = qtlOnly )) expect_equal(called, "xqtl") - expect_false(is.null(computingTime(out)$Analysis$xqtl_coloc)) + expect_true(is_in("xqtl_coloc", computingTime(out)$analysis)) }) test_that(".cbRunVariants warns instead of silently skipping an analysis", { @@ -1536,7 +1512,7 @@ test_that(".cbRunVariants warns instead of silently skipping an analysis", { xqtlColoc = FALSE, jointGwas = TRUE, separateGwas = TRUE, - focalTrait = NULL, + focal = NULL, methodArgs = ColocboostOptions() )) ) @@ -1560,13 +1536,13 @@ test_that(".cbRunVariants warns when xqtlColoc has only GWAS sumstats", { xqtlColoc = TRUE, jointGwas = FALSE, separateGwas = FALSE, - focalTrait = NULL, + focal = NULL, methodArgs = ColocboostOptions(), qtlSumstatBundle = pecotmr:::.cbMergeSumstatBundles(list()) )), "xqtlColoc = TRUE was requested" ) - expect_null(computingTime(out)$Analysis$xqtl_coloc) + expect_false(is_in("xqtl_coloc", computingTime(out)$analysis)) }) test_that("ColocboostOptions() options reach the engine by name", { @@ -1595,7 +1571,7 @@ test_that("ColocboostOptions() options reach the engine by name", { xqtlColoc = TRUE, jointGwas = FALSE, separateGwas = FALSE, - focalTrait = NULL, + focal = NULL, methodArgs = ColocboostOptions(M = 3L, stop_thresh = 0.02), qtlSumstatBundle = qtlOnly )) @@ -1608,7 +1584,7 @@ test_that("ColocboostOptions() options reach the engine by name", { test_that(".cbAppendGwasPairs disambiguates a colliding study key", { local_mocked_bindings( .cbRequireSumStatsQc = function(...) invisible(NULL), - .cbGwasSumStatsBundle = function(gwasSumStats, cutoffs) { + .cbGwasSumStatsBundle = function(gwasSumStats, window, cutoffs) { list(dup = "GWAS") }, .package = "pecotmr" @@ -1635,8 +1611,8 @@ test_that("colocboostPipeline forwards residualizationParam to both sides", { # Y together, so a bundle that reached only the genotypes would # residualize the two against different covariate sets. data(qtlDatasetExample, envir = environment()) - origG <- residualizedGenotypes - origP <- residualizedPhenotypes + origG <- pecotmr:::.qtlResidualizedGenotypes + origP <- pecotmr:::.qtlResidualizedPhenotypes seen <- new.env(parent = emptyenv()) note <- function(which, ra) { assign( @@ -1649,7 +1625,7 @@ test_that("colocboostPipeline forwards residualizationParam to both sides", { ) } local_mocked_bindings( - residualizedGenotypes = function( + .qtlResidualizedGenotypes = function( x, ..., residualizationParam = ResidualizationParam() @@ -1657,7 +1633,7 @@ test_that("colocboostPipeline forwards residualizationParam to both sides", { note("geno", residualizationParam) origG(x, ..., residualizationParam = residualizationParam) }, - residualizedPhenotypes = function( + .qtlResidualizedPhenotypes = function( x, ..., residualizationParam = ResidualizationParam() @@ -1675,3 +1651,394 @@ test_that("colocboostPipeline forwards residualizationParam to both sides", { expect_equal(unique(get("geno", envir = seen)), "FALSE") expect_equal(unique(get("pheno", envir = seen)), "FALSE") }) + +# =========================================================================== +# One outcome per GWAS study; the focal outcome +# =========================================================================== + +# One GWAS study over three rows: two LD blocks on chr1 (100-300, 400-500) +# and one on chr2. +.cbp_makeBlockedGwas <- function() { + gr <- GenomicRanges::GRanges( + c(rep("chr1", 5L), "chr2"), + IRanges::IRanges(c(100L * (1:5), 100L), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = c(sprintf("chr1:%d:A:G", 100L * (1:5)), "chr2:100:A:G"), + A1 = rep("A", 6L), + A2 = rep("G", 6L), + Z = seq_len(6L) / 10, + N = rep(1000L, 6L) + ) + GwasSumStats( + studyName = "G1", + entry = list(gr), + genome = "hg19", + ldReference = .cbp_makeHandle(), + qcOptions = list(ok = 1), + region = GenomicRanges::GRanges( + c("chr1", "chr1", "chr2"), + IRanges::IRanges(c(1L, 301L, 1L), c(300L, 1000L, 1000L)) + ) + ) +} + +# Two GWAS studies over the fixtures' five chr1 variants. +.cbp_makeTwoGwas <- function() { + gr <- .cbp_makeGwasSumStats()[[1L]] + GwasSumStats( + studyName = c("G1", "G2"), + entry = list(gr, gr), + genome = "hg19", + ldReference = .cbp_makeHandle(), + qcOptions = list(ok = 1) + ) +} + +test_that("a GWAS study is one outcome over the rows the QTL data reach", { + local_mocked_bindings( + extractBlockGenotypes = .cbp_mockExtractor(), + .package = "pecotmr" + ) + gws <- .cbp_makeBlockedGwas() + expect_equal(nrow(gws), 3L) + chr1 <- sprintf("chr1:%d:A:G", 100L * (1:5)) + # A window reaching both chr1 blocks gets their union as one outcome; the + # chr2 row is not read. + both <- pecotmr:::.cbGwasSumStatsBundle( + gws, + window = GenomicRanges::GRanges("chr1", IRanges::IRanges(150L, 450L)) + ) + expect_named(both, "G1") + expect_setequal(both$G1$sumstat$variant, chr1) + expect_equal(both$G1$study, "G1") + # A window inside one block reads that block alone. + one <- pecotmr:::.cbGwasSumStatsBundle( + gws, + window = GenomicRanges::GRanges("chr1", IRanges::IRanges(100L, 200L)) + ) + expect_setequal(one$G1$sumstat$variant, chr1[1:3]) + # A study none of whose rows the QTL data reach is left out, and said so. + expect_message( + none <- pecotmr:::.cbGwasSumStatsBundle( + gws, + window = GenomicRanges::GRanges("chr3", IRanges::IRanges(1L, 9L)) + ), + "leaving out GWAS G1" + ) + expect_length(none, 0L) +}) + +test_that("a GWAS study's overlapped rows must share one LD reference", { + local_mocked_bindings( + extractBlockGenotypes = .cbp_mockExtractor(), + .package = "pecotmr" + ) + gws <- pecotmr:::.withRowLdRefs( + .cbp_makeBlockedGwas(), + list(.cbp_makeHandle(), .cbp_makeLdMatrix(), .cbp_makeHandle()) + ) + expect_error( + pecotmr:::.cbGwasSumStatsBundle( + gws, + window = GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(150L, 450L) + ) + ), + "GWAS study 'G1' the QTL data overlap use 2 different LD references" + ) +}) + +test_that(".cbAssertFocalOutcome takes a study name or a named QTL vector", { + ok <- list( + NULL, + NA, + "G1", + c(trait = "ENSG1"), + c(study = "S1", context = "brain", trait = "ENSG1") + ) + for (x in ok) { + expect_invisible(pecotmr:::.cbAssertFocalOutcome(x)) + } + bad <- list( + 1, + c("G1", "G2"), + c(gene = "ENSG1"), + c("brain", trait = "ENSG1"), + c(trait = NA_character_), + character(0), + list(trait = "ENSG1") + ) + for (x in bad) { + expect_error(pecotmr:::.cbAssertFocalOutcome(x), "focalOutcome") + } +}) + +test_that(".cbResolveFocal: the lone GWAS by default, a named one, or none", { + one <- .cbp_makeGwasSumStats() + two <- .cbp_makeTwoGwas() + qtlInfo <- tibble::tibble( + name = c("brain_ENSG1", "liver_ENSG1", "Q1:c1:t1"), + study = c("S1", "S1", "Q1"), + context = c("brain", "liver", "c1"), + trait = c("ENSG1", "ENSG1", "t1") + ) + resolve <- function(focal, gws, keys) { + pecotmr:::.cbResolveFocal(focal, gws, qtlInfo, keys) + } + keys <- c(G1 = "G1", G2 = "G2") + # One study: the GWAS is the joint run's focal outcome, unless NA. + expect_equal(resolve(NULL, one, keys[1]), list(xqtl = NULL, joint = "G1")) + expect_equal(resolve(NA, one, keys[1]), list(xqtl = NULL, joint = NULL)) + # ...and only when it reached the runs. + expect_null(resolve(NULL, one, character(0))$joint) + # Several studies: none, unless one is named. + expect_equal(resolve(NULL, two, keys), list(xqtl = NULL, joint = NULL)) + expect_equal(resolve("G2", two, keys)$joint, "G2") + expect_error(resolve("G3", two, keys), "names no GWAS study") + expect_error(resolve("G1", NULL, character(0)), "no gwasSumStats") + expect_error(resolve("G2", two, keys[1]), "none of its rows overlap") + # A QTL outcome, by as many parts as it takes, is focal in both runs. + expect_equal( + resolve(c(context = "brain", trait = "ENSG1"), two, keys), + list(xqtl = "brain_ENSG1", joint = "brain_ENSG1") + ) + expect_equal(resolve(c(trait = "t1"), two, keys)$xqtl, "Q1:c1:t1") + expect_error(resolve(c(trait = "ENSG1"), two, keys), "matches 2 QTL") + expect_error(resolve(c(trait = "nope"), two, keys), "matches no QTL") +}) + +test_that("the joint run is focal on a lone GWAS study by default", { + seen <- list() + local_mocked_bindings( + extractBlockGenotypes = .cbp_mockExtractor(), + .package = "pecotmr" + ) + local_mocked_bindings( + colocboost = function(...) { + seen[[length(seen) + 1L]] <<- list(...) + list(stub = TRUE) + }, + .package = "colocboost" + ) + # Built once: the runs below differ only in their focal outcome. + qtl <- .cbp_makeQtlSumStats() + oneGwas <- .cbp_makeGwasSumStats() + twoGwas <- .cbp_makeTwoGwas() + run <- function(gws, ...) { + seen <<- list() + suppressMessages(colocboostPipeline( + qtl, + gwasSumStats = gws, + xqtlColoc = FALSE, + jointGwas = TRUE, + ... + )) + seen[[1L]] + } + call <- run(oneGwas) + expect_equal(call$outcome_names, c("Q1:c1:t1", "G1")) + expect_equal(call$focal_outcome_idx, 2L) + off <- run(oneGwas, focalOutcome = NA) + expect_null(off$focal_outcome_idx) + toQtl <- run(oneGwas, focalOutcome = c(trait = "t1")) + expect_equal(toQtl$focal_outcome_idx, 1L) + # Two studies: non-focal unless one is named. + expect_null(run(twoGwas)$focal_outcome_idx) + named <- run(twoGwas, focalOutcome = "G2") + expect_equal(named$outcome_names[[named$focal_outcome_idx]], "G2") +}) + +test_that("a QTL sumstat outcome records the tuple it came from", { + pairs <- list( + `Q1:c1:t1` = list(study = "Q1", context = "c1", trait = "t1"), + G1 = list(study = "G1") + ) + bundle <- list(sumstat = list(`Q1:c1:t1` = 1, G1 = 2)) + info <- pecotmr:::.cbOutcomeInfo( + NULL, + bundle, + FALSE, + c(`Q1:c1:t1` = "ld1", G1 = "ld1"), + pecotmr:::.cbPairsInfo(pairs) + ) + expect_equal(info$study, c("Q1", "G1")) + expect_equal(info$context, c("c1", NA)) + expect_equal(info$trait, c("t1", NA)) +}) + +test_that("a focalOutcome vector with no QTL outcomes to match says so", { + noQtl <- tibble::tibble( + name = character(0), + study = character(0), + context = character(0), + trait = character(0) + ) + expect_error( + pecotmr:::.cbResolveFocal( + c(trait = "t1"), + .cbp_makeGwasSumStats(), + noQtl, + c(G1 = "G1") + ), + "The QTL outcomes are: none" + ) +}) + +test_that("an outcome whose variants its LD reference lacks is left out", { + # The fixtures' LdMatrix holds chr1:100-500; these sit at 1100-1500. + ids <- sprintf("chr1:%d:A:G", 1100L + 100L * (0:4)) + gr <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(1100L + 100L * (0:4), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = ids, + A1 = rep("A", 5L), + A2 = rep("G", 5L), + Z = seq_len(5L) / 10, + N = rep(1000L, 5L) + ) + qss <- QtlSumStats( + studyName = "Q1", + context = "c1", + trait = "t1", + entry = list(gr), + genome = "hg19", + ldReference = .cbp_makeLdMatrix(), + qcOptions = list(ok = 1) + ) + expect_null(pecotmr:::.cbQtlEntryPair(1L, qss, NULL)) + gws <- GwasSumStats( + studyName = "G1", + entry = list(gr), + genome = "hg19", + ldReference = .cbp_makeLdMatrix(), + qcOptions = list(ok = 1) + ) + expect_length(pecotmr:::.cbGwasSumStatsBundle(gws), 0L) +}) + +test_that(".cbQtlWindow places the QTL variants it can parse", { + asX <- function(ids) { + list(X = list(matrix(0, 2L, length(ids), dimnames = list(NULL, ids)))) + } + # Nothing placed -- no QTL side, or only rsIDs -- leaves every GWAS row in. + expect_null(pecotmr:::.cbQtlWindow(NULL, list())) + expect_null(pecotmr:::.cbQtlWindow(asX(c("rs1", "rs2")), list())) + window <- pecotmr:::.cbQtlWindow( + asX(c("1:100:A:G", "rs2", "chr1:400:C:T")), + list() + ) + expect_equal(as.character(GenomicRanges::seqnames(window)), "chr1") + expect_equal(GenomicRanges::start(window), 100L) + expect_equal(GenomicRanges::end(window), 400L) +}) + +test_that(".cbQtlVariants places the variants every QTL outcome reads", { + asX <- function(ids) { + list(X = list(matrix(0, 2L, length(ids), dimnames = list(NULL, ids)))) + } + expect_null(pecotmr:::.cbQtlVariants(NULL, list())) + expect_null(pecotmr:::.cbQtlVariants(asX("rs1"), list())) + placed <- pecotmr:::.cbQtlVariants( + asX(c("1:100:A:G", "rs2")), + list(q1 = list(variantIds = c("chr1:100:A:G", "chr1:700:C:T"))) + ) + expect_identical(as.character(placed), c("chr1:100", "chr1:700")) +}) + +test_that("colocboost refuses QTL data reaching past a given block", { + gr <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(100L * (1:5), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = sprintf("chr1:%d:A:G", 100L * (1:5)), + A1 = "A", + A2 = "G", + Z = 1, + N = 100L + ) + gws <- GwasSumStats( + studyName = "G1", + entry = list(gr), + genome = "hg19", + qcOptions = list(ok = 1), + region = GenomicRanges::GRanges("chr1:1-550") + ) + qtl <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(300L, 600L), width = 1L) + ) + expect_error( + pecotmr:::.cbAppendGwasPairs(list(), gws, qtlVariants = qtl), + "the QTL data: 1 variant(s) past the end of block chr1:1-550", + fixed = TRUE + ) + # Without QTL variants to place there is nothing to check. + expect_null(pecotmr:::.cbCheckBlockReach(NULL, gws)) +}) + +test_that("colocboostPipeline(QtlSumStats) lays a cisWindow around traitPos", { + expect_error( + colocboostPipeline(.cbp_makeQtlSumStats(), cisWindow = 1000), + "colocboostPipeline: `cisWindow` is laid around each tuple's trait", + fixed = TRUE + ) + # Naming a context reaches the same check: the window is laid on the + # tuples colocboost's own selection keeps. + expect_error( + colocboostPipeline( + .cbp_makeQtlSumStats(), + contexts = "c1", + cisWindow = 1000 + ), + "colocboostPipeline: `cisWindow` is laid around each tuple's trait", + fixed = TRUE + ) +}) + +test_that("colocboostPipeline(MSQD) lays cisWindow on its summary statistics", { + local_mocked_bindings( + extractBlockGenotypes = .cbp_mockExtractor(), + .package = "pecotmr" + ) + ss <- .cbp_makeQtlSumStats() + ss$traitPos <- GenomicRanges::GRanges("chr1:300") + mt <- MultiStudyQtlDataset( + qtlDatasets = list( + study1 = .cbp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + ), + sumStats = ss + ) + pairs <- pecotmr:::.cbMultiStudySumstats(mt, NULL, NULL, 100)$qtlPairs + expect_identical(as.character(pairs[[1L]]$span), "chr1:200-400") + # A summary-statistics study without a trait position is an error, as it + # is on its own. + expect_error( + colocboostPipeline(.cbp_makeMultiStudy(), cisWindow = 100), + "colocboostPipeline: `cisWindow` is laid around each tuple's trait", + fixed = TRUE + ) +}) + +# =========================================================================== +# .cbToResultObject +# =========================================================================== + +test_that("separate_gwas runs are keyed by gwasStudy", { + # The three analyses are not parallel: separate_gwas is a named list one + # level deeper, so without gwasStudy its sets would be indistinguishable. + raw <- list( + xqtl_coloc = NULL, + joint_gwas = NULL, + separate_gwas = list(G1 = .cbr_fake(), G2 = .cbr_fake()), + computing_time = list() + ) + x <- .cbToResultObject(raw, .cbr_info()) + expect_equal(nrow(x), 2L) + expect_equal(x$analysis, rep("separate_gwas", 2L)) + expect_setequal(x$gwasStudy, c("G1", "G2")) +}) diff --git a/tests/testthat/test_cpp11.R b/tests/testthat/test_cpp11.R index 2818c855..353583c7 100644 --- a/tests/testthat/test_cpp11.R +++ b/tests/testthat/test_cpp11.R @@ -20,8 +20,6 @@ "bgenSampleIdsCpp", "dentistIterativeImpute", "dentistIterativeImputeFactor", - "lassosumRssCpp", - "lassosumRssFactorCpp", "ldThresholdComponents", "penalizedRssCpp", "penalizedRssFactorCpp", diff --git a/tests/testthat/test_crossValidation.R b/tests/testthat/test_crossValidation.R index 010d59d5..c49fcacb 100644 --- a/tests/testthat/test_crossValidation.R +++ b/tests/testthat/test_crossValidation.R @@ -179,15 +179,24 @@ test_that("maxNumVariants with variantsToKeep retains the specified variants", { }) test_that("a degenerate fold (empty train/test) is skipped, not errored", { + # One fold holding every sample leaves nothing to train on: the fold is + # skipped before any fit, so nothing is predicted or scored. d <- mkXY(n = 10) sp <- data.frame(Sample = rownames(d$X), Fold = rep(1L, nrow(d$X))) + fits <- 0L + countingFit <- function(...) { + fits <<- fits + 1L + mockFitFold(...) + } r <- suppressMessages(cv( d$X, d$Y, samplePartitions = sp, - fitFold = mockFitFold + fitFold = countingFit )) - expect_true(all(is.na(r$prediction[["mock_predicted"]]))) + expect_equal(fits, 0L) + expect_length(r$prediction, 0L) + expect_length(r$performance, 0L) }) test_that("zero-variance predictions yield NA metrics with a message", { @@ -213,6 +222,7 @@ test_that("zero-variance predictions yield NA metrics with a message", { }) test_that("the parallel fold path matches the serial one", { + skip_on_os("windows") d <- mkXY(n = 40, seed = 7) set.seed(1) r1 <- suppressMessages(cv( @@ -220,7 +230,7 @@ test_that("the parallel fold path matches the serial one", { d$Y, fold = 4, fitFold = mockFitFold, - numThreads = 1 + BPPARAM = BiocParallel::SerialParam() )) set.seed(1) r2 <- suppressMessages(cv( @@ -228,7 +238,7 @@ test_that("the parallel fold path matches the serial one", { d$Y, fold = 4, fitFold = mockFitFold, - numThreads = 2 + BPPARAM = BiocParallel::MulticoreParam(2) )) expect_equal(r1$prediction, r2$prediction) }) @@ -322,13 +332,68 @@ test_that("sample names are synthesized when neither matrix carries rownames", { expect_equal(rownames(out$Y), rownames(out$X)) }) -test_that("numThreads = -1 asks BiocParallel for the worker count", { - # -1 means "all available"; anything else is capped at what is available. - expect_equal( - pecotmr:::.cvNumCores(-1), - BiocParallel::multicoreWorkers() +test_that("BPPARAM must be a BiocParallelParam", { + expect_error(pecotmr:::.assertBpparam(2), "must be a BiocParallelParam") + expect_error( + CrossValidationParam(BPPARAM = 4), + "must be a BiocParallelParam" + ) +}) + +test_that("the workers draw from a seeded copy of the caller's BPPARAM", { + bp <- BiocParallel::SerialParam() + # `seed` first, then the param's own RNGseed, and the caller's param is + # left as it was. + expect_identical( + BiocParallel::bpRNGseed(pecotmr:::.seededBpparam(bp, 7L)), + 7L + ) + expect_null(BiocParallel::bpRNGseed(bp)) + own <- BiocParallel::SerialParam(RNGseed = 3L) + expect_identical( + BiocParallel::bpRNGseed(pecotmr:::.seededBpparam(own)), + 3L + ) + # Neither: one draw from the session RNG, so set.seed() still governs. + set.seed(11) + a <- BiocParallel::bpRNGseed(pecotmr:::.seededBpparam(bp)) + set.seed(11) + b <- BiocParallel::bpRNGseed(pecotmr:::.seededBpparam(bp)) + expect_identical(a, b) +}) + +test_that("a worker's error is raised with its own message", { + boom <- function(i) { + if (i == 2L) { + rlang::abort("element two failed") + } + i + } + expect_error( + pecotmr:::.bpMap(1:3, boom, BPPARAM = BiocParallel::SerialParam()), + "^element two failed$" + ) + expect_identical( + pecotmr:::.bpMap(1:2, identity, BPPARAM = BiocParallel::SerialParam()), + list(1L, 2L) ) - expect_equal(pecotmr:::.cvNumCores(1), 1) +}) + +test_that("a threaded engine counts only workers on this machine", { + expect_identical( + pecotmr:::.bpLocalThreads(BiocParallel::SerialParam(), "f"), + 1L + ) + expect_identical( + pecotmr:::.bpLocalThreads(BiocParallel::MulticoreParam(3), "f"), + 3L + ) + rlang::local_options(rlib_message_verbosity = "verbose") + expect_message( + n <- pecotmr:::.bpLocalThreads(BiocParallel::SnowParam(4), "f"), + "f: the workers of a SnowParam need not run on this machine" + ) + expect_identical(n, 1L) }) test_that("a seed makes a CV call reproducible without leaking RNG state", { @@ -350,6 +415,21 @@ test_that(".cvPartitionKey answers NULL when there is no partition to key", { expect_null(pecotmr:::.cvPartitionKey(NULL)) }) +test_that(".cvPartitionKey ignores row order but not fold assignment", { + sp <- data.frame(Sample = c("s1", "s2", "s3"), Fold = c(1L, 2L, 1L)) + shuffled <- sp[c(3, 1, 2), ] + expect_identical( + pecotmr:::.cvPartitionKey(sp), + pecotmr:::.cvPartitionKey(shuffled) + ) + moved <- sp + moved$Fold <- c(1L, 1L, 2L) + expect_false(identical( + pecotmr:::.cvPartitionKey(sp), + pecotmr:::.cvPartitionKey(moved) + )) +}) + test_that("sumstats inputs ignore residualization but refuse crossValidation", { # The asymmetry follows from the defaults, not from taste. CV is off # unless asked for (folds = 0), so a non-default value on a @@ -430,3 +510,46 @@ test_that("CrossValidationParam(fitFullData) is validated at construction", { "fitFullData" ) }) + +test_that("a BPPARAM other than SerialParam() is a cross-validation request", { + expect_silent(pecotmr:::.cvRefuseOnSumstats( + CrossValidationParam(BPPARAM = BiocParallel::SerialParam()), + "fineMappingPipeline", + "QtlSumStats" + )) + expect_error( + pecotmr:::.cvRefuseOnSumstats( + CrossValidationParam(BPPARAM = BiocParallel::MulticoreParam(2)), + "fineMappingPipeline", + "QtlSumStats" + ), + "Remove CrossValidationParam(BPPARAM)", + fixed = TRUE + ) +}) + +test_that("a BiocParallel report without a worker error is raised as is", { + cnd <- structure( + class = c("bplist_error", "bperror", "error", "condition"), + list(message = "no element failed", call = NULL) + ) + attr(cnd, "result") <- list(1L) + expect_error(pecotmr:::.bpRaiseFirstError(cnd), "no element failed") +}) + +# =========================================================================== +# .cvSamplePartition and .cvMetricRow +# =========================================================================== + +test_that(".cvSamplePartition partitions every sample into the requested folds", { + part <- pecotmr:::.cvSamplePartition(paste0("s", 1:20), fold = 4L) + expect_setequal(part$Sample, paste0("s", 1:20)) + expect_setequal(sort(unique(part$Fold)), 1:4) + expect_equal(nrow(part), 20L) +}) + +test_that(".cvMetricRow: < 3 usable predictions -> all-NA row", { + expect_true(all(is.na(pecotmr:::.cvMetricRow(c(1, 2), c(1, 2))))) + ok <- pecotmr:::.cvMetricRow(c(1, 2, 3, 4, 5), c(1.1, 2, 2.9, 4, 5)) + expect_false(is.na(ok[["rsq"]])) +}) diff --git a/tests/testthat/test_ctwasPipeline.R b/tests/testthat/test_ctwasPipeline.R index 7b30649d..d15dd4e4 100644 --- a/tests/testthat/test_ctwasPipeline.R +++ b/tests/testthat/test_ctwasPipeline.R @@ -28,7 +28,7 @@ context("ctwasPipeline") format = "plink2", snpInfo = data.frame( SNP = snpIds, - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = positions, A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -124,7 +124,7 @@ context("ctwasPipeline") genome = "hg19", ldReference = .ctp_makeHandle(snp_n = 6L * n), blockId = blockIds, - qcInfo = if (qc) list(step1 = "ok") else list() + qcOptions = if (qc) list(step1 = "ok") else list() ) } @@ -132,7 +132,7 @@ context("ctwasPipeline") # weights; it has to name five of them, one per weight. The default sits # inside block 1 -- pass 7:11 for a gene that lives in block 2. .ctp_makeTwasWeights <- function(variantIdx = 1:5) { - e <- twasWeightsRow( + e <- TwasWeightsRow( variantIds = map_chr(variantIdx, .ctp_snpId), weights = c(0.1, 0.05, -0.2, 0.3, 0.0) ) @@ -166,7 +166,7 @@ context("ctwasPipeline") cs_95 = rep("susie_1", 5), stringsAsFactors = FALSE ) - fe <- fineMappingRow(variantIds = vids, susieFit = list(), topLoci = tl) + fe <- FineMappingRow(variantIds = vids, susieFit = list(), topLoci = tl) QtlFineMappingResult( studyName = "Q1", context = "c1", @@ -209,7 +209,8 @@ test_that("ctwasPipeline: rejects a per-region list of GwasSumStats", { expect_error( ctwasPipeline( gwasSumStats = list(block1 = ss, block2 = ss), - twasWeights = .ctp_makeTwasWeights() + twasWeights = .ctp_makeTwasWeights(), + method = "susie" ), "must be a GwasSumStats whose elements are LD blocks" ) @@ -220,7 +221,8 @@ test_that("ctwasPipeline: rejects a single-block named list", { expect_error( ctwasPipeline( gwasSumStats = .ctp_makeGwasSumstats(blockIds = "block1"), - twasWeights = list(block1 = .ctp_makeTwasWeights()) + twasWeights = list(block1 = .ctp_makeTwasWeights()), + method = "susie" ), "at least two LD blocks" ) @@ -234,7 +236,8 @@ test_that("ctwasPipeline: rejects un-QCd GwasSumStats in any region", { expect_error( ctwasPipeline( gwasSumStats = ss_noqc, - twasWeights = list(block1 = tw, block2 = tw) + twasWeights = list(block1 = tw, block2 = tw), + method = "susie" ), "has no QC record" ) @@ -249,7 +252,8 @@ test_that("ctwasPipeline: rejects twasWeights keys not present in gwasSumStats", gwasSumStats = .ctp_makeGwasSumstats( blockIds = c("blockA", "blockB") ), - twasWeights = list(blockA = tw, blockC = tw) + twasWeights = list(blockA = tw, blockC = tw), + method = "susie" ), "key.*not present in.*gwasSumStats" ) @@ -269,7 +273,8 @@ test_that("assembleCtwasInputs: allows twasWeights keys to be a subset of gwasSu expect_warning( inputs <- assembleCtwasInputs( gwasSumStats = ss, - twasWeights = list(block1 = tw) + twasWeights = list(block1 = tw), + method = "susie" ), "share 6 variant" ) @@ -290,7 +295,7 @@ test_that("assembleCtwasInputs: accepts a QtlFineMappingResult weight source (to context = "c1", trait = "t1", method = "susie", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = map_chr(1:5, .ctp_snpId), weights = c(0.1, 0.05, -0.2, 0.3, 0.0), weightStandardized = TRUE @@ -304,11 +309,13 @@ test_that("assembleCtwasInputs: accepts a QtlFineMappingResult weight source (to ) itw <- assembleCtwasInputs( gwasSumStats = ss, - twasWeights = list(block1 = tw_std, block2 = tw_std) + twasWeights = list(block1 = tw_std, block2 = tw_std), + method = "susie" ) ifmr <- assembleCtwasInputs( gwasSumStats = ss, - twasWeights = list(block1 = fmr, block2 = fmr) + twasWeights = list(block1 = fmr, block2 = fmr), + method = "susie" ) # Same gene keys, and the resolved weights match the standardized TwasWeights. expect_equal(names(ifmr$weights), names(itw$weights)) @@ -342,13 +349,13 @@ test_that("assembleCtwasInputs: boundary gene fits per-region, spans all", { entry = list(gr), genome = "hg19", ldReference = .ctp_makeHandle(), - qcInfo = if (qc) list(step1 = "ok") else list() + qcOptions = if (qc) list(step1 = "ok") else list() ) } ss1 <- mkBlockGss("G1", map_chr(1:3, .ctp_snpId)) ss2 <- mkBlockGss("G2", map_chr(4:6, .ctp_snpId)) # Cross-boundary weights: v2..v5 (4 variants spanning both blocks). - crossEntry <- twasWeightsRow( + crossEntry <- TwasWeightsRow( variantIds = map_chr(2:5, .ctp_snpId), weights = c(0.1, 0.2, 0.3, 0.4) ) @@ -368,7 +375,8 @@ test_that("assembleCtwasInputs: boundary gene fits per-region, spans all", { mcols(both)$blockId <- c("block1", "block2") inputs <- assembleCtwasInputs( gwasSumStats = both, - twasWeights = list(block1 = tw) + twasWeights = list(block1 = tw), + method = "susie" ) # ctwas fine-maps one region at a time, so the FITTED vector holds only the # variants this block has LD for -- handing susie_rss the other two produces @@ -394,7 +402,8 @@ test_that("ctwasPipeline: a bare TwasWeights is a FLAT source, placed by region" expect_error( ctwasPipeline( gwasSumStats = .ctp_makeGwasSumstats(), - twasWeights = .ctp_makeTwasWeights() + twasWeights = .ctp_makeTwasWeights(), + method = "susie" ), "no `traitPos` provenance" ) @@ -407,7 +416,8 @@ test_that("ctwasPipeline: rejects non-GRanges twasZ", { ctwasPipeline( gwasSumStats = inp$gwasSumStats, twasWeights = inp$twasWeights, - twasZ = "not a GRanges" + twasZ = "not a GRanges", + method = "susie" ), "must be a GRanges" ) @@ -437,7 +447,7 @@ test_that(".ctwasRequireMatchingLdRefs: NULL twas-side handle is allowed", { context = "c1", trait = "t1", method = "susie", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), weights = rep(0.1, 5) )), @@ -456,7 +466,7 @@ test_that(".ctwasRequireMatchingLdRefs: NULL twas-side handle is allowed", { context = "c1", trait = "t1", method = "susie", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), weights = rep(0.1, 3) )), @@ -606,25 +616,27 @@ test_that(".ctwasSnpInfoForGwasBlock: keeps rows the GWAS spells flipped", { expect_equal(keep$id, flippedPanel$id) }) -test_that(".ctwasBuildSingleRegionInfo: pulls chrom + bp span from the GWAS block entry", { - # Bounds come from the block's GWAS variants (the GwasSumStats entry), NOT - # the LD sketch — many blocks can share one whole-chromosome LD payload. - ri <- pecotmr:::.ctwasBuildSingleRegionInfo( - "block1", - .ctp_makeGwasSumstats(blockIds = "block1") +test_that(".ctwasBuildSingleRegionInfo: a given region bounds the block", { + # The LD block a GWAS was split by is its window, however much narrower + # its variants are. + gss <- GwasSumStats( + studyName = "G1", + entry = list(.ctp_blockVariants(1L)), + genome = "hg19", + region = GenomicRanges::GRanges("chr1:1-1000") ) - expect_equal(ri$region_id, "block1") - expect_equal(ri$chrom, 1L) - expect_equal(ri$start, 100L) - expect_equal(ri$stop, 600L) + ri <- pecotmr:::.ctwasBuildSingleRegionInfo("chr1_1_1000", gss) + expect_equal(ri$start, 1L) + expect_equal(ri$stop, 1001L) }) test_that(".ctwasBuildSingleRegionInfo: uses the block entry span, not the wider shared LD sketch", { # Regression: many LD blocks can share one whole-chromosome LD payload, so - # the sketch span (here BP 100-600) is NOT the block's span. The entry here - # covers only 200-400; region bounds must follow the entry, otherwise every - # block collapses to the whole-chromosome span and every SNP is assigned to - # every region (inflating SNP group_size and crushing the gene PIP). + # the sketch span (here BP 100-1200) is NOT the block's span. The entry + # here covers only 200-400; region bounds must follow the entry, otherwise + # every block collapses to the whole-chromosome span and every SNP is + # assigned to every region (inflating SNP group_size and crushing the gene + # PIP). gr <- GenomicRanges::GRanges( seqnames = "chr1", ranges = IRanges::IRanges(start = c(200L, 300L, 400L), width = 1L) @@ -641,11 +653,14 @@ test_that(".ctwasBuildSingleRegionInfo: uses the block entry span, not the wider entry = list(gr), genome = "hg19", ldReference = .ctp_makeHandle(), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) ri <- pecotmr:::.ctwasBuildSingleRegionInfo("blockX", gss) + expect_equal(ri$region_id, "blockX") + expect_equal(ri$chrom, 1L) + # cTWAS reads [start, stop), so stop is one past the window's last base. expect_equal(ri$start, 200L) # entry min, not sketch min (100) - expect_equal(ri$stop, 400L) # entry max, not sketch max (600) + expect_equal(ri$stop, 401L) # one past entry max, not sketch max (1200) }) test_that(".ctwasBuildSingleRegionInfo: multi-chromosome block entry errors", { @@ -665,7 +680,7 @@ test_that(".ctwasBuildSingleRegionInfo: multi-chromosome block entry errors", { entry = list(gr), genome = "hg19", ldReference = .ctp_makeHandle(), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) expect_error( pecotmr:::.ctwasBuildSingleRegionInfo("block1", gss), @@ -719,7 +734,7 @@ test_that(".ctwasLdPanelKey: errors when no candidate file exists", { format = "plink2", snpInfo = data.frame( SNP = "chr1:100:A:G", - CHR = "1", + CHR = "chr1", BP = 100L, A1 = "A", A2 = "G", @@ -819,7 +834,8 @@ test_that("assembleCtwasInputs: each region gets its own block-sized panel", { ) out <- assembleCtwasInputs( gwasSumStats = inp$gwasSumStats, - twasWeights = inp$twasWeights + twasWeights = inp$twasWeights, + method = "susie" ) expect_length(unique(out$LD_map$LD_file), 2L) panels <- pecotmr:::.ctwasCachedPanels(out) @@ -839,7 +855,8 @@ test_that(".ctwasResolveLdPaths: re-mints sentinels lost with the session", { ) out <- assembleCtwasInputs( gwasSumStats = inp$gwasSumStats, - twasWeights = inp$twasWeights + twasWeights = inp$twasWeights, + method = "susie" ) before <- pecotmr:::.ctwasCachedPanels(out) # The sentinels live in the session tempdir; a payload reloaded in a new @@ -855,79 +872,8 @@ test_that(".ctwasResolveLdPaths: re-mints sentinels lost with the session", { expect_equal(loader(tokens[[2L]]), pecotmr:::.ctwasPanelLd(before[[2L]])) }) -test_that(".ctwasResolveMethod: caller-supplied method wins when present", { - e <- twasWeightsRow( - variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), - weights = c(0.1, 0.2, 0.3) - ) - tw <- TwasWeights( - studyName = "Q1", - context = "c1", - trait = "t1", - method = "mrash", - entry = list(e), - ldReference = .ctp_makeHandle() - ) - expect_equal(pecotmr:::.ctwasResolveMethod(list(r1 = tw), "mrash"), "mrash") -}) - -test_that(".ctwasResolveMethod: caller-supplied unknown method errors", { - e <- twasWeightsRow( - variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), - weights = c(0.1, 0.2, 0.3) - ) - tw <- TwasWeights( - studyName = "Q1", - context = "c1", - trait = "t1", - method = "mrash", - entry = list(e), - ldReference = .ctp_makeHandle() - ) - expect_error( - pecotmr:::.ctwasResolveMethod(list(r1 = tw), "bogus"), - "not present in TwasWeights" - ) -}) - -test_that(".ctwasResolveMethod: defaults to ensemble when present among multiple", { - mkTw <- function(m) { - e <- twasWeightsRow( - variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), - weights = c(0.1, 0.2, 0.3) - ) - TwasWeights( - studyName = "Q1", - context = "c1", - trait = "t1", - method = m, - entry = list(e), - ldReference = .ctp_makeHandle() - ) - } - # Build a multi-method TwasWeights by stitching two methods together. - tw <- TwasWeights( - studyName = c("Q1", "Q1"), - context = c("c1", "c1"), - trait = c("t1", "t1"), - method = c("mrash", "ensemble"), - entry = list( - twasWeightsRow( - variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), - weights = c(0.1, 0.2, 0.3) - ), - twasWeightsRow( - variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), - weights = c(0.4, 0.5, 0.6) - ) - ), - ldReference = .ctp_makeHandle() - ) - expect_equal(pecotmr:::.ctwasResolveMethod(list(r1 = tw)), "ensemble") -}) - -test_that(".ctwasResolveMethod: single method auto-picked when only one available", { - e <- twasWeightsRow( +test_that(".ctwasResolveMethod: no-ensemble TwasWeights need `method`", { + e <- TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), weights = c(0.1, 0.2, 0.3) ) @@ -939,35 +885,18 @@ test_that(".ctwasResolveMethod: single method auto-picked when only one availabl entry = list(e), ldReference = .ctp_makeHandle() ) - expect_equal(pecotmr:::.ctwasResolveMethod(list(r1 = tw)), "mrash") -}) - -test_that(".ctwasResolveMethod: multi-method + no ensemble + no caller method errors", { - tw <- TwasWeights( - studyName = c("Q1", "Q1"), - context = c("c1", "c1"), - trait = c("t1", "t1"), - method = c("mrash", "susie"), - entry = list( - twasWeightsRow( - variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), - weights = c(0.1, 0.2, 0.3) - ), - twasWeightsRow( - variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), - weights = c(0.4, 0.5, 0.6) - ) - ), - ldReference = .ctp_makeHandle() - ) + # One method present is still not a default: only "ensemble" is. expect_error( pecotmr:::.ctwasResolveMethod(list(r1 = tw)), - "Supply a `method` argument" + str_c( + "pass `method` to choose the weights\\. These TwasWeights carry ", + "no 'ensemble' weights to default to \\(available: mrash\\)" + ) ) }) # --------------------------------------------------------------------------- -# .ctwasResolveMethods (plural) — the pipeline's fan-out resolver +# .ctwasResolveMethod on the shapes a pipeline hands it # --------------------------------------------------------------------------- .ctp_multiMethodTw <- function(methods = c("mrash", "susie")) { TwasWeights( @@ -976,7 +905,7 @@ test_that(".ctwasResolveMethod: multi-method + no ensemble + no caller method er trait = rep("t1", length(methods)), method = methods, entry = map(methods, function(m) { - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), weights = c(0.1, 0.2, 0.3) ) @@ -985,43 +914,42 @@ test_that(".ctwasResolveMethod: multi-method + no ensemble + no caller method er ) } -test_that(".ctwasResolveMethods: unspecified + multiple + no ensemble -> ALL methods", { - tw <- .ctp_multiMethodTw(c("mrash", "susie")) - expect_setequal( - pecotmr:::.ctwasResolveMethods(list(r1 = tw)), - c("mrash", "susie") - ) -}) - -test_that(".ctwasResolveMethods: ensemble wins, single auto-picks, explicit restricts", { +test_that(".ctwasResolveMethod reads one flat source or a list of them", { + # A flat TwasWeights, and a pre-bucketed list with an empty block. expect_equal( - pecotmr:::.ctwasResolveMethods( - list(r1 = .ctp_multiMethodTw(c("mrash", "ensemble"))) - ), + pecotmr:::.ctwasResolveMethod(.ctp_multiMethodTw(c( + "mrash", + "ensemble" + ))), "ensemble" ) expect_equal( - pecotmr:::.ctwasResolveMethods( - list(r1 = .ctp_multiMethodTw("mrash")) - ), - "mrash" - ) - expect_equal( - pecotmr:::.ctwasResolveMethods( + pecotmr:::.ctwasResolveMethod( list(r1 = .ctp_multiMethodTw(c("mrash", "susie")), r2 = NULL), method = "susie" ), "susie" ) expect_error( - pecotmr:::.ctwasResolveMethods( + pecotmr:::.ctwasResolveMethod( list(r1 = .ctp_multiMethodTw("mrash")), method = "lasso" ), - "not present" + "method 'lasso' not present in the weight sources" ) }) +test_that(".ctwasResolveMethod: a fine-mapping weight source has no default", { + # A fine-mapping result's weights come from one of its methods, and none + # of them is an "ensemble" -- even one named that way would be a guess. + src <- .ctp_makeFmrWeightSource() + expect_error( + pecotmr:::.ctwasResolveMethod(src), + "one of its fine-mapping methods \\(available: susie\\)" + ) + expect_equal(pecotmr:::.ctwasResolveMethod(src, "susie"), "susie") +}) + # --------------------------------------------------------------------------- # .ctwasGwasStudy — single-disease invariant # --------------------------------------------------------------------------- @@ -1041,34 +969,58 @@ test_that(".ctwasGwasStudy: unique study, errors on mixed studies", { # --------------------------------------------------------------------------- # Phase 5: internal LD-block placement (by start(region) == cTWAS p0 rule) # --------------------------------------------------------------------------- -test_that(".ctwasPlaceByAnchor: homes each gene by start(region), half-open, chr-agnostic", { +# Three LD blocks split from one GWAS by their windows, as cTWAS takes them: +# one single-row slice per block, named by its blockId. The variants sit well +# inside each window (chr1:500, chr1:1500, chr22:800). +.ctp_windowGrid <- function() { + gr <- GenomicRanges::GRanges( + c("chr1", "chr1", "chr22"), + IRanges::IRanges(start = c(500L, 1500L, 800L), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = c("chr1:500:G:A", "chr1:1500:G:A", "chr22:800:G:A"), + A1 = "A", + A2 = "G", + Z = 0, + N = 1000L + ) + blocks <- GenomicRanges::GRanges( + c("chr1:1-1000", "chr1:1001-2000", "chr22:1-1000") + ) + names(blocks) <- c("b1", "b2", "b3") + pecotmr:::.ctwasGwasByBlock(GwasSumStats( + studyName = "G1", + entry = list(gr), + genome = "hg19", + region = blocks + )) +} + +test_that(".ctwasPlaceByAnchor homes genes by start(region)", { region <- GenomicRanges::GRanges( - c("chr1", "chr1", "22", "chr2"), + c("chr1", "chr1", "chr22", "chr2"), IRanges::IRanges( start = c(500, 1500, 800, 100), end = c(600, 1600, 900, 200) ) ) - grid <- setNames( - vector("list", 3), - c("chr1_1_1000", "chr1_1000_2000", "chr22_1_1000") - ) - home <- pecotmr:::.ctwasPlaceByAnchor(region, grid) - # chr1:500 -> [1,1000); chr1:1500 -> [1000,2000); "22":800 -> chr22 block - # (chr prefix normalized); chr2 -> no block -> NA. - expect_equal(home, c("chr1_1_1000", "chr1_1000_2000", "chr22_1_1000", NA)) + home <- pecotmr:::.ctwasPlaceByAnchor(region, .ctp_windowGrid()) + # chr22:800 -> the chr22 block; chr2 has no block -> NA. + expect_equal(home, c("b1", "b2", "b3", NA)) }) -test_that(".ctwasPlaceByAnchor: block interval is half-open [start, stop)", { +test_that(".ctwasPlaceByAnchor: a block holds its whole window", { + # chr1:900 lies between block 1's variant (500) and block 2's (1500): the + # window, not the variants, decides. The blocks' names are only names, and + # the last base of a window (1000) is its own, the next (1001) the next + # block's. region <- GenomicRanges::GRanges( "chr1", - IRanges::IRanges(start = c(1000, 999), end = c(1000, 999)) + IRanges::IRanges(start = c(900, 1000, 1001), width = 1) ) - grid <- setNames(vector("list", 2), c("chr1_1_1000", "chr1_1000_2000")) - # start==1000 falls in the SECOND block (>= 1000), 999 in the first. expect_equal( - pecotmr:::.ctwasPlaceByAnchor(region, grid), - c("chr1_1000_2000", "chr1_1_1000") + pecotmr:::.ctwasPlaceByAnchor(region, .ctp_windowGrid()), + c("b1", "b1", "b2") ) }) @@ -1087,7 +1039,7 @@ test_that(".ctwasIsPreBucketed / .ctwasCombineWeightSources: dispatch flat vs pr test_that(".ctwasBucketWeights: places a flat 2-gene source into its home blocks", { mkE <- function() { - twasWeightsRow( + TwasWeightsRow( variantIds = map_chr(1:5, .ctp_snpId), weights = c(0.1, 0.05, -0.2, 0.3, 0.0) ) @@ -1300,11 +1252,11 @@ test_that(".ctwasFilterMethod: subsets rows to the requested method", { trait = c("t1", "t1"), method = c("mrash", "susie"), entry = list( - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), weights = c(0.1, 0.2, 0.3) ), - twasWeightsRow( + TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), weights = c(0.4, 0.5, 0.6) ) @@ -1329,46 +1281,40 @@ test_that(".ctwasFilterMethod: subsets rows to the requested method", { list(R = R, snpInfo = snpInfo, variance = variance) } -test_that(".ctwasBuildWeights: scales non-standardized weights by sqrt(variance)", { +test_that(".ctwasBuildWeights: only raw weights are scaled by sqrt(variance)", { panel <- .ctp_makeLdPanel() # Replace the default unit variance with non-trivial values; raw # weights should be multiplied by sqrt(variance) before reaching the - # final wgt matrix. - panel$variance <- setNames(c(0.5, 1, 2, 4, 8, 16), panel$snpInfo$id) - ids5 <- map_chr(1:5, .ctp_snpId) - rawW <- c(0.1, 0.2, 0.3, 0.4, 0.5) - tw <- TwasWeights( - studyName = "Q1", - context = "c1", - trait = "t1", - method = "susie", - entry = list(twasWeightsRow(variantIds = ids5, weights = rawW)), - ldReference = .ctp_makeHandle() - ) - wl <- pecotmr:::.ctwasBuildWeights(tw, panel) - expected <- unname(rawW * sqrt(panel$variance[ids5])) - expect_equal(as.numeric(wl[[1L]]$wgt), expected, tolerance = 1e-12) -}) - -test_that(".ctwasBuildWeights: standardized weights bypass variance scaling", { - panel <- .ctp_makeLdPanel() + # final wgt matrix, and standardized weights bypass the scaling. panel$variance <- setNames(c(0.5, 1, 2, 4, 8, 16), panel$snpInfo$id) ids5 <- map_chr(1:5, .ctp_snpId) rawW <- c(0.1, 0.2, 0.3, 0.4, 0.5) - tw <- TwasWeights( - studyName = "Q1", - context = "c1", - trait = "t1", - method = "susie", - entry = list(twasWeightsRow( - variantIds = ids5, - weights = rawW, - weightStandardized = TRUE - )), - ldReference = .ctp_makeHandle() - ) - wl <- pecotmr:::.ctwasBuildWeights(tw, panel) - expect_equal(as.numeric(wl[[1L]]$wgt), rawW, tolerance = 1e-12) + for (standardized in c(FALSE, TRUE)) { + tw <- TwasWeights( + studyName = "Q1", + context = "c1", + trait = "t1", + method = "susie", + entry = list(TwasWeightsRow( + variantIds = ids5, + weights = rawW, + weightStandardized = standardized + )), + ldReference = .ctp_makeHandle() + ) + wl <- pecotmr:::.ctwasBuildWeights(tw, panel) + expected <- if (standardized) { + rawW + } else { + unname(rawW * sqrt(panel$variance[ids5])) + } + expect_equal( + as.numeric(wl[[1L]]$wgt), + expected, + tolerance = 1e-12, + info = str_c("weightStandardized = ", standardized) + ) + } }) # Build an LD-panel fixture with realistic chr:pos:A2:A1 variant IDs so @@ -1450,54 +1396,6 @@ test_that(".ctwasIsSusieFit: recognizes the susie intermediate shape", { ))) }) -test_that(".ctwasRenormalizeSusieWeights: alpha renorm + colSums", { - # Original fit covers 4 variants; drop variant 4, renormalize over {1,2,3}. - origVids <- sprintf("chr1:%d:A:G", 100L * (1:4)) - origW <- c(0.1, 0.2, 0.3, 0.4) - # Toy lbf_variable: 2 effects, 4 variants. Constructed so the kept - # subset yields easily-predictable softmax weights. - lbf <- rbind( - c(0, 0, 0, 100), # effect 1: only v4 has signal - c(10, 0, -10, 0) - ) # effect 2: v1 dominates - mu <- matrix(c(1, 2, 3, 4, 1, 2, 3, 4), nrow = 2, byrow = TRUE) - xCol <- rep(1, 4) - fits <- list( - alpha = lbfToAlpha(lbf), - mu = mu, - X_column_scale_factors = xCol - ) - out <- pecotmr:::.ctwasRenormalizeSusieWeights( - fits, - origVids = origVids, - origW = origW, - keptIdx = c(1L, 2L, 3L), - harmonizedW = origW[1:3] - ) - # Effect 1 lbf over {v1,v2,v3} = c(0,0,0) -> uniform alpha = 1/3 - # Effect 2 lbf over {v1,v2,v3} = c(10,0,-10) -> v1 ≈ 1 - # weight[v1] = (1/3)*1 + ~1*1 = ~1.33 - expect_equal(length(out), 3L) - expect_true(out[[1L]] > out[[2L]] && out[[1L]] > out[[3L]]) -}) - -test_that(".ctwasRenormalizeSusieWeights: returns NULL on fit/entry dimension mismatch", { - fits <- list( - alpha = matrix(1 / 5, 2, 5), - mu = matrix(0, 2, 5), - X_column_scale_factors = rep(1, 5) - ) - out <- pecotmr:::.ctwasRenormalizeSusieWeights( - fits, - # entry says 3, fit covers 5 -> mismatch - origVids = sprintf("chr1:%d:A:G", 100L * (1:3)), - origW = rep(0.1, 3), - keptIdx = 1:3, - harmonizedW = rep(0.1, 3) - ) - expect_null(out) -}) - test_that(".ctwasRenormalizeSusieWeights: signFlip carries over to mu", { # All variants kept; harmonized weights have opposite sign on v2. origVids <- sprintf("chr1:%d:A:G", 100L * (1:3)) @@ -1570,56 +1468,20 @@ test_that(".ctwasRenormalizeSusieWeights: honours a non-uniform prior", { ) }) -test_that(".ctwasRenormalizeSusieWeights: skips Omega-weighted susieInf fits", { - # coef.susie for susieInf / susieAsh is colSums(alpha * mu)/scale + - # theta/scale. Recomputing from alpha and mu alone would drop theta, so - # these fits fall back to the plain subset-w-and-R path instead. - origVids <- sprintf("chr1:%d:A:G", 100L * (1:4)) - origW <- c(0.1, 0.2, 0.3, 0.4) - base <- list( - alpha = lbfToAlpha(rbind(c(2, 0, -2, 0), c(0, 2, 0, -2))), - mu = rbind(c(1, 2, 3, 4), c(1, 2, 3, 4)), - X_column_scale_factors = rep(1, 4) - ) - args <- list( - origVids = origVids, - origW = origW, - keptIdx = c(1L, 2L, 3L), - harmonizedW = origW[1:3] - ) - expect_type( - exec(pecotmr:::.ctwasRenormalizeSusieWeights, !!!c(list(base), args)), - "double" - ) - withTheta <- c(base, list(theta = rep(0.1, 4))) - expect_null(exec( - pecotmr:::.ctwasRenormalizeSusieWeights, - !!!c(list(withTheta), args) - )) - withOmega <- c(base, list(omega_weights = rep(1, 4))) - expect_null(exec( - pecotmr:::.ctwasRenormalizeSusieWeights, - !!!c(list(withOmega), args) - )) -}) - test_that(".ctwasSnpInfoForGwasBlock: restricts panel snpInfo to block GWAS variants", { - ss <- .ctp_makeGwasSumstats() + # Block 1's GWAS rows (variants 1..6) against the whole 12-variant panel. + ss <- .ctp_makeGwasSumstats(blockIds = "block1") panelInfo <- data.frame( chrom = 1L, - id = map_chr(1:6, .ctp_snpId), # whole panel - pos = seq(100L, by = 100L, length.out = 6L), + id = map_chr(1:12, .ctp_snpId), # whole panel + pos = seq(100L, by = 100L, length.out = 12L), alt = "A", ref = "G", stringsAsFactors = FALSE ) blockInfo <- pecotmr:::.ctwasSnpInfoForGwasBlock(ss, panelInfo) - # Restricted to the variant IDs on the GwasSumStats entry. - expect_true(all( - blockInfo$id %in% - as.character(S4Vectors::mcols(ss[[1L]])$SNP) - )) - expect_true(nrow(blockInfo) <= nrow(panelInfo)) + # Restricted to the variant IDs on the GwasSumStats entry, in panel order. + expect_equal(blockInfo$id, map_chr(1:6, .ctp_snpId)) }) test_that(".ctwasBuildWeights: keys per-tuple weights, adds gene metadata", { @@ -1655,7 +1517,7 @@ test_that(".ctwasBuildWeights: drops variants not present in the LD panel", { context = "c1", trait = "t1", method = "susie", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = c(ids3, missing), weights = c(0.1, 0.2, 0.3, 0.4, 0.5) )), @@ -1680,7 +1542,7 @@ test_that(".ctwasBuildWeights: intersects with gwasSnpIds when supplied", { context = "c1", trait = "t1", method = "susie", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = ids5, weights = c(0.1, 0.2, 0.3, 0.4, 0.5) )), @@ -1791,7 +1653,7 @@ test_that(".ctwasGlobalPanelInfo: NULL when the collection has no sketch", { entry = list(.ctp_blockVariants(1L)), genome = "hg19", blockId = "block1", - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) expect_identical(ldReference(gs), list()) # .ctwasRegionGwasLd reports the missing-sketch case with its own @@ -1962,7 +1824,8 @@ test_that("assembleCtwasInputs: assembles the documented input shape for ctwas", ) inputs <- assembleCtwasInputs( gwasSumStats = inp$gwasSumStats, - twasWeights = inp$twasWeights + twasWeights = inp$twasWeights, + method = "susie" ) # Two regions, two LD_map rows. expect_equal(nrow(inputs$region_info), 2L) @@ -1997,7 +1860,8 @@ test_that("assembleCtwasInputs: forwards a twasZ argument as z_gene", { inputs <- assembleCtwasInputs( gwasSumStats = inp$gwasSumStats, twasWeights = inp$twasWeights, - twasZ = twasZ + twasZ = twasZ, + method = "susie" ) expect_equal(inputs$z_gene$id, "Q1|c1|t1|susie") }) @@ -2064,7 +1928,8 @@ test_that("ctwasPipeline: dispatches assemble → est → screen → finemap and ) out <- ctwasPipeline( gwasSumStats = inp$gwasSumStats, - twasWeights = inp$twasWeights + twasWeights = inp$twasWeights, + method = "susie" ) # Each ctwas step was invoked exactly once. expect_true(length(capturedAssemble) > 0L) @@ -2077,7 +1942,8 @@ test_that("ctwasPipeline: dispatches assemble → est → screen → finemap and expect_equal(unname(capturedScreen$group_prior), c(0.1, 0.0001)) # finemap consumes screen's screened_region_data. expect_named(capturedFinemap$region_data, "block1") - # Output is a CtwasResult: one (gwasStudy, study, context, method) row. + # Output is a CtwasResult: one row per (run, region), and this run's + # genes, placed without a region_id, share one chromosome. expect_s4_class(out, "CtwasResult") expect_equal(nrow(out), 1L) expect_equal(methodNames(out), "susie") @@ -2085,21 +1951,23 @@ test_that("ctwasPipeline: dispatches assemble → est → screen → finemap and expect_equal(contexts(out), "c1") expect_equal(as.character(out$gwasStudy), "G1") # The run's jointly-estimated param is carried on the row. - expect_equal( - unname(ctwasGroupPriors(out$entry[[1L]])$group_prior), - c(0.1, 0.0001) - ) + expect_equal(unname(out$groupPriors[[1L]]$group_prior), c(0.1, 0.0001)) # ctwasPosteriors aggregates the per-gene rows, tagged with run identity. fm <- ctwasPosteriors(out) - expect_equal(nrow(fm), 2L) + expect_s4_class(fm, "GRanges") + expect_equal(length(fm), 2L) expect_true(all( - c("gwasStudy", "study", "context", "method", "susie_pip") %in% names(fm) + c("gwasStudy", "study", "context", "method", "susie_pip") %in% + names(S4Vectors::mcols(fm)) )) expect_setequal(fm$id, c("block1|Q1|c1|t1|susie", "block2|Q1|c1|t1|susie")) # susieAlpha aggregates the fuller per-effect table, likewise tagged. sa <- susieAlpha(out) - expect_equal(nrow(sa), 2L) - expect_true(all(c("gwasStudy", "context", "susie_alpha") %in% names(sa))) + expect_equal(length(sa), 2L) + expect_true(all( + c("gwasStudy", "context", "susie_alpha") %in% + names(S4Vectors::mcols(sa)) + )) }) test_that("ctwasPipeline: keepSnps retains the SNP background as a dedicated row", { @@ -2144,7 +2012,12 @@ test_that("ctwasPipeline: keepSnps retains the SNP background as a dedicated row extractBlockGenotypes = .ctp_mockExtractor(), .package = "pecotmr" ) - out <- ctwasPipeline(inp$gwasSumStats, inp$twasWeights, keepSnps = TRUE) + out <- ctwasPipeline( + inp$gwasSumStats, + inp$twasWeights, + keepSnps = TRUE, + method = "susie" + ) # A gene (c1) row plus the dedicated SNP row. expect_equal(nrow(out), 2L) expect_setequal(contexts(out), c("c1", "SNP")) @@ -2175,7 +2048,11 @@ test_that("ctwasPipeline: keepSnps retains the SNP background as a dedicated row ), z_snp = data.frame(id = "chr1:100:G:A", z = 1.0), z_gene = data.frame(id = "block1|Q1|c1|t1|susie", z = 2.0), - weights = setNames(list(list(wgt = 1)), "block1|Q1|c1|t1|susie"), + # Placed by chrom / p0 / p1, as ctwas's own weights are. + weights = setNames( + list(list(wgt = 1, chrom = 1, p0 = 100L, p1 = 100L)), + "block1|Q1|c1|t1|susie" + ), snp_map = list(block1 = data.frame(id = "chr1:100:G:A")), param = list( group_prior = c(c1 = 0.1, SNP = 1e-4), @@ -2214,30 +2091,6 @@ test_that("ctwasPipeline: keepSnps retains the SNP background as a dedicated row ) } -test_that("mergeCtwasBoundaryRegions: LD path splices updated_* back + merge_res", { - skip_if_not_installed("ctwas") - captured <- NULL - local_mocked_bindings( - postprocess_region_merging = function(...) { - captured <<- list(...) - .ctp_mergeReturn() - }, - .package = "ctwas" - ) - out <- mergeCtwasBoundaryRegions( - .ctp_finemapResult(hasLd = TRUE), - pipThresh = 0.5 - ) - # LD path passed the loader closures + pip_thresh through. - expect_equal(captured$pip_thresh, 0.5) - expect_true(is.function(captured$LD_loader_fun)) - # updated_* spliced onto the result; merge_res carries the full postprocess out. - expect_equal(out$finemap_res$susie_pip, 0.99) - expect_equal(out$susie_alpha_res$susie_alpha, 0.99) - expect_equal(out$region_info$region_id, "block1_merged") - expect_true(!is.null(out$merge_res)) -}) - test_that("mergeCtwasBoundaryRegions passes no unnamed argument to ctwas", { skip_if_not_installed("ctwas") # Regression: methodArgs was merged with c(), which appends a MethodOptions @@ -2285,17 +2138,6 @@ test_that("mergeCtwasBoundaryRegions: no-LD path uses postprocess_region_merging expect_equal(out$finemap_res$susie_pip, 0.99) }) -test_that("mergeCtwasBoundaryRegions: empty first-pass finemap returns unchanged", { - skip_if_not_installed("ctwas") - fmr <- .ctp_finemapResult() - fmr$finemap_res <- fmr$finemap_res[0, ] - expect_message( - out <- mergeCtwasBoundaryRegions(fmr), - "no first-pass finemap" - ) - expect_null(out$merge_res) -}) - test_that("ctwasPipeline: mergeBoundary = TRUE re-fine-maps and flows into CtwasResult", { skip_if_not_installed("ctwas") inp <- .ctp_makeMultiBlockInputs() @@ -2355,7 +2197,8 @@ test_that("ctwasPipeline: mergeBoundary = TRUE re-fine-maps and flows into Ctwas out <- ctwasPipeline( inp$gwasSumStats, inp$twasWeights, - boundaryMergeParam = BoundaryMergeParam(enabled = TRUE) + boundaryMergeParam = BoundaryMergeParam(enabled = TRUE), + method = "susie" ) expect_true(merged) # merging ran expect_s4_class(out, "CtwasResult") @@ -2442,10 +2285,17 @@ test_that("estCtwasGroupPriors: fallbackToPrefit recovers from accurate-EM NaN d extractBlockGenotypes = .ctp_mockExtractor(), .package = "pecotmr" ) + # Assembled once; the two estimation calls below differ only in the + # fallback setting. + inputs <- assembleCtwasInputs( + inp$gwasSumStats, + inp$twasWeights, + method = "susie" + ) # Without fallback: the NaN error propagates. expect_error( estCtwasGroupPriors( - assembleCtwasInputs(inp$gwasSumStats, inp$twasWeights), + inputs, ctwasPriorParam = CtwasPriorParam(fallbackToPrefit = FALSE) ), "contains NAs" @@ -2455,7 +2305,7 @@ test_that("estCtwasGroupPriors: fallbackToPrefit recovers from accurate-EM NaN d # est_param), so the mocked SNP prior 1e-4 emerges as 1e-4 * thin # (default thin = 0.1) → 1e-5. The group_prior_var is not thinned. est <- estCtwasGroupPriors( - assembleCtwasInputs(inp$gwasSumStats, inp$twasWeights), + inputs, ctwasPriorParam = CtwasPriorParam(fallbackToPrefit = TRUE) ) expect_equal(unname(est$param$group_prior), c(0.05, 1e-5)) @@ -2498,7 +2348,11 @@ test_that("estCtwasGroupPriors fallback drops degenerate regions before fit_EM", .package = "pecotmr" ) est <- estCtwasGroupPriors( - assembleCtwasInputs(inp$gwasSumStats, inp$twasWeights), + assembleCtwasInputs( + inp$gwasSumStats, + inp$twasWeights, + method = "susie" + ), ctwasPriorParam = CtwasPriorParam(fallbackToPrefit = TRUE) ) # only the qualifying region reached fit_EM; the degenerate region was filtered @@ -2531,7 +2385,7 @@ test_that("(real ctwas) prefit fallback skips a degenerate region fit_EM would r niter = 3L, groupPriorVarStructure = "shared_all", thin = 1, - numThreads = 1L + threads = 1L ), "EM did not converge in 3 iterations" ) @@ -2574,7 +2428,11 @@ test_that("estCtwasGroupPriors / screenCtwasRegions / finemapCtwasRegions can be .package = "pecotmr" ) # Step 1 - inputs <- assembleCtwasInputs(inp$gwasSumStats, inp$twasWeights) + inputs <- assembleCtwasInputs( + inp$gwasSumStats, + inp$twasWeights, + method = "susie" + ) expect_true("region_info" %in% names(inputs)) expect_true("LD_loader_fun" %in% names(inputs)) # Step 2 @@ -2631,11 +2489,11 @@ test_that("ctwasPipeline: real-engine end-to-end on the bundled example panel", # with no genes in it, so a real partition needs a gene on both sides -- # the previous per-region list dodged this by putting the SAME GWAS block # and the SAME gene under two region ids. - geneOne <- twasWeightsRow( + geneOne <- TwasWeightsRow( variantIds = .ctp_panelSnpInfo(gh)$SNP[1:5], weights = c(0.1, -0.2, 0.05, 0.0, 0.3) ) - geneTwo <- twasWeightsRow( + geneTwo <- TwasWeightsRow( variantIds = .ctp_panelSnpInfo(gh)$SNP[9:13], weights = c(0.2, 0.1, -0.15, 0.05, 0.0) ) @@ -2678,8 +2536,8 @@ test_that("ctwasPipeline: real-engine end-to-end on the bundled example panel", entry = list(unlist(gss)), genome = unique(unname(GenomeInfoDb::genome(gss))), ldReference = ldReference(gss), - qcInfo = qcInfo(gss), - ldBlocks = twoBlocks + qcOptions = qcOptions(gss), + region = twoBlocks ) res <- suppressMessages(suppressWarnings( ctwasPipeline( @@ -2696,7 +2554,8 @@ test_that("ctwasPipeline: real-engine end-to-end on the bundled example panel", min_group_size = 1L, min_p_single_effect = 0 ) - ) + ), + method = "susie" ) )) @@ -2711,9 +2570,10 @@ test_that("ctwasPipeline: real-engine end-to-end on the bundled example panel", # The gene we passed in was fine-mapped and shows up in the aggregated # finemap table, tagged with the run identity. fm <- ctwasPosteriors(res) - expect_true(!is.null(fm) && nrow(fm) > 0L) + expect_gt(length(fm), 0L) expect_true(all( - c("gwasStudy", "study", "context", "method", "susie_pip") %in% names(fm) + c("gwasStudy", "study", "context", "method", "susie_pip") %in% + names(S4Vectors::mcols(fm)) )) # Either gene may survive ctwas's region screen; what matters here is that # a fine-mapped gene carries the full run identity in its id. @@ -2727,12 +2587,15 @@ test_that("ctwasPipeline: real-engine end-to-end on the bundled example panel", expect_true(all(fm$context == "brain")) # The fuller per-effect table is retained and reconstructable. sa <- susieAlpha(res) - expect_true(!is.null(sa) && nrow(sa) > 0L) - expect_true(all(c("susie_pip", "susie_alpha", "region_id") %in% names(sa))) + expect_gt(length(sa), 0L) + expect_true(all( + c("susie_pip", "susie_alpha", "region_id") %in% + names(S4Vectors::mcols(sa)) + )) }) # =========================================================================== -# .ctwasFilterVariants — ported from R/ctwasWrapper.R::trimCtwasVariants +# .ctwasFilterVariants # =========================================================================== # The filter has four knobs: # 1. twasWeightCutoff — drop |w| < cutoff @@ -2833,53 +2696,45 @@ test_that(".ctwasFilterVariants: returns NULL when no variants survive", { expect_null(out) }) -test_that(".ctwasBuildWeights: maxNumVariants caps the per-gene weight matrix", { +test_that(".ctwasBuildWeights: the variant cap and weight cutoff apply", { data(qtlDatasetExample) - qd <- qtlDatasetExample - gh <- pecotmr:::.qtlGenotypeSe(qd) + gh <- pecotmr:::.qtlGenotypeSe(qtlDatasetExample) vids <- .ctp_panelSnpInfo(gh)$SNP[1:5] - ent <- twasWeightsRow( - variantIds = vids, - weights = c(0.1, -0.2, 0.05, 0.3, 0.15) - ) - tw <- TwasWeights( - studyName = "study1", - context = "brain", - trait = "ENSG_example", - method = "susie", - entry = list(ent), - ldReference = gh - ) ldPanel <- .ctp_fullPanel(gh) - wl <- pecotmr:::.ctwasBuildWeights(tw, ldPanel, maxNumVariants = 3L) - expect_equal(wl[[1L]]$n_wgt, 3L) - expect_equal(nrow(wl[[1L]]$wgt), 3L) - # Top 3 by |w| from c(0.1, -0.2, 0.05, 0.3, 0.15): 0.3, -0.2, 0.15 - expect_setequal(rownames(wl[[1L]]$wgt), vids[c(4L, 2L, 5L)]) -}) - -test_that(".ctwasBuildWeights: twasWeightCutoff drops low-magnitude variants", { - data(qtlDatasetExample) - qd <- qtlDatasetExample - gh <- pecotmr:::.qtlGenotypeSe(qd) - vids <- .ctp_panelSnpInfo(gh)$SNP[1:5] - ent <- twasWeightsRow( - variantIds = vids, - # v1 (0.005) and v3 (0.001) will be dropped at cutoff 0.01 - weights = c(0.005, 0.2, 0.001, 0.3, 0.1) - ) - tw <- TwasWeights( - studyName = "study1", - context = "brain", - trait = "ENSG_example", - method = "susie", - entry = list(ent), - ldReference = gh + # Each case: the weights, the filter setting, and the variants kept. + cases <- list( + # Top 3 by |w| from c(0.1, -0.2, 0.05, 0.3, 0.15): 0.3, -0.2, 0.15 + maxNumVariants = list( + c(0.1, -0.2, 0.05, 0.3, 0.15), + list(maxNumVariants = 3L), + c(4L, 2L, 5L) + ), + # v1 (0.005) and v3 (0.001) fall below the 0.01 cutoff + twasWeightCutoff = list( + c(0.005, 0.2, 0.001, 0.3, 0.1), + list(twasWeightCutoff = 0.01), + c(2L, 4L, 5L) + ) ) - ldPanel <- .ctp_fullPanel(gh) - wl <- pecotmr:::.ctwasBuildWeights(tw, ldPanel, twasWeightCutoff = 0.01) - expect_equal(wl[[1L]]$n_wgt, 3L) - expect_setequal(rownames(wl[[1L]]$wgt), vids[c(2L, 4L, 5L)]) + for (nm in names(cases)) { + cs <- cases[[nm]] + tw <- TwasWeights( + studyName = "study1", + context = "brain", + trait = "ENSG_example", + method = "susie", + entry = list(TwasWeightsRow(variantIds = vids, weights = cs[[1L]])), + ldReference = gh + ) + wl <- exec(pecotmr:::.ctwasBuildWeights, tw, ldPanel, !!!cs[[2L]]) + expect_equal(wl[[1L]]$n_wgt, 3L, info = nm) + expect_equal(nrow(wl[[1L]]$wgt), 3L, info = nm) + expect_equal( + sort(rownames(wl[[1L]]$wgt)), + sort(vids[cs[[3L]]]), + info = nm + ) + } }) # =========================================================================== @@ -2887,13 +2742,18 @@ test_that(".ctwasBuildWeights: twasWeightCutoff drops low-magnitude variants", { # =========================================================================== test_that("mergeCtwasBoundaryRegions: no first-pass finemap_res returns unchanged", { + skip_if_not_installed("ctwas") fmr <- list(finemap_res = NULL, region_data = "rd") - expect_identical(mergeCtwasBoundaryRegions(fmr), fmr) + expect_message( + expect_identical(mergeCtwasBoundaryRegions(fmr), fmr), + "no first-pass finemap" + ) fmr0 <- list(finemap_res = data.frame()[0, ], region_data = "rd") - expect_identical(mergeCtwasBoundaryRegions(fmr0), fmr0) + expect_identical(suppressMessages(mergeCtwasBoundaryRegions(fmr0)), fmr0) }) test_that("mergeCtwasBoundaryRegions: LD path forwards carried state + splices updated_*", { + skip_if_not_installed("ctwas") captured <- NULL local_mocked_bindings( postprocess_region_merging = function(...) { @@ -2929,6 +2789,7 @@ test_that("mergeCtwasBoundaryRegions: LD path forwards carried state + splices u expect_true(all( c("LD_map", "LD_loader_fun", "snpinfo_loader_fun") %in% names(captured) )) + expect_true(is.function(captured$LD_loader_fun)) expect_equal(captured$pip_thresh, 0.5) expect_equal(captured$maxSNP, 100) expect_identical(captured$region_data, "rd") @@ -2943,36 +2804,6 @@ test_that("mergeCtwasBoundaryRegions: LD path forwards carried state + splices u expect_identical(out$merge_res$selected_boundary_genes$id, "g") }) -test_that("mergeCtwasBoundaryRegions: no-LD path used when LD loaders are absent", { - called <- NULL - local_mocked_bindings( - postprocess_region_merging_noLD = function(...) { - called <<- "noLD" - list( - updated_finemap_res = data.frame(id = "g"), - updated_susie_alpha_res = NULL - ) - }, - .package = "ctwas" - ) - fmr <- list( - finemap_res = data.frame(id = "g", type = "gene", susie_pip = 0.6), - susie_alpha_res = NULL, - region_data = "rd", - region_info = "ri", - z_snp = "zs", - z_gene = data.frame(id = "g"), - weights = "w", - snp_map = "sm", - LD_map = NULL, - LD_loader_fun = NULL, - snpinfo_loader_fun = NULL, - param = list(group_prior = 0.1, group_prior_var = 5) - ) - out <- mergeCtwasBoundaryRegions(fmr) - expect_equal(called, "noLD") -}) - # =========================================================================== # assembleCtwasInputs: remaining input-validation branches # --------------------------------------------------------------------------- @@ -2981,19 +2812,6 @@ test_that("mergeCtwasBoundaryRegions: no-LD path used when LD loaders are absent # guard would surface a different error). # =========================================================================== -test_that("assembleCtwasInputs: rejects an unnamed gwasSumStats list", { - skip_if_not_installed("ctwas") - ss <- .ctp_makeGwasSumstats() - tw <- .ctp_makeTwasWeights() - expect_error( - assembleCtwasInputs( - gwasSumStats = list(ss, ss), # unnamed - twasWeights = list(block1 = tw) - ), - "must be a GwasSumStats whose elements are LD blocks" - ) -}) - test_that("assembleCtwasInputs: an unnamed twasWeights list is a FLAT source (needs region)", { skip_if_not_installed("ctwas") ss <- .ctp_makeGwasSumstats() @@ -3003,7 +2821,8 @@ test_that("assembleCtwasInputs: an unnamed twasWeights list is a FLAT source (ne expect_error( assembleCtwasInputs( gwasSumStats = ss, - twasWeights = list(tw) + twasWeights = list(tw), + method = "susie" ), # unnamed -> flat "no `traitPos` provenance" ) @@ -3015,7 +2834,8 @@ test_that("assembleCtwasInputs: rejects a non-GwasSumStats gwas input", { expect_error( assembleCtwasInputs( gwasSumStats = "not a GwasSumStats", - twasWeights = list(block1 = tw) + twasWeights = list(block1 = tw), + method = "susie" ), "must be a GwasSumStats whose elements are LD blocks" ) @@ -3027,13 +2847,14 @@ test_that("assembleCtwasInputs: rejects a weight source that is neither TwasWeig expect_error( assembleCtwasInputs( gwasSumStats = ss, - twasWeights = list(block1 = "not a weight source") + twasWeights = list(block1 = "not a weight source"), + method = "susie" ), "must be a TwasWeights or QtlFineMappingResult" ) }) -test_that("assembleCtwasInputs: rejects a non-FineMappingResultBase fineMappingResult", { +test_that("assembleCtwasInputs: the rescue source is a QtlFineMappingResult", { skip_if_not_installed("ctwas") ss <- .ctp_makeGwasSumstats() tw <- .ctp_makeTwasWeights() @@ -3041,9 +2862,27 @@ test_that("assembleCtwasInputs: rejects a non-FineMappingResultBase fineMappingR assembleCtwasInputs( gwasSumStats = ss, twasWeights = list(block1 = tw), - fineMappingResult = "not a fine-mapping result" + fineMappingResult = "not a fine-mapping result", + method = "susie" ), - "must be a FineMappingResultBase" + "must be a QtlFineMappingResult" + ) + # A GWAS result is keyed by a study and method no gene shares, so it can + # only ever have matched a gene by a coincidence of names. + tl <- data.frame(variant_id = "chr1:100:A:G", pip = 0.5) + gwasFmr <- GwasFineMappingResult( + studyName = "Q1", + method = "susie", + entry = list(FineMappingRow(tl$variant_id, NULL, tl)) + ) + expect_error( + assembleCtwasInputs( + gwasSumStats = ss, + twasWeights = list(block1 = tw), + fineMappingResult = gwasFmr, + method = "susie" + ), + "the genes' own fine-mapping" ) }) @@ -3057,7 +2896,7 @@ test_that("assembleCtwasInputs: skips a block whose TwasWeights lacks the resolv context = "c1", trait = "t1", method = m, - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = ids5, weights = c(0.1, 0.2, 0.3, 0.4, 0.5) )), @@ -3069,8 +2908,7 @@ test_that("assembleCtwasInputs: skips a block whose TwasWeights lacks the resolv .package = "pecotmr" ) # Resolved method is "ensemble" (present in block1); block2 carries only - # "mrash", so .ctwasFilterMethod returns NULL and the block is skipped - # in the second pass (the `if (is.null(twMethod)) next` branch). + # "mrash", so .ctwasFilterMethod returns NULL and the block is skipped. inputs <- assembleCtwasInputs( gwasSumStats = ss, twasWeights = list(block1 = mkTw("ensemble"), block2 = mkTw("mrash")) @@ -3081,20 +2919,16 @@ test_that("assembleCtwasInputs: skips a block whose TwasWeights lacks the resolv }) # =========================================================================== -# .ctwasResolveMethod / .ctwasFilterMethod edge branches +# .ctwasFilterMethod edge branch # =========================================================================== -test_that(".ctwasResolveMethod: errors when no method entries exist", { - expect_error(pecotmr:::.ctwasResolveMethod(list()), "no method entries") -}) - test_that(".ctwasFilterMethod: returns NULL when no row matches the method", { tw <- .ctp_makeTwasWeights() # method == "susie" expect_null(pecotmr:::.ctwasFilterMethod(tw, "mrash")) }) # =========================================================================== -# .ctwasHarmonizeWeights / .ctwasRenormalizeSusieWeights early NULL returns +# .ctwasHarmonizeWeights early NULL returns # =========================================================================== test_that(".ctwasHarmonizeWeights: returns NULL when there is nothing to parse", { @@ -3135,38 +2969,10 @@ test_that(".ctwasHarmonizeWeights: returns NULL when harmonizeAlleles fails", { )) }) -test_that(".ctwasRenormalizeSusieWeights: returns NULL when fit components are NULL", { - fits <- list( - lbf_variable = NULL, - mu = matrix(0, 2, 3), - X_column_scale_factors = rep(1, 3) - ) - expect_null(pecotmr:::.ctwasRenormalizeSusieWeights( - fits, - origVids = sprintf("chr1:%d:A:G", 100L * (1:3)), - origW = rep(0.1, 3), - keptIdx = 1:3, - harmonizedW = rep(0.1, 3) - )) -}) - # =========================================================================== # .ctwasBuildWeights: per-gene skip branches + variance / renorm paths # =========================================================================== -test_that("TwasWeightsRow: rejects mismatched variantIds/weights lengths", { - # The weights are per-variant mcols on the entry's element now, so a - # length mismatch cannot be represented. It is refused at construction - # rather than producing a gene that gets silently dropped downstream. - expect_error( - twasWeightsRow( - variantIds = map_chr(1:5, .ctp_snpId), - weights = c(0.1, 0.2, 0.3) - ), - "length\\(weights\\) is 3 but 5 variants were supplied" - ) -}) - test_that(".ctwasBuildWeights: skips a gene when harmonization yields nothing", { local_mocked_bindings( .ctwasHarmonizeWeights = function(...) NULL, @@ -3208,7 +3014,7 @@ test_that(".ctwasBuildWeights: SuSiE renormalization fires when variants are dro mu = rbind(c(1, 2, 3, 4, 5), c(6, 7, 8, 9, 10)), X_column_scale_factors = rep(1, 5L) ) - ent <- twasWeightsRow( + ent <- TwasWeightsRow( variantIds = c(ids4, bogus), weights = c(0.1, 0.2, 0.3, 0.4, 0.5), methodFits = fits @@ -3272,9 +3078,9 @@ test_that(".ctwasGetFinemapAux: parses pip + cs_95 membership + purity", { context = "c1", trait = "t1", method = "susie", - entry = list(fineMappingRow(tl$variant_id, NULL, tl)) + entry = list(FineMappingRow(tl$variant_id, NULL, tl)) ) - aux <- pecotmr:::.ctwasGetFinemapAux(fmr, "Q1", "c1", "t1", "susie") + aux <- pecotmr:::.ctwasGetFinemapAux(fmr, "Q1", "c1", "t1") expect_equal(aux$pip[["chr1:200:G:A"]], 0.6) expect_length(aux$csMembers, 2L) expect_setequal(aux$csMembers[[1L]], c("chr1:100:G:A", "chr1:200:G:A")) @@ -3294,9 +3100,9 @@ test_that(".ctwasGetFinemapAux: cs_95 without a purity column yields NA purity", context = "c1", trait = "t1", method = "susie", - entry = list(fineMappingRow(tl$variant_id, NULL, tl)) + entry = list(FineMappingRow(tl$variant_id, NULL, tl)) ) - aux <- pecotmr:::.ctwasGetFinemapAux(fmr, "Q1", "c1", "t1", "susie") + aux <- pecotmr:::.ctwasGetFinemapAux(fmr, "Q1", "c1", "t1") expect_length(aux$csMembers, 1L) expect_setequal(aux$csMembers[[1L]], c("chr1:100:A:G", "chr1:200:A:G")) expect_true(all(is.na(aux$csPurity))) @@ -3313,9 +3119,9 @@ test_that(".ctwasGetFinemapAux: no cs_95 column yields empty CS membership", { context = "c1", trait = "t1", method = "susie", - entry = list(fineMappingRow(tl$variant_id, NULL, tl)) + entry = list(FineMappingRow(tl$variant_id, NULL, tl)) ) - aux <- pecotmr:::.ctwasGetFinemapAux(fmr, "Q1", "c1", "t1", "susie") + aux <- pecotmr:::.ctwasGetFinemapAux(fmr, "Q1", "c1", "t1") expect_length(aux$csMembers, 0L) expect_length(aux$csPurity, 0L) expect_equal(aux$pip[["chr1:200:A:G"]], 0.8) @@ -3335,9 +3141,9 @@ test_that(".ctwasGetFinemapAux: a cs_95 column naming no set yields none", { context = "c1", trait = "t1", method = "susie", - entry = list(fineMappingRow(tl$variant_id, NULL, tl)) + entry = list(FineMappingRow(tl$variant_id, NULL, tl)) ) - aux <- pecotmr:::.ctwasGetFinemapAux(fmr, "Q1", "c1", "t1", "susie") + aux <- pecotmr:::.ctwasGetFinemapAux(fmr, "Q1", "c1", "t1") expect_length(aux$csMembers, 0L) expect_identical(aux$csPurity, numeric(0)) expect_equal(aux$pip[["chr1:200:A:G"]], 0.3) @@ -3367,7 +3173,7 @@ test_that(".ctwasFixMolecularId: rows without a gene id are left alone", { }) test_that(".ctwasGetFinemapAux: NULL input, no-match tuple, and empty topLoci all return NULL", { - expect_null(pecotmr:::.ctwasGetFinemapAux(NULL, "Q1", "c1", "t1", "susie")) + expect_null(pecotmr:::.ctwasGetFinemapAux(NULL, "Q1", "c1", "t1")) tl <- data.frame( variant_id = "chr1:100:A:G", pip = 0.5, @@ -3378,25 +3184,19 @@ test_that(".ctwasGetFinemapAux: NULL input, no-match tuple, and empty topLoci al context = "c1", trait = "t1", method = "susie", - entry = list(fineMappingRow(tl$variant_id, NULL, tl)) + entry = list(FineMappingRow(tl$variant_id, NULL, tl)) ) # No matching (study, context, trait, method) tuple -> NULL. - expect_null(pecotmr:::.ctwasGetFinemapAux(fmr, "NOPE", "c1", "t1", "susie")) + expect_null(pecotmr:::.ctwasGetFinemapAux(fmr, "NOPE", "c1", "t1")) # Matching tuple but an empty topLoci -> NULL. fmrEmpty <- QtlFineMappingResult( studyName = "Q1", context = "c1", trait = "t1", method = "susie", - entry = list(fineMappingRow(character(0), NULL, data.frame())) + entry = list(FineMappingRow(character(0), NULL, data.frame())) ) - expect_null(pecotmr:::.ctwasGetFinemapAux( - fmrEmpty, - "Q1", - "c1", - "t1", - "susie" - )) + expect_null(pecotmr:::.ctwasGetFinemapAux(fmrEmpty, "Q1", "c1", "t1")) }) # =========================================================================== @@ -3423,7 +3223,7 @@ test_that(".ctwasSnpInfoForGwasBlock: returns an empty frame when the block has entry = list(gr), genome = "hg19", ldReference = .ctp_makeHandle(), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) panelInfo <- data.frame( chrom = 1L, @@ -3518,7 +3318,7 @@ test_that(".ctwasRunToRows: empty weights -> no rows; a context mixing studies e test_that(".ctwasBucketWeights: unplaced genes warn + drop; empty blocks skipped", { mkE <- function() { - twasWeightsRow( + TwasWeightsRow( variantIds = map_chr(1:5, .ctp_snpId), weights = c(0.1, 0.05, -0.2, 0.3, 0.0) ) @@ -3549,7 +3349,7 @@ test_that(".ctwasBucketWeights: unplaced genes warn + drop; empty blocks skipped test_that(".ctwasBucketWeights: errors when no gene lands in any block", { mkE <- function() { - twasWeightsRow( + TwasWeightsRow( variantIds = map_chr(1:5, .ctp_snpId), weights = c(0.1, 0.05, -0.2, 0.3, 0.0) ) @@ -3578,7 +3378,8 @@ test_that("assembleCtwasInputs: single-block + NULL twasWeights guards", { expect_error( assembleCtwasInputs( .ctp_makeGwasSumstats(blockIds = "block1"), - .ctp_makeTwasWeights() + .ctp_makeTwasWeights(), + method = "susie" ), "at least two LD blocks" ) @@ -3593,7 +3394,7 @@ test_that("weight-source / method / gwas-study guards reject degenerate input", pecotmr:::.ctwasRequireNamedLists(.ctp_makeGwasSumstats(), 42), "must be a TwasWeights" ) - expect_error(pecotmr:::.ctwasResolveMethods(list()), "no method entries") + expect_error(pecotmr:::.ctwasResolveMethod(list()), "no method entries") expect_error( pecotmr:::.ctwasGwasStudyFromZSnp(data.frame(study = c("D1", "D2"))), "multiple GWAS studies" @@ -3657,27 +3458,18 @@ test_that("bundled cTWAS payloads carry one resolvable token per region", { expect_equal(length(unique(live)), nrow(payload$LD_map)) loader <- resolved$LD_loader_fun panels <- pecotmr:::.ctwasCachedPanels(resolved) + # Both loader closures are re-keyed onto the new tokens; rewriting + # LD_map alone would leave them unable to find their panels. for (i in seq_along(live)) { expect_equal( loader(live[[i]]), pecotmr:::.ctwasPanelLd(panels[[i]]) ) + expect_false(is.null(resolved$snpinfo_loader_fun(live[[i]]))) } } }) -test_that("resolving the LD token keeps the loader cache keys in step", { - data(ctwasEstExample) - resolved <- pecotmr:::.ctwasResolveLdPaths(ctwasEstExample) - token <- resolved$LD_map$LD_file[[1]] - - # Rewriting LD_map without re-keying the closures would leave the loader - # unable to find its panel -- the failure this pairing exists to prevent. - expect_true(file.exists(token)) - expect_true(is.matrix(resolved$LD_loader_fun(token))) - expect_false(is.null(resolved$snpinfo_loader_fun(token))) -}) - test_that("an ordinary LD path is left alone", { # A token still on disk -- the caller's own file, or this session's # sentinel -- needs nothing re-minted. @@ -3902,6 +3694,39 @@ test_that("row coordinates prefer the gene cache, then the variant id", { expect_null(f(1L, "rsNOTPARSEABLE", NULL)) }) +test_that("ranged results drop only the rows they cannot place, saying so", { + df <- data.frame( + id = c("chr1:100:A:G", "geneX", "geneY", "rsNOTPARSEABLE"), + susie_pip = c(0.1, 0.2, 0.3, 0.4) + ) + gc <- list(geneX = list(chrom = "chr1", start = 500L, end = 900L)) + expect_warning( + out <- pecotmr:::.ctwasRangePayload(df, gc), + "2 result row\\(s\\) could not be placed on the genome" + ) + expect_s4_class(out, "GRanges") + expect_equal(out$id, c("chr1:100:A:G", "geneX")) + expect_equal(start(out), c(100L, 500L)) + expect_equal(end(out), c(100L, 900L)) +}) + +test_that("a table with no placeable row stays whole, without a warning", { + df <- data.frame(id = c("geneY", "rsNOTPARSEABLE"), susie_pip = c(0.3, 0.4)) + expect_no_warning(out <- pecotmr:::.ctwasRangePayload(df, NULL)) + expect_identical(out, df) + expect_null(pecotmr:::.ctwasRangePayload(NULL, NULL)) +}) + +test_that("the unplaced-row warning names at most five ids", { + cnd <- tryCatch( + pecotmr:::.ctwasWarnUnplaced(sprintf("gene%d", 1:7)), + warning = identity + ) + expect_match(conditionMessage(cnd), "7 result row\\(s\\)") + expect_equal(stringr::str_count(conditionMessage(cnd), "gene[0-9]"), 5L) + expect_null(pecotmr:::.ctwasWarnUnplaced(character(0))) +}) + test_that("trait positions are NULL when the weights do not carry them", { data(twasWeightsExample) expect_false( @@ -4028,23 +3853,6 @@ test_that(".ctwasPrefitRegionFilter honours min_var = 0 and min_gene = 0", { ) }) -test_that(".ctwasBlockGrFromIds places unparseable ids on chrUn", { - # asGranges() warns on the unparseable id before erroring; the fallback - # catches the error, and the warning is incidental to what is tested. - gr <- suppressWarnings( - pecotmr:::.ctwasBlockGrFromIds(c("chr1_100_200", "not-a-region")) - ) - expect_equal( - as.character(GenomicRanges::seqnames(gr)), - c("chr1", "chrUn") - ) - # start = 1, end = 0 is a deliberately EMPTY range, so an unplaced block - # overlaps nothing rather than silently matching everything. - expect_equal(GenomicRanges::start(gr), c(100L, 1L)) - expect_equal(GenomicRanges::end(gr), c(200L, 0L)) - expect_equal(GenomicRanges::width(gr)[[2L]], 0L) -}) - test_that(".ctwasCoordField falls back for an unplaced feature", { expect_equal(pecotmr:::.ctwasCoordField(NULL, "chrom"), "chrUnplaced") expect_equal(pecotmr:::.ctwasCoordField2(NULL, "start"), 1L) @@ -4064,11 +3872,11 @@ test_that(".ctwasBuildSingleRegionInfo reports an empty block accurately", { genome = "hg19", blockId = "b1" ) - # Emptiness is checked before the chromosome count -- otherwise a block - # with no variants is reported as spanning "multiple chromosomes ()". + # Emptiness is checked before the window -- a block empty from the start + # has only a placeholder for one. expect_error( pecotmr:::.ctwasBuildSingleRegionInfo("b1", gss), - "has no variants to define region bounds" + "has no variants for cTWAS to fit" ) }) @@ -4090,7 +3898,7 @@ test_that(".ctwasBuildSingleRegionInfo reports an empty block accurately", { entry = list(mkGr("chr1", c(100L, 200L)), mkGr("chr1", c(300L, 400L))), genome = "hg19", blockId = c("b1", "b2"), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) } @@ -4106,7 +3914,7 @@ test_that(".ctwasFirstPass requires an LD reference on every region", { test_that("ctwasPipeline aborts when no genes could be modeled", { local_mocked_bindings( .ctwasRequireNamedLists = function(...) invisible(NULL), - .ctwasResolveMethods = function(...) "susie", + .ctwasResolveMethod = function(...) "susie", .ctwasGwasStudy = function(...) "G1", .ctwasRunMethod = function(...) list(), .package = "pecotmr" @@ -4118,12 +3926,12 @@ test_that("ctwasPipeline aborts when no genes could be modeled", { }) test_that(".ctwasAlignGeneWeights returns NULL when the row has no variants", { - row <- twasWeightsRow(variantIds = character(0), weights = numeric(0)) + row <- TwasWeightsRow(variantIds = character(0), weights = numeric(0)) expect_null(pecotmr:::.ctwasAlignGeneWeights(row, NULL, NULL)) }) test_that(".ctwasTraitPosAt is bounded by the traitPos column length", { - row <- fineMappingRow( + row <- FineMappingRow( variantIds = c("chr1:100:A:G", "chr1:200:C:T"), susieFit = list(pip = c(0.8, 0.2)), topLoci = data.frame( @@ -4184,31 +3992,27 @@ test_that(".ctwasRenormalizeSusieWeights skips fits it cannot slice", { }) test_that(".ctwasResolveAndValidateWeights requires region_id names", { - local_mocked_bindings( - .ctwasResolveWeightBuckets = function(twasWeights, gwasSumStats) { - list("a", "b") - }, - .package = "pecotmr" - ) - expect_error( - pecotmr:::.ctwasResolveAndValidateWeights(list(x = 1), NULL), - "must resolve to a named list keyed by region_id" + # A partially-named list is as unusable as an unnamed one: the blank key + # cannot address a region. + buckets <- list( + unnamed = list("a", "b"), + blank = stats::setNames(list("a", "b"), c("r1", "")) ) -}) - -test_that(".ctwasResolveAndValidateWeights rejects a blank region name", { + current <- NULL local_mocked_bindings( .ctwasResolveWeightBuckets = function(twasWeights, gwasSumStats) { - stats::setNames(list("a", "b"), c("r1", "")) + current }, .package = "pecotmr" ) - # A partially-named list is as unusable as an unnamed one: the blank key - # cannot address a region. - expect_error( - pecotmr:::.ctwasResolveAndValidateWeights(list(x = 1), NULL), - "must resolve to a named list keyed by region_id" - ) + for (nm in names(buckets)) { + current <- buckets[[nm]] + expect_error( + pecotmr:::.ctwasResolveAndValidateWeights(list(x = 1), NULL), + "must resolve to a named list keyed by region_id", + info = nm + ) + } }) test_that("asCtwasResult: keepSnps must be a flag", { @@ -4221,7 +4025,6 @@ test_that("asCtwasResult: keepSnps must be a flag", { test_that("the ctwas concat helpers answer an empty vector of their own type", { expect_identical(pecotmr:::.ctwasConcat(list()), list()) - expect_identical(pecotmr:::.ctwasConcatInt(list()), integer(0)) expect_identical(pecotmr:::.ctwasConcatChr(list()), character(0)) }) @@ -4273,3 +4076,204 @@ test_that(".ctwasRegionGwasLd refuses a region whose rows use two references", { "2 different LD references; a region's LD is one matrix" ) }) + +# =========================================================================== +# The rescues read the fine-mapping method they are told to +# =========================================================================== + +# A gene's fine-mapping under two methods that disagree about variant 3: susie +# puts its PIP at 0.9, susieInf at 0.01. +.ctp_twoMethodRescue <- function(vids) { + fit <- function(pip3, rest) { + pip <- rep(rest, 5L) + pip[[3L]] <- pip3 + FineMappingRow( + variantIds = vids, + susieFit = list(), + topLoci = data.frame(variant_id = vids, pip = pip) + ) + } + QtlFineMappingResult( + studyName = rep("study1", 2L), + context = rep("brain", 2L), + trait = rep("ENSG_example", 2L), + method = c("susie", "susieInf"), + entry = list(fit(0.9, 0.05), fit(0.01, 0.2)) + ) +} + +test_that(".ctwasRescueSource narrows the result to the named method", { + data(qtlDatasetExample) + vids <- .ctp_panelSnpInfo(pecotmr:::.qtlGenotypeSe(qtlDatasetExample))$SNP + fmr <- .ctp_twoMethodRescue(vids[1:5]) + expect_null(pecotmr:::.ctwasRescueSource(NULL, NULL)) + narrowed <- pecotmr:::.ctwasRescueSource(fmr, "susieInf") + expect_identical(as.character(narrowed$method), "susieInf") + expect_error( + pecotmr:::.ctwasRescueSource(fmr, NULL), + "must name the method of it .*available: susie, susieInf" + ) + expect_error( + pecotmr:::.ctwasRescueSource(fmr, "ensemble"), + "'ensemble' is not a method of `fineMappingResult`" + ) + expect_error( + pecotmr:::.ctwasRescueSource(NULL, "susie"), + "names a method of `fineMappingResult`, which was not given" + ) +}) + +test_that("an ensemble gene is rescued by the fine-mapping method named", { + data(qtlDatasetExample) + gh <- pecotmr:::.qtlGenotypeSe(qtlDatasetExample) + vids <- .ctp_panelSnpInfo(gh)$SNP[1:5] + # Variant 3 carries the smallest weight, so the cap drops it unless a + # rescue keeps it. + tw <- TwasWeights( + studyName = "study1", + context = "brain", + trait = "ENSG_example", + method = "ensemble", + entry = list(TwasWeightsRow( + variantIds = vids, + weights = c(0.1, -0.2, 0.05, 0.3, 0.15) + )), + ldReference = gh + ) + fmr <- .ctp_twoMethodRescue(vids) + kept <- function(fineMappingMethod) { + wl <- pecotmr:::.ctwasBuildWeights( + tw, + .ctp_fullPanel(gh), + fineMappingResult = pecotmr:::.ctwasRescueSource( + fmr, + fineMappingMethod + ), + minPipCutoff = 0.5, + maxNumVariants = 3L + ) + rownames(wl[[1L]]$wgt) + } + expect_true(vids[[3L]] %in% kept("susie")) + expect_false(vids[[3L]] %in% kept("susieInf")) +}) + +# =========================================================================== +# Narrowed rows: the SuSiE fits that renormalize weights +# =========================================================================== + +# One gene's SuSiE weights on variants `variantIdx`, fitted on all five and +# narrowed to the first four; `fits` is the stored fit. +.ctp_narrowedSusieWeights <- function( + variantIdx = 1:5, + method = "susie", + fits = list( + alpha = matrix(0.2, 1L, 5L), + mu = matrix(0.1, 1L, 5L), + X_column_scale_factors = rep(1, 5L) + ) +) { + tw <- TwasWeights( + studyName = "Q1", + context = "c1", + trait = "t1", + method = method, + entry = list(TwasWeightsRow( + variantIds = map_chr(variantIdx, .ctp_snpId), + weights = c(0.1, 0.05, -0.2, 0.3, 0.0), + methodFits = fits + )), + ldReference = .ctp_makeHandle() + ) + endoapply(tw, utils::head, 4L) +} + +test_that("the narrowed rows checked are SuSiE-fitted rows of the method", { + narrowed <- .ctp_narrowedSusieWeights() + cnd <- tryCatch( + pecotmr:::.ctwasCheckFitCoverage( + list(block1 = narrowed, block2 = .ctp_narrowedSusieWeights(7:11)), + "susie", + "f()" + ), + warning = identity + ) + expect_s3_class(cnd, "pecotmrFitCoverage") + expect_match(conditionMessage(cnd), "f\\(\\): 2 row\\(s\\)") + # Another method's rows are not read. + expect_no_warning( + pecotmr:::.ctwasCheckFitCoverage(narrowed, "lasso", "f()") + ) + # Nor is a fit that is not SuSiE's, which renormalizes nothing. + lasso <- .ctp_narrowedSusieWeights( + method = "lasso", + fits = list(beta = rep(0.1, 5L)) + ) + expect_null(pecotmr:::.ctwasSusieFitRows(lasso, "lasso")) + expect_no_warning(pecotmr:::.ctwasCheckFitCoverage(lasso, "lasso", "f()")) + # A fine-mapping weight source gives its topLoci effects, not its fit. + vids <- map_chr(1:5, .ctp_snpId) + tl <- data.frame(variant_id = vids, pip = rep(0.2, 5L)) + fmr <- QtlFineMappingResult( + studyName = "Q1", + context = "c1", + trait = "t1", + method = "susie", + entry = list(FineMappingRow(vids, list(pip = tl$pip), tl)) + ) + expect_no_warning(pecotmr:::.ctwasCheckFitCoverage( + list(block1 = endoapply(fmr, utils::head, 4L)), + "susie", + "f()" + )) +}) + +test_that("assembleCtwasInputs warns about narrowed SuSiE weights", { + skip_if_not_installed("ctwas") + local_mocked_bindings( + extractBlockGenotypes = .ctp_mockExtractor(), + .package = "pecotmr" + ) + cnd <- .fitCoverageCondition(assembleCtwasInputs( + gwasSumStats = .ctp_makeGwasSumstats(), + twasWeights = list( + block1 = .ctp_narrowedSusieWeights(), + block2 = .ctp_narrowedSusieWeights(7:11) + ), + method = "susie" + )) + expect_s3_class(cnd, "pecotmrFitCoverage") + expect_match(conditionMessage(cnd), "assembleCtwasInputs\\(\\): 2 row") +}) + +# A stand-in for assembleCtwasInputs() that warns as it does about a narrowed +# row, then stops the run. +.ctp_warnThenStop <- function(...) { + warn("assembleCtwasInputs(): narrowed", class = "pecotmrFitCoverage") + abort("assembled") +} + +test_that("ctwasPipeline warns once, under its own name", { + skip_if_not_installed("ctwas") + local_mocked_bindings( + assembleCtwasInputs = .ctp_warnThenStop, + .package = "pecotmr" + ) + msgs <- character(0) + expect_error( + withCallingHandlers( + ctwasPipeline( + gwasSumStats = .ctp_makeGwasSumstats(), + twasWeights = .ctp_narrowedSusieWeights(), + method = "susie" + ), + pecotmrFitCoverage = function(w) { + msgs <<- c(msgs, conditionMessage(w)) + invokeRestart("muffleWarning") + } + ), + "assembled" + ) + expect_length(msgs, 1L) + expect_match(msgs, "ctwasPipeline\\(\\): 1 row") +}) diff --git a/tests/testthat/test_ctwasWrapper.R b/tests/testthat/test_ctwasWrapper.R index 79e0602d..ba7f6639 100644 --- a/tests/testthat/test_ctwasWrapper.R +++ b/tests/testthat/test_ctwasWrapper.R @@ -30,7 +30,7 @@ test_that("the geneZ bundle reaches compute_gene_z", { ) pecotmr:::.ctwasEnsureZGene( inputs, - numThreads = 1L, + threads = 1L, extra = CtwasGeneZOptions(logfile = "gene-z.log") ) expect_equal(seen$logfile, "gene-z.log") @@ -38,7 +38,7 @@ test_that("the geneZ bundle reaches compute_gene_z", { # A supplied z_gene still short-circuits without calling the engine. seen <- NULL inputs$z_gene <- data.frame(id = "t1", z = 2.0) - pecotmr:::.ctwasEnsureZGene(inputs, numThreads = 1L) + pecotmr:::.ctwasEnsureZGene(inputs, threads = 1L) expect_null(seen) }) diff --git a/tests/testthat/test_fineMappingPipeline.R b/tests/testthat/test_fineMappingPipeline.R index 0497f2ba..0a88a8df 100644 --- a/tests/testthat/test_fineMappingPipeline.R +++ b/tests/testthat/test_fineMappingPipeline.R @@ -18,7 +18,7 @@ context("fineMappingPipeline") format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -136,7 +136,7 @@ context("fineMappingPipeline") gr } -.fmp_makeQtlSumStats <- function(qc = TRUE) { +.fmp_makeQtlSumStats <- function(qc = TRUE, traitPos = NULL) { QtlSumStats( studyName = "Q1", context = "c1", @@ -144,24 +144,67 @@ context("fineMappingPipeline") entry = list(.fmp_makeSumstatsGr()), genome = "hg19", ldReference = .fmp_makeHandle(), - qcInfo = if (qc) list(step1 = "ok") else list() + qcOptions = if (qc) list(step1 = "ok") else list(), + traitPos = traitPos ) } +# A trait position for the summary statistics above: a MultiStudyQtlDataset +# lays its `cisWindow` there too, and 1000 bp around it keeps every variant. +.fmp_traitPos <- function() { + GenomicRanges::GRanges("chr1:300") +} + .fmp_makeGwasSumStats <- function(qc = TRUE, studyName = "G1") { GwasSumStats( studyName = studyName, entry = list(.fmp_makeSumstatsGr()), genome = "hg19", ldReference = .fmp_makeHandle(), - qcInfo = if (qc) list(step1 = "ok") else list() + qcOptions = if (qc) list(step1 = "ok") else list() ) } +# The fixtures most tests read, built once: every constructor validates its +# whole collection, so rebuilding them in each test was a large share of this +# file's run time. Tests only read them (a change makes a local copy). +.fmp_qdA <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") +.fmp_qdAB <- .fmp_makeQtlDataset() +.fmp_qss <- .fmp_makeQtlSumStats() +.fmp_gss <- .fmp_makeGwasSumStats() +.fmp_qdTwoCtxA <- .fmp_makeQtlDataset( + contexts = c("brain", "liver"), + traits = "ENSG_A" +) +.fmp_qdTwoCtxAB <- .fmp_makeQtlDataset(contexts = c("brain", "liver")) +# One individual-level study plus embedded summary statistics placed at +# .fmp_traitPos(), so a `cisWindow` can be laid on both. +.fmp_msqd <- MultiStudyQtlDataset( + qtlDatasets = list(study1 = .fmp_qdA), + sumStats = .fmp_makeQtlSumStats(traitPos = .fmp_traitPos()) +) + +# The result class each summary-statistics input comes back as. +.fmp_resultClass <- c( + GwasSumStats = "GwasFineMappingResult", + QtlSumStats = "QtlFineMappingResult" +) + +# One susie fit of a summary-statistics input under `susieRssParam`. +.fmp_fitRss <- function(input, susieRssParam = SusieRssParam()) { + suppressMessages(fineMappingPipeline( + input, + methods = "susie", + initializeWithSusieInf = FALSE, + susieRssParam = susieRssParam + )) +} + # Mocks for the SuSiE fitters + post-processor. Return tiny payloads keyed # only by the token so post-process knows what to wrap. The `userArgs` -# parameter (per-method kwargs merged in by .fmMergeUserArgs) is accepted -# but ignored — the mocks don't simulate downstream susie behaviour. +# parameter (per-method kwargs merged in by .fmMergeUserArgs) is recorded +# when a `capture` environment is given and otherwise ignored -- the mocks +# don't simulate downstream susie behaviour. .fmp_mockFitIndiv <- function(capture = NULL) { function( X, @@ -264,7 +307,7 @@ context("fineMappingPipeline") if (is.null(vids)) { vids <- "chr1:1200:A:G" } - fineMappingRow( + FineMappingRow( variantIds = vids, susieFit = list(method = method, payload = fit), topLoci = data.frame( @@ -430,26 +473,6 @@ test_that(".fmCheckMethodCapabilities: mvsusie on GwasSumStats rejected", { ) }) -test_that(".fmTraitsInRegion: keeps genes overlapping the region; NULL keeps all", { - # g1: 1000-1500, g2: 2000-2500, g3: 3000-3500 (width 500). - se <- .fmp_makeSe( - traits = c("g1", "g2", "g3"), - starts = c(1000L, 2000L, 3000L) - ) - r1 <- GenomicRanges::GRanges("chr1", IRanges::IRanges(900L, 1600L)) # g1 only - r12 <- GenomicRanges::GRanges("chr1", IRanges::IRanges(900L, 2600L)) # g1 + g2 - expect_equal(pecotmr:::.fmTraitsInRegion(se, c("g1", "g2", "g3"), r1), "g1") - expect_setequal( - pecotmr:::.fmTraitsInRegion(se, c("g1", "g2", "g3"), r12), - c("g1", "g2") - ) - # NULL region (gene/cisWindow mode) leaves the set unchanged. - expect_setequal( - pecotmr:::.fmTraitsInRegion(se, c("g1", "g2", "g3"), NULL), - c("g1", "g2", "g3") - ) -}) - # =========================================================================== # .fmResolveSusieChain # =========================================================================== @@ -473,7 +496,7 @@ test_that(".fmResolveSusieChain: keeps susieInf when explicitly requested", { expect_true(res$keepInf) }) -test_that(".fmResolveSusieChain: no chain when addSusieInf=FALSE", { +test_that(".fmResolveSusieChain: no chain or susieInf run for susie alone", { res <- pecotmr:::.fmResolveSusieChain( c("susie"), initializeWithSusieInf = FALSE @@ -491,7 +514,7 @@ test_that(".fmCacheLookup: NULL fineMappingResult returns NULL", { }) test_that(".fmCacheLookup: returns matching entry by 4-tuple", { - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(token = "susie"), topLoci = data.frame( @@ -521,7 +544,7 @@ test_that(".fmCacheLookup: returns matching entry by 4-tuple", { }) test_that(".fmCacheLookupGwas: matches on study/method/blockId", { - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(token = "susie"), topLoci = data.frame( @@ -530,9 +553,9 @@ test_that(".fmCacheLookupGwas: matches on study/method/blockId", { stringsAsFactors = FALSE ) ) - # GwasFineMappingResult assigns the synthetic blockId "region_1" - # when none is supplied; the lookup must include it in the 3-tuple - # key (multi-block FMRs disambiguate per-block fits by blockId). + # GwasFineMappingResult names a row with no blockId by its own span; the + # lookup keys on that span (multi-block FMRs disambiguate per-block fits + # by it). fmr <- GwasFineMappingResult( studyName = "g1", method = "susie", @@ -551,9 +574,24 @@ test_that(".fmCacheLookupGwas: matches on study/method/blockId", { expect_null(pecotmr:::.fmCacheLookupGwas(fmr, "ghost", "susie", key)) }) +test_that(".fmCacheLookupGwas: a one-block cache answers for that block only", { + # A cache holding one block of a study is no fit for its other blocks, so + # the range is compared even when only one row matches (study, method). + fmr <- GwasFineMappingResult( + studyName = "g1", + method = "susie", + entry = list(.sc_makeFineMappingRow(3)) + ) + key <- pecotmr:::.rtlRangeKeys(fmr)[[1L]] + expect_false(is.null( + pecotmr:::.fmCacheLookupGwas(fmr, "g1", "susie", key) + )) + expect_null( + pecotmr:::.fmCacheLookupGwas(fmr, "g1", "susie", "chr1_10100_10300") + ) +}) + test_that(".fmCacheLookupGwas: the range key disambiguates multi-block FMRs", { - # With one row per (study, method) the range never has to be consulted; - # it only becomes load-bearing once a study is swept across blocks. e1 <- .sc_makeFineMappingRow(3) e2 <- .sc_makeFineMappingRow(3, offset = 10000L) fmr <- GwasFineMappingResult( @@ -574,7 +612,7 @@ test_that(".fmCacheLookupGwas: the range key disambiguates multi-block FMRs", { }) test_that(".fmCacheLookup: non-QtlFineMappingResult input returns NULL", { - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(token = "susie"), topLoci = data.frame( @@ -591,26 +629,6 @@ test_that(".fmCacheLookup: non-QtlFineMappingResult input returns NULL", { expect_null(pecotmr:::.fmCacheLookup(gwasFmr, "g1", "c1", "t1", "susie")) }) -test_that(".fmCacheLookupGwas: non-GwasFineMappingResult input returns NULL", { - e <- fineMappingRow( - variantIds = "chr1:100:A:G", - susieFit = list(token = "susie"), - topLoci = data.frame( - variant_id = "chr1:100:A:G", - pip = 0.5, - stringsAsFactors = FALSE - ) - ) - qtlFmr <- QtlFineMappingResult( - studyName = "s1", - context = "c1", - trait = "t1", - method = "susie", - entry = list(e) - ) - expect_null(pecotmr:::.fmCacheLookupGwas(qtlFmr, "s1", "susie", "region_1")) -}) - # =========================================================================== # .fmBuildQtlResult / .fmBuildGwasResult — empty-entries errors # =========================================================================== @@ -640,7 +658,7 @@ test_that(".fmBuildGwasResult: empty entries errors", { # =========================================================================== test_that(".rbindFineMappingResult: rejects non-FineMappingResultBase input", { - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(token = "susie"), topLoci = data.frame( @@ -667,7 +685,7 @@ test_that(".rbindFineMappingResult: rejects non-FineMappingResultBase input", { }) test_that(".rbindFineMappingResult: rejects mixed Qtl/Gwas inputs", { - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(token = "susie"), topLoci = data.frame( @@ -695,7 +713,7 @@ test_that(".rbindFineMappingResult: rejects mixed Qtl/Gwas inputs", { }) test_that(".rbindFineMappingResult: concatenates two GwasFineMappingResult collections", { - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(token = "susie"), topLoci = data.frame( @@ -720,7 +738,7 @@ test_that(".rbindFineMappingResult: concatenates two GwasFineMappingResult colle }) test_that("combineFineMappingResults: row-binds same-class collections; rejects mixed class/empty", { - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(token = "susie"), topLoci = data.frame( @@ -776,11 +794,7 @@ test_that(".fmExtractZn: errors on missing SNP / Z / N columns", { # fineMappingPipeline(QtlDataset) # =========================================================================== -test_that("fineMappingPipeline(QtlDataset): runs univariate dispatch with mocked fitters", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) +test_that("fineMappingPipeline(QtlDataset): univariate rows record traitPos", { local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -789,7 +803,7 @@ test_that("fineMappingPipeline(QtlDataset): runs univariate dispatch with mocked ) res <- suppressMessages( fineMappingPipeline( - qd, + .fmp_qdAB, methods = "susie", cisWindow = 1000L, initializeWithSusieInf = FALSE @@ -799,27 +813,6 @@ test_that("fineMappingPipeline(QtlDataset): runs univariate dispatch with mocked # 1 context x 2 traits x 1 method = 2 rows. expect_equal(nrow(res), 2L) expect_setequal(methodNames(res), "susie") -}) - -test_that("fineMappingPipeline(QtlDataset): threads real trait positions into traitPos provenance", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieIndiv = .fmp_mockFitIndiv(), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" - ) - res <- suppressMessages( - fineMappingPipeline( - qd, - methods = "susie", - cisWindow = 1000L, - initializeWithSusieInf = FALSE - ) - ) tp <- traitPosition(res) expect_s4_class(tp, "GRanges") expect_length(tp, nrow(res)) @@ -835,7 +828,7 @@ test_that("fineMappingPipeline(QtlDataset): threads real trait positions into tr expect_equal(ent[["ENSG_B"]], 2499L) # genomicRegion() reports the REALIZED variant span now, not the nominal cis # window (traitPos +/- cisWindow). The window is gone because it had no - # correct update rule under subsetRegion(); the span is in sync with the + # correct update rule under subsetting; the span is in sync with the # variants by construction. It still sits inside the window the fit was # drawn from, which is what this checks. reg <- genomicRegion(res) @@ -848,7 +841,7 @@ test_that("fineMappingPipeline(QtlDataset): threads real trait positions into tr }) test_that(".fmAfForX: returns directional effect-allele af aligned to colnames(X)", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + qd <- .fmp_qdA local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .package = "pecotmr" @@ -865,17 +858,21 @@ test_that(".fmAfForX: returns directional effect-allele af aligned to colnames(X c("chr1:300:A:G", "chr1:100:A:G", "chr1:200:A:G") ) ) - af <- pecotmr:::.fmAfForX(qd, X, region = region) + noFilter <- pecotmr:::.qtlResolveFilter() + af <- pecotmr:::.fmAfForX(qd, X, genotypeFilter = noFilter, region = region) expect_length(af, 3L) expect_false(anyNA(af)) # region matched -> every fitted variant has an af - expect_equal( - af, - unname(af(qd, region = region, samples = rownames(X))[colnames(X)]) + blk <- pecotmr:::.qtlExtractBlock( + qd, + window = region, + samples = rownames(X), + filter = noFilter ) + expect_equal(af, unname(setNames(blk$af, blk$variantIds)[colnames(X)])) }) test_that(".fmAfForX: returns NULL for an empty block or a non-QtlDataset source", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + qd <- .fmp_qdA emptyX <- matrix(numeric(0), nrow = 0L, ncol = 0L) expect_null(pecotmr:::.fmAfForX(qd, emptyX)) X <- matrix( @@ -891,7 +888,7 @@ test_that("fineMappingPipeline(QtlDataset): threads directional af into postproc # Regression for af = NA in credibleSets: the individual-level univariate path must # forward a non-NULL, directional effect-allele frequency to the # post-processor (which writes it into the topLoci `af` column). - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + qd <- .fmp_qdA captured <- new.env(parent = emptyenv()) captured$af <- "UNSET" captured$cols <- NULL @@ -913,7 +910,7 @@ test_that("fineMappingPipeline(QtlDataset): threads directional af into postproc captured$af <- af captured$cols <- colnames(dataX) vids <- colnames(dataX) - fineMappingRow( + FineMappingRow( variantIds = vids, susieFit = list(method = method), topLoci = data.frame( @@ -947,7 +944,7 @@ test_that("fineMappingPipeline(QtlDataset): threads directional af into postproc }) test_that("fineMappingPipeline(QtlDataset): seed argument is accepted and runs", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + qd <- .fmp_qdA local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -967,7 +964,7 @@ test_that("fineMappingPipeline(QtlDataset): seed argument is accepted and runs", expect_equal(nrow(res), 1L) }) -test_that(".fmTopPcScores: clean matrix -> samples x min(nPCs, traits) topPC scores", { +test_that(".fmTopPcScores: samples x min(nPCs, traits) scores, else NULL", { set.seed(7) n <- 30L Y <- matrix( @@ -1001,12 +998,14 @@ test_that(".fmTopPcScores: clean matrix -> samples x min(nPCs, traits) topPC sco scn <- fn(Yna, 10L) expect_equal(nrow(scn), n - 2L) expect_false(any(c("s1", "s2") %in% rownames(scn))) + # (f) fewer than two complete rows, fewer than two traits with variance, + # or nPCs = 0 leaves nothing to score. + expect_null(fn(matrix(c(1, NA), 2, 2), 2L)) + expect_null(fn(cbind(a = rep(1, 4), b = rnorm(4)), 2L)) + expect_null(fn(Y, 0L)) }) -test_that("fineMappingPipeline( - QtlDataset, - usePCA -): top-PC susie rows keyed topPC{i}", { +test_that("fineMappingPipeline(QtlDataset, usePCA): rows keyed topPC{i}", { qd <- .fmp_makeQtlDataset( contexts = "brain", traits = c("ENSG_A", "ENSG_B", "ENSG_C") @@ -1038,7 +1037,7 @@ test_that("fineMappingPipeline( test_that(".fmLookupMrmashFit: finds the mr.mash fit by (study, trait)", { mkEntry <- function(fits) { - twasWeightsRow( + TwasWeightsRow( variantIds = c("chr1:100:A:G", "chr1:200:A:G"), weights = c(0.1, 0.2), methodFits = fits @@ -1067,7 +1066,7 @@ test_that(".fmLookupMrmashFit: finds the mr.mash fit by (study, trait)", { test_that(".fmLookupMrmashCv: finds the per-fold CV payload by (study, trait)", { mkEntry <- function(cv) { - twasWeightsRow( + TwasWeightsRow( variantIds = c("chr1:100:A:G", "chr1:200:A:G"), weights = c(0.1, 0.2), cvResult = cv @@ -1187,25 +1186,8 @@ test_that(".fmBuildMvsusiePriorCv: mode C reuses full-fit w0/V with per-fold U", expect_equal(captured[[2]]$mixture_prior$matrices$Z, diag(2) * 3) # fold 2's U }) -test_that("enabling two screen metrics errors at the constructor", { - # It used to take a pipeline call to find this out; now the bundle - # refuses to be built, so the mistake is caught where it is written. - expect_error( - SignalScreenParam(pip = 0.5, absZ = 5), - "only one screening metric" - ) - # 0 is the long-standing "off" spelling, so this is one screen, not two. - expect_equal( - pecotmr:::.screenResolve(SignalScreenParam(pip = 0, absZ = 5)), - list(metric = "absZ", cutoff = 5) - ) -}) - test_that("fineMappingPipeline(QtlDataset): pipCutoffToSkip skips no-signal univariate traits", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB # Stateful screen: reject the first block (ENSG_A), keep the rest (ENSG_B). seen <- 0L local_mocked_bindings( @@ -1232,12 +1214,9 @@ test_that("fineMappingPipeline(QtlDataset): pipCutoffToSkip skips no-signal univ expect_setequal(traitNames(res), "ENSG_B") }) -test_that("fineMappingPipeline( - QtlDataset, - cvFolds>1 -): attaches cvResult end to end", { +test_that("fineMappingPipeline(QtlDataset): CV folds attach a cvResult", { skip_if_not_installed("susieR") - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + qd <- .fmp_qdA # Real susie fits drive CV; the genotype extraction and the full-data # post-processor are mocked (the mock SNP ids are not chr:pos:a1:a2, which the # real buildTopLoci requires). CV runs its own real .fmFitSusieIndiv, so the @@ -1273,11 +1252,8 @@ test_that("fineMappingPipeline( expect_false(anyNA(cv$prediction[["susie_predicted"]])) }) -test_that("fineMappingPipeline( - QtlDataset, - crossValidation = CrossValidationParam(folds = 0) -): leaves cvResult NULL", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") +test_that("fineMappingPipeline(QtlDataset): no CV folds leaves cvResult NULL", { + qd <- .fmp_qdA local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -1307,13 +1283,6 @@ test_that("fineMappingPipeline( # tests above). # =========================================================================== -test_that(".cvSamplePartition partitions every sample into the requested folds", { - part <- pecotmr:::.cvSamplePartition(paste0("s", 1:20), fold = 4L) - expect_setequal(part$Sample, paste0("s", 1:20)) - expect_setequal(sort(unique(part$Fold)), 1:4) - expect_equal(nrow(part), 20L) -}) - test_that(".fmWeightsCv returns twasWeightsCv-shaped output keyed by snake method", { skip_if_not_installed("susieR") set.seed(42) @@ -1412,47 +1381,42 @@ test_that(".fmSliceCv / .fmAttachCv slice one method and round-trip onto an entr pip = 0.5, stringsAsFactors = FALSE ) - e <- fineMappingRow("chr1:100:A:G", list(), tl) + e <- FineMappingRow("chr1:100:A:G", list(), tl) e2 <- pecotmr:::.fmAttachCv(e, sl) expect_identical(pecotmr:::.fmrPartsCvResult(e2), sl) }) -test_that("fineMappingPipeline(QtlDataset): RSS-only method rejected by capability check", { - qd <- .fmp_makeQtlDataset() +test_that("fineMappingPipeline(QtlDataset): a TWAS-only method is rejected", { expect_error( - fineMappingPipeline(qd, methods = "mrmash"), + fineMappingPipeline(.fmp_qdAB, methods = "mrmash"), "TWAS-weight-oriented" ) }) test_that("fineMappingPipeline(QtlDataset): unknown context errors", { - qd <- .fmp_makeQtlDataset() expect_error( - fineMappingPipeline(qd, methods = "susie", contexts = "ghost"), + fineMappingPipeline(.fmp_qdAB, methods = "susie", contexts = "ghost"), "no study has: ghost" ) }) -test_that("fineMappingPipeline(QtlDataset): empty traitId filter errors", { - qd <- .fmp_makeQtlDataset(traits = "ENSG_A") +test_that("fineMappingPipeline(QtlDataset): empty trait filter errors", { expect_error( - fineMappingPipeline(qd, methods = "susie", traitId = "ENSG_Z"), + fineMappingPipeline(.fmp_qdA, methods = "susie", traitId = "ENSG_Z"), "no traits selected" ) }) test_that("fineMappingPipeline(QtlDataset): mvsusie with single trait/context rejected", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") expect_error( - fineMappingPipeline(qd, methods = "mvsusie"), + fineMappingPipeline(.fmp_qdA, methods = "mvsusie"), "mvsusie requires multi-trait or multi-context" ) }) test_that("fineMappingPipeline(QtlDataset): fsusie with single trait rejected", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") expect_error( - fineMappingPipeline(qd, methods = "fsusie"), + fineMappingPipeline(.fmp_qdA, methods = "fsusie"), "fsusie requires multi-trait" ) }) @@ -1491,10 +1455,7 @@ test_that("fineMappingPipeline(QtlDataset): fsusie with single trait rejected", } test_that("fineMappingPipeline(QtlDataset): mvsusie multi-trait single-context dispatch", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmPostprocessOne = .fmp_mockPostprocess(), @@ -1536,7 +1497,7 @@ test_that("fineMappingPipeline(QtlDataset): mvsusie multi-trait single-context d }) test_that("fineMappingPipeline(QtlDataset): mvsusie multi-context single-trait dispatch", { - qd <- .fmp_makeQtlDataset(contexts = c("brain", "liver"), traits = "ENSG_A") + qd <- .fmp_qdTwoCtxA local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmPostprocessOne = .fmp_mockPostprocess(), @@ -1588,7 +1549,7 @@ test_that("fineMappingPipeline(QtlDataset): pipCutoffToSkip drops null contexts test_that("fineMappingPipeline(QtlDataset): pipCutoffToSkip skips mvsusie when < 2 contexts survive", { # susie runs alongside so the result still has rows after mvsusie is skipped. - qd <- .fmp_makeQtlDataset(contexts = c("brain", "liver"), traits = "ENSG_A") + qd <- .fmp_qdTwoCtxA local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -1617,10 +1578,7 @@ test_that("fineMappingPipeline(QtlDataset): pipCutoffToSkip skips mvsusie when < }) test_that("fineMappingPipeline(QtlDataset): mvsusie both multi falls back to per-context multi-trait", { - qd <- .fmp_makeQtlDataset( - contexts = c("brain", "liver"), - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdTwoCtxAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmPostprocessOne = .fmp_mockPostprocess(), @@ -1650,17 +1608,14 @@ test_that("fineMappingPipeline(QtlDataset): multi-trait auto-detection USES the # canonical create_mixture_prior(R=ncol). Routed through the engine, it now # looks up a prior cross-trait mr.mash fit (study, context fixed; trait # match-any) and reweights from it. - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB fitParts <- list( dataDrivenPriorMatrices = list(U = list(K = diag(2)), w = c(K = 1)), w0 = c(K_grid1 = 1), V = diag(2) ) mkE <- function() { - twasWeightsRow( + TwasWeightsRow( variantIds = c("chr1:100:A:G", "chr1:200:A:G"), weights = c(0.1, 0.2), methodFits = fitParts @@ -1707,10 +1662,7 @@ test_that("fineMappingPipeline(QtlDataset): multi-trait auto-detection USES the }) test_that("fineMappingPipeline(QtlDataset): multi-trait without mrmashPrior keeps the canonical prior", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB sawMixturePrior <- FALSE sawCanonical <- FALSE local_mocked_bindings( @@ -1742,12 +1694,9 @@ test_that("fineMappingPipeline(QtlDataset): multi-trait without mrmashPrior keep test_that("fineMappingPipeline(QtlDataset): mvsusie resume cache short-circuits the joint fitter", { # All conditions of the cross-trait group are already in the prior partial # result -> the engine reuses the cached entries and never calls mvsusie. - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB cachedEntry <- function() { - fineMappingRow( + FineMappingRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), susieFit = list(token = "mvsusie_cached"), topLoci = data.frame( @@ -1791,10 +1740,7 @@ test_that("fineMappingPipeline(QtlDataset): mvsusie resume cache short-circuits }) test_that("fineMappingPipeline(QtlDataset): jointSpec='context' produces one joint row per trait", { - qd <- .fmp_makeQtlDataset( - contexts = c("brain", "liver"), - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdTwoCtxAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmPostprocessOne = .fmp_mockPostprocess(), @@ -1827,7 +1773,7 @@ test_that("fineMappingPipeline(QtlDataset): jointSpec='context' produces one joi }) test_that("fineMappingPipeline(QtlDataset): jointSpec='context' + univariate compose without double-fitting mvsusie", { - qd <- .fmp_makeQtlDataset(contexts = c("brain", "liver"), traits = "ENSG_A") + qd <- .fmp_qdTwoCtxA local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -1860,10 +1806,7 @@ test_that("fineMappingPipeline(QtlDataset): jointSpec='context' + univariate com }) test_that("fineMappingPipeline(QtlDataset): jointSpec='context' with only one context skips with message", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmPostprocessOne = .fmp_mockPostprocess(), @@ -1888,10 +1831,7 @@ test_that("fineMappingPipeline(QtlDataset): jointSpec='context' with only one co }) test_that("fineMappingPipeline(QtlDataset): jointSpec='trait' produces one joint row per context", { - qd <- .fmp_makeQtlDataset( - contexts = c("brain", "liver"), - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdTwoCtxAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmPostprocessOne = .fmp_mockPostprocess(), @@ -1919,10 +1859,7 @@ test_that("fineMappingPipeline(QtlDataset): jointSpec='trait' produces one joint }) test_that("fineMappingPipeline(QtlDataset): jointSpec='trait' with fsusie wires fsusieR::susiF", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmPostprocessOne = .fmp_mockPostprocess(), @@ -1960,10 +1897,7 @@ test_that("fineMappingPipeline(QtlDataset): fsusie receives the CredibleSetParam # while nothing did -- the row described the retired fsusieWrapper() while # the pipeline called fitFsusie(). `--L` was silently ignored and susiF # ran at its own default. The mocked susiF records what it was handed. - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmPostprocessOne = .fmp_mockPostprocess(), @@ -1994,10 +1928,7 @@ test_that("fineMappingPipeline(QtlDataset): fsusie receives the CredibleSetParam }) test_that("fineMappingPipeline(QtlDataset): fsusie multi-trait per context dispatch", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmPostprocessOne = .fmp_mockPostprocess(), @@ -2027,20 +1958,25 @@ test_that("fineMappingPipeline(QtlDataset): fsusie multi-trait per context dispa # fineMappingPipeline(MultiStudyQtlDataset) # =========================================================================== -test_that("fineMappingPipeline(MultiStudyQtlDataset): aggregates results across constituent QtlDatasets", { - qd1 <- QtlDataset( - studyName = "s1", - genotypes = .fmp_makeHandle(), - phenotypes = list(brain = .fmp_makeSe(traits = "ENSG_A")), - genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0) - ) - qd2 <- QtlDataset( - studyName = "s2", - genotypes = .fmp_makeHandle(), - phenotypes = list(brain = .fmp_makeSe(traits = "ENSG_A")), - genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0) +# Two individual-level studies of one trait in one context, built once. +.fmp_twoStudies <- MultiStudyQtlDataset( + qtlDatasets = list( + s1 = QtlDataset( + studyName = "s1", + genotypes = .fmp_makeHandle(), + phenotypes = list(brain = .fmp_makeSe(traits = "ENSG_A")), + genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0) + ), + s2 = QtlDataset( + studyName = "s2", + genotypes = .fmp_makeHandle(), + phenotypes = list(brain = .fmp_makeSe(traits = "ENSG_A")), + genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0) + ) ) - mt <- MultiStudyQtlDataset(qtlDatasets = list(s1 = qd1, s2 = qd2)) +) + +test_that("fineMappingPipeline(MultiStudyQtlDataset): aggregates results across constituent QtlDatasets", { local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -2049,7 +1985,7 @@ test_that("fineMappingPipeline(MultiStudyQtlDataset): aggregates results across ) res <- suppressMessages( fineMappingPipeline( - mt, + .fmp_twoStudies, methods = "susie", cisWindow = 1000L, initializeWithSusieInf = FALSE @@ -2110,7 +2046,7 @@ test_that("fineMappingPipeline(MultiStudy): list selections stay per study", { ) }) -test_that("fineMappingPipeline(QtlDataset): traitId chosen per context", { +test_that("fineMappingPipeline(QtlDataset): trait chosen per context", { local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -2149,15 +2085,7 @@ test_that("fineMappingPipeline(MultiStudyQtlDataset): per-study options are not ) expect_error( suppressMessages(fineMappingPipeline( - MultiStudyQtlDataset( - qtlDatasets = list( - study1 = .fmp_makeQtlDataset( - contexts = "brain", - traits = "ENSG_A" - ) - ), - sumStats = .fmp_makeQtlSumStats() - ), + .fmp_msqd, methods = "susie", cisWindow = 1000L, credibleSetParam = CredibleSetParam(coverage = 0.9), @@ -2182,15 +2110,7 @@ test_that("fineMappingPipeline(MultiStudyQtlDataset): a misspelled option errors # The method no longer takes `...`, so a typo cannot be swallowed. expect_error( fineMappingPipeline( - MultiStudyQtlDataset( - qtlDatasets = list( - study1 = .fmp_makeQtlDataset( - contexts = "brain", - traits = "ENSG_A" - ) - ), - sumStats = .fmp_makeQtlSumStats() - ), + .fmp_msqd, methods = "susie", credibelSet = CredibleSetParam() ), @@ -2201,12 +2121,6 @@ test_that("fineMappingPipeline(MultiStudyQtlDataset): a misspelled option errors test_that("fineMappingPipeline(MSQD): L / Lgreedy reach the per-study fit", { # One individual-level study and one embedded QtlSumStats, so both # per-study workers (.fmPerStudy and .fmSumStats) are exercised. - mt <- MultiStudyQtlDataset( - qtlDatasets = list( - study1 = .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") - ), - sumStats = .fmp_makeQtlSumStats() - ) capX <- new.env(parent = emptyenv()) capRss <- new.env(parent = emptyenv()) local_mocked_bindings( @@ -2218,7 +2132,7 @@ test_that("fineMappingPipeline(MSQD): L / Lgreedy reach the per-study fit", { ) suppressMessages( fineMappingPipeline( - mt, + .fmp_msqd, methods = "susie", cisWindow = 1000L, initializeWithSusieInf = FALSE, @@ -2239,19 +2153,6 @@ test_that("fineMappingPipeline(MSQD): L / Lgreedy reach the per-study fit", { }) test_that("fineMappingPipeline(MultiStudyQtlDataset): jointRegions=FALSE merges per region in each study", { - qd1 <- QtlDataset( - studyName = "s1", - genotypes = .fmp_makeHandle(), - phenotypes = list(brain = .fmp_makeSe(traits = "ENSG_A")), - genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0) - ) - qd2 <- QtlDataset( - studyName = "s2", - genotypes = .fmp_makeHandle(), - phenotypes = list(brain = .fmp_makeSe(traits = "ENSG_A")), - genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0) - ) - mt <- MultiStudyQtlDataset(qtlDatasets = list(s1 = qd1, s2 = qd2)) local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -2263,7 +2164,7 @@ test_that("fineMappingPipeline(MultiStudyQtlDataset): jointRegions=FALSE merges IRanges::IRanges(c(50L, 350L), c(350L, 650L)) ) res <- suppressMessages(fineMappingPipeline( - mt, + .fmp_twoStudies, methods = "susie", traitId = "ENSG_A", region = regions, @@ -2285,14 +2186,6 @@ test_that("fineMappingPipeline(MultiStudyQtlDataset): jointRegions=FALSE merges }) test_that("fineMappingPipeline(MSQD): embedded sumstats record ldReference", { - qd <- QtlDataset( - studyName = "s1", - genotypes = .fmp_makeHandle(), - phenotypes = list(brain = .fmp_makeSe(traits = "ENSG_A")), - genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0) - ) - ss <- .fmp_makeQtlSumStats() - mt <- MultiStudyQtlDataset(qtlDatasets = list(s1 = qd), sumStats = ss) local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -2302,7 +2195,7 @@ test_that("fineMappingPipeline(MSQD): embedded sumstats record ldReference", { ) res <- suppressMessages( fineMappingPipeline( - mt, + .fmp_msqd, methods = "susie", cisWindow = 1000L, initializeWithSusieInf = FALSE @@ -2315,45 +2208,53 @@ test_that("fineMappingPipeline(MSQD): embedded sumstats record ldReference", { }) # =========================================================================== -# fineMappingPipeline(QtlSumStats) +# fineMappingPipeline(QtlSumStats) and fineMappingPipeline(GwasSumStats) # =========================================================================== -test_that("fineMappingPipeline(QtlSumStats): runs end-to-end with mocked RSS fitters", { - ss <- .fmp_makeQtlSumStats() +test_that("fineMappingPipeline(*SumStats): runs with mocked RSS fitters", { local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieRss = .fmp_mockFitRss(), .fmPostprocessOne = .fmp_mockPostprocess(), .package = "pecotmr" ) - res <- suppressMessages( - fineMappingPipeline( - ss, - methods = "susie", - initializeWithSusieInf = FALSE + for (input in list(.fmp_qss, .fmp_gss)) { + kind <- class(input)[[1L]] + res <- .fmp_fitRss(input) + expect_s4_class(res, .fmp_resultClass[[kind]]) + expect_equal(nrow(res), 1L, info = kind) + expect_equal(methodNames(res), "susie", info = kind) + # The result carries the build its summary statistics name. + expect_identical( + unique(unname(GenomeInfoDb::genome(res))), + "hg19", + info = kind ) - ) - expect_s4_class(res, "QtlFineMappingResult") - expect_equal(nrow(res), 1L) + } }) -test_that("fineMappingPipeline(QtlSumStats): un-QCd input rejected", { - ss <- .fmp_makeQtlSumStats(qc = FALSE) - expect_error( - fineMappingPipeline(ss, methods = "susie"), - "has no QC record" +test_that("fineMappingPipeline(*SumStats): un-QCd input rejected", { + unQcd <- list( + .fmp_makeQtlSumStats(qc = FALSE), + .fmp_makeGwasSumStats(qc = FALSE) ) + for (input in unQcd) { + expect_error( + fineMappingPipeline(input, methods = "susie"), + "has no QC record", + info = class(input)[[1L]] + ) + } }) test_that("fineMappingPipeline(QtlSumStats): empty selection rejected", { - ss <- .fmp_makeQtlSumStats() expect_error( - fineMappingPipeline(ss, methods = "susie", traitId = "ghost"), + fineMappingPipeline(.fmp_qss, methods = "susie", traitId = "ghost"), "no entries matched" ) # A context no study has is caught earlier, when the selection is parsed. expect_error( - fineMappingPipeline(ss, methods = "susie", contexts = "ghost"), + fineMappingPipeline(.fmp_qss, methods = "susie", contexts = "ghost"), "no study has: ghost" ) }) @@ -2362,54 +2263,75 @@ test_that("fineMappingPipeline(QtlSumStats): empty selection rejected", { # fineMappingPipeline(GwasSumStats) # =========================================================================== -test_that("fineMappingPipeline(GwasSumStats): runs end-to-end with mocked RSS fitters", { - gss <- .fmp_makeGwasSumStats() +test_that("fineMappingPipeline(GwasSumStats): a blockId gives no window", { local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieRss = .fmp_mockFitRss(), .fmPostprocessOne = .fmp_mockPostprocess(), .package = "pecotmr" ) - res <- suppressMessages( - fineMappingPipeline( + regionOf <- function(blockId) { + gss <- GwasSumStats( + studyName = "G1", + entry = list(.fmp_makeSumstatsGr()), + genome = "hg19", + ldReference = .fmp_makeHandle(), + blockId = blockId, + qcOptions = list(step1 = "ok") + ) + res <- suppressMessages(fineMappingPipeline( gss, methods = "susie", initializeWithSusieInf = FALSE - ) - ) - expect_s4_class(res, "GwasFineMappingResult") - expect_equal(nrow(res), 1L) - expect_setequal(methodNames(res), "susie") + )) + reg <- genomicRegion(res) + c(GenomicRanges::start(reg), GenomicRanges::end(reg)) + } + # A blockId is a name, however it is spelled, so the window is the + # entry's span; a window the caller means goes in `region`. + expect_equal(regionOf("chr1_50_600"), c(100L, 500L)) + expect_equal(regionOf("block1"), c(100L, 500L)) }) -test_that("fineMappingPipeline(GwasSumStats): opaque blockId, entry's span", { +test_that("fineMappingPipeline(GwasSumStats): a range keeps its origin", { local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieRss = .fmp_mockFitRss(), .fmPostprocessOne = .fmp_mockPostprocess(), .package = "pecotmr" ) - regionOf <- function(blockId) { + fitOver <- function(...) { gss <- GwasSumStats( studyName = "G1", entry = list(.fmp_makeSumstatsGr()), genome = "hg19", ldReference = .fmp_makeHandle(), - blockId = blockId, - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok"), + ... ) - res <- suppressMessages(fineMappingPipeline( + suppressMessages(fineMappingPipeline( gss, methods = "susie", initializeWithSusieInf = FALSE )) - reg <- genomicRegion(res) - c(GenomicRanges::start(reg), GenomicRanges::end(reg)) } - # A blockId spelling coordinates is the region's boundary; an opaque - # label says nothing, so the region is the entry's own variant span. - expect_equal(regionOf("chr1_50_600"), c(50L, 600L)) - expect_equal(regionOf("block1"), c(100L, 500L)) + # A window named in a blockId column gives the block its range and key. + named <- fitOver( + region = GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(1L, 2000L), + blockId = "b1" + ) + ) + expect_identical(named$blockId, "b1") + expect_identical(as.character(genomicRegion(named)), "chr1:1-2000") + expect_true(named$regionGiven) + # Without one, the row keeps its seqname as its name, and its span bounds + # the block, computed. + bare <- fitOver() + expect_identical(bare$blockId, "chr1") + expect_identical(as.character(genomicRegion(bare)), "chr1:100-500") + expect_false(bare$regionGiven) }) test_that("fineMappingPipeline(GwasSumStats): threads per-variant N", { @@ -2439,7 +2361,7 @@ test_that("fineMappingPipeline(GwasSumStats): threads per-variant N", { entry = list(gr), genome = "hg19", ldReference = .fmp_makeHandle(), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) captured <- new.env(parent = emptyenv()) captured$n <- "UNSET" @@ -2462,7 +2384,7 @@ test_that("fineMappingPipeline(GwasSumStats): threads per-variant N", { if (is.null(vids)) { vids <- snp_ids } - fineMappingRow( + FineMappingRow( variantIds = vids, susieFit = list(method = method), topLoci = data.frame( @@ -2492,23 +2414,28 @@ test_that("fineMappingPipeline(GwasSumStats): threads per-variant N", { # ---- PIP-screen graceful skip: a screened region -> empty result, not error ---- +# A collection whose rows QC audited as `audits` (one list per row). +.fmp_withAudits <- function(x, audits) { + x$qcAudit <- S4Vectors::SimpleList(audits) + x +} + # A GwasSumStats whose (single) entry was emptied by summaryStatsQc's PIP screen: -# 0-variant entry + qcInfo$entryAudit[[1]]$pipScreenSkipped = TRUE (+ reason). +# 0-variant entry + an audit with pipScreenSkipped = TRUE (+ reason). .fmp_makeScreenedGwas <- function( studyName = "G1", reason = "no signals above PIP threshold 0.025" ) { - GwasSumStats( + gss <- GwasSumStats( studyName = studyName, entry = list(GenomicRanges::GRanges()), genome = "hg19", ldReference = .fmp_makeHandle(), - qcInfo = list( - entryAudit = list(list( - pipScreenSkipped = TRUE, - pipScreenReason = reason - )) - ) + qcOptions = list(step1 = "ok") + ) + .fmp_withAudits( + gss, + list(list(pipScreenSkipped = TRUE, pipScreenReason = reason)) ) } @@ -2525,12 +2452,15 @@ test_that("fineMappingPipeline(GwasSumStats): a PIP-screened region yields an em expect_s4_class(res, "GwasFineMappingResult") expect_equal(nrow(res), 0L) # graceful skip, not stop("no ... tuples") # An audit recording the skip but no reason gets the screen's own. - noReason <- GwasSumStats( - studyName = "G1", - entry = list(GenomicRanges::GRanges()), - genome = "hg19", - ldReference = .fmp_makeHandle(), - qcInfo = list(entryAudit = list(list(pipScreenSkipped = TRUE))) + noReason <- .fmp_withAudits( + GwasSumStats( + studyName = "G1", + entry = list(GenomicRanges::GRanges()), + genome = "hg19", + ldReference = .fmp_makeHandle(), + qcOptions = list(step1 = "ok") + ), + list(list(pipScreenSkipped = TRUE)) ) expect_message( fineMappingPipeline( @@ -2543,16 +2473,17 @@ test_that("fineMappingPipeline(GwasSumStats): a PIP-screened region yields an em }) test_that("fineMappingPipeline(GwasSumStats): mixed screened + real keeps only the real region", { - gss <- GwasSumStats( - studyName = c("Gskip", "Greal"), - entry = list(GenomicRanges::GRanges(), .fmp_makeSumstatsGr()), - genome = "hg19", - ldReference = .fmp_makeHandle(), - qcInfo = list( - entryAudit = list( - list(pipScreenSkipped = TRUE, pipScreenReason = "no signal"), - list() - ) + gss <- .fmp_withAudits( + GwasSumStats( + studyName = c("Gskip", "Greal"), + entry = list(GenomicRanges::GRanges(), .fmp_makeSumstatsGr()), + genome = "hg19", + ldReference = .fmp_makeHandle(), + qcOptions = list(step1 = "ok") + ), + list( + list(pipScreenSkipped = TRUE, pipScreenReason = "no signal"), + list() ) ) local_mocked_bindings( @@ -2578,7 +2509,7 @@ test_that("fineMappingPipeline(GwasSumStats): a 0-variant entry is skipped even entry = list(GenomicRanges::GRanges()), genome = "hg19", ldReference = .fmp_makeHandle(), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) res <- suppressMessages( fineMappingPipeline( @@ -2592,19 +2523,17 @@ test_that("fineMappingPipeline(GwasSumStats): a 0-variant entry is skipped even }) test_that("fineMappingPipeline(QtlSumStats): a screened trait is skipped gracefully", { - qss <- QtlSumStats( - studyName = "Q1", - context = "c1", - trait = "t1", - entry = list(GenomicRanges::GRanges()), - genome = "hg19", - ldReference = .fmp_makeHandle(), - qcInfo = list( - entryAudit = list(list( - pipScreenSkipped = TRUE, - pipScreenReason = "no signal" - )) - ) + qss <- .fmp_withAudits( + QtlSumStats( + studyName = "Q1", + context = "c1", + trait = "t1", + entry = list(GenomicRanges::GRanges()), + genome = "hg19", + ldReference = .fmp_makeHandle(), + qcOptions = list(step1 = "ok") + ), + list(list(pipScreenSkipped = TRUE, pipScreenReason = "no signal")) ) res <- suppressMessages( fineMappingPipeline( @@ -2618,226 +2547,143 @@ test_that("fineMappingPipeline(QtlSumStats): a screened trait is skipped gracefu }) # ---- SER fallback (shared sumstat SuSiE-RSS path: GwasSumStats + QtlSumStats) ---- +# +# Both summary-statistics inputs reach the same SuSiE-RSS block, so each test +# runs it once per input kind. -test_that("fineMappingPipeline(GwasSumStats): serFallback + reliable R keeps multi-effect", { - gss <- .fmp_makeGwasSumStats() +test_that("fineMappingPipeline(*SumStats): serFallback keeps a reliable fit", { local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieRss = .fmp_mockFitRssDiag(flag = FALSE), .fmPostprocessOne = .fmp_mockPostprocess(), .package = "pecotmr" ) - res <- suppressMessages( - fineMappingPipeline( - gss, - methods = "susie", - initializeWithSusieInf = FALSE, - susieRssParam = SusieRssParam( - serFallback = TRUE, - rMismatch = "eb" - ) - ) - ) - sf <- susieFit(res, studyName = "G1", method = "susie") - # Multi-effect fit reported (payload keeps the multi tag, not the ser tag). - expect_equal(sf$payload$multiTag, "multi") - expect_false(sf$serFallbackUsed) - expect_false(sf$R_reliability_flag) - # keepFullFit="fallback": non-fallback region carries no retained fit. - expect_null(sf$multiEffectFit) + for (input in list(.fmp_gss, .fmp_qss)) { + kind <- class(input)[[1L]] + sf <- susieFit(.fmp_fitRss( + input, + SusieRssParam(serFallback = TRUE, rMismatch = "eb") + )) + # Multi-effect fit reported (payload keeps the multi tag, not the ser + # tag). + expect_equal(sf$payload$multiTag, "multi", info = kind) + expect_false(sf$serFallbackUsed, info = kind) + expect_false(sf$R_reliability_flag, info = kind) + # keepFullFit="fallback": non-fallback region carries no retained fit. + expect_null(sf$multiEffectFit, info = kind) + } }) -test_that("fineMappingPipeline(GwasSumStats): serFallback + unreliable R falls back to SER", { - gss <- .fmp_makeGwasSumStats() +test_that("fineMappingPipeline(*SumStats): unreliable R falls back to SER", { local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieRss = .fmp_mockFitRssDiag(flag = TRUE), .fmPostprocessOne = .fmp_mockPostprocess(), .package = "pecotmr" ) - res <- suppressMessages( - fineMappingPipeline( - gss, - methods = "susie", - initializeWithSusieInf = FALSE, - susieRssParam = SusieRssParam( - serFallback = TRUE, - rMismatch = "eb" - ) - ) - ) - sf <- susieFit(res, studyName = "G1", method = "susie") - # Reported result is the single-effect ser_model. - expect_equal(sf$payload$serTag, "ser") - expect_true(sf$serFallbackUsed) - expect_true(sf$R_reliability_flag) - # Fallback region retains the pre-fallback multi-effect fit. - expect_false(is.null(sf$multiEffectFit)) - expect_equal(sf$multiEffectFit$multiTag, "multi") + for (input in list(.fmp_gss, .fmp_qss)) { + kind <- class(input)[[1L]] + sf <- susieFit(.fmp_fitRss( + input, + SusieRssParam(serFallback = TRUE, rMismatch = "eb") + )) + # Reported result is the single-effect ser_model. + expect_equal(sf$payload$serTag, "ser", info = kind) + expect_true(sf$serFallbackUsed, info = kind) + expect_true(sf$R_reliability_flag, info = kind) + # Fallback region retains the pre-fallback multi-effect fit. + expect_false(is.null(sf$multiEffectFit), info = kind) + expect_equal(sf$multiEffectFit$multiTag, "multi", info = kind) + } }) -test_that("fineMappingPipeline(GwasSumStats): serFallback=FALSE default is behavior-preserving", { - gss <- .fmp_makeGwasSumStats() +test_that("fineMappingPipeline(*SumStats): serFallback=FALSE changes nothing", { + cap <- new.env(parent = emptyenv()) local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRssDiag(flag = TRUE), + .fmFitSusieRss = .fmp_mockFitRssDiag(flag = TRUE, capture = cap), .fmPostprocessOne = .fmp_mockPostprocess(), .package = "pecotmr" ) - res <- suppressMessages( - fineMappingPipeline( - gss, - methods = "susie", - initializeWithSusieInf = FALSE - ) - ) - sf <- susieFit(res, studyName = "G1", method = "susie") - # No fallback even though flag=TRUE; multi-effect result kept. - expect_equal(sf$payload$multiTag, "multi") - # Feature off: the susieFit carries NO diagnostic fields (byte-identical to - # pre-change behavior). - expect_false("R_reliability_flag" %in% names(sf)) - expect_false("serFallbackUsed" %in% names(sf)) - expect_false("multiEffectFit" %in% names(sf)) + for (input in list(.fmp_gss, .fmp_qss)) { + kind <- class(input)[[1L]] + sf <- susieFit(.fmp_fitRss(input)) + # With serFallback off (the default), the shared block never fires the + # fallback nor forwards a non-default rFinite/rMismatch -- even though + # the mock flags the fit unreliable -- so the multi-effect result is + # kept and the fit carries NO diagnostic fields. + expect_null(cap$rFinite, info = kind) + expect_equal(cap$rMismatch, "none", info = kind) + expect_equal(sf$payload$multiTag, "multi", info = kind) + expect_false("R_reliability_flag" %in% names(sf), info = kind) + expect_false("serFallbackUsed" %in% names(sf), info = kind) + expect_false("multiEffectFit" %in% names(sf), info = kind) + } }) -test_that("fineMappingPipeline(GwasSumStats): rFinite/rMismatch forwarded; rFinite defaults to panel N", { - gss <- .fmp_makeGwasSumStats() +test_that("fineMappingPipeline(*SumStats): SusieRssParam reaches the fitter", { + # rFinite defaults to the LD-panel sample size (40 in .fmp_makeHandle) and + # an explicit one is forwarded verbatim; rMismatch -- eb_mix too, which + # susieR >= 0.16.6 takes -- and the susie_rss_control() settings pass + # through unrestricted, and with no control the fitter sees NULL. cap <- new.env(parent = emptyenv()) local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRssDiag(flag = FALSE, capture = cap), + .fmFitSusieRss = .fmp_mockFitRssDiag(capture = cap), .fmPostprocessOne = .fmp_mockPostprocess(), .package = "pecotmr" ) - suppressMessages( - fineMappingPipeline( - gss, - methods = "susie", - initializeWithSusieInf = FALSE, - susieRssParam = SusieRssParam( - serFallback = TRUE, - rMismatch = "eb" - ) - ) - ) - # rFinite defaulted to the LD-panel sample size (40 in .fmp_makeHandle). - expect_equal(cap$rFinite, 40L) - expect_equal(cap$rMismatch, "eb") - - # Explicit rFinite is forwarded verbatim. - cap2 <- new.env(parent = emptyenv()) - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRssDiag(flag = FALSE, capture = cap2), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" - ) - suppressMessages( - fineMappingPipeline( - gss, - methods = "susie", - initializeWithSusieInf = FALSE, - susieRssParam = SusieRssParam( + control <- SusieRssControlOptions( + check_prior = TRUE, + mismatch_estimator = "map" + ) + for (input in list(.fmp_gss, .fmp_qss)) { + kind <- class(input)[[1L]] + .fmp_fitRss(input, SusieRssParam(serFallback = TRUE, rMismatch = "eb")) + expect_equal(cap$rFinite, 40L, info = kind) + expect_equal(cap$rMismatch, "eb", info = kind) + expect_null(cap$rssControl, info = kind) + .fmp_fitRss( + input, + SusieRssParam( serFallback = TRUE, rFinite = 12345, - rMismatch = "eb" - ) - ) - ) - expect_equal(cap2$rFinite, 12345) - - # eb_mix (susieR >= 0.16.6) is passed through to R_mismatch unrestricted. - cap3 <- new.env(parent = emptyenv()) - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRssDiag(flag = FALSE, capture = cap3), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" - ) - suppressMessages( - fineMappingPipeline( - gss, - methods = "susie", - initializeWithSusieInf = FALSE, - susieRssParam = SusieRssParam( - serFallback = TRUE, - rMismatch = "eb_mix" - ) - ) - ) - expect_equal(cap3$rMismatch, "eb_mix") - - # rssControl (susie_rss_control() settings) forwarded through to the fitter. - cap4 <- new.env(parent = emptyenv()) - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRssDiag(flag = FALSE, capture = cap4), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" - ) - suppressMessages( - fineMappingPipeline( - gss, - methods = "susie", - initializeWithSusieInf = FALSE, - susieRssParam = SusieRssParam( - control = SusieRssControlOptions( - check_prior = TRUE, - mismatch_estimator = "map" - ) + rMismatch = "eb_mix", + control = control ) ) - ) - expect_equal( - cap4$rssControl, - list(check_prior = TRUE, mismatch_estimator = "map") - ) - # default: no rssControl -> fitter sees NULL - cap5 <- new.env(parent = emptyenv()) - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRssDiag(flag = FALSE, capture = cap5), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" - ) - suppressMessages( - fineMappingPipeline( - gss, - methods = "susie", - initializeWithSusieInf = FALSE + expect_equal(cap$rFinite, 12345, info = kind) + expect_equal(cap$rMismatch, "eb_mix", info = kind) + expect_equal( + cap$rssControl, + list(check_prior = TRUE, mismatch_estimator = "map"), + info = kind ) - ) - expect_null(cap5$rssControl) + } }) -test_that("fineMappingPipeline(GwasSumStats): keepFullFit='all' retains fit on non-fallback region", { - gss <- .fmp_makeGwasSumStats() +test_that("fineMappingPipeline(*SumStats): keepFullFit='all' retains the fit", { local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieRss = .fmp_mockFitRssDiag(flag = FALSE), .fmPostprocessOne = .fmp_mockPostprocess(), .package = "pecotmr" ) - res <- suppressMessages( - fineMappingPipeline( - gss, - methods = "susie", - initializeWithSusieInf = FALSE, - susieRssParam = SusieRssParam( - serFallback = TRUE, - rMismatch = "eb", - keepFullFit = "all" - ) - ) - ) - sf <- susieFit(res, studyName = "G1", method = "susie") - expect_false(is.null(sf$multiEffectFit)) - expect_equal(sf$multiEffectFit$multiTag, "multi") + keepAll <- SusieRssParam( + serFallback = TRUE, + rMismatch = "eb", + keepFullFit = "all" + ) + for (input in list(.fmp_gss, .fmp_qss)) { + kind <- class(input)[[1L]] + # A region that did not fall back still keeps its multi-effect fit. + sf <- susieFit(.fmp_fitRss(input, keepAll)) + expect_false(is.null(sf$multiEffectFit), info = kind) + expect_equal(sf$multiEffectFit$multiTag, "multi", info = kind) + } }) test_that("fineMappingPipeline(QtlSumStats): top-level L / Lgreedy reach the susie fit", { - ss <- .fmp_makeQtlSumStats() cap <- new.env(parent = emptyenv()) local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), @@ -2847,7 +2693,7 @@ test_that("fineMappingPipeline(QtlSumStats): top-level L / Lgreedy reach the sus ) suppressMessages( fineMappingPipeline( - ss, + .fmp_qss, methods = "susie", initializeWithSusieInf = FALSE, credibleSetParam = CredibleSetParam( @@ -2863,7 +2709,6 @@ test_that("fineMappingPipeline(QtlSumStats): top-level L / Lgreedy reach the sus }) test_that("fineMappingPipeline(QtlSumStats): per-method L beats the top-level L", { - ss <- .fmp_makeQtlSumStats() cap <- new.env(parent = emptyenv()) local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), @@ -2873,7 +2718,7 @@ test_that("fineMappingPipeline(QtlSumStats): per-method L beats the top-level L" ) suppressMessages( fineMappingPipeline( - ss, + .fmp_qss, methods = list(susie = list(L = 7L)), initializeWithSusieInf = FALSE, credibleSetParam = CredibleSetParam(maxNumSingleEffects = 4L) @@ -2882,229 +2727,28 @@ test_that("fineMappingPipeline(QtlSumStats): per-method L beats the top-level L" expect_equal(cap$userArgs$L, 7L) }) -test_that("fineMappingPipeline(QtlSumStats): serFallback=FALSE default leaves the QTL path unchanged", { - ss <- .fmp_makeQtlSumStats() - cap <- new.env(parent = emptyenv()) - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRssDiag(flag = TRUE, capture = cap), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" - ) - res <- suppressMessages( - fineMappingPipeline( - ss, - methods = "susie", - initializeWithSusieInf = FALSE - ) - ) - expect_s4_class(res, "QtlFineMappingResult") - # With serFallback off (the default), the shared block never fires the - # fallback nor forwards a non-default rFinite/rMismatch -- even though the - # mock flags the fit unreliable -- so the result is byte-identical to before. - expect_null(cap$rFinite) - expect_equal(cap$rMismatch, "none") - sf <- susieFit( - res, - studyName = "Q1", - context = "c1", - trait = "t1", - method = "susie" - ) - expect_false("R_reliability_flag" %in% names(sf)) - expect_false("serFallbackUsed" %in% names(sf)) - expect_false("multiEffectFit" %in% names(sf)) -}) - -test_that("fineMappingPipeline(QtlSumStats): serFallback + reliable R keeps multi-effect", { - ss <- .fmp_makeQtlSumStats() - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRssDiag(flag = FALSE), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" - ) - res <- suppressMessages( - fineMappingPipeline( - ss, - methods = "susie", - initializeWithSusieInf = FALSE, - susieRssParam = SusieRssParam( - serFallback = TRUE, - rMismatch = "eb" - ) - ) - ) - sf <- susieFit( - res, - studyName = "Q1", - context = "c1", - trait = "t1", - method = "susie" - ) - # Multi-effect fit reported (payload keeps the multi tag, not the ser tag). - expect_equal(sf$payload$multiTag, "multi") - expect_false(sf$serFallbackUsed) - expect_false(sf$R_reliability_flag) - # keepFullFit="fallback": non-fallback region carries no retained fit. - expect_null(sf$multiEffectFit) -}) - -test_that("fineMappingPipeline(QtlSumStats): serFallback + unreliable R falls back to SER", { - ss <- .fmp_makeQtlSumStats() - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRssDiag(flag = TRUE), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" - ) - res <- suppressMessages( - fineMappingPipeline( - ss, - methods = "susie", - initializeWithSusieInf = FALSE, - susieRssParam = SusieRssParam( - serFallback = TRUE, - rMismatch = "eb" - ) - ) - ) - sf <- susieFit( - res, - studyName = "Q1", - context = "c1", - trait = "t1", - method = "susie" - ) - # Reported result is the single-effect ser_model. - expect_equal(sf$payload$serTag, "ser") - expect_true(sf$serFallbackUsed) - expect_true(sf$R_reliability_flag) - # Fallback region retains the pre-fallback multi-effect fit. - expect_false(is.null(sf$multiEffectFit)) - expect_equal(sf$multiEffectFit$multiTag, "multi") -}) - -test_that("fineMappingPipeline(QtlSumStats): rFinite/rMismatch forwarded; rFinite defaults to panel N", { - ss <- .fmp_makeQtlSumStats() - cap <- new.env(parent = emptyenv()) - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRssDiag(flag = FALSE, capture = cap), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" - ) - suppressMessages( - fineMappingPipeline( - ss, - methods = "susie", - initializeWithSusieInf = FALSE, - susieRssParam = SusieRssParam( - serFallback = TRUE, - rMismatch = "eb" - ) - ) - ) - # rFinite defaulted to the LD-panel sample size (40 in .fmp_makeHandle). - expect_equal(cap$rFinite, 40L) - expect_equal(cap$rMismatch, "eb") - - # Explicit rFinite is forwarded verbatim. - cap2 <- new.env(parent = emptyenv()) - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRssDiag(flag = FALSE, capture = cap2), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" - ) - suppressMessages( - fineMappingPipeline( - ss, - methods = "susie", - initializeWithSusieInf = FALSE, - susieRssParam = SusieRssParam( - serFallback = TRUE, - rFinite = 12345, - rMismatch = "eb" - ) - ) - ) - expect_equal(cap2$rFinite, 12345) -}) - -test_that("fineMappingPipeline(QtlSumStats): keepFullFit='all' retains fit on non-fallback region", { - ss <- .fmp_makeQtlSumStats() - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRssDiag(flag = FALSE), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" - ) - res <- suppressMessages( - fineMappingPipeline( - ss, - methods = "susie", - initializeWithSusieInf = FALSE, - susieRssParam = SusieRssParam( - serFallback = TRUE, - rMismatch = "eb", - keepFullFit = "all" - ) - ) - ) - sf <- susieFit( - res, - studyName = "Q1", - context = "c1", - trait = "t1", - method = "susie" - ) - expect_false(is.null(sf$multiEffectFit)) - expect_equal(sf$multiEffectFit$multiTag, "multi") -}) - -test_that("fineMappingPipeline(GwasSumStats): un-QCd input rejected", { - gss <- .fmp_makeGwasSumStats(qc = FALSE) - expect_error( - fineMappingPipeline(gss, methods = "susie"), - "has no QC record" - ) -}) - test_that("fineMappingPipeline(GwasSumStats): non-RSS family rejected by capability check", { - gss <- .fmp_makeGwasSumStats() expect_error( - fineMappingPipeline(gss, methods = "fsusie"), + fineMappingPipeline(.fmp_gss, methods = "fsusie"), "not supported on GwasSumStats" ) }) # ---- ser (LD-free single-effect regression); sumstat-only, not GWAS-only ---- -test_that("fineMappingPipeline(QtlSumStats): ser dispatches via .fmFitSusieSer", { - ss <- .fmp_makeQtlSumStats() +test_that("fineMappingPipeline(*SumStats): ser runs via .fmFitSusieSer", { local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieSer = .fmp_mockFitSer(), .fmPostprocessOne = .fmp_mockPostprocess(), .package = "pecotmr" ) - res <- suppressMessages(fineMappingPipeline(ss, methods = "ser")) - expect_s4_class(res, "QtlFineMappingResult") - expect_setequal(methodNames(res), "ser") -}) - -test_that("fineMappingPipeline(GwasSumStats): ser dispatches via .fmFitSusieSer", { - gss <- .fmp_makeGwasSumStats() - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieSer = .fmp_mockFitSer(), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" - ) - res <- suppressMessages(fineMappingPipeline(gss, methods = "ser")) - expect_s4_class(res, "GwasFineMappingResult") - expect_setequal(methodNames(res), "ser") + for (input in list(.fmp_qss, .fmp_gss)) { + kind <- class(input)[[1L]] + res <- suppressMessages(fineMappingPipeline(input, methods = "ser")) + expect_s4_class(res, .fmp_resultClass[[kind]]) + expect_equal(methodNames(res), "ser", info = kind) + } }) test_that("ser is sumstat-only: rejected on QtlDataset, allowed on all sumstat kinds", { @@ -3143,20 +2787,12 @@ test_that("fineMappingPipeline(ANY): unsupported input class errors", { }) # =========================================================================== -# Cache hit short-circuits the fit -# =========================================================================== - -# =========================================================================== -# .fmFitSusieIndiv / .fmFitSusieRss — chained-init and branch coverage -# =========================================================================== - -# =========================================================================== -# QtlSumStats: empty selection, mvsusie single-context rejection, cache hits +# QtlSumStats: mvsusie single-context rejection and auto-detection, cache hits # =========================================================================== .fmp_makeMultiCtxQtlSumStats <- function() { - # Multi-row QtlSumStats: 2 contexts x 1 trait so the test can filter to - # a single context and exercise both selRows filters. + # Multi-row QtlSumStats: 2 contexts x 1 trait, the shape a cross-context + # joint fit takes. e1 <- .fmp_makeSumstatsGr() e2 <- .fmp_makeSumstatsGr() QtlSumStats( @@ -3166,22 +2802,11 @@ test_that("fineMappingPipeline(ANY): unsupported input class errors", { entry = list(e1, e2), genome = "hg19", ldReference = .fmp_makeHandle(), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) } -test_that("fineMappingPipeline(QtlSumStats): traitId filter that selects no rows errors", { - ss <- .fmp_makeMultiCtxQtlSumStats() - expect_error( - fineMappingPipeline(ss, methods = "susie", traitId = "ghost"), - "no entries matched" - ) -}) - -test_that("fineMappingPipeline( - QtlSumStats): mvsusie rejected when every (study, - trait -) has only one context", { +test_that("fineMappingPipeline(QtlSumStats): mvsusie needs two contexts", { # Build a single-context-per-(study, trait) collection. Mvsusie requires # at least two contexts per (study, trait) group. ss <- QtlSumStats( @@ -3191,7 +2816,7 @@ test_that("fineMappingPipeline( entry = list(.fmp_makeSumstatsGr(), .fmp_makeSumstatsGr()), genome = "hg19", ldReference = .fmp_makeHandle(), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) expect_error( fineMappingPipeline(ss, methods = "mvsusie"), @@ -3199,10 +2824,7 @@ test_that("fineMappingPipeline( ) }) -test_that("fineMappingPipeline( - QtlSumStats): mvsusie auto-detection fits cross-context per (study, - trait -)", { +test_that("fineMappingPipeline(QtlSumStats): mvsusie auto-joins contexts", { # Multi-context (c1, c2) single-trait collection: mvsusie without an explicit # jointSpecification routes through the joint engine -> per-context rows that # share the cross-context RSS fit, each tagged with the co-fit membership. @@ -3228,8 +2850,8 @@ test_that("fineMappingPipeline( }) test_that("fineMappingPipeline(QtlSumStats): cache hit short-circuits the RSS fitter", { - ss <- .fmp_makeQtlSumStats() - cachedEntry <- fineMappingRow( + ss <- .fmp_qss + cachedEntry <- FineMappingRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), susieFit = list(token = "susie_cached"), topLoci = data.frame( @@ -3273,8 +2895,8 @@ test_that("fineMappingPipeline(QtlSumStats): cache hit short-circuits the RSS fi # =========================================================================== test_that("fineMappingPipeline(GwasSumStats): cache hit short-circuits the RSS fitter", { - gss <- .fmp_makeGwasSumStats() - cachedEntry <- fineMappingRow( + gss <- .fmp_gss + cachedEntry <- FineMappingRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), susieFit = list(token = "susie_cached"), topLoci = data.frame( @@ -3320,8 +2942,8 @@ test_that("fineMappingPipeline(GwasSumStats): wrong-shape cache (QtlFineMappingR # When `fineMappingResult` is a QtlFineMappingResult the GwasSumStats # method's cache-lookup branch should treat it as a cache miss and # still invoke the RSS fitter. - gss <- .fmp_makeGwasSumStats() - cachedEntry <- fineMappingRow( + gss <- .fmp_gss + cachedEntry <- FineMappingRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:5)), susieFit = list(token = "susie_cached"), topLoci = data.frame( @@ -3360,9 +2982,9 @@ test_that("fineMappingPipeline(GwasSumStats): wrong-shape cache (QtlFineMappingR }) test_that("fineMappingPipeline(QtlDataset): cache hit avoids the fitter", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + qd <- .fmp_qdA # Build a cache that already has the (study1, brain, ENSG_A, susie) row. - cachedEntry <- fineMappingRow( + cachedEntry <- FineMappingRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), susieFit = list(token = "susie_cached"), topLoci = data.frame( @@ -3401,87 +3023,11 @@ test_that("fineMappingPipeline(QtlDataset): cache hit avoids the fitter", { expect_equal(nrow(res), 1L) }) - -context("univariate_pipeline") - -# =========================================================================== -# Post-S4-refactor cleanup -# --------------------------------------------------------------------------- -# The S4 refactor removed `univariateAnalysisPipeline()`, -# `rssAnalysisPipeline()`, `loadStudyLd()`, `loadRssData()`, and -# `rssBasicQc()` as functional pipelines. They are now `.Deprecated()` -# no-ops that return `NULL` invisibly. The `QcResult` / -# `FineMappingResult` classes and `regionDataToSusieRssInput()` helper -# were also removed. Their replacements live behind a different S4 API -# (`fineMappingPipeline()` dispatched on `GwasSumStats` / `QtlSumStats` / -# `QtlDataset`, `summaryStatsQc()`, `fineMappingRow()`) with different -# signatures and contracts, so the legacy mocked pipeline tests cannot -# be ported in a meaningful way and have been removed. -# -# What survives in this file: -# * Deprecation no-op checks for the removed public wrappers. -# * Tests for `resolveLdInput()`, which is still a live internal helper -# in `dentistQc.R` with an unchanged signature. -# =========================================================================== - -# =========================================================================== -# resolveLdInput (still-live internal helper in dentistQc.R) -# =========================================================================== - -test_that("resolveLdInput errors when both R and X are NULL", { - expect_error( - pecotmr:::resolveLdInput(R = NULL, X = NULL), - "Either R .* or X .* must be provided" - ) -}) - -test_that("resolveLdInput errors when both R and X are provided", { - R <- diag(5) - X <- matrix(rnorm(50), 10, 5) - expect_error( - pecotmr:::resolveLdInput(R = R, X = X), - "Provide either R or X, not both" - ) -}) - -test_that("resolveLdInput with R returns R unchanged", { - R <- diag(5) - result <- pecotmr:::resolveLdInput(R = R, nSample = 100) - expect_equal(result$R, R) - expect_equal(result$nSample, 100) -}) - -test_that("resolveLdInput with X computes LD and infers nSample", { - set.seed(42) - X <- matrix(rbinom(200, 2, 0.3), 20, 10) - result <- pecotmr:::resolveLdInput(X = X) - expect_equal(nrow(result$R), 10) - expect_equal(ncol(result$R), 10) - expect_equal(result$nSample, 20) -}) - -test_that("resolveLdInput errors when nSample required but missing", { - R <- diag(5) - expect_error( - pecotmr:::resolveLdInput(R = R, needNSample = TRUE), - "nSample is required" - ) -}) - -test_that("resolveLdInput does not error when nSample not needed", { - R <- diag(5) - result <- pecotmr:::resolveLdInput(R = R, needNSample = FALSE) - expect_equal(result$R, R) - expect_null(result$nSample) -}) # =========================================================================== # Residualization settings propagation # =========================================================================== -# These used to be four loose flags scraped off the call stack by -# .resPickFlags() (sys.frames() + get(envir = )), then four translated -# argument names via .resArgsFor(). The accessors now take the bundle -# itself, so there is no translation left to test -- only that the bundle -# travels intact. +# The accessors take the ResidualizationParam bundle itself, so there is no +# translation to test -- only that the bundle travels intact. test_that(".fmResidGeno / .fmResidPheno forward the bundle to the accessors", { capturedGeno <- NULL @@ -3492,11 +3038,11 @@ test_that(".fmResidGeno / .fmResidPheno forward the bundle to the accessors", { } fakePheno <- function(x, ...) { capturedPheno <<- list(...) - matrix(0, 0, 0) + list(c1 = matrix(0, 0, 0)) } local_mocked_bindings( - residualizedGenotypes = fakeGeno, - residualizedPhenotypes = fakePheno, + .qtlResidualizedGenotypes = fakeGeno, + .qtlResidualizedPhenotypes = fakePheno, .package = "pecotmr" ) res <- ResidualizationParam( @@ -3506,7 +3052,12 @@ test_that(".fmResidGeno / .fmResidPheno forward the bundle to the accessors", { ) # Passed, not scraped: the settings reach the accessors because the # caller hands them over, with no enclosing frame involved. - pecotmr:::.fmResidGeno(NULL, contexts = "c1", residualizationParam = res) + pecotmr:::.fmResidGeno( + NULL, + contexts = "c1", + residualizationParam = res, + genotypeFilter = pecotmr:::.qtlResolveFilter() + ) pecotmr:::.fmResidPheno(NULL, contexts = "c1", residualizationParam = res) for (captured in list(capturedGeno, capturedPheno)) { got <- captured$residualizationParam @@ -3520,9 +3071,9 @@ test_that(".fmResidGeno / .fmResidPheno forward the bundle to the accessors", { test_that("an absent bundle becomes the constructor's own defaults", { captured <- NULL local_mocked_bindings( - residualizedPhenotypes = function(x, ...) { + .qtlResidualizedPhenotypes = function(x, ...) { captured <<- list(...) - matrix(0, 0, 0) + list(c1 = matrix(0, 0, 0)) }, .package = "pecotmr" ) @@ -3532,49 +3083,6 @@ test_that("an absent bundle becomes the constructor's own defaults", { expect_length(captured$residualizationParam, 0L) }) -# =========================================================================== -# Removed during the post-S4-refactor cleanup (for traceability) -# --------------------------------------------------------------------------- -# univariateAnalysisPipeline input-validation tests (12): -# * X non-matrix / non-numeric / Y non-numeric / multi-column Y / -# single-column Y / X-Y row mismatch / maf length mismatch / -# maf out of bounds / invalid xScalar / wrong-length xScalar / -# non-numeric yScalar / non-positive L / non-positive lGreedy. -# univariateAnalysisPipeline functional tests (4): -# * minimal valid input; twasWeights = TRUE; respects xScalar; -# cvFolds = 0. -# univariateAnalysisPipeline mocked-pipeline tests (16): -# * pip_cutoff_to_skip branch (3); LD reference filtering (2); -# filter_X branch (2); main susie + post-processing (4); -# TWAS weights (4); coverage forwarding (2); combined LD + -# filter_X (1); null imiss/maf cutoffs (1). -# univariateAnalysisPipeline af/maf single-source tests (6): -# * af supplied (no maf); maf supplied (no af); both disagreeing; -# neither with mafCutoff errors; neither without mafCutoff runs; -# af-derived MAF parity with explicit maf. -# rssAnalysisPipeline tests (~21): -# * input-file validation; empty sumstats branches; pip_cutoff_to_skip -# branches; full QC + imputation + fine-mapping; method-name -# conventions (NO_QC / SLALOM / DENTIST / RAISS); outlierNumber -# plumbing; finemappingMethod = NULL skip; ldMismatchQcMethod = NULL; -# impute = FALSE; diagnostics branches (BCR + SER re-analysis); -# finemappingOpts passthrough; mafCutoff (af single source); -# finemapping-defaults passthrough; X-as-LD genotype path; -# mixture-LD passthrough. -# regionDataToSusieRssInput tests (3): -# * correlation-backed input; genotype-backed input; rejects -# default rownames as variant IDs. -# loadStudyLd tests (2): -# * single path returns loadLdMatrix output unchanged; comma-separated -# paths build a mixture LdData with a list of genotype handles. -# -# Replacement APIs (do NOT speculatively port — that is out of scope for -# this cleanup): `fineMappingPipeline()` dispatched on `GwasSumStats` / -# `QtlSumStats` / `QtlDataset`; `summaryStatsQc()` (returns a SumStats -# with `qcInfo()` populated); `fineMappingRow(variantIds, ...)`; -# `result$finemappingEntry` (was `result$finemappingResult`). -# =========================================================================== - # =========================================================================== # Multi-region / jointRegions (P3) # =========================================================================== @@ -3599,7 +3107,7 @@ test_that(".fmMergeEntries concatenates variants, renumbers CS, lists susieFit", # Ids must encode coordinates: the merge now emits a row payload, whose # element is built from the range and alleles the id renders. mk <- function(vids, cs95, fit) { - fineMappingRow( + FineMappingRow( variantIds = vids, susieFit = fit, topLoci = data.frame( @@ -3625,10 +3133,11 @@ test_that(".fmMergeEntries concatenates variants, renumbers CS, lists susieFit", expect_equal(names(fit), c("region1", "region2")) }) -test_that(".fmMergeEntries returns a single entry unchanged", { +test_that(".fmMergeEntries: no entries -> NULL; one comes back unchanged", { + expect_null(pecotmr:::.fmMergeEntries(list(NULL, NULL))) # Ids must encode coordinates now: the payload builds its element from the # range and alleles the id renders. - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(), topLoci = data.frame(variant_id = "chr1:100:A:G", pip = 0.5) @@ -3644,7 +3153,7 @@ test_that(".fmMergeEntries renumbers past a region with no cs column", { if (!is.null(cs95)) { tl$cs_95 <- cs95 } - fineMappingRow(variantIds = vids, susieFit = NULL, topLoci = tl) + FineMappingRow(variantIds = vids, susieFit = NULL, topLoci = tl) } m <- pecotmr:::.fmMergeEntries(list( mk("chr1:100:A:G", "susie_1"), @@ -3655,8 +3164,22 @@ test_that(".fmMergeEntries renumbers past a region with no cs column", { expect_equal(tl$cs_95, c("susie_1", NA, "susie_2")) }) +test_that("fineMappingPipeline(QtlDataset): region is a GRanges", { + # Given in R, a window is a GRanges; a string or a table is refused rather + # than read, so its base is never in doubt. + expect_error( + fineMappingPipeline( + .fmp_qdAB, + methods = "susie", + region = "chr1:1-600" + ), + "`region` must be a GRanges (got character)", + fixed = TRUE + ) +}) + test_that("fineMappingPipeline(QtlDataset): region + cisWindow is rejected", { - qd <- .fmp_makeQtlDataset() + qd <- .fmp_qdAB expect_error( fineMappingPipeline( qd, @@ -3669,10 +3192,7 @@ test_that("fineMappingPipeline(QtlDataset): region + cisWindow is rejected", { }) test_that("fineMappingPipeline(QtlDataset): jointRegions=FALSE merges per-region fits", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -3705,7 +3225,7 @@ test_that("fineMappingPipeline(QtlDataset): jointRegions=FALSE merges per-region }) test_that("fineMappingPipeline(QtlDataset): jointRegions=TRUE fits one concatenated block", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + qd <- .fmp_qdA local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -3737,10 +3257,7 @@ test_that("fineMappingPipeline(QtlDataset): jointRegions=TRUE fits one concatena }) test_that("fineMappingPipeline(QtlDataset): mvsusie jointRegions=FALSE merges per-region fits", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmPostprocessOne = .fmp_mockPostprocess(), @@ -3774,10 +3291,7 @@ test_that("fineMappingPipeline(QtlDataset): mvsusie jointRegions=FALSE merges pe }) test_that("fineMappingPipeline(QtlDataset): fsusie jointRegions=FALSE merges per-region fits", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmPostprocessOne = .fmp_mockPostprocess(), @@ -3809,10 +3323,9 @@ test_that("fineMappingPipeline(QtlDataset): fsusie jointRegions=FALSE merges per }) test_that("fineMappingPipeline(QtlDataset): jointSpec + jointRegions=FALSE merges per region", { - qd <- .fmp_makeQtlDataset( - contexts = c("brain", "liver"), - traits = c("ENSG_A", "ENSG_B") - ) + # One trait: the cross-context joint and the per-region merge are what is + # tested, and each further trait only repeats them. + qd <- .fmp_qdTwoCtxA local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmPostprocessOne = .fmp_mockPostprocess(), @@ -3830,15 +3343,15 @@ test_that("fineMappingPipeline(QtlDataset): jointSpec + jointRegions=FALSE merge res <- suppressMessages(fineMappingPipeline( qd, methods = "mvsusie", - traitId = c("ENSG_A", "ENSG_B"), + traitId = "ENSG_A", region = regions, jointRegions = FALSE, jointSpecification = "context" )) expect_s4_class(res, "QtlFineMappingResult") - # cross-context joint -> per-context rows (2 contexts x 2 traits = 4), each - # merged across the 2 regions. - expect_equal(nrow(res), 4L) + # cross-context joint -> one row per context, each merged across the 2 + # regions. + expect_equal(nrow(res), 2L) expect_setequal(as.character(res$context), c("brain", "liver")) fit <- susieFit( res, @@ -3871,7 +3384,7 @@ test_that(".fmCacheLookupGwas: NULL / non-GwasFineMappingResult -> NULL", { context = "c1", trait = "t1", method = "susie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( "chr1:100:A:G", list(), data.frame(variant_id = "chr1:100:A:G", pip = 0.9) @@ -3899,7 +3412,7 @@ test_that(".fmBuildMvsusiePriorCv: NULL CV -> NULL; NULL fold fits are skipped", c("c1", "c2") ) expect_equal(out[["1"]], "PRIOR") - expect_null(out[["2"]]) # NULL fold -> next (831) + expect_null(out[["2"]]) # a NULL fold fit is skipped }) test_that(".fmFoldFitAt finds a fold's fit by name, else by position", { @@ -3913,84 +3426,31 @@ test_that(".fmFoldFitAt finds a fold's fit by name, else by position", { expect_null(fn(3L, c(1, 2, 3), unnamed)) }) -test_that(".fmTopPcScores: PCA scores for multi-trait Y; degenerate inputs -> NULL", { - expect_null(pecotmr:::.fmTopPcScores(matrix(1, 5, 1), 2L)) # < 2 traits - expect_null(pecotmr:::.fmTopPcScores(matrix(c(1, NA), 2, 2), 2L)) # < 2 complete - expect_null(pecotmr:::.fmTopPcScores( - cbind(a = rep(1, 4), b = rnorm(4)), - 2L - )) # < 2 nonzero-var - set.seed(1) - Y <- matrix( - rnorm(20), - 10, - 2, - dimnames = list(paste0("s", 1:10), c("t1", "t2")) - ) - sc <- pecotmr:::.fmTopPcScores(Y, 2L) - expect_equal(dim(sc), c(10L, 2L)) - expect_equal(colnames(sc), c("topPC1", "topPC2")) -}) - -test_that(".fmMergeEntries: empty -> NULL; merges per-region entries + relabels CS", { - expect_null(pecotmr:::.fmMergeEntries(list(NULL, NULL))) - e1 <- fineMappingRow( - "chr1:100:A:G", - list(a = 1), - data.frame(variant_id = "chr1:100:A:G", pip = 0.9, cs_95 = "susie_1") - ) - e2 <- fineMappingRow( - "chr1:200:A:G", - list(b = 2), - data.frame(variant_id = "chr1:200:A:G", pip = 0.8, cs_95 = "susie_1") - ) - m <- pecotmr:::.fmMergeEntries(list(e1, e2)) - expect_equal( - pecotmr:::.fmrPartsVariantIds(m), - c("chr1:100:A:G", "chr1:200:A:G") - ) - # region2's CS is relabelled - expect_equal( - pecotmr:::.fmrPartsTopLoci(m)$cs_95, - c("susie_1", "susie_2") - ) - expect_equal( - names(pecotmr:::.fmrPartsSusieFit(m)), - c("region1", "region2") - ) -}) - test_that(".fmTwasMethodKey: bare token without adapter returned unchanged", { - expect_equal(pecotmr:::.fmTwasMethodKey("lasso"), "lasso") # no adapter (1170) + expect_equal(pecotmr:::.fmTwasMethodKey("lasso"), "lasso") # no adapter expect_equal(pecotmr:::.fmTwasMethodKey("susie"), "susie") # adapter -> stripped }) -test_that(".cvMetricRow: < 3 usable predictions -> all-NA row", { - expect_true(all(is.na(pecotmr:::.cvMetricRow(c(1, 2), c(1, 2))))) # < 3 (1182) - ok <- pecotmr:::.cvMetricRow(c(1, 2, 3, 4, 5), c(1.1, 2, 2.9, 4, 5)) - expect_false(is.na(ok[["rsq"]])) -}) - test_that(".fmSliceCv: NULL cv or missing predicted key -> NULL", { - expect_null(pecotmr:::.fmSliceCv(NULL, "susie")) # 1323 + expect_null(pecotmr:::.fmSliceCv(NULL, "susie")) cv <- list( samplePartition = NULL, prediction = list(enet_predicted = matrix(0, 1, 1)), performance = list(enet_performance = matrix(0, 1, 6)) ) - expect_null(pecotmr:::.fmSliceCv(cv, "susie")) # pk absent (1327) + expect_null(pecotmr:::.fmSliceCv(cv, "susie")) # no susie_predicted key expect_true( "enet_predicted" %in% names(pecotmr:::.fmSliceCv(cv, "enet")$prediction) ) }) test_that(".fmAttachCv: NULL entry or NULL cvResult returns the entry unchanged", { - e <- fineMappingRow( + e <- FineMappingRow( "chr1:100:A:G", list(), data.frame(variant_id = "chr1:100:A:G", pip = 0.9) ) - expect_identical(pecotmr:::.fmAttachCv(e, NULL), e) # 1336 + expect_identical(pecotmr:::.fmAttachCv(e, NULL), e) expect_null(pecotmr:::.fmAttachCv(NULL, list(x = 1))) expect_equal( pecotmr:::.fmrPartsCvResult( @@ -4001,27 +3461,17 @@ test_that(".fmAttachCv: NULL entry or NULL cvResult returns the entry unchanged" }) # ---- jointSpec dispatch branches in the QtlSumStats / MultiStudy methods ----- -# (dispatchers mocked; the real joint fitting is covered in test_jointSpecification.R) - -test_that(".fmTopPcScores: nPCs = 0 -> k < 1 -> NULL", { - set.seed(3) - Y <- matrix( - rnorm(20), - 10, - 2, - dimnames = list(paste0("s", 1:10), c("t1", "t2")) - ) - expect_null(pecotmr:::.fmTopPcScores(Y, 0L)) # k < 1 (858) -}) +# (dispatchers mocked; the real joint fitting is covered in +# test_jointSpecification.R) test_that("fineMappingPipeline(QtlSumStats): mvsusie-only jointSpec returns the joint result", { - ss <- .fmp_makeQtlSumStats() + ss <- .fmp_qss jr <- QtlFineMappingResult( studyName = "Q1", context = "c1", trait = "t1", method = "mvsusie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( "chr1:100:A:G", list(), data.frame(variant_id = "chr1:100:A:G", pip = 0.9) @@ -4039,19 +3489,19 @@ test_that("fineMappingPipeline(QtlSumStats): mvsusie-only jointSpec returns the ) ) expect_s4_class(res, "QtlFineMappingResult") - expect_setequal(as.character(res$method), "mvsusie") # 1843-1857 + expect_setequal(as.character(res$method), "mvsusie") }) test_that("fineMappingPipeline(QtlSumStats): joint spec plus per-entry susie", { # The joint spec consumes mvsusie; susie, asked for alongside it, still # runs per entry, and the two results are combined. - ss <- .fmp_makeQtlSumStats() + ss <- .fmp_qss jr <- QtlFineMappingResult( studyName = "Q1", context = "c1", trait = "t1", method = "mvsusie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( "chr1:100:A:G", list(), data.frame(variant_id = "chr1:100:A:G", pip = 0.9) @@ -4090,14 +3540,13 @@ test_that("fineMappingPipeline(QtlSumStats): no auto-joint fit is an error", { }) test_that("fineMappingPipeline(QtlSumStats): mvsusie-only jointSpec with no fits -> error", { - ss <- .fmp_makeQtlSumStats() local_mocked_bindings( .fmDispatchJointSpecsQtlSumStats = function(...) NULL, .package = "pecotmr" ) expect_error( suppressMessages(fineMappingPipeline( - ss, + .fmp_qss, methods = "mvsusie", jointSpecification = "context" )), @@ -4105,21 +3554,12 @@ test_that("fineMappingPipeline(QtlSumStats): mvsusie-only jointSpec with no fits ) }) -.fmp_makeMultiStudy <- function() { - MultiStudyQtlDataset( - qtlDatasets = list( - study1 = .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") - ), - sumStats = .fmp_makeQtlSumStats() - ) -} - test_that("MultiStudyQtlDataset forwards the mvsusie prior settings", { # `mrmashPrior` and `dataDrivenPriorWeightsCutoff` configure the mvsusie # data-driven reweighted prior. They used to reach ONLY jointCfg (the # cross-study joint phase); the per-study config omitted them, so every # per-study recursion silently refit mr.mash and used the 1e-10 cutoff. - mt <- .fmp_makeMultiStudy() + mt <- .fmp_msqd seen <- new.env(parent = emptyenv()) seen$perStudy <- NULL seen$sumStats <- NULL @@ -4152,26 +3592,58 @@ test_that("MultiStudyQtlDataset forwards the mvsusie prior settings", { } }) +test_that("fineMappingPipeline(MSQD) lays cisWindow on its sumstats", { + local_mocked_bindings( + extractBlockGenotypes = .fmp_mockExtractor(), + .fmFitSusieIndiv = .fmp_mockFitIndiv(), + .fmFitSusieRss = .fmp_mockFitRss(), + .fmPostprocessOne = .fmp_mockPostprocess(), + .package = "pecotmr" + ) + res <- suppressMessages(fineMappingPipeline( + .fmp_msqd, + methods = "susie", + cisWindow = 100L, + initializeWithSusieInf = FALSE + )) + fromSumStats <- which(res$study == "Q1") + expect_identical( + as.character(genomicRegion(res)[fromSumStats]), + "chr1:200-400" + ) + # A summary-statistics study without a trait position is an error, as it + # is on its own. + bare <- MultiStudyQtlDataset( + qtlDatasets = list(study1 = .fmp_qdA), + sumStats = .fmp_qss + ) + expect_error( + fineMappingPipeline(bare, methods = "susie", cisWindow = 100L), + "fineMappingPipeline: `cisWindow` is laid around each tuple's trait", + fixed = TRUE + ) +}) + test_that("fineMappingPipeline(MultiStudyQtlDataset): region + cisWindow is rejected", { expect_error( fineMappingPipeline( - .fmp_makeMultiStudy(), + .fmp_msqd, methods = "mvsusie", region = GenomicRanges::GRanges("chr1", IRanges::IRanges(1, 100)), cisWindow = 1000L ), "specify either" - ) # 1694 + ) }) test_that("fineMappingPipeline(MultiStudyQtlDataset): mvsusie-only jointSpec returns the joint result", { - mt <- .fmp_makeMultiStudy() + mt <- .fmp_msqd jr <- QtlFineMappingResult( studyName = "study1", context = "brain", trait = "ENSG_A", method = "mvsusie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( "chr1:100:A:G", list(), data.frame(variant_id = "chr1:100:A:G", pip = 0.9) @@ -4189,19 +3661,19 @@ test_that("fineMappingPipeline(MultiStudyQtlDataset): mvsusie-only jointSpec ret ) ) expect_s4_class(res, "QtlFineMappingResult") - expect_setequal(as.character(res$method), "mvsusie") # 1709-1726 + expect_setequal(as.character(res$method), "mvsusie") }) test_that("fineMappingPipeline(MultiStudy): joint spec, rest per component", { # The joint spec consumes mvsusie; susie, asked for alongside it, still # runs on every component -- the study and the embedded sumstats. - mt <- .fmp_makeMultiStudy() + mt <- .fmp_msqd jr <- QtlFineMappingResult( studyName = "study1", context = "brain", trait = "ENSG_A", method = "mvsusie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( "chr1:100:A:G", list(), data.frame(variant_id = "chr1:100:A:G", pip = 0.9) @@ -4227,10 +3699,42 @@ test_that("fineMappingPipeline(MultiStudy): joint spec, rest per component", { expect_gt(sum(res$method == "susie"), 1L) }) -test_that("fineMappingPipeline(MultiStudy): an unselected component sits out", { - # One context vector applies to every component; one lacking it keeps - # none of its tuples and contributes no rows. - mt <- .fmp_makeMultiStudy() +test_that("fineMappingPipeline(MultiStudy): an unselected component sits out", { + # One context vector applies to every component; one lacking it keeps + # none of its tuples and contributes no rows. + mt <- .fmp_msqd + local_mocked_bindings( + extractBlockGenotypes = .fmp_mockExtractor(), + .fmFitSusieIndiv = .fmp_mockFitIndiv(), + .fmFitSusieRss = .fmp_mockFitRss(), + .fmPostprocessOne = .fmp_mockPostprocess(), + .package = "pecotmr" + ) + fit <- function(contexts) { + suppressMessages(fineMappingPipeline( + mt, + methods = "susie", + contexts = contexts, + cisWindow = 1000L, + initializeWithSusieInf = FALSE + )) + } + expect_warning( + sumstatsOnly <- fit("c1"), + "study 'study1' is missing requested context\\(s\\): c1" + ) + expect_setequal(as.character(sumstatsOnly$study), "Q1") + expect_warning( + studyOnly <- fit("brain"), + "study 'Q1' is missing requested context\\(s\\): brain" + ) + expect_setequal(as.character(studyOnly$study), "study1") +}) + +test_that("fineMappingPipeline(MultiStudy): trait selection skips a study", { + # A trait vector applies to every component too: one carrying none of + # the traits sits out, and the run is refused only when none carries any. + mt <- .fmp_msqd local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -4238,37 +3742,34 @@ test_that("fineMappingPipeline(MultiStudy): an unselected component sits out", { .fmPostprocessOne = .fmp_mockPostprocess(), .package = "pecotmr" ) - fit <- function(contexts) { + fit <- function(traitId) { suppressMessages(fineMappingPipeline( mt, methods = "susie", - contexts = contexts, + traitId = traitId, cisWindow = 1000L, initializeWithSusieInf = FALSE )) } - expect_warning( - sumstatsOnly <- fit("c1"), - "study 'study1' is missing requested context\\(s\\): c1" - ) - expect_setequal(as.character(sumstatsOnly$study), "Q1") - expect_warning( - studyOnly <- fit("brain"), - "study 'Q1' is missing requested context\\(s\\): brain" + expect_setequal(as.character(fit("t1")$study), "Q1") + expect_setequal(as.character(fit("ENSG_A")$study), "study1") + expect_error( + fit("absent"), + "fineMappingPipeline(MultiStudyQtlDataset): no traits selected.", + fixed = TRUE ) - expect_setequal(as.character(studyOnly$study), "study1") }) test_that("fineMappingPipeline(MultiStudy): joint rows record scale override", { # The study's own slot scales its residuals; the per-call override says # otherwise and wins, and the joint rows record what was used. - mt <- .fmp_makeMultiStudy() + mt <- .fmp_msqd jr <- QtlFineMappingResult( studyName = "study1", context = "brain", trait = "ENSG_A", method = "mvsusie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( "chr1:100:A:G", list(), data.frame(variant_id = "chr1:100:A:G", pip = 0.9) @@ -4396,7 +3897,7 @@ test_that(".fmPostprocessOne wraps a fit into a FineMappingRow", { postprocessFinemappingFits = function(...) list(x = 1), formatFinemappingOutput = function(post, primaryMethod, ...) { list( - finemappingEntry = fineMappingRow( + finemappingEntry = FineMappingRow( "chr1:100:A:G", list(), data.frame(variant_id = "chr1:100:A:G", pip = 0.5) @@ -4441,11 +3942,26 @@ test_that(".fmPostprocessOne errors when output carries no FineMappingRow", { ) }) -test_that(".fmWeightsCv covers per-fold prior, NULL-weights, and no-overlap branches", { - # mvPriorCv supplies a prior for fold "1" only: fold 1 takes the per-fold - # prior (else-branch) and returns weights whose rownames don't overlap the - # test columns (no-common `next`); fold 2 has no prior, so .fmFoldWeights - # returns NULL (NULL-weights `next`). +test_that(".fmWeightsCv: fold prior else mvPrior; weightless folds give NA", { + # Three folds of ten. Fold 1 has its own prior in mvPriorCv and weights + # (all 1) on the test variants; fold 2 has its own prior but its fit + # returns no weights; fold 3 has no prior of its own, so it takes the + # full-data mvPrior, and its weights share no variant with the test + # genotypes. Each fold fit records the prior it was handed. + set.seed(3) + X <- matrix( + rbinom(60, 2, 0.4), + 30, + 2, + dimnames = list(str_c("s", 1:30), c("chr1:100:A:G", "chr1:200:A:G")) + ) + Y <- matrix(rnorm(60), 30, 2, dimnames = list(rownames(X), c("c1", "c2"))) + sp <- data.frame(Sample = rownames(X), Fold = rep(1:3, each = 10)) + fullPrior <- list(priorVariance = diag(2) * 3) + foldPriors <- list( + "1" = list(priorVariance = diag(2)), + "2" = list(priorVariance = diag(2) * 2) + ) local_mocked_bindings( .fmFoldWeights = function( token, @@ -4456,75 +3972,69 @@ test_that(".fmWeightsCv covers per-fold prior, NULL-weights, and no-overlap bran pos, mvPrior ) { - if (is.null(mvPrior)) { + trained <- sp$Fold[is_in(sp$Sample, rownames(Xtr))] + heldOut <- setdiff(sp$Fold, trained) + if (heldOut == 2L) { return(NULL) } - matrix(0.5, 1L, 1L, dimnames = list("not_a_variant", NULL)) + vars <- if (heldOut == 1L) colnames(Xtr) else "not_a_variant" + W <- matrix(1, length(vars), ncol(Ytr), dimnames = list(vars, NULL)) + `attr<-`(W, "fit", list(prior = mvPrior)) }, .package = "pecotmr" ) - set.seed(3) - X <- matrix( - rbinom(40, 2, 0.4), - 20, - 2, - dimnames = list(paste0("s", 1:20), c("chr1:100:A:G", "chr1:200:A:G")) - ) - Y <- matrix(rnorm(40), 20, 2, dimnames = list(rownames(X), c("c1", "c2"))) cv <- pecotmr:::.fmWeightsCv( X, Y, tokens = "mvsusie", methodArgs = list(mvsusie = list()), - fold = 2L, - coverage = 0.95, + fold = 3L, + samplePartition = sp, verbose = 0, - mvPriorCv = list("1" = list(priorVariance = diag(2))) - ) - expect_named( - cv, - c("samplePartition", "prediction", "performance", "foldFits") - ) -}) - -test_that("fineMappingPipeline(QtlSumStats): susieInf RSS chain (mocked)", { - ss <- .fmp_makeQtlSumStats() - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieRss = .fmp_mockFitRss(), - .fmPostprocessOne = .fmp_mockPostprocess(), - .package = "pecotmr" + mvPrior = fullPrior, + mvPriorCv = foldPriors + ) + # A fold takes its own prior when mvPriorCv has one, else mvPrior. + expect_identical(cv$foldFits$fold_1$mvsusie$prior, foldPriors[["1"]]) + expect_identical(cv$foldFits$fold_3$mvsusie$prior, fullPrior) + # A fold whose fit returns no weights keeps no fit either. + expect_length(cv$foldFits$fold_2, 0L) + # Only fold 1 predicts: X %*% W, the dosage row sums. NULL weights (fold + # 2) and weights on no test variant (fold 3) leave their samples NA ... + pred <- cv$prediction[["mvsusie_predicted"]] + f1 <- sp$Sample[sp$Fold == 1L] + expect_equal( + pred[f1, ], + cbind(c1 = rowSums(X[f1, ]), c2 = rowSums(X[f1, ])) ) - res <- suppressMessages( - fineMappingPipeline( - ss, - methods = "susieInf", - initializeWithSusieInf = FALSE, - verbose = 1 - ) + expect_true(all(is.na(pred[!is_in(rownames(pred), f1), ]))) + # ... and those samples are left out of the score, not counted. + expect_equal( + cv$performance[["mvsusie_performance"]][, "corr"], + drop(cor(Y[f1, ], rowSums(X[f1, ]))) ) - expect_s4_class(res, "QtlFineMappingResult") - expect_setequal(as.character(res$method), "susieInf") }) -test_that("fineMappingPipeline(GwasSumStats): susieInf RSS chain (mocked)", { - gss <- .fmp_makeGwasSumStats() +test_that("fineMappingPipeline(*SumStats): susieInf RSS chain (mocked)", { local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieRss = .fmp_mockFitRss(), .fmPostprocessOne = .fmp_mockPostprocess(), .package = "pecotmr" ) - res <- suppressMessages( - fineMappingPipeline( - gss, - methods = "susieInf", - initializeWithSusieInf = FALSE, - verbose = 1 + for (input in list(.fmp_qss, .fmp_gss)) { + kind <- class(input)[[1L]] + res <- suppressMessages( + fineMappingPipeline( + input, + methods = "susieInf", + initializeWithSusieInf = FALSE, + verbose = 1 + ) ) - ) - expect_s4_class(res, "GwasFineMappingResult") - expect_setequal(methodNames(res), "susieInf") + expect_s4_class(res, .fmp_resultClass[[kind]]) + expect_equal(methodNames(res), "susieInf", info = kind) + } }) test_that(".fmFoldWeights covers mvPrior residual var, missing rownames, unknown token", { @@ -4532,7 +4042,7 @@ test_that(".fmFoldWeights covers mvPrior residual var, missing rownames, unknown fitMvsusie = function(X, Y, ...) { list(vn = colnames(X), R = ncol(as.matrix(Y))) }, - # weights WITHOUT rownames -> .fmFoldWeights sets them from Xtr (1231) + # weights WITHOUT rownames -> .fmFoldWeights sets them from Xtr mvsusieWeights = function(mvsusieFit = NULL, ...) { matrix(0.01, length(mvsusieFit$vn), mvsusieFit$R) }, @@ -4545,7 +4055,7 @@ test_that(".fmFoldWeights covers mvPrior residual var, missing rownames, unknown dimnames = list(paste0("s", 1:20), c("chr1:100:A:G", "chr1:200:A:G")) ) Y <- matrix(rnorm(40), 20, 2) - # mvPrior carrying a residualVariance exercises line 1227 + # an mvPrior carrying a residualVariance hands it to the fit W <- pecotmr:::.fmFoldWeights( "mvsusie", X, @@ -4556,7 +4066,7 @@ test_that(".fmFoldWeights covers mvPrior residual var, missing rownames, unknown mvPrior = list(priorVariance = diag(2), residualVariance = diag(2)) ) expect_equal(rownames(W), colnames(X)) - # an unknown token falls through to NULL (1241) + # an unknown token falls through to NULL expect_null(pecotmr:::.fmFoldWeights("bogus", X, Y, 0.95, list(), NULL)) }) @@ -4587,7 +4097,7 @@ test_that(".fmWeightsCv fills Y rownames and reports per-fold fit failures", { 2, dimnames = list(paste0("s", 1:20), c("chr1:100:A:G", "chr1:200:A:G")) ) - Y <- matrix(rnorm(20), 20, 1) # no rownames -> filled from X (1258) + Y <- matrix(rnorm(20), 20, 1) # no rownames -> filled from X expect_message( cv <- suppressWarnings(pecotmr:::.fmWeightsCv( X, @@ -4598,46 +4108,47 @@ test_that(".fmWeightsCv fills Y rownames and reports per-fold fit failures", { verbose = 1 )), "CV fold .* failed" - ) # 1291-1294 + ) }) -test_that(".fmWeightsCv skips a fold that holds out every sample", { - X <- matrix( - rbinom(40, 2, 0.4), - 20, - 2, - dimnames = list(paste0("s", 1:20), c("chr1:100:A:G", "chr1:200:A:G")) - ) - Y <- matrix(rnorm(20), 20, 1, dimnames = list(rownames(X), NULL)) - sp <- data.frame(Sample = rownames(X), Fold = 1L) # single fold = all test -> 1273 - cv <- pecotmr:::.fmWeightsCv( - X, - Y, - tokens = "susie", - methodArgs = list(susie = list()), - fold = 1L, - samplePartition = sp, - verbose = 0 - ) - expect_true(all(is.na(cv$prediction[["susie_predicted"]]))) +test_that("fineMappingPipeline CV retains a lean per-fold fit", { + f <- .twcvFixture + expect_false(is.null(f$cv$foldFits)) + expect_equal(names(f$cv$foldFits), c("fold_1", "fold_2", "fold_3")) + # lean: only the fields the weight extractors read + fit1 <- f$cv$foldFits[["fold_1"]][["susie"]] + expect_true(all(c("pip", "alpha", "mu") %in% names(fit1))) + expect_false("lbf_variable" %in% names(fit1)) + # and it slices per method onto the row payload + expect_equal(names(f$slice$foldFits), c("fold_1", "fold_2", "fold_3")) }) # --- method-level branches (drive the pipeline methods with mocked fitters) --- test_that(".fmAfForX returns NULL when af yields nothing", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") - local_mocked_bindings(af = function(...) NULL, .package = "pecotmr") + qd <- .fmp_qdA + local_mocked_bindings( + .qtlExtractBlock = function(...) { + list(af = numeric(0), variantIds = character(0)) + }, + .package = "pecotmr" + ) X <- matrix( 0, 3, 2, dimnames = list(paste0("s", 1:3), c("chr1:100:A:G", "chr1:200:A:G")) ) - expect_null(pecotmr:::.fmAfForX(qd, X, traitId = "ENSG_A")) + expect_null(pecotmr:::.fmAfForX( + qd, + X, + genotypeFilter = pecotmr:::.qtlResolveFilter(), + traitId = "ENSG_A" + )) }) -test_that("fineMappingPipeline(QtlDataset): explicit valid contexts arg is honored", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") +test_that("fineMappingPipeline(QtlDataset): a valid context is honored", { + qd <- .fmp_qdTwoCtxA local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -4654,33 +4165,33 @@ test_that("fineMappingPipeline(QtlDataset): explicit valid contexts arg is honor ) ) expect_s4_class(res, "QtlFineMappingResult") + # The context left out is not fit. + expect_setequal(contexts(res), "brain") }) test_that("fineMappingPipeline(QtlDataset): region selects traits by rowRanges overlap", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), .fmPostprocessOne = .fmp_mockPostprocess(), .package = "pecotmr" ) - region <- GenomicRanges::GRanges("chr1", IRanges::IRanges(1L, 3000L)) + # ENSG_A spans 1000-1499 and ENSG_B 2000-2499: the region reaches only A. + region <- GenomicRanges::GRanges("chr1", IRanges::IRanges(1L, 1600L)) res <- suppressMessages( fineMappingPipeline( - qd, + .fmp_qdAB, methods = "susie", region = region, initializeWithSusieInf = FALSE ) ) expect_s4_class(res, "QtlFineMappingResult") + expect_setequal(traitNames(res), "ENSG_A") }) test_that("fineMappingPipeline(QtlDataset): too few shared samples errors", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + qd <- .fmp_qdA local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), # residualized X carries a sample absent from Y -> < 2 shared samples @@ -4709,7 +4220,7 @@ test_that("fineMappingPipeline(QtlDataset): too few shared samples errors", { }) test_that("fineMappingPipeline(QtlDataset): errors when no tuple produces a result", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + qd <- .fmp_qdA local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmSerScreen = function(...) FALSE, # screen out every block @@ -4726,34 +4237,8 @@ test_that("fineMappingPipeline(QtlDataset): errors when no tuple produces a resu ) }) -test_that("fineMappingPipeline(QtlDataset): usePCA fine-maps top PCs of a multi-trait context", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) - local_mocked_bindings( - extractBlockGenotypes = .fmp_mockExtractor(), - .fmFitSusieIndiv = .fmp_mockFitIndiv(), - .fmPostprocessOne = .fmp_mockPostprocess(), - .fmSerScreen = function(...) TRUE, - .package = "pecotmr" - ) - res <- suppressMessages( - fineMappingPipeline( - qd, - methods = "susie", - usePCA = TRUE, - nPCs = 1L, - cisWindow = 1000L, - initializeWithSusieInf = FALSE - ) - ) - expect_s4_class(res, "QtlFineMappingResult") - expect_true(any(grepl("PC", as.character(res$trait)))) -}) - test_that("fineMappingPipeline(QtlDataset): usePCA skips single-trait contexts", { - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + qd <- .fmp_qdA local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -4777,7 +4262,7 @@ test_that("fineMappingPipeline(QtlDataset): usePCA skips single-trait contexts", }) test_that("fineMappingPipeline(MultiStudyQtlDataset): jointSpec with no intersecting scope errors", { - mt <- .fmp_makeMultiStudy() + mt <- .fmp_msqd # The joint engine yields nothing for this scope -> the no-joint-fits stop. local_mocked_bindings( .fmDispatchJointSpecsMultiStudy = function(...) NULL, @@ -4793,16 +4278,16 @@ test_that("fineMappingPipeline(MultiStudyQtlDataset): jointSpec with no intersec ) }) -# --- usePCA sub-branches. Use methods="mvsusie" so the univariate dispatch is -# skipped (no 1531 stop / SER entanglement); the PCA path still runs susie, and -# the mvsusie joint dispatch is mocked to keep a non-empty result (no 1647). +# --- usePCA sub-branches. The tests using methods = "mvsusie" skip the +# univariate dispatch (and its SER screen); the PCA path still runs susie, and +# the mocked mvsusie joint dispatch keeps the result non-empty. .fmp_jr <- function() { QtlFineMappingResult( studyName = "study1", context = "brain", trait = "ENSG_A", method = "mvsusie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( "chr1:100:A:G", list(), data.frame(variant_id = "chr1:100:A:G", pip = 0.9) @@ -4811,15 +4296,12 @@ test_that("fineMappingPipeline(MultiStudyQtlDataset): jointSpec with no intersec } test_that("fineMappingPipeline(QtlDataset): usePCA skips a context whose PCA yields no scores", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), .fmPostprocessOne = .fmp_mockPostprocess(), - .fmTopPcScores = function(...) NULL, # 1577 next + .fmTopPcScores = function(...) NULL, # PCA yields no scores .package = "pecotmr" ) res <- suppressMessages(fineMappingPipeline( @@ -4834,16 +4316,13 @@ test_that("fineMappingPipeline(QtlDataset): usePCA skips a context whose PCA yie }) test_that("fineMappingPipeline(QtlDataset): usePCA reuses a cached PC entry", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB cachedFMR <- QtlFineMappingResult( studyName = "study1", context = "brain", trait = "topPC1", method = "susie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( "chr1:100:A:G", list(), data.frame(variant_id = "chr1:100:A:G", pip = 0.9) @@ -4872,14 +4351,11 @@ test_that("fineMappingPipeline(QtlDataset): usePCA reuses a cached PC entry", { initializeWithSusieInf = FALSE, fineMappingResult = cachedFMR )) - expect_true(any(as.character(res$trait) == "topPC1")) # 1584 cache hit + expect_true(any(as.character(res$trait) == "topPC1")) # from the cache }) test_that("fineMappingPipeline(QtlDataset): usePCA + region uses the region genotype block", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmFitSusieIndiv = .fmp_mockFitIndiv(), @@ -4896,14 +4372,11 @@ test_that("fineMappingPipeline(QtlDataset): usePCA + region uses the region geno nPCs = 1L, region = region )) - expect_true(any(grepl("PC", as.character(res$trait)))) # 1591-1592 region block + expect_true(any(grepl("PC", as.character(res$trait)))) }) test_that("fineMappingPipeline(QtlDataset): usePCA skips a PC block with too few shared samples", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), .fmResidGeno = function(x, ...) { @@ -4916,7 +4389,7 @@ test_that("fineMappingPipeline(QtlDataset): usePCA skips a PC block with too few c("chr1:100:A:G", "chr1:200:A:G") ) ) - }, # PC common < 2 -> 1595 + }, # < 2 samples shared with the PCs .fmDispatchJointSpecsQtlDataset = function(...) .fmp_jr(), .package = "pecotmr" ) @@ -4927,17 +4400,14 @@ test_that("fineMappingPipeline(QtlDataset): usePCA skips a PC block with too few nPCs = 1L, cisWindow = 1000L )) - expect_false(any(grepl("PC", as.character(res$trait)))) # 1595 + 1607 + expect_false(any(grepl("PC", as.character(res$trait)))) }) test_that("fineMappingPipeline(QtlDataset): usePCA skips a PC block screened out by SER", { - qd <- .fmp_makeQtlDataset( - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) + qd <- .fmp_qdAB local_mocked_bindings( extractBlockGenotypes = .fmp_mockExtractor(), - .fmSerScreen = function(...) FALSE, # PC screened -> 1597 + .fmSerScreen = function(...) FALSE, # the PC block is screened out .fmDispatchJointSpecsQtlDataset = function(...) .fmp_jr(), .package = "pecotmr" ) @@ -4948,10 +4418,9 @@ test_that("fineMappingPipeline(QtlDataset): usePCA skips a PC block screened out nPCs = 1L, cisWindow = 1000L )) - expect_false(any(grepl("PC", as.character(res$trait)))) # 1597 + 1607 + expect_false(any(grepl("PC", as.character(res$trait)))) }) - # --------------------------------------------------------------------------- # RSS panel filters: mafCutoff / macCutoff / imissCutoff on QtlSumStats and # GwasSumStats input. @@ -4961,11 +4430,12 @@ test_that("fineMappingPipeline(QtlDataset): usePCA skips a PC block screened out # and the LD matrix are built, so the two cannot fall out of alignment. # --------------------------------------------------------------------------- -# @noRd -.rssf_qcd <- function() { +# The bundled QTL summary statistics, QC'd once: summaryStatsQc() is the slow +# step, and every test below only reads the result. +.rssf_ss <- local({ data(qtlSumStatsExample, envir = environment()) suppressMessages(summaryStatsQc(qtlSumStatsExample)) -} +}) # @noRd .rssf_n <- function(ss, ...) { @@ -4980,41 +4450,33 @@ test_that("fineMappingPipeline(QtlDataset): usePCA skips a PC block screened out } test_that("fineMappingPipeline(QtlSumStats) filters nothing by default", { - ss <- .rssf_qcd() + ss <- .rssf_ss expect_equal(.rssf_n(ss), sum(lengths(ss))) }) -test_that("fineMappingPipeline(QtlSumStats) drops panel-rare variants", { - ss <- .rssf_qcd() - full <- .rssf_n(ss) - loose <- .rssf_n(ss, mafCutoff = 0.05) - tight <- .rssf_n(ss, mafCutoff = 0.2) - expect_lt(loose, full) - expect_lt(tight, loose) -}) - -test_that("fineMappingPipeline RSS cutoffs agree with .panelVariantFilter", { +test_that("fineMappingPipeline RSS MAF cutoffs match .panelVariantFilter", { # The pipeline must drop exactly the variants the shared filter names -- # no more (which would mean something else is filtering) and no fewer - # (which would mean the cutoff silently did nothing). - ss <- .rssf_qcd() + # (which would mean the cutoff silently did nothing) -- so panel-rare + # variants go, and a tighter cutoff drops more. + ss <- .rssf_ss ids <- variantIds(ss) + kept <- sum(lengths(ss)) for (cut in c(0.05, 0.2)) { expected <- length(.panelVariantFilter( ldReference(ss)[[1L]], ids, PanelFilterParam(mafCutoff = cut) )) - expect_equal( - .rssf_n(ss, mafCutoff = cut), - expected, - label = str_c("mafCutoff ", cut) - ) + n <- .rssf_n(ss, mafCutoff = cut) + expect_equal(n, expected, label = str_c("mafCutoff ", cut)) + expect_lt(n, kept, label = str_c("mafCutoff ", cut)) + kept <- n } }) test_that("fineMappingPipeline RSS treats MAC as a MAF equivalent", { - ss <- .rssf_qcd() + ss <- .rssf_ss nSamp <- ncol(ldReference(ss)[[1L]]) expect_equal( .rssf_n(ss, macCutoff = 0.1 * 2 * nSamp), @@ -5023,14 +4485,13 @@ test_that("fineMappingPipeline RSS treats MAC as a MAF equivalent", { }) test_that("fineMappingPipeline RSS honours a missingness cutoff", { - ss <- .rssf_qcd() + ss <- .rssf_ss expect_lt(.rssf_n(ss, imissCutoff = 0), sum(lengths(ss))) expect_equal(.rssf_n(ss, imissCutoff = 1), sum(lengths(ss))) }) - test_that(".fmExtractZn keeps z, ids and n aligned after filtering", { - ss <- .rssf_qcd() + ss <- .rssf_ss entry <- pecotmr:::.collectionEntry(ss, 1L) sketch <- ldReference(ss)[[1L]] unfiltered <- pecotmr:::.fmExtractZn(entry, "t") @@ -5125,21 +4586,6 @@ test_that("FineMappingMethodsParam takes lists or constructors per entry", { ) }) -test_that("fineMappingPipeline accepts the record and the character form", { - skip_if_not_installed("susieR") - byName <- pecotmr:::.fmNormalizeMethods( - c("susie", "susieInf"), - inputKind = "QtlDataset" - ) - expect_equal(byName$tokens, c("susie", "susieInf")) - byRecord <- pecotmr:::.fmNormalizeMethods( - FineMappingMethodsParam(qtlDatasetMethods = list(susie = list(L = 3))), - inputKind = "QtlDataset" - ) - expect_equal(byRecord$tokens, "susie") - expect_equal(byRecord$methodArgs$susie$L, 3) -}) - test_that("argument checking narrows to the engine the input class reaches", { skip_if_not_installed("susieR") skip_if_not_installed("mvsusieR") @@ -5296,9 +4742,11 @@ test_that("CredibleSetParam owns the single-effect bounds", { )$maxNumSingleEffectsGreedy, 3L ) - # addSusieInf stands alone: it selects a chained initialisation between - # methods rather than describing credible sets. - expect_false("addSusieInf" %in% names(formals(CredibleSetParam))) + # initializeWithSusieInf stands alone: it selects a chained + # initialisation between methods rather than describing credible sets. + expect_false( + "initializeWithSusieInf" %in% names(formals(CredibleSetParam)) + ) expect_false("fitStructureArgs" %in% getNamespaceExports("pecotmr")) }) @@ -5319,6 +4767,11 @@ test_that("SignalScreenParam resolves each metric to a pipeline spec", { # list(metric, cutoff). .asScreen() canonicalizes either. expect_null(pecotmr:::.screenResolve(SignalScreenParam())) expect_equal(pecotmr:::.screenResolve(SignalScreenParam(pip = 0.5)), 0.5) + # A per-context pip vector passes through with its names. + expect_equal( + pecotmr:::.screenResolve(SignalScreenParam(pip = c(brain = 0.3))), + c(brain = 0.3) + ) expect_equal( pecotmr:::.screenResolve(SignalScreenParam(absZ = 5)), list(metric = "absZ", cutoff = 5) @@ -5353,6 +4806,31 @@ test_that("SignalScreenParam rejects two metrics and negative absZ / bf", { ) }) +test_that(".fmSerScreen / .fmScreenActive / .fmSerScreenColumns", { + set.seed(2) + X <- matrix( + rnorm(40), + 20, + 2, + dimnames = list(paste0("s", 1:20), c("chr1:100:A:G", "chr1:200:A:G")) + ) + y <- rnorm(20) + expect_true(pecotmr:::.fmSerScreen(X, y, 0)) # disabled + expect_true(pecotmr:::.fmSerScreen(X, c(1, rep(NA, 19)), 0.5)) # < 2 obs + expect_type(pecotmr:::.fmSerScreen(X, y, 0.5), "logical") # real susie fit + local_mocked_bindings( + susie = function(...) stop("boom"), + .package = "susieR" + ) + expect_true(pecotmr:::.fmSerScreen(X, y, 0.5)) # fit fails -> keep + expect_false(pecotmr:::.fmScreenActive(0)) + expect_true(pecotmr:::.fmScreenActive(0.5)) + expect_length( + pecotmr:::.fmSerScreenColumns(X, matrix(rnorm(40), 20, 2), 0), + 2L + ) +}) + test_that("every recursion forwards each cfg field its callee accepts", { ns <- asNamespace("pecotmr") cases <- list( @@ -5379,10 +4857,7 @@ test_that("every recursion forwards each cfg field its callee accepts", { ) for (cs in cases) { fields <- .cfgFieldNames(cs$builder) - accepted <- setdiff( - names(formals(get(cs$callee, envir = ns))), - "..." - ) + accepted <- setdiff(names(formals(get(cs$callee, envir = ns))), "...") passed <- .argNamesPassed(cs$site) # A field the record carries AND the callee accepts must be passed. dropped <- setdiff(intersect(fields, accepted), passed) @@ -5424,7 +4899,7 @@ test_that("MultiStudyQtlDataset takes every component argument", { test_that("QtlDataset: a CV-only run keeps the CV and skips the full fit", { skip_if_not_installed("susieR") - qd <- .fmp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + qd <- .fmp_qdA # The full-data post-processor stops the test if it is reached: a # cross-validation-only run must not fit, or summarize, the full data. local_mocked_bindings( @@ -5444,7 +4919,7 @@ test_that("QtlDataset: a CV-only run keeps the CV and skips the full fit", { verbose = 0 )) expect_equal(nrow(res), 1L) - expect_equal(lengths(res), 0L) + expect_equal(unname(lengths(res)), 0L) expect_null(susieFit( res, studyName = "study1", @@ -5461,7 +4936,7 @@ test_that("QtlDataset: a CV-only run keeps the CV and skips the full fit", { ) expect_true("susie_predicted" %in% names(cv$prediction)) # Fold-level results cannot be published, so the export refuses. - expect_error(exportToBed(res, tempfile(fileext = ".bed")), "fitFullData") + expect_error(writeBed(res, tempfile(fileext = ".bed")), "fitFullData") }) test_that(".fmMergeEntries keeps a merged cross-validation-only row fit-free", { @@ -5487,8 +4962,8 @@ test_that(".fmCacheForRun reuses only rows that carry what the run asks for", { trait = c("fullCv", "full", "cvOnly"), method = rep("susie", 3L), entry = list( - fineMappingRow(vid, list(a = 1), tl, cvResult = cv), - fineMappingRow(vid, list(a = 1), tl), + FineMappingRow(vid, list(a = 1), tl, cvResult = cv), + FineMappingRow(vid, list(a = 1), tl), pecotmr:::.fmCvOnlyRow(cv) ) ) @@ -5504,7 +4979,7 @@ test_that(".fmCacheForRun reuses only rows that carry what the run asks for", { ) }) -test_that("CredibleSetParam accessors read and replace, L is get-only", { +test_that("CredibleSetParam fields read and replace, L is fixed", { cs <- CredibleSetParam(coverage = 0.95) expect_equal(csCoverage(cs), 0.95) expect_equal(maxNumSingleEffects(cs), 10L) @@ -5513,34 +4988,26 @@ test_that("CredibleSetParam accessors read and replace, L is get-only", { # Copy semantics: replacement rebinds a modified copy, so another name # holding the original still sees the old value. cs2 <- cs - csCoverage(cs2) <- 0.9 + cs2$coverage <- 0.9 expect_equal(csCoverage(cs2), 0.9) expect_equal(csCoverage(cs), 0.95) expect_s4_class(cs2, "CredibleSetParam") # The slot's declared type still holds through a replacement. - expect_error(csCoverage(cs) <- "wide", "not valid for @.+coverage") + expect_error(cs$coverage <- "wide", "coverage") - # L / Lgreedy are deliberately get-only: they are seeded onto each + # L / Lgreedy are deliberately fixed: they are seeded onto each # SuSiE-family token's own arguments, so changing one needs a refit, not - # a re-summary. A setter would hand back a record that looks applied. - ns <- asNamespace("pecotmr") - expect_false(exists("setL", envir = ns, inherits = FALSE)) - expect_false(exists("setLgreedy", envir = ns, inherits = FALSE)) + # a re-summary. A replacement would hand back a record that looks + # applied, so `$<-` refuses them. + expect_error(cs$maxNumSingleEffects <- 5L, "needs a refit") + expect_error(cs$maxNumSingleEffectsGreedy <- 2L, "needs a refit") expect_true(is.function(maxNumSingleEffectsGreedy)) }) -test_that("every settable CredibleSetParam field has both accessors", { - # The pairing is the contract: a field you can read and not write is a - # deliberate exception, so it must be one of exactly these two. - # - # The accessor is now the field name itself -- the get* prefix is gone -- - # except where the bare field name would have been unusable or taken, so - # those three are named here rather than derived. Writers are the - # matching `<-` replacement generics. - getOnly <- c("maxNumSingleEffects", "maxNumSingleEffectsGreedy") - # The slots now carry their accessors' names, so `coverage` is the only - # field whose accessor is not derivable from it. +test_that("every CredibleSetParam field has a getter", { + # The getter is the field name itself, except `coverage`, whose bare name + # is an IRanges generic -- so that one is named here, not derived. renamed <- c(coverage = "csCoverage") ns <- asNamespace("pecotmr") for (f in names(formals(CredibleSetParam))) { @@ -5549,21 +5016,12 @@ test_that("every settable CredibleSetParam field has both accessors", { exists(accessor, envir = ns, inherits = FALSE), info = paste("no accessor for", f) ) - # The writer is the replacement form of the accessor name, not a - # set* function: `csCoverage(p) <- v`, never `setCoverage(p, v)`. - expect_equal( - exists(str_c(accessor, "<-"), envir = ns, inherits = FALSE), - !is_in(f, getOnly), - info = paste("replacement presence wrong for", f) - ) } }) -test_that("CredibleSetParam accessors read and replace every field", { - # The pairing test above asserts the accessors EXIST; this one dispatches - # them. Existence is checked with exists(), which never reaches the - # generic, so without this the setGeneric bodies in AllGenerics.R and the - # copy semantics of each setter go unexercised. +test_that("CredibleSetParam getters read and $<- replaces every field", { + # Dispatching each getter is what exercises the setGeneric bodies in + # AllGenerics.R; existence alone never reaches them. cs <- CredibleSetParam() expect_equal(secondaryCoverage(cs), c(0.7, 0.5)) expect_equal(signalCutoff(cs), 0.025) @@ -5574,12 +5032,12 @@ test_that("CredibleSetParam accessors read and replace every field", { # Replacement on a copy; `cs` itself keeps its original values. edited <- cs - secondaryCoverage(edited) <- 0.6 - signalCutoff(edited) <- 0.1 - minAbsCorr(edited) <- 0.5 - medianAbsCorr(edited) <- 0.4 - includeAllCs(edited) <- TRUE - perCsColumns(edited) <- "alpha" + edited$secondaryCoverage <- 0.6 + edited$signalCutoff <- 0.1 + edited$minAbsCorr <- 0.5 + edited$medianAbsCorr <- 0.4 + edited$includeAllCs <- TRUE + edited$perCsColumns <- "alpha" expect_equal(secondaryCoverage(edited), 0.6) expect_equal(signalCutoff(edited), 0.1) expect_equal(minAbsCorr(edited), 0.5) @@ -5589,8 +5047,9 @@ test_that("CredibleSetParam accessors read and replace every field", { expect_equal(secondaryCoverage(cs), c(0.7, 0.5)) expect_false(includeAllCs(cs)) - # Replacement revalidates, so a wrong-typed value is refused. - expect_error(includeAllCs(cs) <- "yes", "includeAllCs") + # Replacement goes through the constructor, so a wrong-typed value is + # refused exactly as CredibleSetParam() refuses it. + expect_error(cs$includeAllCs <- "yes", "includeAllCs") }) # --------------------------------------------------------------------------- @@ -5649,24 +5108,23 @@ test_that("CredibleSetParam validity catches range and length errors", { ) }) -test_that("CredibleSetParam setters are held to the same checks", { +test_that("CredibleSetParam replacements are held to the same checks", { cs <- CredibleSetParam() - # The setter path used to bypass every one of these: its body is - # `x@slot <- value; validObject(x)`, and before setValidity() existed - # validObject() only checked the slot's type. - expect_error(csCoverage(cs) <- 1.5, "coverage") - expect_error(csCoverage(cs) <- c(0.9, 0.95), "coverage") - expect_error(minAbsCorr(cs) <- -1, "minAbsCorr") - expect_error(signalCutoff(cs) <- 2, "signalCutoff") - expect_error(secondaryCoverage(cs) <- c(0.7, 3), "secondaryCoverage") - # perCsColumns was the sharpest asymmetry: the constructor refused a - # bad level via arg_match() while the setter accepted it. - expect_error(perCsColumns(cs) <- "bogus", "perCsColumns") + # A replacement is a rebuild through CredibleSetParam(), so it is refused + # exactly where the constructor would refuse the value. + expect_error(cs$coverage <- 1.5, "coverage") + expect_error(cs$coverage <- c(0.9, 0.95), "coverage") + expect_error(cs$minAbsCorr <- -1, "minAbsCorr") + expect_error(cs$signalCutoff <- 2, "signalCutoff") + expect_error(cs$secondaryCoverage <- c(0.7, 3), "secondaryCoverage") + # perCsColumns was the sharpest asymmetry of the old setters: the + # constructor refused a bad level via arg_match() while they accepted it. + expect_error(cs$perCsColumns <- "bogus", "perCsColumns") # Valid replacements still go through. ok <- cs - csCoverage(ok) <- 0.9 - minAbsCorr(ok) <- 0.5 - medianAbsCorr(ok) <- 0.4 + ok$coverage <- 0.9 + ok$minAbsCorr <- 0.5 + ok$medianAbsCorr <- 0.4 expect_equal(csCoverage(ok), 0.9) expect_equal(minAbsCorr(ok), 0.5) expect_equal(medianAbsCorr(ok), 0.4) @@ -5725,36 +5183,6 @@ test_that(".fmOwnedEngineArgs owns nothing for an unknown engine", { ) }) -test_that(".fmBlockIdRange recovers a block boundary the variants cannot give", { - # Adjacent LD blocks leave gaps, so the realized variant span is narrower - # than the block; only blockId carries the boundary. - gr <- .fmBlockIdRange("chr22_49355984_50799822") - expect_s4_class(gr, "GRanges") - expect_identical(as.character(GenomicRanges::seqnames(gr)), "chr22") - expect_identical(GenomicRanges::start(gr), 49355984L) - expect_identical(GenomicRanges::end(gr), 50799822L) - # the chr:start-end spelling works too - expect_identical( - as.character(.fmBlockIdRange("chr1:100-200")), - as.character(GenomicRanges::GRanges("chr1:100-200")) - ) - # anything that is not coordinates is not guessed at - expect_null(.fmBlockIdRange("ENSG00000283047")) - expect_null(.fmBlockIdRange(NA_character_)) - expect_null(.fmBlockIdRange(NULL)) - expect_null(.fmBlockIdRange(c("chr1_1_2", "chr1_3_4"))) -}) - -test_that(".fmRssFitWindow prefers the block boundary over the variant span", { - ids <- c("chr22:49363017:A:T", "chr22:50598205:C:G") - withBlock <- .fmRssFitWindow(NULL, ids, "chr22_49355984_50799822") - expect_identical(GenomicRanges::start(withBlock), 49355984L) - # No parseable blockId -> the fit's own variants define the window. - noBlock <- .fmRssFitWindow(NULL, ids, NULL) - expect_identical(GenomicRanges::start(noBlock), 49363017L) - expect_identical(GenomicRanges::end(noBlock), 50598205L) -}) - test_that(".fmBlockWindow falls back to the trait's own cis window", { data(qtlDatasetExample) explicit <- GenomicRanges::GRanges("chr1:1-999") @@ -5769,7 +5197,9 @@ test_that(".fmBlockWindow falls back to the trait's own cis window", { cfgNarrow <- list(data = qtlDatasetExample, cisWindow = 1000) cfgWide <- list(data = qtlDatasetExample, cisWindow = 500000) ctx <- contexts(qtlDatasetExample)[[1L]] - tid <- rownames(molecularTraits(qtlDatasetExample, contexts = ctx))[[1L]] + tid <- rownames(molecularTraits(qtlDatasetExample, context = ctx)[[ctx]])[[ + 1L + ]] narrow <- .fmBlockWindow(NULL, ctx, tid, cfgNarrow) wide <- .fmBlockWindow(NULL, ctx, tid, cfgWide) expect_lt(GenomicRanges::start(wide), GenomicRanges::start(narrow)) @@ -5780,29 +5210,46 @@ test_that(".fmBlockWindow falls back to the trait's own cis window", { ) }) -test_that("a supplied block key survives into the result; a seqname fallback does not", { +test_that("a GWAS row carries its block name and window into its fit", { data(gwasSumStatsS4Example) - gss <- gwasSumStatsS4Example - gr <- .collectionEntry(gss, 1L) + gr <- .collectionEntry(gwasSumStatsS4Example, 1L) derived <- .fmGwasRangeKey(gr) - # (a) No manifest and no explicit blockId: GwasSumStats() falls back to the - # bare seqname, which carries no coordinates and must NOT override the - # entry's own range key. - bare <- gss - S4Vectors::mcols(bare)$blockId <- rep("chr22", nrow(bare)) - expect_identical(.fmGwasBlockId(bare, 1L, gr), derived) + # (a) No windows: GwasSumStats() names the row by its seqname, which the + # fit keeps, and its window is the span it was built with. + bare <- GwasSumStats(studyName = "s", entry = list(gr), genome = "hg19") + block <- .fmGwasBlock(bare, 1L, gr, .rowRegions(bare)) + expect_identical(block$id, "chr22") + expect_false(block$given) + expect_identical(as.character(block$region), as.character(range(gr))) - # (b) A coordinate-bearing key -- from an ldBlocks manifest or an explicit - # vector -- IS the block boundary and wins. Adjacent blocks leave gaps, so + # (b) A range the caller gave -- here a `region` window keyed by name -- + # IS the block boundary and keeps its key. Adjacent blocks leave gaps, so # it is wider than the variants that survived QC. - supplied <- gss - key <- "chr22_1_50000000" - S4Vectors::mcols(supplied)$blockId <- rep(key, nrow(supplied)) - expect_identical(.fmGwasBlockId(supplied, 1L, gr), key) - expect_false(identical(.fmGwasBlockId(supplied, 1L, gr), derived)) + named <- GwasSumStats( + studyName = "s", + entry = list(gr), + genome = "hg19", + region = GenomicRanges::GRanges( + "chr22", + IRanges::IRanges(1L, 50000000L), + blockId = "b7" + ) + ) + block <- .fmGwasBlock(named, 1L, gr, .rowRegions(named)) + expect_identical(block$id, "b7") + expect_true(block$given) + expect_identical(as.character(block$region), "chr22:1-50000000") + + # (c) A name is kept as it is; only a row with none, from a collection + # saved before the column existed, is named by its span. + expect_identical( + .fmGwasBlockName("chr22_1_50000000", gr), + "chr22_1_50000000" + ) + expect_identical(.fmGwasBlockName(NA_character_, gr), derived) - # (c) The resume cache keys on the DERIVED range either way, so supplying a + # (d) The resume cache keys on the DERIVED range either way, so supplying a # wider boundary cannot make the cache miss. expect_identical(.fmGwasRangeKey(gr), derived) }) @@ -5810,7 +5257,7 @@ test_that("a supplied block key survives into the result; a seqname fallback doe # --------------------------------------------------------------------------- # Provenance columns (dataType / dataSource / standardized) # -# These three are what exportToBed() / exportToVcf() publish as data_type, +# These three are what writeBed() / writeGwasVcf() publish as data_type, # data_source and weight_standardized. Only the first is an outside fact; the # other two follow from the branch the pipeline took, so they are derived and # the summary-statistics methods refuse to be told. @@ -5862,7 +5309,7 @@ test_that("fineMappingPipeline(QtlDataset) omits dataType when not supplied", { test_that("fineMappingPipeline(QtlSumStats) records sumstat / standardized", { res <- suppressWarnings(suppressMessages(fineMappingPipeline( - .rssf_qcd(), + .rssf_ss, methods = "susie", dataType = "bulk_rnaseq" ))) @@ -5880,7 +5327,7 @@ test_that("no pipeline takes a weight-scale declaration any more", { # derived and a declaration could only contradict it. expect_error( fineMappingPipeline( - .rssf_qcd(), + .rssf_ss, methods = "susie", weightStandardized = FALSE ), @@ -5899,7 +5346,7 @@ test_that("no pipeline takes a weight-scale declaration any more", { }) test_that(".fmMsDataSource leaves a mixed collection's joint rows NA", { - expect_true(is.na(pecotmr:::.fmMsDataSource(.fmp_makeMultiStudy()))) + expect_true(is.na(pecotmr:::.fmMsDataSource(.fmp_msqd))) }) test_that(".fmMsDataSource gives an individual-level collection's joint rows", { @@ -5923,6 +5370,7 @@ test_that("individual-level genotypes reach the fitter standardized", { X <- pecotmr:::.fmResidGeno( qtlDatasetExample, ResidualizationParam(), + genotypeFilter = pecotmr:::.qtlResolveFilter(), contexts = "brain", traitId = "ENSG_example", cisWindow = 1e6 @@ -5932,24 +5380,11 @@ test_that("individual-level genotypes reach the fitter standardized", { expect_true(all(abs(sds[sds > 0] - 1) < 1e-10)) }) -test_that("a constant genotype column comes back as zeros, not NaN", { - # `.qtlResidualizeQr()` treats anything below sqrt(.Machine$double.eps) as - # constant: lm.fit residuals of a constant column are ~1e-16 rather than - # 0, and dividing the (also tiny) residuals by that amplifies roundoff to - # unit scale. The column is zeroed instead, and .dropZeroVariance() - # removes it downstream. - Y <- cbind(a = c(1, 2, 3, 4), b = c(2, 2, 2, 2)) - out <- pecotmr:::.qtlResidualizeQr(Y, NULL, scaleResiduals = TRUE) - expect_equal(unname(out[, "b"]), rep(0, 4)) - expect_equal(sd(out[, "a"]), 1) - expect_false(anyNA(out)) -}) - test_that("the genotype scale comes from the accessor, not the pipeline", { - # ONE knob: ResidualizationParam(scaleResiduals=) per call, with the - # QtlDataset's own slot as the default. The pipelines add no mechanism of - # their own -- they only RECORD what the accessor resolved, so a wrong - # record and a wrong scale cannot come apart. + # ONE knob: ResidualizationParam(scaleResiduals=), TRUE when unset. The + # pipelines add no mechanism of their own -- they only RECORD what the + # residualizer resolved, so a wrong record and a wrong scale cannot come + # apart. data(qtlDatasetExample, envir = environment()) recorded <- function(..., dataset = qtlDatasetExample) { res <- suppressMessages(fineMappingPipeline( @@ -5963,11 +5398,6 @@ test_that("the genotype scale comes from the accessor, not the pipeline", { expect_true(recorded()) expect_true(recorded(scaleResiduals = TRUE)) expect_false(recorded(scaleResiduals = FALSE)) - # Unset falls back to the object, which is where the default lives. - off <- methods::initialize(qtlDatasetExample, scaleResiduals = FALSE) - expect_false(recorded(dataset = off)) - # An explicit per-call value overrides the object either way. - expect_true(recorded(scaleResiduals = TRUE, dataset = off)) }) test_that("the pipelines add no second standardization mechanism", { @@ -5988,7 +5418,11 @@ test_that("the hatch does not reach a summary-statistics fit", { # There are no genotypes to scale, and the RSS likelihood is in # standardized units whatever anyone asks, so the flag stays TRUE. res <- suppressWarnings(suppressMessages( - fineMappingPipeline(.rssf_qcd(), methods = "susie") + fineMappingPipeline( + .rssf_ss, + methods = "susie", + residualizationParam = ResidualizationParam(scaleResiduals = FALSE) + ) )) expect_true(all(as.logical(S4Vectors::mcols(res)$standardized))) }) @@ -6005,7 +5439,7 @@ test_that("QtlDataset: joint fits get every caller setting", { rp <- ResidualizationParam(scaleResiduals = FALSE) expect_error( suppressMessages(fineMappingPipeline( - .fmp_makeQtlDataset(contexts = c("brain", "liver")), + .fmp_qdTwoCtxAB, methods = "mvsusie", traitId = "ENSG_A", cisWindow = 1000L, @@ -6038,7 +5472,7 @@ test_that("MultiStudyQtlDataset: per-study joint fits get every setting", { rp <- ResidualizationParam(scaleResiduals = FALSE) expect_error( suppressMessages(fineMappingPipeline( - .fmp_makeMultiStudy(), + .fmp_msqd, methods = "mvsusie", cisWindow = 1000L, jointSpecification = "context", @@ -6060,7 +5494,7 @@ test_that("MultiStudyQtlDataset: per-study joint fits get every setting", { ind$args$pipCutoffToSkip, pecotmr:::.screenResolve(SignalScreenParam(pip = 0.1)) ) - expect_equal(mafCutoff(ind$data), 0.05) + expect_equal(ind$args$genotypeFilter$mafCutoff, 0.05) }) test_that("MultiStudyQtlDataset: cross-study joint fits get their settings", { @@ -6071,7 +5505,7 @@ test_that("MultiStudyQtlDataset: cross-study joint fits get their settings", { panel <- PanelFilterParam(mafCutoff = 0.05) expect_error( suppressMessages(fineMappingPipeline( - .fmp_makeMultiStudy(), + .fmp_msqd, methods = "mvsusie", jointSpecification = "study", fitRetention = "full", @@ -6084,7 +5518,6 @@ test_that("MultiStudyQtlDataset: cross-study joint fits get their settings", { expect_equal(ss$args$cutoffs, pecotmr:::.panelCutoffs(panel)) }) - # ============================================================================= # The LD reference dispatch: an LdMatrix or a GenotypeMixture as ldReference # ============================================================================= @@ -6103,16 +5536,19 @@ test_that("MultiStudyQtlDataset: cross-study joint fits get their settings", { entry = list(.collectionEntry(gss, 1L)), genome = "hg19", ldReference = ld, - qcInfo = qcInfo(gss) + qcOptions = qcOptions(gss) ) } +# A real susie fit. L = 4 still finds the example's three credible sets, and +# fits cheaper than the default L = 10; every route compared uses it. # @noRd .fmp_fitSusie <- function(x) { suppressWarnings(suppressMessages(fineMappingPipeline( x, methods = "susie", - initializeWithSusieInf = FALSE + initializeWithSusieInf = FALSE, + credibleSetParam = CredibleSetParam(maxNumSingleEffects = 4L) ))) } @@ -6170,7 +5606,7 @@ test_that("fine-mapping runs on a GenotypeMixture reference", { entry = list(.collectionEntry(gss, 1L)), genome = "hg19", ldReference = mix, - qcInfo = qcInfo(gss) + qcOptions = qcOptions(gss) ) res <- .fmp_fitSusie(withMix) expect_s4_class(ldReference(res)[[1L]], "GenotypeMixture") @@ -6222,7 +5658,7 @@ test_that("the rFinite default needs the reference's size", { entry = list(gr, gr), genome = "hg19", ldReference = refs, - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) } @@ -6264,3 +5700,129 @@ test_that("mvsusie on QtlSumStats refuses contexts on two LD references", { "a joint fit uses one LD matrix" ) }) + +# =========================================================================== +# A GWAS row spanning a whole chromosome is fine-mapped, but said +# =========================================================================== + +# A study's row over `starts` on chr1. +.fmp_spanningGwas <- function(starts, studies = "G1") { + gr <- GenomicRanges::GRanges("chr1", IRanges::IRanges(starts, width = 1L)) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = sprintf("chr1:%d:A:G", starts), + A1 = "A", + A2 = "G", + Z = seq_along(starts) / 10, + N = 1000L + ) + GwasSumStats( + studyName = studies, + entry = rep(list(gr), length(studies)), + genome = "hg19", + qcOptions = list(step1 = "ok") + ) +} + +test_that(".fmWarnChromosomeRows flags rows spanning a chromosome's worth", { + # An LD block's worth of variants passes in silence. + expect_silent( + pecotmr:::.fmWarnChromosomeRows(.fmp_spanningGwas(c(100L, 5e6))) + ) + expect_warning( + pecotmr:::.fmWarnChromosomeRows(.fmp_spanningGwas(c(100L, 3e7))), + "20 Mb, as a whole chromosome does \\(G1 chr1_100_30000000\\)" + ) + # Past five rows the list is cut short. + six <- .fmp_spanningGwas(c(100L, 3e7), studies = str_c("G", 1:6)) + expect_warning( + pecotmr:::.fmWarnChromosomeRows(six), + "6 GWAS row\\(s\\).*G5 chr1_100_30000000, \\.\\.\\.\\)" + ) +}) + +test_that("fineMappingPipeline(QtlSumStats): cisWindow sets each window", { + local_mocked_bindings( + extractBlockGenotypes = .fmp_mockExtractor(), + .fmFitSusieRss = .fmp_mockFitRss(), + .fmPostprocessOne = .fmp_mockPostprocess(), + .package = "pecotmr" + ) + ss <- .fmp_qss + ss$traitPos <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(300L, width = 1L) + ) + res <- suppressMessages(fineMappingPipeline( + ss, + methods = "susie", + cisWindow = 100, + initializeWithSusieInf = FALSE + )) + expect_identical(as.character(genomicRegion(res)), "chr1:200-400") + expect_equal(length(res[[1L]]), 3L) + # The selection is parsed before the window is laid, so naming a context + # works alongside it. + picked <- suppressMessages(fineMappingPipeline( + ss, + methods = "susie", + contexts = "c1", + cisWindow = 100, + initializeWithSusieInf = FALSE + )) + expect_identical(as.character(genomicRegion(picked)), "chr1:200-400") + # Without one, the result keeps the tuple's own window. + plain <- suppressMessages(fineMappingPipeline( + .fmp_qss, + methods = "susie", + initializeWithSusieInf = FALSE + )) + expect_identical(as.character(genomicRegion(plain)), "chr1:100-500") + expect_error( + fineMappingPipeline( + .fmp_qss, + methods = "susie", + cisWindow = 100 + ), + "laid around each tuple's trait position" + ) +}) + +test_that("fineMappingPipeline refuses a phenotype QC its fits cannot take", { + # Resolved before any study runs: a fit cannot take a missing phenotype, + # so naAction = "keep" is refused up front, on either input form. + keep <- PhenotypeFilterParam(naAction = "keep") + expect_error( + fineMappingPipeline( + .fmp_qdA, + methods = "susie", + phenotypeFilterParam = keep + ), + "naAction = \"keep\" is not available" + ) + expect_error( + fineMappingPipeline( + .fmp_msqd, + methods = "susie", + phenotypeFilterParam = keep + ), + "naAction = \"keep\" is not available" + ) +}) + +# =========================================================================== +# .fmAfByVar +# =========================================================================== + +test_that(".fmAfByVar reads AF, and is NULL when af was never declared", { + mk <- function(cm) { + .dfToEntryGranges(suppressWarnings(.resolveSumstatCols( + .afm_df("effect_allele_frequency", 0.8), + cm, + "lbl" + ))) + } + gA <- mk(.afm_cm(af = "effect_allele_frequency")) + expect_equal(unname(.fmAfByVar(gA, "chr1:100:A:G")), 0.8) + gM <- mk(.afm_cm(maf = "effect_allele_frequency")) + expect_null(.fmAfByVar(gM, "chr1:100:A:G")) +}) diff --git a/tests/testthat/test_fineMappingRow.R b/tests/testthat/test_fineMappingRow.R index 568d81d0..0afcabd8 100644 --- a/tests/testthat/test_fineMappingRow.R +++ b/tests/testthat/test_fineMappingRow.R @@ -1,100 +1,31 @@ # Tests for FineMappingRow (S4 class) -# Helper for adjustPips tests, migrated from test_dataStructures.R - -.makeAdjustEntry <- function(vids, maxNumSingleEffects = 2L) { - p <- length(vids) - set.seed(11L) - lbf <- matrix( - rnorm(maxNumSingleEffects * p), - nrow = maxNumSingleEffects, - ncol = p - ) - colnames(lbf) <- vids - alpha <- lbfToAlpha(lbf) - pip <- as.numeric(1 - apply(1 - alpha, 2, prod)) - fineMappingRow( - variantIds = vids, - susieFit = list( - pip = pip, - alpha = alpha, - lbf_variable = lbf, - mu = matrix(0, maxNumSingleEffects, p), - X_column_scale_factors = rep(1, p) - ), - topLoci = data.frame( - variant_id = vids, - pip = pip, - betahat = rep(0, p), - sebetahat = rep(1, p), - stringsAsFactors = FALSE - ) - ) -} - - # =========================================================================== -# Tests migrated from test_dataStructures.R (topLoci, adjustPips) +# A row as GRanges, and adjustPips on a kept subset # =========================================================================== -test_that(".fmrRowTopLoci() tables convert to ranges", { - tl <- data.frame( - variant_id = c("1:100:A:G", "1:200:C:T"), - pip = c(0.9, 0.1), - betahat = c(0.5, -0.2), - sebetahat = c(0.1, 0.2), - cs = c(1L, 0L), - method = "susie", - stringsAsFactors = FALSE - ) - ent <- fineMappingRow( - variantIds = tl$variant_id, - susieFit = list(), - topLoci = tl - ) - # .fmrRowTopLoci() is the per-row table; topLoci() converts once, after - # the aggregate view has stacked the rows, so the conversion is tested - # through the converter it now lives in. - out <- .fmrRowTopLoci(ent) - expect_s3_class(out, "data.frame") - gr <- pecotmr:::.fmeTopLociGRanges(out) - expect_s4_class(gr, "GRanges") - expect_equal(length(gr), 2) - expect_equal(S4Vectors::mcols(gr)$pip, c(0.9, 0.1)) -}) - - -test_that(".fmrRowTopLoci() empty input converts to empty ranges", { - ent <- fineMappingRow( - variantIds = character(0), +test_that("as(row, 'GRanges') is the element a collection stores", { + ids <- c("chr1:100:A:G", "chr1:200:C:T") + row <- FineMappingRow( + variantIds = ids, susieFit = list(), - topLoci = data.frame() + topLoci = data.frame(variant_id = ids, pip = c(0.7, 0.2)) ) - gr <- pecotmr:::.fmeTopLociGRanges(.fmrRowTopLoci(ent)) + gr <- as(row, "GRanges") expect_s4_class(gr, "GRanges") - expect_equal(length(gr), 0) -}) - - -test_that(".fmrRowTopLoci() always returns the per-row table", { - tl <- data.frame( - variant_id = "1:100:A:G", - pip = 0.9, - betahat = 0.5, - sebetahat = 0.1, - cs = 1L, - stringsAsFactors = FALSE - ) - ent <- fineMappingRow( - variantIds = tl$variant_id, - susieFit = list(), - topLoci = tl + expect_identical(gr$pip, c(0.7, 0.2)) + x <- QtlFineMappingResult( + studyName = "s", + context = "c", + trait = "t", + method = "susie", + entry = list(row) ) - expect_s3_class(.fmrRowTopLoci(ent), "data.frame") + expect_identical(unname(x[[1L]]), unname(gr)) }) # ============================================================================= -# extractBlockGenotypes returns RSE +# adjustPips: renormalize PIPs on a kept subset of variants # ============================================================================= test_that("adjustPips renormalizes PIPs on a kept FineMappingRow subset", { @@ -114,7 +45,6 @@ test_that("adjustPips renormalizes PIPs on a kept FineMappingRow subset", { expect_false(identical(unname(origPips[keep]), susieFit(adj)$pip)) }) - test_that("adjustPips errors when the intersection is empty", { vids <- paste0("chr1:", 1:4, ":A:G") entry <- .makeAdjustEntry(vids) @@ -124,7 +54,6 @@ test_that("adjustPips errors when the intersection is empty", { ) }) - test_that("adjustPips tolerates a chr-prefix difference between entry and keepVariants", { vids <- paste0("chr1:", 1:6, ":A:G") entry <- .makeAdjustEntry(vids) @@ -135,35 +64,12 @@ test_that("adjustPips tolerates a chr-prefix difference between entry and keepVa expect_equal(ncol(susieFit(adj)$lbf_variable), 4) }) - -test_that("adjustPips on a FineMappingResultBase collection renormalizes each entry", { - vidsA <- paste0("chr1:", 1:6, ":A:G") - vidsB <- paste0("chr1:", 3:8, ":A:G") - entryA <- .makeAdjustEntry(vidsA) - entryB <- .makeAdjustEntry(vidsB) - fmr <- QtlFineMappingResult( - studyName = c("s1", "s1"), - context = c("c1", "c2"), - trait = c("g1", "g1"), - method = c("susie", "susie"), - entry = list(entryA, entryB) - ) - # Keep only variants shared by both entries' raw sets. - keep <- intersect(vidsA, vidsB) - adj <- adjustPips(fmr, keep) - expect_s4_class(adj, "QtlFineMappingResult") - expect_equal(nrow(adj), 2L) - expect_equal(variantIds(pecotmr:::.collectionEntry(adj, 1L)), keep) - expect_equal(variantIds(pecotmr:::.collectionEntry(adj, 2L)), keep) -}) - - # === Tests migrated from test_s4Constructors.R (FineMappingRow) === test_that("FineMappingRow: constructor stores slots and accessors return them", { tl <- .sc_makeTopLoci(3) tl$variant_id <- sprintf("chr9:%d:A:G", 100L * (1:3)) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = sprintf("chr9:%d:A:G", 100L * (1:3)), susieFit = list(payload = 1L), topLoci = tl @@ -179,7 +85,6 @@ test_that("FineMappingRow: constructor stores slots and accessors return them", expect_equal(out$variant_id, sprintf("chr9:%d:A:G", 100L * (1:3))) }) - test_that("FineMappingRow: pip returns named pip vector keyed by variant_id", { entry <- .sc_makeFineMappingRow(3) pip <- .fmrRowPip(entry) @@ -194,7 +99,7 @@ test_that("FineMappingRow: resolveWeights returns topLoci posterior effect align expect_equal(wr$weights, rep(0.05, 3)) expect_equal(length(wr$variantIds), length(wr$weights)) # empty topLoci -> empty pair - empty <- fineMappingRow( + empty <- FineMappingRow( variantIds = character(0), susieFit = list(), topLoci = data.frame( @@ -206,9 +111,8 @@ test_that("FineMappingRow: resolveWeights returns topLoci posterior effect align expect_length(.fmrRowResolveWeights(empty)$variantIds, 0L) }) - test_that("FineMappingRow: pip returns numeric(0) when topLoci is empty", { - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = character(0), susieFit = list(), topLoci = data.frame( @@ -220,14 +124,12 @@ test_that("FineMappingRow: pip returns numeric(0) when topLoci is empty", { expect_equal(.fmrRowPip(entry), numeric(0)) }) - test_that("FineMappingRow: credibleSets filters to rows in any credible set", { entry <- .sc_makeFineMappingRow(3) # last row has cs_95 = "susie_0" res <- .fmrRowCs(entry) expect_equal(nrow(res), 2L) }) - test_that("FineMappingRow: credibleSets/topLoci surface the directional af column", { # Regression: the posterior view must carry the topLoci `af` (effect-allele # frequency) through to .fmrRowCs() / .fmrRowTopLoci(), not drop it to NA. The @@ -243,10 +145,9 @@ test_that("FineMappingRow: credibleSets/topLoci surface the directional af colum expect_equal(unname(tl$af), rep(0.87, nrow(tl))) }) - test_that("FineMappingRow: validity errors when topLoci is missing required cols", { expect_error( - fineMappingRow( + FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(), topLoci = data.frame(other = 1, stringsAsFactors = FALSE) @@ -255,7 +156,6 @@ test_that("FineMappingRow: validity errors when topLoci is missing required cols ) }) - # === cvResult slot (cross-validation payload) === test_that("FineMappingRow stores and returns a cvResult payload", { @@ -269,7 +169,7 @@ test_that("FineMappingRow stores and returns a cvResult payload", { prediction = list(susie_predicted = matrix(0, 2, 1)), performance = list(susie_performance = matrix(0, 1, 6)) ) - e <- fineMappingRow( + e <- FineMappingRow( variantIds = tl$variant_id, susieFit = list(), topLoci = tl, @@ -284,14 +184,14 @@ test_that("FineMappingRow cvResult defaults to NULL and rejects non-list", { pip = 0.5, stringsAsFactors = FALSE ) - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(), topLoci = tl ) expect_null(.fmrPartsCvResult(e)) expect_error( - fineMappingRow( + FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(), topLoci = tl, @@ -302,25 +202,9 @@ test_that("FineMappingRow cvResult defaults to NULL and rejects non-list", { }) # =========================================================================== -# TwasWeightsRow +# show(), credibleSets and adjustPips on one row # =========================================================================== -test_that("QtlFineMappingResult: rejects rows that are not row payloads", { - expect_error( - QtlFineMappingResult( - studyName = "s1", - context = "c1", - trait = "t1", - method = "susie", - entry = list("not_an_entry") - ), - "must be a fine-mapping row" - ) -}) - - -# === Tests migrated from test_showMethods.R (FineMappingRow) === - test_that("show.FineMappingRow reports variant count and CS count", { e_with_cs <- .sh_makeFmEntry(n = 3, with_cs = TRUE) # 2 distinct cs > 0 out <- capture.output(show(e_with_cs)) @@ -335,41 +219,31 @@ test_that("show.FineMappingRow reports variant count and CS count", { pip = c(0.1, 0.2), stringsAsFactors = FALSE ) - e_no_cs <- fineMappingRow( + e_no_cs <- FineMappingRow( variantIds = c("chr9:100:A:G", "chr9:200:A:G"), susieFit = list(), topLoci = tl ) out_no <- capture.output(show(e_no_cs)) expect_true(any(grepl("0 credible sets", out_no))) -}) - -# === marginalEffects maxPval filter === - -test_that("FineMappingRow: marginalEffects applies the maxPval filter", { - tl <- data.frame( - variant_id = c("chr1:100:A:G", "chr1:200:A:G", "chr1:300:A:G"), - pip = c(0.9, 0.5, 0.1), - marginal_p = c(0.001, 0.5, NA_real_), - stringsAsFactors = FALSE - ) - entry <- fineMappingRow( - variantIds = tl$variant_id, - susieFit = list(), - topLoci = tl + # An empty row has no variants and so no sets. + empty <- FineMappingRow( + variantIds = character(0), + susieFit = list(pip = numeric(0)), + topLoci = data.frame( + variant_id = character(0), + pip = numeric(0), + stringsAsFactors = FALSE + ) ) - out <- .fmrRowMarginalEffects(entry, maxPval = 0.01) - # Drops the p = 0.5 row and the NA-p row; keeps only v1. - expect_equal(nrow(out), 1L) - expect_equal(out$variant_id, "chr1:100:A:G") + expect_output(show(empty), "0 variants, 0 credible sets") }) - # === credibleSets empty / cs-less topLoci projections === test_that("FineMappingRow: credibleSets returns empty posterior view when topLoci is empty", { - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = character(0), susieFit = list(), topLoci = data.frame( @@ -384,14 +258,13 @@ test_that("FineMappingRow: credibleSets returns empty posterior view when topLoc expect_true(all(c("variant_id", "pip") %in% names(res))) }) - test_that("FineMappingRow: credibleSets returns empty posterior view when the cs column is absent", { tl <- data.frame( variant_id = c("chr9:100:A:G", "chr9:200:A:G"), pip = c(0.1, 0.2), stringsAsFactors = FALSE ) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = c("chr9:100:A:G", "chr9:200:A:G"), susieFit = list(), topLoci = tl @@ -401,7 +274,6 @@ test_that("FineMappingRow: credibleSets returns empty posterior view when the cs expect_equal(nrow(res), 0L) }) - # === adjustPips: missing alpha + mu2-driven posterior recompute === test_that("FineMappingRow: adjustPips errors when susieFit lacks alpha", { @@ -410,7 +282,7 @@ test_that("FineMappingRow: adjustPips errors when susieFit lacks alpha", { pip = c(0.6, 0.4), stringsAsFactors = FALSE ) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = c("chr1:100:A:G", "chr1:200:A:G"), susieFit = list(), topLoci = tl @@ -421,7 +293,6 @@ test_that("FineMappingRow: adjustPips errors when susieFit lacks alpha", { ) }) - test_that("FineMappingRow: adjustPips subsets mu2 and recomputes posterior_sd", { vids <- paste0("chr1:", 1:5, ":A:G") p <- length(vids) @@ -433,7 +304,7 @@ test_that("FineMappingRow: adjustPips subsets mu2 and recomputes posterior_sd", pip <- as.numeric(1 - apply(1 - alpha, 2, prod)) mu <- matrix(rnorm(L * p), L, p) mu2 <- mu^2 + 1 # plausible second moment (>= mean^2) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = vids, susieFit = list( pip = pip, @@ -488,7 +359,7 @@ test_that("credibleSets / topLoci minPurity filters CS by purity, independent of ) attr(cst, "coverage") <- c(0.95, 0.70, 0.50) tl <- buildTopLoci(fit, cst, variantNames = vn, method = "susie") - e <- fineMappingRow(variantIds = vn, susieFit = fit, topLoci = tl) + e <- FineMappingRow(variantIds = vn, susieFit = fit, topLoci = tl) # credibleSets: minPurity is orthogonal to coverage -> keeps only the pure CS members expect_equal(nrow(.fmrRowCs(e, coverage = 0.95)), 4L) @@ -505,7 +376,6 @@ test_that("credibleSets / topLoci minPurity filters CS by purity, independent of expect_equal(nrow(.fmrRowTopLoci(e, signalCutoff = 0)), 5L) # default (NULL) unchanged }) - # =========================================================================== # adjustPips: renormalize the stored alpha (prior-correct), reject # Omega-weighted fits, handle null_weight, and recompute credible sets @@ -534,7 +404,7 @@ test_that("credibleSets / topLoci minPurity filters CS by purity, independent of list( lbf = lbf, alpha = alpha, - entry = fineMappingRow( + entry = FineMappingRow( variantIds = vids, susieFit = list( pip = pip, @@ -589,7 +459,7 @@ test_that("adjustPips refuses an Omega-weighted (susieInf / susieAsh) fit", { entry <- .makeAdjustEntry(vids) fit <- .fmrPartsSusieFit(entry) fit$theta <- rep(0.1, length(vids)) - weighted <- fineMappingRow( + weighted <- FineMappingRow( variantIds = vids, susieFit = fit, topLoci = .fmrRowTopLoci(entry, raw = TRUE) @@ -606,7 +476,7 @@ test_that("adjustPips keeps the null_weight column in the renormalization", { raw <- matrix(runif(L * (p + 1)), L, p + 1) alpha <- raw / rowSums(raw) pip <- as.numeric(1 - apply(1 - alpha[, seq_len(p), drop = FALSE], 2, prod)) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = vids, susieFit = list(pip = pip, alpha = alpha, null_index = p + 1L), topLoci = data.frame( @@ -634,7 +504,7 @@ test_that("adjustPips errors when alpha's width matches neither variant count", entry <- .makeAdjustEntry(vids) fit <- .fmrPartsSusieFit(entry) fit$alpha <- cbind(fit$alpha, fit$alpha) - broken <- fineMappingRow( + broken <- FineMappingRow( variantIds = vids, susieFit = fit, topLoci = .fmrRowTopLoci(entry, raw = TRUE) @@ -642,6 +512,50 @@ test_that("adjustPips errors when alpha's width matches neither variant count", expect_error(adjustPips(broken, vids[1:3]), "8 columns but the entry has 4") }) +test_that("adjustPips restricts a narrowed row's fit by the fit's own ids", { + # The row holds variants 3:6 of the six its fit was made with. The kept + # ones are found among the fit's columns by id, not by their position in + # the row, which would pick the fit's columns 1:2. + vids <- paste0("chr1:", 1:6, ":A:G") + entry <- .makeAdjustEntry(vids) + narrowed <- methods::new( + "FineMappingRow", + variants = variants(entry)[3:6], + susieFit = susieFit(entry), + fitVariants = vids + ) + adj <- adjustPips(narrowed, vids[3:4]) + alpha <- susieFit(entry)$alpha[, 3:4] + expect_equal(variantIds(adj), vids[3:4]) + expect_equal(unname(susieFit(adj)$alpha), unname(alpha / rowSums(alpha))) + expect_equal(pecotmr:::.fmRowFitVariants(adj), vids[3:4]) +}) + +test_that("adjustPips refuses a row holding a variant its fit never had", { + fitted <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A") + expect_equal( + pecotmr:::.adjustPipsFitIdx(fitted[c(3L, 1L)], fitted), + c(3L, 1L) + ) + expect_error( + pecotmr:::.adjustPipsFitIdx(c(fitted[[1L]], "chr1:900:A:G"), fitted), + "1 of the row's variants are not among the 3 its fit was made with" + ) +}) + +test_that("a row records its fit's variants only when it carries a fit", { + vids <- paste0("chr1:", 1:3, ":A:G") + tl <- data.frame(variant_id = vids, pip = c(0.5, 0.3, 0.2)) + fitted <- FineMappingRow(vids, list(pip = tl$pip), tl) + expect_equal(pecotmr:::.fmRowFitVariants(fitted), vids) + cvOnly <- FineMappingRow(vids, NULL, tl, cvResult = list(r2 = 0.1)) + expect_equal(pecotmr:::.fmRowFitVariants(cvOnly), vids) + expect_equal( + pecotmr:::.fmRowFitVariants(FineMappingRow(vids, list(), tl)), + character(0) + ) +}) + test_that("adjustPips recomputes credible sets instead of remapping indices", { vids <- paste0("chr1:", 1:6, ":A:G") p <- length(vids) @@ -650,7 +564,7 @@ test_that("adjustPips recomputes credible sets instead of remapping indices", { lbf <- matrix(rnorm(L * p, sd = 3), L, p, dimnames = list(NULL, vids)) alpha <- lbfToAlpha(lbf) pip <- as.numeric(1 - apply(1 - alpha, 2, prod)) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = vids, susieFit = list( pip = pip, @@ -699,7 +613,7 @@ test_that("adjustPips subsets mvsusie-shaped coef rows and 3-D clfsr", { fit <- .fmrPartsSusieFit(entry) fit$coef <- matrix(seq_len(p * R), nrow = p, ncol = R) fit$clfsr <- array(seq_len(L * p * R), dim = c(L, p, R)) - mv <- fineMappingRow( + mv <- FineMappingRow( variantIds = vids, susieFit = fit, topLoci = .fmrRowTopLoci(entry, raw = TRUE) @@ -715,16 +629,6 @@ test_that("adjustPips subsets mvsusie-shaped coef rows and 3-D clfsr", { ) }) -test_that(".fmrRowTopLoci(raw = TRUE) returns the stored table verbatim", { - vids <- paste0("chr1:", 1:4, ":A:G") - entry <- .makeAdjustEntry(vids) - raw <- .fmrRowTopLoci(entry, raw = TRUE) - expect_equal(nrow(raw), length(vids)) - expect_true(all(c("betahat", "sebetahat") %in% names(raw))) - # The default view filters by pip and projects; raw does neither. - expect_false(identical(names(raw), names(.fmrRowTopLoci(entry)))) -}) - # =========================================================================== # lbf (merged from test_getLbf.R when R/getLbf.R was folded # into R/FineMappingRow.R + R/AllClasses.R) @@ -741,7 +645,7 @@ test_that("lbf returns the wide variant x effect lbf matrix", { lbf_variable = lbf ) class(fit) <- "susie" - e <- fineMappingRow( + e <- FineMappingRow( variantIds = vids, susieFit = fit, topLoci = data.frame( @@ -758,7 +662,7 @@ test_that("lbf returns the wide variant x effect lbf matrix", { }) test_that("lbf is empty when the fit carries no lbf matrix", { - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(pip = 0.5), topLoci = data.frame( @@ -770,48 +674,6 @@ test_that("lbf is empty when the fit carries no lbf matrix", { expect_equal(nrow(.fmrRowLbf(e)), 0L) }) -test_that("lbf aggregates over a collection, carrying identity + NA-filling ragged effects", { - vids <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A") - mkEntry <- function(maxNumSingleEffects) { - lbf <- matrix( - seq_len(maxNumSingleEffects * length(vids)), - nrow = maxNumSingleEffects, - byrow = TRUE - ) # L x p - fit <- structure( - list(lbf_variable = lbf, pip = rep(0.3, length(vids))), - class = "susie" - ) - fineMappingRow( - variantIds = vids, - susieFit = fit, - topLoci = data.frame( - variant_id = vids, - pip = rep(0.3, length(vids)), - stringsAsFactors = FALSE - ) - ) - } - # Two entries with different effect counts (L = 2 vs 3) exercise the NA-fill of - # the ragged lbf_L columns described in the collection method's contract. - res <- QtlFineMappingResult( - studyName = c("s1", "s1"), - context = c("brain", "blood"), - trait = c("g", "g"), - method = c("susie", "susie"), - entry = list(mkEntry(2L), mkEntry(3L)) - ) - w <- lbf(res) - expect_true(all( - c("study", "context", "trait", "method", "variant_id") %in% names(w) - )) - expect_equal(nrow(w), 6L) # 2 entries x 3 variants - expect_setequal(unique(w$context), c("brain", "blood")) - expect_true("lbf_L3" %in% names(w)) - expect_true(all(is.na(w$lbf_L3[w$context == "brain"]))) # L = 2 entry: no effect 3 - expect_true(all(!is.na(w$lbf_L3[w$context == "blood"]))) # L = 3 entry: present -}) - # =========================================================================== # credibleSetSummary (merged from test_credibleSetSummary.R # when R/credibleSetSummary.R was folded in) @@ -858,7 +720,7 @@ test_that("credibleSetSummary returns one row per CS with size/purity/V/logBF/le ) attr(cst, "coverage") <- c(0.95, 0.70, 0.50) tl <- buildTopLoci(fit, cst, variantNames = vn, method = "susie") - e <- fineMappingRow(variantIds = vn, susieFit = fit, topLoci = tl) + e <- FineMappingRow(variantIds = vn, susieFit = fit, topLoci = tl) s <- .fmrRowCredibleSetSummary(e) s <- s[order(s$cs), , drop = FALSE] @@ -900,7 +762,7 @@ test_that("credibleSetSummary is empty when there are no credible sets", { ) attr(cst, "coverage") <- c(0.95, 0.70, 0.50) tl <- buildTopLoci(fit, cst, variantNames = vn, method = "susie") - e <- fineMappingRow(variantIds = vn, susieFit = fit, topLoci = tl) + e <- FineMappingRow(variantIds = vn, susieFit = fit, topLoci = tl) expect_equal(nrow(.fmrRowCredibleSetSummary(e)), 0L) }) @@ -916,7 +778,7 @@ test_that("credibleSetSummary is empty when the requested coverage column is abs cs_95_purity = c(0.9, 0.9), stringsAsFactors = FALSE ) - e <- fineMappingRow(variantIds = vn, susieFit = list(x = 1), topLoci = tl) + e <- FineMappingRow(variantIds = vn, susieFit = list(x = 1), topLoci = tl) expect_equal(nrow(.fmrRowCredibleSetSummary(e, coverage = 0.99)), 0L) }) @@ -932,7 +794,7 @@ test_that("credibleSetSummary reports NA cs_log_bf when the fit carries no lbf m cs_95_purity = c(0.88, 0.88), stringsAsFactors = FALSE ) - e <- fineMappingRow( + e <- FineMappingRow( variantIds = vn, susieFit = list(trimmed = TRUE), topLoci = tl @@ -957,102 +819,19 @@ test_that("credibleSetSummary reports NA cs_log_bf when the effect's lbf row is stringsAsFactors = FALSE ) fit <- structure(list(lbf_variable = lbf), class = "susie") - e <- fineMappingRow(variantIds = vn, susieFit = fit, topLoci = tl) + e <- FineMappingRow(variantIds = vn, susieFit = fit, topLoci = tl) expect_true(is.na(.fmrRowCredibleSetSummary(e)$cs_log_bf)) }) -test_that("credibleSetSummary aggregates across a collection with entry identity", { - mkEntry <- function() { - vn <- c("chr1:100:A:G", "chr1:200:C:T") - tl <- data.frame( - variant_id = vn, - pip = c(0.7, 0.2), - logBF = c(2.5, 0.3), - cs_95 = c("susie_1", "susie_1"), - cs_95_purity = c(0.9, 0.9), - stringsAsFactors = FALSE - ) - fineMappingRow(variantIds = vn, susieFit = list(x = 1), topLoci = tl) - } - res <- QtlFineMappingResult( - studyName = c("s", "s"), - context = c("brain", "blood"), - trait = c("g", "g"), - method = c("susie", "susie"), - entry = list(mkEntry(), mkEntry()) - ) - s <- credibleSetSummary(res) - expect_true(all( - c("study", "context", "trait", "method", "cs") %in% names(s) - )) - expect_equal(nrow(s), 2L) # one CS per entry - expect_setequal(unique(s$context), c("brain", "blood")) -}) - # =========================================================================== # fsusieCredibleBand / fsusieAffectedRegions (merged from # test_fsusieAccessors.R when R/fsusieAccessors.R was folded in) # =========================================================================== -.fsa_makeFit <- function(post_processing = "none") { - set.seed(1) - n <- 150L - p <- 24L - J <- 16L - X <- matrix( - rnorm(n * p), - n, - p, - dimnames = list( - paste0("s", seq_len(n)), - paste0("chr1:", seq_len(p) * 100, ":A:G") - ) - ) - b1 <- sin(seq(0, 2 * pi, length.out = J)) - b2 <- cos(seq(0, pi, length.out = J)) - Y <- X[, 3] %o% b1 + X[, 10] %o% b2 + matrix(rnorm(n * J, sd = 0.3), n, J) - colnames(Y) <- paste0("f", seq_len(J)) - suppressWarnings(fsusieR::susiF( - X = X, - Y = Y, - pos = seq_len(J), - L = 5, - post_processing = post_processing, - verbose = FALSE - )) -} -.fsa_entry <- function(fit, purityVal = 0.85) { - vids <- names(fit$csd_X) - pipv <- if (!is.null(fit$pip)) { - as.numeric(fit$pip) - } else { - rep(0.1, length(vids)) - } - # Canonical CS labels + purity from the fit's CS membership, mirroring what - # The fsusie post-processing writes into a real FMR's topLoci - # (cs_95 / cs_95_purity). - cs95 <- rep("fsusie_0", length(vids)) - for (l in seq_along(fit$cs)) { - idx <- fit$cs[[l]] - if (is.numeric(idx)) { - idx <- as.integer(idx) - } - cs95[idx] <- paste0("fsusie_", l) - } - tl <- data.frame( - variant_id = vids, - pip = pipv, - cs_95 = cs95, - cs_95_purity = ifelse(cs95 != "fsusie_0", purityVal, 0), - stringsAsFactors = FALSE - ) - fineMappingRow(variantIds = vids, susieFit = fit, topLoci = tl) -} - test_that("fsusieCredibleBand returns a long effect + band table (lower <= effect <= upper)", { skip_if_not_installed("fsusieR") skip_if_not_installed("wavethresh") - cb <- .fmrRowFsusieCredibleBand(.fsa_entry(.fsa_makeFit())) + cb <- .fmrRowFsusieCredibleBand(.fsa_entry(.fsa_fits$none)) expect_named( cb, c("cs", "chrom", "pos", "effect", "lower", "upper", "halfwidth") @@ -1068,7 +847,7 @@ test_that("trimmed fSuSiE keeps curves, bands and coloc inputs", { skip_if_not_installed("fsusieR") skip_if_not_installed("wavethresh") for (mode in c("none", "TI")) { - fit <- .fsa_makeFit(mode) + fit <- .fsa_fits[[mode]] expectedFit <- pecotmr:::.fsusiePopulateCredibleBand(fit) tables <- list(list(sets = list(cs = list()))) trimmed <- pecotmr:::trimFinemappingFit( @@ -1111,12 +890,11 @@ test_that("trimmed fSuSiE keeps curves, bands and coloc inputs", { } }) - test_that("fsusieAffectedRegions returns a GRanges with cs / purity / direction", { skip_if_not_installed("fsusieR") skip_if_not_installed("wavethresh") gr <- .fmrRowFsusieAffectedRegions(.fsa_entry( - .fsa_makeFit(), + .fsa_fits$none, purityVal = 0.85 )) expect_s4_class(gr, "GRanges") @@ -1132,7 +910,7 @@ test_that("fsusieAffectedRegions returns a GRanges with cs / purity / direction" }) test_that("fsusie accessors degrade to empty for a non-fSuSiE / trimmed fit (no wavelet slots)", { - e <- fineMappingRow( + e <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(pip = 0.5), topLoci = data.frame( @@ -1147,7 +925,7 @@ test_that("fsusie accessors degrade to empty for a non-fSuSiE / trimmed fit (no # ---- fsusieTraitEffects --------------------------------------------- -# The pipeline stamps trait_positions onto the stored fit (jointEngine.R) and +# The pipeline records trait_positions on the stored fit (jointEngine.R) and # keeps the matching names in the row's jointTraits column; rebuild that pairing # here, since .fsa_makeFit() returns the raw susiF fit. .fsa_jointFit <- function(fit, pos) { @@ -1158,7 +936,7 @@ test_that("fsusie accessors degrade to empty for a non-fSuSiE / trimmed fit (no test_that("fsusieTraitEffects evaluates the curve at each joint trait", { skip_if_not_installed("fsusieR") skip_if_not_installed("wavethresh") - fit <- .fsa_makeFit() + fit <- .fsa_fits$none nTrait <- length(fit$outing_grid) # Positions BETWEEN grid points, so the interpolation is doing real work. pos <- as.numeric(seq_len(nTrait)) + 0.5 @@ -1210,7 +988,7 @@ test_that("fsusieTraitEffects evaluates the curve at each joint trait", { test_that("fsusieTraitEffects refuses a fit whose positions and names disagree", { skip_if_not_installed("fsusieR") skip_if_not_installed("wavethresh") - fit <- .fsa_makeFit() + fit <- .fsa_fits$none res <- QtlFineMappingResult( studyName = "s", context = "brain", @@ -1231,7 +1009,7 @@ test_that("fsusieTraitEffects returns zero rows for a non-fsusie fit", { context = "brain", trait = "g", method = "susie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(pip = 0.5), topLoci = data.frame(variant_id = "chr1:100:A:G", pip = 0.5) @@ -1242,65 +1020,6 @@ test_that("fsusieTraitEffects returns zero rows for a non-fsusie fit", { expect_true(all(c("cs", "jointTrait", "traitPos", "effect") %in% names(te))) }) -test_that("fsusieCredibleBand + fsusieAffectedRegions aggregate across a collection", { - skip_if_not_installed("fsusieR") - skip_if_not_installed("wavethresh") - fit <- .fsa_makeFit() # deterministic; reuse for both rows - res <- QtlFineMappingResult( - studyName = c("s", "s"), - context = c("brain", "blood"), - trait = c("g", "g"), - method = c("fsusie", "fsusie"), - entry = list(.fsa_entry(fit), .fsa_entry(fit)) - ) - - cb <- fsusieCredibleBand(res) - expect_true(all( - c( - "study", - "context", - "trait", - "method", - "cs", - "effect", - "lower", - "upper" - ) %in% - names(cb) - )) - expect_gt(nrow(cb), 0) - expect_setequal(unique(cb$context), c("brain", "blood")) - - gr <- fsusieAffectedRegions(res) - expect_s4_class(gr, "GRanges") - expect_gt(length(gr), 0) - expect_true(all( - c("study", "context", "trait", "cs", "purity", "direction") %in% - names(S4Vectors::mcols(gr)) - )) - expect_setequal(unique(S4Vectors::mcols(gr)$context), c("brain", "blood")) -}) - -test_that("fsusieAffectedRegions on a collection of non-fSuSiE entries is an empty GRanges", { - e <- fineMappingRow( - variantIds = "chr1:100:A:G", - susieFit = list(pip = 0.5), - topLoci = data.frame( - variant_id = "chr1:100:A:G", - pip = 0.5, - stringsAsFactors = FALSE - ) - ) - res <- QtlFineMappingResult( - studyName = "s", - context = "c", - trait = "t", - method = "susie", - entry = list(e) - ) - expect_equal(length(fsusieAffectedRegions(res)), 0L) -}) - test_that(".fsusieChrom returns NA when the fit has no named variants", { expect_true(is.na(pecotmr:::.fsusieChrom(list(csd_X = c(1, 2, 3))))) # unnamed expect_true(is.na(pecotmr:::.fsusieChrom(list()))) # no csd_X @@ -1329,7 +1048,7 @@ test_that(".fsusieCsMapFromTopLoci falls back to index labels when topLoci lacks list(fitted_wc2 = 1, fitted_func = list(1), outing_grid = 1:2, alpha = 1) } .fsa_bareEntry <- function() { - fineMappingRow( + FineMappingRow( variantIds = "chr1:100:A:G", susieFit = .fsa_fakeFit(), topLoci = data.frame( @@ -1434,7 +1153,7 @@ test_that("credibleSets warns when the coverage has no purity column to filter o # outside -- and a coverage with no sets returns earlier, so that route # cannot reach it either. tl$cs_95_purity <- NULL - e <- fineMappingRow(variantIds = vn, susieFit = fit, topLoci = tl) + e <- FineMappingRow(variantIds = vn, susieFit = fit, topLoci = tl) expect_warning( .fmrRowCs(e, coverage = 0.95, minPurity = 0.8), @@ -1455,7 +1174,7 @@ test_that("credibleSets warns when the coverage has no purity column to filter o test_that("topLoci must have one row per supplied variant", { vids <- .fmr_vids(3L) expect_error( - fineMappingRow( + FineMappingRow( variantIds = vids, susieFit = list(fake = TRUE), topLoci = data.frame( @@ -1473,7 +1192,7 @@ test_that("topLoci must list the variants in the same order", { # order check catches it. vids <- .fmr_vids(3L) expect_error( - fineMappingRow( + FineMappingRow( variantIds = vids, susieFit = list(fake = TRUE), topLoci = data.frame( @@ -1636,7 +1355,6 @@ test_that("a fit with no stored sets falls back to the per-variant column", { expect_equal(s$cs, "susie_1") }) - # =========================================================================== # Purity filtering, coverage defaults and column projection # =========================================================================== @@ -1668,11 +1386,6 @@ test_that("an unusable coverage falls back to 0.95", { expect_equal(pecotmr:::.adjustPipsCoverage(NULL), 0.95) }) -test_that("the credible-set prefix defaults to cs with no method column", { - tl <- tibble(variant_id = c("a", "b"), pip = c(0.1, 0.9)) - expect_equal(pecotmr:::.adjustPipsMethodLabel(tl), "cs") -}) - test_that("projecting an absent column yields typed NAs of the right length", { # One NA per row, of the requested type, so the column binds against the # rest of the table instead of collapsing it. @@ -1686,7 +1399,6 @@ test_that("projecting an absent column yields typed NAs of the right length", { expect_equal(pecotmr:::.tlCol(tl, "pip", "numeric"), c(0.1, 0.9)) }) - # =========================================================================== # Credible-set summary assembly and PIP adjustment # =========================================================================== @@ -1831,30 +1543,6 @@ test_that(".adjustPipsMethodLabel defaults to 'cs'", { ) }) -test_that("show(FineMappingRow) reports zero sets for an empty row", { - empty <- fineMappingRow( - variantIds = character(0), - susieFit = list(pip = numeric(0)), - topLoci = data.frame( - variant_id = character(0), - pip = numeric(0), - stringsAsFactors = FALSE - ) - ) - expect_output(show(empty), "0 variants, 0 credible sets") - withCs <- fineMappingRow( - variantIds = c("chr1:1:A:G", "chr1:2:C:T"), - susieFit = list(pip = c(0.9, 0.1)), - topLoci = data.frame( - variant_id = c("chr1:1:A:G", "chr1:2:C:T"), - pip = c(0.9, 0.1), - cs_95 = c("L1_1", "L1_0"), - stringsAsFactors = FALSE - ) - ) - expect_output(show(withCs), "2 variants, 1 credible sets") -}) - test_that(".csLog10Bf and .csMeanEffect return NA, never -Inf or NaN", { # Both previously disagreed with their own missing-column branch: an empty # or all-NA column yielded -Inf / NaN from max() / mean() while a missing @@ -1927,7 +1615,7 @@ test_that("an empty credible band still declares halfwidth", { # @noRd .fte_row <- function(fit) { - fineMappingRow( + FineMappingRow( variantIds = "chr1:100:A:G", susieFit = fit, topLoci = data.frame( @@ -2012,7 +1700,7 @@ test_that("a credible-set label matching no fit effect claims none", { }) test_that("a NULL posterior table projects to an empty GRanges", { - gr <- .fmeTopLociGRanges(NULL) + gr <- .variantTableGRanges(NULL) expect_s4_class(gr, "GRanges") expect_length(gr, 0L) }) @@ -2026,7 +1714,7 @@ test_that("a fit whose prior variances all vanished labels nothing", { colnames(lbf) <- vids alpha <- lbfToAlpha(lbf) pip <- as.numeric(1 - apply(1 - alpha, 2, prod)) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = vids, susieFit = list( pip = pip, diff --git a/tests/testthat/test_fineMappingWrappers.R b/tests/testthat/test_fineMappingWrappers.R index 564fc52f..8c3c4312 100644 --- a/tests/testthat/test_fineMappingWrappers.R +++ b/tests/testthat/test_fineMappingWrappers.R @@ -41,20 +41,21 @@ context("susie_finemapping") list(z = z, R = R, ids = ids, flipped = 6L) } -test_that("lbf_to_alpha_vector converts correctly", { - lbf <- c(a = -0.5, b = 1.2, c = 0.3) - alpha <- pecotmr:::lbfToAlphaVector(lbf) - expect_length(alpha, 3) - expect_equal(sum(alpha), 1, tolerance = 1e-10) - expect_true(alpha["b"] > alpha["a"]) -}) - -test_that("lbf_to_alpha_vector with prior weights", { - lbf <- c(a = 1, b = 1, c = 1) # Equal LBFs - pw <- c(0.5, 0.25, 0.25) - alpha <- pecotmr:::lbfToAlphaVector(lbf, priorWeights = pw) - expect_true(alpha[1] > alpha[2]) - expect_equal(sum(alpha), 1, tolerance = 1e-10) +test_that("lbf_to_alpha_vector normalizes moderate and extreme LBFs", { + # Very large and very negative values must neither overflow nor + # underflow to a degenerate posterior. + cases <- list( + moderate = c(a = -0.5, b = 1.2, c = 0.3), + large = c(a = 500, b = 500.1, c = 499), + negative = c(a = -1000, b = -999, c = -1001) + ) + for (nm in names(cases)) { + alpha <- pecotmr:::lbfToAlphaVector(cases[[nm]]) + expect_equal(length(alpha), 3L, info = nm) + expect_true(all(is.finite(alpha)), info = nm) + expect_equal(sum(alpha), 1, tolerance = 1e-10, info = nm) + expect_true(alpha["b"] > alpha["a"], info = nm) + } }) test_that("lbf_to_alpha_vector renormalizes an all-zero lbf to the prior", { @@ -93,30 +94,6 @@ test_that("lbf_to_alpha_vector handles single element", { expect_equal(alpha[["a"]], 1.0) }) -test_that("lbf_to_alpha_vector handles very large LBFs without overflow", { - lbf <- c(a = 500, b = 500.1, c = 499) - alpha <- pecotmr:::lbfToAlphaVector(lbf) - expect_true(all(is.finite(alpha))) - expect_equal(sum(alpha), 1, tolerance = 1e-10) - expect_true(alpha["b"] > alpha["a"]) -}) - -test_that("lbf_to_alpha_vector handles very negative LBFs", { - lbf <- c(a = -1000, b = -999, c = -1001) - alpha <- pecotmr:::lbfToAlphaVector(lbf) - expect_true(all(is.finite(alpha))) - expect_equal(sum(alpha), 1, tolerance = 1e-10) - expect_true(alpha["b"] > alpha["a"]) -}) - -test_that("lbf_to_alpha_vector with unequal prior weights", { - lbf <- c(a = 0.5, b = 0.5, c = 0.5) - pw <- c(0.8, 0.1, 0.1) - alpha <- pecotmr:::lbfToAlphaVector(lbf, priorWeights = pw) - expect_equal(sum(alpha), 1, tolerance = 1e-10) - expect_true(alpha[1] > 0.7) -}) - # ============================================================================= # lbfToAlpha (matrix version) # ============================================================================= @@ -145,15 +122,6 @@ test_that("lbfToAlpha handles single-row matrix", { expect_equal(sum(result), 1, tolerance = 1e-10) }) -test_that("lbfToAlpha handles large matrix", { - set.seed(42) - lbf <- matrix(rnorm(100), nrow = 10, ncol = 10) - colnames(lbf) <- sprintf("chr1:%d:A:G", 100L * (1:10)) - result <- lbfToAlpha(lbf) - expect_equal(dim(result), c(10, 10)) - expect_equal(rowSums(result), rep(1, 10), tolerance = 1e-10) -}) - test_that("lbfToAlpha with mixed zero and nonzero rows", { lbf <- matrix(c(0, 0, 0, 1, 2, 3), nrow = 2, byrow = TRUE) colnames(lbf) <- sprintf("chr1:%d:A:G", 100L * (1:3)) @@ -339,40 +307,92 @@ test_that("susieInfWeights returns zeros without proper fit structure", { expect_equal(result, rep(0, 5)) }) -# ============================================================================= -# glmnetWeights -# ============================================================================= - -test_that("glmnetWeights produces non-zero weights for correlated data", { - skip_if_not_installed("glmnet") - set.seed(42) - n <- 100 - p <- 10 - X <- matrix(rnorm(n * p), n, p) - beta_true <- c(3, -2, rep(0, p - 2)) - y <- X %*% beta_true + rnorm(n) - - w <- glmnetWeights(X, y, alpha = 0.5) - expect_length(w, p) - expect_true(any(w != 0)) -}) - -test_that("glmnetWeights handles zero-variance columns", { - skip_if_not_installed("glmnet") - set.seed(42) - n <- 100 +# ---- susieWeights ---- +test_that("susieWeights with alpha/mu/X_column_scale_factors calls coef.susie", { p <- 5 - X <- matrix(rnorm(n * p), n, p) - X[, 3] <- 1 # zero variance column - y <- X[, 1] * 2 + rnorm(n) + L <- 2 + mock_fit <- list( + alpha = matrix( + c( + 0.9, + 0.05, + 0.02, + 0.02, + 0.01, + 0.1, + 0.1, + 0.6, + 0.1, + 0.1 + ), + nrow = L, + ncol = p, + byrow = TRUE + ), + mu = matrix( + c( + 2.0, + 0.1, + 0.05, + 0.03, + 0.01, + 0.5, + 0.2, + 1.5, + 0.1, + 0.05 + ), + nrow = L, + ncol = p, + byrow = TRUE + ), + X_column_scale_factors = rep(1.0, p), + pip = runif(p), + intercept = 0 + ) + result <- susieWeights(susieFit = mock_fit) + expect_length(result, p) + expect_true(is.numeric(result)) + expect_true(any(result != 0)) +}) + +# ---- susieAshWeights / susieInfWeights ---- +# The fit is each extractor's third argument (susieAshFit / susieInfFit). +test_that("susieAshWeights / susieInfWeights error on dimension mismatch", { + mock_fit <- list(pip = c(0.1, 0.2)) + X <- matrix(rnorm(30), nrow = 10, ncol = 3) + for (fn in c("susieAshWeights", "susieInfWeights")) { + expect_error( + exec(fn, X, NULL, mock_fit), + "Dimension mismatch", + info = fn + ) + } +}) - w <- glmnetWeights(X, y, alpha = 1) - expect_length(w, p) - expect_equal(w[3], 0) +test_that("susieAshWeights / susieInfWeights add theta to the sparse part", { + # The weights are coef.susie() without its intercept: the mappable + # effect colSums(alpha * mu) plus the fit's theta, on the X scale. + p <- 4 + L <- 2 + set.seed(5) + fit <- list( + alpha = matrix(runif(L * p), nrow = L, ncol = p), + mu = matrix(rnorm(L * p), nrow = L, ncol = p), + theta = rnorm(p), + X_column_scale_factors = c(1, 2, 0.5, 1), + pip = runif(p), + intercept = 0.7 + ) + want <- (colSums(fit$alpha * fit$mu) + fit$theta) / + fit$X_column_scale_factors + for (fn in c("susieAshWeights", "susieInfWeights")) { + expect_equal(exec(fn, NULL, NULL, fit), want, info = fn) + } }) # ============================================================================= -# postprocessFinemappingFits: analysisScript and V=NULL branches (Tier 1) +# postprocessFinemappingFits: V = NULL branch # ============================================================================= # Helper: build a minimal synthetic SuSiE-family output for post-processing @@ -491,7 +511,7 @@ test_that("formatFinemappingOutput does not duplicate top loci variants", { stringsAsFactors = FALSE ) vids <- sprintf("chr1:%d:A:G", 100L * (1:4)) - fm <- fineMappingRow( + fm <- FineMappingRow( variantIds = vids, susieFit = list(pip = 1:4), topLoci = data.frame( @@ -572,36 +592,9 @@ test_that(".translate_legacy_top_loci_cs_columns leaves existing pip column alon # ============================================================================ -# Unified top-loci: hard gating coverage per OpenSpec tasks 4.27 / 4.28. -# These tests are the implementation gate for the buildTopLoci migration. +# Unified top-loci (buildTopLoci): schema, CS columns and coverage handling # ============================================================================ -# Reuse the existing local helper. Re-declared inside this block so the file -# remains correct whether the unified-section tests are run alone or as part of -# the full file. -if (!exists(".makeUnivariateData", inherits = FALSE)) { - .makeUnivariateData <- function( - seed = 42, - n = 300, - p = 50, - effect_idx = integer(0), - effect_size = NULL - ) { - set.seed(seed) - X <- matrix(rnorm(n * p), n, p) - colnames(X) <- sprintf("chr1:%d:G:A", seq_len(p)) - beta <- rep(0, p) - if (length(effect_idx) > 0) { - if (is.null(effect_size)) { - effect_size <- rep(1.5, length(effect_idx)) - } - beta[effect_idx] <- effect_size - } - y <- as.numeric(X %*% beta) + rnorm(n, sd = 0.5) - list(X = X, y = y) - } -} - .UNIFIED_TOP_LOCI_COLS <- c( "variant_id", "chrom", @@ -929,28 +922,38 @@ test_that("buildTopLoci: mvsusie per-condition lfsr + effect (long)", { expect_false(any(c("conditional_effect", "lfsr") %in% names(tl0))) }) -test_that("topLoci surfaces the mvsusie lfsr through the projector", { - tl <- data.frame( - variant_id = c("chr1:100:A:G", "chr1:200:C:T"), - chrom = "1", - pos = c(100L, 200L), - A1 = c("A", "C"), - A2 = c("G", "T"), - pip = c(0.6, 0.4), - posterior_mean = c(0.1, 0.2), - posterior_sd = c(0.05, 0.05), - cs_95 = c("mvsusie_1", "mvsusie_1"), - lfsr = c(0.001, 0.02), - stringsAsFactors = FALSE +test_that("theta is the posterior effect's infinitesimal part, not an extra", { + nV <- 12 + th <- rnorm(nV, sd = 0.05) + fit <- .thetaFit(nV, th) + vids <- sprintf("chr1:%d:A:T", seq_len(nV) * 1000) + tl <- buildTopLoci( + fit = fit, + csTables = NULL, + variantNames = vids, + method = "susie_inf" ) - e <- fineMappingRow( - variantIds = tl$variant_id, - susieFit = list(pip = tl$pip), - topLoci = tl + sparse <- colSums(fit$alpha * fit$mu) + # coef.susie() sums the sparse and infinitesimal terms, so the published + # effect ALREADY contains theta -- publishing theta only exposes the split. + expect_equal(tl$posterior_mean, sparse + th, tolerance = 1e-10) + expect_equal(tl$posterior_theta, th, tolerance = 1e-10) + expect_equal( + tl$posterior_mean - tl$posterior_theta, + sparse, + tolerance = 1e-10 ) - out <- .fmrRowTopLoci(e, signalCutoff = 0) - expect_true(is_in("lfsr", names(out))) - expect_equal(out$lfsr, c(0.001, 0.02)) +}) + +test_that("a fit with no infinitesimal term reports theta = 0, not NA", { + tl <- buildTopLoci( + fit = .thetaFit(12), + csTables = NULL, + variantNames = sprintf("chr1:%d:A:T", seq_len(12) * 1000), + method = "susie" + ) + expect_true(all(tl$posterior_theta == 0)) + expect_false(anyNA(tl$posterior_theta)) }) test_that("buildTopLoci derives CS columns from the ACTUAL coverages (no hardcoded 0.95/0.70/0.50)", { @@ -1017,7 +1020,7 @@ test_that("buildTopLoci: per-variant logBF is the max single-effect lbf", { expect_true("logBF" %in% names(tl)) expect_equal(tl$logBF, apply(lbf, 2, max)) # c(2.0, 3.0, 0.2) # surfaced through topLoci's projection too - e <- fineMappingRow(variantIds = vids, susieFit = fit, topLoci = tl) + e <- FineMappingRow(variantIds = vids, susieFit = fit, topLoci = tl) expect_true("logBF" %in% names(.fmrRowTopLoci(e, signalCutoff = 0))) }) @@ -1030,8 +1033,7 @@ test_that("buildTopLoci emits the fixed columns in order on a non-empty fit", { "0.7" = list(c(1L, 2L)), "0.5" = list(c(1L, 2L)) ), - nSamples = 419, - n_variants = 11332 + nSamples = 419 ) other_q <- list(condition_id = "Ast_DeJager_eQTL") out <- .runBuildTopLoci( @@ -1040,7 +1042,7 @@ test_that("buildTopLoci emits the fixed columns in order on a non-empty fit", { sumstats = list(betahat = c(0.2, -0.1), sebetahat = c(0.05, 0.04)), af = c(0.10, 0.25), otherQuantities = other_q, - region = "chr10:10823338-14348298" + region = GenomicRanges::GRanges("chr10:10823338-14348298") ) expect_equal(names(out), .UNIFIED_TOP_LOCI_COLS) expect_equal(unique(out$gene), "ENSG00000179403") @@ -1367,30 +1369,6 @@ test_that("postprocessFinemappingFits forwards medianAbsCorr to susie_get_cs (OR expect_gte(.n_cs95(pOr), .n_cs95(pStrict)) }) -test_that("postprocessFinemappingFits with medianAbsCorr = NULL is a no-op", { - d <- .makeUnivariateData(seed = 7, effect_idx = c(20)) - fit <- susieR::susie(d$X, d$y, L = 5) - p1 <- postprocessFinemappingFits( - list(susie = fit), - dataX = d$X, - dataY = d$y, - credibleSetParam = CredibleSetParam( - coverage = 0.95 - ) - ) - p2 <- postprocessFinemappingFits( - list(susie = fit), - dataX = d$X, - dataY = d$y, - credibleSetParam = CredibleSetParam( - coverage = 0.95, - medianAbsCorr = NULL - ) - ) - expect_equal(p1$top_loci$cs_95, p2$top_loci$cs_95) - expect_equal(p1$top_loci$af, p2$top_loci$af) -}) - test_that("cs_95 / cs_70 / cs_50 are character strings of the form '_'", { variant_ids <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:T:C") # Variants 1 and 2 in CS 1 (at 95), variant 3 in CS 2 (at 95). All three @@ -1459,6 +1437,8 @@ test_that("per-method CS indices are independent across susie and susieInf (post has_susie_inf_1 <- any(susie_inf_rows$cs_95 == "susie_inf_1") expect_true(has_susie_1 || nrow(susie_rows) == 0L) expect_true(has_susie_inf_1 || nrow(susie_inf_rows) == 0L) + # A variant both methods report gets one row per method, never two. + expect_equal(anyDuplicated(tl[, c("variant_id", "method")]), 0L) }) test_that("cs_95_purity = 0 when cs_95 is '_0', and in (0, 1] otherwise", { @@ -1499,40 +1479,6 @@ test_that("overlapping CS within one method: one row per variant; smallest cs_id expect_equal(out$cs_95, "susie_1") }) -test_that("overlapping CS across methods produces one row per method", { - d <- .makeUnivariateData(seed = 22, effect_idx = c(12, 32)) - fits <- fitSusieInfThenSusie(d$X, d$y) - post <- postprocessFinemappingFits( - fits, - dataX = d$X, - dataY = d$y, - credibleSetParam = CredibleSetParam( - coverage = 0.95, - secondaryCoverage = c(0.7, 0.5) - ) - ) - tl <- post$top_loci - if (nrow(tl) > 0L) { - cnt_per_method <- table(tl$variant_id, tl$method) - shared <- rownames(cnt_per_method)[ - apply(cnt_per_method > 0, 1, sum) >= 2L - ] - if (length(shared) > 0L) { - v <- shared[[1]] - rows_for_v <- tl[tl$variant_id == v, , drop = FALSE] - expect_gte(length(unique(rows_for_v$method)), 2L) - } else { - succeed( - "no shared variants in this fixture; cross-method uniqueness rule is structural" - ) - } - } else { - succeed( - "empty top_loci from this fixture; cross-method uniqueness rule is structural" - ) - } -}) - test_that("formatFinemappingOutput exposes exactly one top_loci field; no top_loci_long, no wide top_loci, no top_loci_export", { d <- .makeUnivariateData(seed = 23, effect_idx = c(15, 40)) fits <- fitSusieInfThenSusie(d$X, d$y) @@ -1548,7 +1494,7 @@ test_that("formatFinemappingOutput exposes exactly one top_loci field; no top_lo expect_true("top_loci" %in% names(out)) expect_false("top_loci_long" %in% names(out)) expect_false("top_loci_export" %in% names(out)) - # The exposed top_loci has the unified 22-column schema. + # The exposed top_loci has the unified schema. expect_equal(names(out$top_loci), .UNIFIED_TOP_LOCI_COLS) }) @@ -1575,57 +1521,6 @@ test_that("postprocessFinemappingFits does not return top_loci_long anywhere", { } }) -test_that("build_top_loci_long / build_top_loci_wide / build_top_loci_export are removed from the package", { - # Two layered checks. (1) The new helper must be reachable. (2) The old - # helpers must NOT be reachable — neither in the package namespace (if the - # package is installed) nor in .GlobalEnv (when this file is source-loaded - # against the fresh R/ tree for testing). The contract is that the trio is - # gone end-to-end after the migration. - resolve <- function(name) { - if (exists(name, envir = .GlobalEnv, inherits = FALSE)) { - return(get(name, envir = .GlobalEnv)) - } - ns_ok <- tryCatch(asNamespace("pecotmr"), error = function(e) NULL) - if (!is.null(ns_ok) && exists(name, envir = ns_ok, inherits = FALSE)) { - return(get(name, envir = ns_ok)) - } - NULL - } - expect_false( - is.null(resolve("buildTopLoci")), - info = "buildTopLoci must be defined after the migration" - ) - # The removed trio: only fail if a definition exists in the SAME source - # tree we just loaded (i.e. globalenv). The installed-package namespace - # may still carry stale copies from an earlier install; the gate only - # cares that the new source tree does not redefine them. - expect_false(exists( - "build_top_loci_long", - envir = .GlobalEnv, - inherits = FALSE - )) - expect_false(exists( - "build_top_loci_wide", - envir = .GlobalEnv, - inherits = FALSE - )) - expect_false(exists( - "build_top_loci_export", - envir = .GlobalEnv, - inherits = FALSE - )) - expect_false(exists( - ".emptyTopLoci_long", - envir = .GlobalEnv, - inherits = FALSE - )) - expect_false(exists( - ".emptyTopLoci_export", - envir = .GlobalEnv, - inherits = FALSE - )) -}) - test_that("buildTopLoci raises an explicit error on invalid variant_id rather than silently filling NA", { variant_ids <- c("not_a_valid_id") cs_at_cov <- list("0.95" = list(1L), "0.7" = list(1L), "0.5" = list(1L)) @@ -1678,7 +1573,7 @@ test_that("missing region produces NA grange columns rather than silent omission method = "susie", otherQuantities = list(condition_id = "ctx") ) - # grange_* must still be present columns of the 22-col schema, with NA values. + # grange_* must still be present columns of the schema, with NA values. expect_true(all(c("grange_start", "grange_end") %in% names(out))) expect_true(all(is.na(out$grange_start))) expect_true(all(is.na(out$grange_end))) @@ -2047,22 +1942,25 @@ test_that(".asLbfMatrix prefers lbf_variable, falls back to lBF, else NULL", { }) # ---- .parseGrange ---- -test_that(".parseGrange returns NA for NULL/empty/invalid and parses valid regions", { +test_that(".parseGrange reads a window's bounds, NA without one", { expect_equal( pecotmr:::.parseGrange(NULL), c(start = NA_integer_, end = NA_integer_) ) expect_equal( - pecotmr:::.parseGrange(""), + pecotmr:::.parseGrange(GenomicRanges::GRanges()), c(start = NA_integer_, end = NA_integer_) ) expect_equal( - pecotmr:::.parseGrange("not_a_region"), - c(start = NA_integer_, end = NA_integer_) + pecotmr:::.parseGrange(GenomicRanges::GRanges( + "chr10:10823338-14348298" + )), + c(start = 10823338L, end = 14348298L) ) - expect_equal( + # A window is a GRanges; a string is refused rather than read. + expect_error( pecotmr:::.parseGrange("chr10:10823338-14348298"), - c(start = 10823338L, end = 14348298L) + "`region` must be a GRanges" ) }) @@ -2708,7 +2606,7 @@ test_that("susieRssWeights retains fit unless fitRetention is none", { expect_false(is.null(attr(w, "fit"))) }) -test_that("susieInfRssWeights works", { +test_that("susieInfRssWeights adds the fit's infinitesimal theta", { skip_if_not_installed("susieR") set.seed(42) p <- 20 @@ -2716,42 +2614,58 @@ test_that("susieInfRssWeights works", { R <- diag(p) z <- rnorm(p) stat <- list(z = z, n = rep(n, p), variantNames = .rrwIds(p)) - fit <- susieR::susie_rss(z = z, R = R, n = n, L = 5) - w <- susieInfRssWeights(stat, .rrwLdMatrix(R), susieInfRssFit = fit) - expect_equal(length(w), p) - expect_true(all(is.finite(w))) -}) - -test_that("mvsusieWeights real fit returns p x K weights or errors on unstable small data", { - skip_if_not_installed("mvsusieR") - m <- .rrwMulti(n = 80, p = 8, K = 2) - res <- tryCatch( - suppressMessages(mvsusieWeights(X = m$X, Y = m$Y, L = 5, LGreedy = 2)), - error = function(e) e - ) - if (inherits(res, "error")) { - # mvSuSiE can be numerically unstable on tiny (X, Y); a clean error is - # acceptable here. The coef-extraction path is covered by the mocked tests - # in test_rrMrmashMvsusie.R. - succeed("mvsusieWeights errored on small data (documented instability)") - } else { - expect_equal(dim(res), c(m$p, m$K)) - expect_true(all(is.finite(res))) - } + # The fit fineMappingPipeline() makes for susieInf: it carries theta, the + # infinitesimal effects. A plain susie_rss() fit has no theta, and the + # extractor returns all-zero weights for it. + fit <- suppressMessages(susieR::susie_rss( + z = z, + R = R, + n = n, + L = 5, + unmappable_effects = "inf" + )) + expect_true(any(fit$theta != 0)) + w <- susieInfRssWeights( + stat, + .rrwLdMatrix(R), + susieInfRssFit = fit, + fitRetention = "none" + ) + # coef.susie(): the sparse alpha * mu effects plus theta, divided by the + # scale factors. theta is a one-column matrix; the weights are a vector. + expect_equal( + w, + (colSums(fit$alpha * fit$mu) + drop(fit$theta)) / + fit$X_column_scale_factors + ) }) -test_that("susieAshRssWeights returns weights of length p", { +test_that("susieAshRssWeights adds the fit's ash theta", { skip_if_not_installed("susieR") f <- .rrwStatLd() - fit <- susieR::susie_rss( + # The fit fineMappingPipeline() makes for susieAsh: it carries theta, the + # ash-shrunk unmappable effects. A plain susie_rss() fit has no theta, + # and the extractor returns all-zero weights for it. + fit <- suppressMessages(susieR::susie_rss( z = f$stat$z, R = f$LD, n = median(f$stat$n), - L = 5 + L = 5, + unmappable_effects = "ash" + )) + expect_true(any(fit$theta != 0)) + w <- susieAshRssWeights( + f$stat, + f$ldReference, + susieAshRssFit = fit, + fitRetention = "none" + ) + # coef.susie(): the sparse alpha * mu effects plus theta, divided by the + # scale factors. + expect_equal( + w, + (colSums(fit$alpha * fit$mu) + fit$theta) / fit$X_column_scale_factors ) - w <- susieAshRssWeights(f$stat, f$ldReference, susieAshRssFit = fit) - expect_length(w, f$p) - expect_true(all(is.finite(w))) }) test_that("mvsusieRssWeights returns p x K weights from a supplied fit", { @@ -2822,15 +2736,6 @@ test_that("mvsusieRssWeights checks the fit against the statistics' block", { ) }) -test_that("mvsusieRssWeights refuses to fine-map when no fit is supplied", { - skip_if_not_installed("mvsusieR") - m <- .rrwMulti(n = 80, p = 8, K = 2) - expect_error( - mvsusieRssWeights(m$stat, m$ldReference), - "`mvsusieRssFit` is required" - ) -}) - test_that("mvsusieRssWeights demands a fit before anything else", { skip_if_not_installed("mvsusieR") f <- .rrwStatLd() @@ -2922,10 +2827,19 @@ test_that("mvsusieWeights returns coefficients from provided fit", { ) } +# One fit at the default prior serves every test below that uses it: each +# susiF() fit takes about a second. +.fw_fsusieDefault <- if ( + requireNamespace("fsusieR", quietly = TRUE) && + requireNamespace("wavethresh", quietly = TRUE) +) { + .fw_makeFsusieFit() +} + test_that("fsusieWeights returns a variants x features matrix with variant rownames", { skip_if_not_installed("fsusieR") skip_if_not_installed("wavethresh") - obj <- .fw_makeFsusieFit() + obj <- .fw_fsusieDefault W <- fsusieWeights(fsusieFit = obj$fit, variantIds = colnames(obj$X)) expect_true(is.matrix(W)) expect_equal(nrow(W), ncol(obj$X)) @@ -2936,7 +2850,7 @@ test_that("fsusieWeights returns a variants x features matrix with variant rowna test_that("computeCsTable (fsusie): within-CS purity, not cal_cor_cs", { skip_if_not_installed("fsusieR") skip_if_not_installed("wavethresh") - obj <- .fw_makeFsusieFit() + obj <- .fw_fsusieDefault ct <- computeCsTable(obj$fit, obj$X, coverage = 0.95, csInput = "fsusie") # purity is recorded as min.abs.corr, the susieR-path shape that # .csPurityVec reads @@ -2954,7 +2868,7 @@ test_that("computeCsTable (fsusie): within-CS purity, not cal_cor_cs", { test_that("fsusieWeights matches fsusieR's own out_prep reconstruction (post_processing='none')", { skip_if_not_installed("fsusieR") skip_if_not_installed("wavethresh") - obj <- .fw_makeFsusieFit() + obj <- .fw_fsusieDefault fit <- obj$fit # The alpha-weighted sum over SNPs of the per-SNP feature-domain curves that # fsusieWeights reconstructs must equal fSuSiE's own fitted_func[[l]] (built @@ -2985,7 +2899,7 @@ test_that("fsusieWeights matches fsusieR's own out_prep reconstruction (post_pro test_that("fsusieWeights concentrates weight on the causal SNPs", { skip_if_not_installed("fsusieR") skip_if_not_installed("wavethresh") - obj <- .fw_makeFsusieFit() + obj <- .fw_fsusieDefault W <- fsusieWeights(fsusieFit = obj$fit, variantIds = colnames(obj$X)) rowNorm <- sqrt(rowSums(W^2)) top2 <- names(sort(rowNorm, decreasing = TRUE))[1:2] @@ -3024,7 +2938,7 @@ test_that("fsusieWeights errors without a fit and on an unusable (trimmed, no co .msc_entry <- function(vid, pip, cs, csName = "cs_95") { tl <- data.frame(variant_id = vid, pip = pip, stringsAsFactors = FALSE) tl[[csName]] <- cs - fineMappingRow(variantIds = vid, susieFit = list(), topLoci = tl) + FineMappingRow(variantIds = vid, susieFit = list(), topLoci = tl) } .msc_fmr <- function(entries, method = "susie") { n <- length(entries) @@ -3110,7 +3024,7 @@ test_that("mergeSusieCs: a condition with no usable CS is skipped, valid ones ke c(0.9, 0.8), c("susie_1", "susie_1") ) - noCs <- fineMappingRow( + noCs <- FineMappingRow( variantIds = "chr1:300:A:G", susieFit = list(), topLoci = data.frame(variant_id = "chr1:300:A:G", pip = 0.9) @@ -3126,7 +3040,7 @@ test_that("mergeSusieCs: NULL when no condition contributes a credible set", { 0.9, "susie_0" ))))) # all _0 - noCs <- fineMappingRow( + noCs <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(), topLoci = data.frame(variant_id = "chr1:100:A:G", pip = 0.9) @@ -3167,7 +3081,7 @@ test_that("mergeSusieCs: input that is not a fine-mapping result errors", { context = "c1", trait = "t1", method = "susie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( variantIds = vids, susieFit = list(sets = list(cs = cs), pip = pip), topLoci = data.frame( @@ -3215,7 +3129,7 @@ test_that("computeCsCorrelation reads a panel's factor or an LdMatrix alike", { unname(computeLd(panel)), variants = SummarizedExperiment::rowRanges(panel) ), - qcInfo = qcInfo(gss) + qcOptions = qcOptions(gss) ) vids <- names(SummarizedExperiment::rowRanges(panel))[1:40] set.seed(3) @@ -3235,7 +3149,7 @@ test_that("computeCsCorrelation reads a panel's factor or an LdMatrix alike", { context = "c1", trait = "t1", method = "fsusie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( variantIds = vids, susieFit = structure(list(cs = cs, pip = pip), class = "susiF"), topLoci = data.frame( @@ -3378,18 +3292,12 @@ test_that("disjoint sets neither warn nor relabel", { expect_equal(eff, c(1L, 1L, 1L, 2L, 2L, 0L)) }) -test_that(".fmEffectIndices parses L-names and falls back to position", { - expect_equal(.fmEffectIndices(list(L1 = 1, L2 = 2, L7 = 3)), c(1L, 2L, 7L)) - expect_equal(.fmEffectIndices(list(1, 2, 3)), c(1L, 2L, 3L)) -}) - context("post_finemapping_cs_extraction") -# A single-row QtlFineMappingResult standing in for the retired -# FineMappingRow. topLoci defaults to one row per variant: the row-payload -# builder requires the two to be aligned, where the entry tolerated an empty -# table beside a non-empty variant list. +# A single-row QtlFineMappingResult wrapping one FineMappingRow. topLoci +# defaults to one row per variant: the row-payload builder requires the two +# to be aligned. .testFineMappingRow <- function( variantIds, susieFit = list(), @@ -3407,7 +3315,7 @@ context("post_finemapping_cs_extraction") context = "c1", trait = "t1", method = "susie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( variantIds = variantIds, susieFit = susieFit, topLoci = topLoci @@ -3419,22 +3327,12 @@ context("post_finemapping_cs_extraction") # susieResult # =========================================================================== -test_that("susieResult returns NULL for empty input", { - result <- susieResult(list()) - expect_null(result) -}) - -test_that("susieResult returns NULL when finemappingEntry missing", { - result <- susieResult(list(some_data = 42)) - expect_null(result) -}) - test_that("susieResult reads a bare FineMappingRow, its documented input", { # The guard used to require a FineMappingResultBase, so the documented # input -- a row -- came back NULL without a word. fit <- list(pip = c(0.2, 0.8), sets = list(cs = list())) ids <- c("chr1:100:A:G", "chr1:200:C:T") - row <- fineMappingRow( + row <- FineMappingRow( variantIds = ids, susieFit = fit, topLoci = data.frame(variant_id = ids, pip = c(0.2, 0.8)) @@ -3454,6 +3352,21 @@ test_that("susieResult returns trimmed result when present", { expect_equal(result, mock_result) }) +test_that("susieResult warns about a narrowed entry and returns its fit", { + fit <- list(pip = c(0.1, 0.5, 0.3), sets = list(cs = list())) + fe <- .testFineMappingRow( + variantIds = c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A"), + susieFit = fit + ) + expect_warning( + out <- susieResult(list( + finemappingEntry = endoapply(fe, utils::head, 2L) + )), + "susieResult\\(\\): the stored fit was made with 3 variants" + ) + expect_equal(out, fit) +}) + # =========================================================================== # extractTopPipInfo # =========================================================================== @@ -3470,24 +3383,12 @@ test_that("extractTopPipInfo finds top PIP variant", { expect_equal(result$top_variant, "chr1:200:C:T") expect_equal(result$top_pip, 0.7) expect_equal(result$top_z, 3.5) + expect_equal(result$p_value, pecotmr:::.zToPvalue(3.5)) expect_equal(result$top_variant_index, 2) expect_true(is.na(result$cs_name)) expect_true(is.na(result$variants_per_cs)) }) -test_that("extractTopPipInfo computes p_value from z", { - con_data <- list( - finemappingEntry = .testFineMappingRow( - variantIds = c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A"), - susieFit = list(pip = c(0.9, 0.05, 0.05)) - ), - sumstats = list(z = c(5.0, 0.5, -0.3)) - ) - result <- extractTopPipInfo(con_data$finemappingEntry, con_data$sumstats) - expected_pval <- pecotmr:::.zToPvalue(5.0) - expect_equal(result$p_value, expected_pval) -}) - test_that("extractTopPipInfo handles ties by taking first max", { con_data <- list( finemappingEntry = .testFineMappingRow( @@ -3530,6 +3431,7 @@ test_that("extractCsInfo extracts single CS correctly", { expect_equal(result$top_variant, "chr1:200:C:T") expect_equal(result$top_pip, 0.8) expect_equal(result$variants_per_cs, 2) + expect_equal(result$p_value, pecotmr:::.zToPvalue(4.5), tolerance = 1e-10) expect_true(is.na(result$cs_corr_max)) expect_true(is.na(result$cs_corr_min)) expect_false("cs_corr_1" %in% colnames(result)) @@ -3575,26 +3477,60 @@ test_that("extractCsInfo builds correlation columns from the ldSource", { expect_equal(result$cs_corr_min, rep(abs(cc[1, 2]), 2)) }) -test_that("extractCsInfo computes p_value from z-score", { +test_that("extractCsInfo names a narrowed row's sets by the fit's variants", { + # The set indices point into the variables the fit was made with. Named + # by the variants the narrowed row holds instead, they would land one + # variant off. data(qtlSumStatsExample) + vids <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A", "chr1:400:T:C") + pip <- c(0.1, 0.6, 0.2, 0.1) + tl <- data.frame(variant_id = vids, pip = pip, z = c(1, 4, 2, 0.5)) fe <- .testFineMappingRow( - variantIds = c("chr1:100:A:G", "chr1:200:C:T"), - susieFit = list(sets = list(cs = list(L_1 = c(1, 2)))) + variantIds = vids, + susieFit = list(pip = pip, sets = list(cs = list(L_1 = c(2L, 3L)))), + topLoci = tl ) - top_loci_table <- data.frame( - variant_id = c("chr1:100:A:G", "chr1:200:C:T"), - pip = c(0.9, 0.1), - z = c(5.0, 0.5), - stringsAsFactors = FALSE + narrowed <- endoapply(fe, utils::tail, 3L) + expect_warning( + out <- extractCsInfo( + narrowed, + csNames = "L_1", + topLociTable = tl, + ldSource = qtlSumStatsExample + ), + "extractCsInfo\\(\\): the stored fit was made with 4 variants" ) - result <- extractCsInfo( - fe, - csNames = "L_1", - topLociTable = top_loci_table, - ldSource = qtlSumStatsExample + expect_equal(out$top_variant, "chr1:200:C:T") + expect_equal(out$variants_per_cs, 2L) + expect_equal(out$top_variant_index, 2L) + expect_warning( + top <- extractTopPipInfo(narrowed, sumstats = list(z = tl$z)), + "extractTopPipInfo\\(\\)" + ) + expect_equal(top$top_variant, "chr1:200:C:T") + expect_equal(top$top_z, 4) +}) + +test_that("computeCsCorrelation of a narrowed row warns, on the fit's sets", { + data(qtlSumStatsExample) + ss <- qtlSumStatsExample + vids <- rownames(ldReference(ss)[[1L]]) + fe <- .testFineMappingRow( + variantIds = vids, + susieFit = list( + sets = list(cs = list(L_1 = 1:3, L_2 = 90:91)), + pip = rep(0.01, length(vids)) + ) + ) + full <- computeCsCorrelation(fe, ss) + # Narrowed past both of L_2's variants: the correlation is still the + # fit's, read off its own variants. + narrowed <- endoapply(fe, utils::head, 50L) + expect_warning( + cc <- computeCsCorrelation(narrowed, ss), + "computeCsCorrelation\\(\\): the stored fit was made with" ) - expected_pval <- pecotmr:::.zToPvalue(5.0) - expect_equal(result$p_value, expected_pval, tolerance = 1e-10) + expect_equal(cc, full) }) # =========================================================================== @@ -3605,7 +3541,7 @@ test_that("susieResult returns NULL when the trimmed susie fit is empty", { conData <- list( # An empty fit with variants present: topLoci must still be aligned # row-for-row, which the entry did not enforce. - finemappingEntry = fineMappingRow( + finemappingEntry = FineMappingRow( variantIds = c("chr1:100:A:G", "chr1:200:C:T"), susieFit = list(), topLoci = data.frame( @@ -3676,8 +3612,8 @@ test_that("buildTopLoci rejects variant ids it cannot place", { "buildTopLoci: parseVariantId produced invalid coordinates" ) # ...and well-formed ids parse to their chrom/pos. - ok <- pecotmr:::.btlParseVariants(c("chr1:100:A:G", "chr1:200:C:T")) - expect_equal(ok$chrom, c("1", "1")) + ok <- pecotmr:::.btlParseVariants(c("chr1:100:A:G", "1:200:C:T")) + expect_equal(ok$chrom, c("chr1", "chr1")) expect_equal(ok$pos, c(100L, 200L)) }) @@ -3813,7 +3749,7 @@ test_that("the N column falls back to the fit N and recycles a scalar", { # buildTopLoci per-condition blocks # =========================================================================== -test_that("conditional lfsr passes through when no coverage level matches", { +test_that("conditional lfsr is all-NA when the fit carries no clfsr", { clf <- array(0.1, dim = c(2L, 3L, 1L)) out <- pecotmr:::.btlCondLfsr( list(lfsr = clf), @@ -3998,8 +3934,9 @@ test_that("the fsusie fast path uses a trimmed fit's precomputed coef", { # =========================================================================== test_that("susieInf is skipped as a result when it was only a chain input", { - # Requesting susie alone with addSusieInf still fits an inf model to chain - # from, but keepInf is FALSE so it must not surface as its own method. + # Requesting susie alone with initializeWithSusieInf still fits an inf + # model to chain from, but keepInf is FALSE so it must not surface as + # its own method. chainOnly <- pecotmr:::.fmResolveSusieChain("susie", TRUE) expect_false(chainOnly$keepInf) expect_null(pecotmr:::.fmXFitOne( @@ -4175,20 +4112,6 @@ test_that("a credible set naming an out-of-range effect is skipped", { expect_true(all(is.na(out))) }) -test_that("no credible sets leaves the conditional lfsr untouched", { - clf <- array(0.05, dim = c(2L, 3L, 1L)) - tbl <- list(list(sets = list(cs = list()))) - out <- pecotmr:::.btlCondLfsr( - list(clfsr = clf), - conditionIdx = 1L, - coverageValues = 0.95, - covSorted = 0.95, - csTables = tbl, - nV = 3L - ) - expect_true(all(is.na(out))) -}) - # --------------------------------------------------------------------------- # susieInf chaining and per-token skips: a chained token reuses the shared # susieInf fit, and a token that produces no fit drops out of the block. @@ -4428,7 +4351,7 @@ test_that(".btlCondLfsr yields all-NA when the primary CS is empty", { }) .fmw_pipRow <- function() { - fineMappingRow( + FineMappingRow( variantIds = c("chr1:100:A:G", "chr1:200:C:T"), susieFit = list(pip = c(0.8, 0.2)), topLoci = data.frame( @@ -4439,16 +4362,6 @@ test_that(".btlCondLfsr yields all-NA when the primary CS is empty", { ) } -test_that("mergeSusieCs returns NULL when no row carries a credible set", { - res <- GwasFineMappingResult( - studyName = "G1", - method = "susie", - entry = list(.fmw_pipRow()) - ) - # The rows have pip but no cs_95 column, so nothing is extracted. - expect_null(mergeSusieCs(res, coverage = 0.95)) -}) - test_that(".extractCsEntryRows needs a resolvable pip column", { topLoci <- data.frame( variant_id = c("v1", "v2"), @@ -4467,7 +4380,7 @@ test_that(".extractCsEntryRows needs a resolvable pip column", { test_that("susieResult returns NULL for an empty susie fit", { expect_null(susieResult(list())) expect_null(susieResult(list(a = 1))) - row <- fineMappingRow( + row <- FineMappingRow( variantIds = "chr1:1:A:G", susieFit = list(), topLoci = data.frame( @@ -4523,7 +4436,7 @@ test_that(".fsusieScaleCols reads the wavelet columns off a flat prior", { test_that("fsusieWeights attaches the fit only when asked", { skip_if_not_installed("fsusieR") skip_if_not_installed("wavethresh") - obj <- .fw_makeFsusieFit() + obj <- .fw_fsusieDefault kept <- fsusieWeights( fsusieFit = obj$fit, variantIds = colnames(obj$X), @@ -4731,25 +4644,6 @@ test_that("serWeights extracts weights from a single-effect fit", { expect_error(serWeights(), "no 'ser' fit supplied") }) -test_that("ser is reachable as a TWAS method", { - # It is fit-derived like susie/mvsusie, so it carries no learner - # arguments and its entry is an empty stub. - expect_true(is_in("ser", names(pecotmr:::.twasMethodMap))) - expect_equal(pecotmr:::.twasMethodMap$ser$impl, "serWeights") - expect_length(pecotmr:::.twasMethodMap$ser$args, 0L) - expect_setequal( - pecotmr:::.twasNormalizeMethods(c("ser", "lasso"))$tokens, - c("ser", "lasso") - ) - # Nothing to configure, same as the other fit-derived methods. - expect_error( - TwasWeightsMethodsParam( - qtlSumStatsMethods = list(ser = list(nope = 1)) - ), - "nothing to configure here" - ) -}) - test_that(".fmSerScreen: disables on 0, skips no-signal, keeps signal + adaptive", { skip_if_not_installed("susieR") set.seed(1) @@ -5039,7 +4933,7 @@ test_that(".fmFitSusieIndiv: susieInf branch passes convergence_method='pip', re expect_equal(captured$lastArgs$unmappable_effects, "inf") }) -test_that(".fmFitSusieIndiv: chained branch (chainFromInf) propagates susieInf fit as model_init", { +test_that(".fmFitSusieIndiv: a chained token starts from the susieInf fit", { captured <- new.env(parent = emptyenv()) X <- matrix(rnorm(20), 10, 2) y <- rnorm(10) @@ -5049,25 +4943,18 @@ test_that(".fmFitSusieIndiv: chained branch (chainFromInf) propagates susieInf f susie = .fmp_capturingSusie(captured), .package = "susieR" ) - pecotmr:::.fmFitSusieIndiv(X, y, "susie", chainFromInf = infFit) - # prepareSusieFromInfArgs writes the susieInf fit into model_init and - # sets unmappable_effects to "none" for the `susie` token. - expect_identical(captured$lastArgs$model_init, infFit) - expect_equal(captured$lastArgs$unmappable_effects, "none") -}) - -test_that(".fmFitSusieIndiv: chained susieAsh branch sets unmappable_effects='ash'", { - captured <- new.env(parent = emptyenv()) - X <- matrix(rnorm(20), 10, 2) - y <- rnorm(10) - infFit <- list(V = c(0.1, 0.2)) - local_mocked_bindings( - susie = .fmp_capturingSusie(captured), - .package = "susieR" - ) - pecotmr:::.fmFitSusieIndiv(X, y, "susieAsh", chainFromInf = infFit) - expect_equal(captured$lastArgs$unmappable_effects, "ash") - expect_identical(captured$lastArgs$model_init, infFit) + # prepareSusieFromInfArgs writes the susieInf fit into model_init and sets + # each token's unmappable_effects. + unmappable <- c(susie = "none", susieAsh = "ash") + for (token in names(unmappable)) { + pecotmr:::.fmFitSusieIndiv(X, y, token, chainFromInf = infFit) + expect_identical(captured$lastArgs$model_init, infFit, info = token) + expect_equal( + captured$lastArgs$unmappable_effects, + unmappable[[token]], + info = token + ) + } }) test_that(".fmFitSusieIndiv: unchained susieAsh branch sets convergence_method='pip'", { @@ -5110,7 +4997,7 @@ test_that(".fmFitSusieRss: susieInf branch passes convergence_method='pip', refi expect_equal(captured$lastArgs$unmappable_effects, "inf") }) -test_that(".fmFitSusieRss: chained branch (chainFromInf) propagates susieInf fit as model_init", { +test_that(".fmFitSusieRss: a chained token starts from the susieInf fit", { captured <- new.env(parent = emptyenv()) z <- rnorm(3) R <- diag(3) @@ -5120,24 +5007,16 @@ test_that(".fmFitSusieRss: chained branch (chainFromInf) propagates susieInf fit susie_rss = .fmp_capturingSusieRss(captured), .package = "susieR" ) - pecotmr:::.fmFitSusieRss(z, R, n, "susie", chainFromInf = infFit) - expect_identical(captured$lastArgs$model_init, infFit) - expect_equal(captured$lastArgs$unmappable_effects, "none") -}) - -test_that(".fmFitSusieRss: chained susieAsh branch sets unmappable_effects='ash'", { - captured <- new.env(parent = emptyenv()) - z <- rnorm(3) - R <- diag(3) - n <- 1000 - infFit <- list(V = c(0.1, 0.2)) - local_mocked_bindings( - susie_rss = .fmp_capturingSusieRss(captured), - .package = "susieR" - ) - pecotmr:::.fmFitSusieRss(z, R, n, "susieAsh", chainFromInf = infFit) - expect_equal(captured$lastArgs$unmappable_effects, "ash") - expect_identical(captured$lastArgs$model_init, infFit) + unmappable <- c(susie = "none", susieAsh = "ash") + for (token in names(unmappable)) { + pecotmr:::.fmFitSusieRss(z, R, n, token, chainFromInf = infFit) + expect_identical(captured$lastArgs$model_init, infFit, info = token) + expect_equal( + captured$lastArgs$unmappable_effects, + unmappable[[token]], + info = token + ) + } }) test_that(".fmFitSusieRss: unchained susieAsh branch sets convergence_method='pip'", { @@ -5176,39 +5055,14 @@ test_that(".buildMvsusieReweightedPrior: empty reweighted w0 -> canonical(V)", { V = diag(2) ) res <- pecotmr:::.buildMvsusieReweightedPrior(fp, c("c1", "c2")) - expect_equal(res$residualVariance, diag(2)) # w0 names disjoint from U (749) -}) - -test_that(".fmSerScreen / .fmScreenActive / .fmSerScreenColumns", { - set.seed(2) - X <- matrix( - rnorm(40), - 20, - 2, - dimnames = list(paste0("s", 1:20), c("chr1:100:A:G", "chr1:200:A:G")) - ) - y <- rnorm(20) - expect_true(pecotmr:::.fmSerScreen(X, y, 0)) # disabled - expect_true(pecotmr:::.fmSerScreen(X, c(1, rep(NA, 19)), 0.5)) # < 2 obs (880) - expect_type(pecotmr:::.fmSerScreen(X, y, 0.5), "logical") # real susie fit - local_mocked_bindings( - susie = function(...) stop("boom"), - .package = "susieR" - ) - expect_true(pecotmr:::.fmSerScreen(X, y, 0.5)) # fit fails -> keep (886) - expect_false(pecotmr:::.fmScreenActive(0)) - expect_true(pecotmr:::.fmScreenActive(0.5)) - expect_length( - pecotmr:::.fmSerScreenColumns(X, matrix(rnorm(40), 20, 2), 0), - 2L - ) + expect_equal(res$residualVariance, diag(2)) # w0 names disjoint from U }) test_that(".fmFitXBlock fits the susieInf indiv chain + cross-validates (mocked)", { local_mocked_bindings( .fmFitSusieIndiv = function(...) list(), .fmPostprocessOne = function(fit, method, dataX, dataY, ...) { - fineMappingRow( + FineMappingRow( colnames(dataX), list(), data.frame(variant_id = colnames(dataX), pip = 0.5) @@ -5424,10 +5278,6 @@ test_that("krigingOutlierQc forwards methodArgs to susieR::kriging_rss", { ) }) -# Fixtures moved here with the tests that use them. - -# Fixtures moved here with the tests that use them. - # --------------------------------------------------------------------------- # buildTopLoci: the PIP filter and the z-only source # --------------------------------------------------------------------------- @@ -5556,13 +5406,6 @@ test_that("mu and mu2 of different shapes yield no conditional lfsr", { ))) }) -test_that("an empty window parses to no coordinates", { - expect_equal( - .parseGrange(GenomicRanges::GRanges()), - c(start = NA_integer_, end = NA_integer_) - ) -}) - test_that("merging two already-merged blocks changes nothing", { parent <- list(a = "a", b = "b") once <- .ufUnion("a", "b", parent) diff --git a/tests/testthat/test_genotypeHandle.R b/tests/testthat/test_genotypeHandle.R index de075fdf..4988381f 100644 --- a/tests/testthat/test_genotypeHandle.R +++ b/tests/testthat/test_genotypeHandle.R @@ -41,17 +41,20 @@ test_that("GenotypeHandle: partial pgen/pvar/psam triplet errors", { ) }) -test_that("GenotypeHandle: ldMeta without region errors", { +test_that("GenotypeHandle: ldMeta without which errors", { expect_error( GenotypeHandle(ldMeta = "x.tsv"), - "`ldMeta` requires a `region`" + "`ldMeta` requires `block`" ) }) -test_that("GenotypeHandle: region without ldMeta errors", { +test_that("GenotypeHandle: which without ldMeta errors", { expect_error( - GenotypeHandle(path = gds_path, region = "chr1:1-100"), - "`region` is only meaningful when `ldMeta`" + GenotypeHandle( + path = gds_path, + block = GenomicRanges::GRanges("chr1:1-100") + ), + "`block` is only meaningful when `ldMeta`" ) }) @@ -133,26 +136,16 @@ test_that("GenotypeHandle: pgen/pvar/psam triplet with matching stems builds pli test_that(".genotypeHandleFromPlink2Triplet: accepts .pvar.zst by stripping the .zst", { skip_if_not_installed("pgenlibr") - # We only check that the stem-validation accepts the zst-suffixed pvar; - # the actual file does not exist, so the downstream reader will error. + # The stems agree once the .zst is stripped, so the call gets past the + # stem check and fails only in the reader, on the files not existing. expect_error( pecotmr:::.genotypeHandleFromPlink2Triplet( pgen = "/tmp/x.pgen", pvar = "/tmp/x.pvar.zst", psam = "/tmp/x.psam" ), - NA # stems agree, so the stem-check should not fire - ) |> - suppressWarnings() |> - tryCatch(error = function(e) { - # The downstream reader will fail because /tmp/x.pgen doesn't exist — - # but the failure mode is what we want to confirm is *not* the stem - # mismatch error. - expect_false(grepl( - "must share a common path stem", - conditionMessage(e) - )) - }) + "PLINK2 .pgen file.*File does not exist" + ) }) test_that(".genotypeHandleFromPlink2Triplet: errors when stems disagree", { @@ -181,38 +174,13 @@ test_that(".genotypeHandleFromPlink2Triplet: errors on non-character input", { # .genotypeHandleFromLdMeta: dispatch by file extension # =========================================================================== -.gh_makeLdMetaForGds <- function() { - meta <- data.frame( - chrom = "chr21", - start = 17000000L, - end = 18000000L, - path = gds_path, - stringsAsFactors = FALSE - ) - f <- tempfile(fileext = ".tsv") - write.table(meta, f, sep = "\t", quote = FALSE, row.names = FALSE) - f -} - -.gh_makeLdMetaForVcf <- function() { - meta <- data.frame( - chrom = "chr21", - start = 17000000L, - end = 18000000L, - path = vcf_path, - stringsAsFactors = FALSE - ) - f <- tempfile(fileext = ".tsv") - write.table(meta, f, sep = "\t", quote = FALSE, row.names = FALSE) - f -} - -.gh_makeLdMetaForBed <- function() { +# An LD-meta file whose one row names `path` for chr21:17000000-18000000. +.gh_makeLdMeta <- function(path) { meta <- data.frame( chrom = "chr21", start = 17000000L, end = 18000000L, - path = paste0(plink_prefix, ".bed"), + path = path, stringsAsFactors = FALSE ) f <- tempfile(fileext = ".tsv") @@ -220,66 +188,34 @@ test_that(".genotypeHandleFromPlink2Triplet: errors on non-character input", { f } -.gh_makeLdMetaForPgen <- function() { - meta <- data.frame( - chrom = "chr21", - start = 17000000L, - end = 18000000L, - path = paste0(plink_prefix, ".pgen"), - stringsAsFactors = FALSE - ) - f <- tempfile(fileext = ".tsv") - write.table(meta, f, sep = "\t", quote = FALSE, row.names = FALSE) - f -} - -.gh_makeLdMetaForCor <- function() { - # findValidFilePath needs the target file to exist (otherwise it falls - # back to returning the meta-TSV path itself, which would dead-end the - # downstream format dispatch elsewhere). Materialize an empty .cor.xz so - # we exercise the proper "cor.xz payload" rejection branch. - corPath <- tempfile(fileext = ".cor.xz") - file.create(corPath) - meta <- data.frame( - chrom = "chr21", - start = 17000000L, - end = 18000000L, - path = corPath, - stringsAsFactors = FALSE - ) - f <- tempfile(fileext = ".tsv") - write.table(meta, f, sep = "\t", quote = FALSE, row.names = FALSE) - list(meta = f, cor = corPath) -} - -test_that("an LD-meta row naming a .gds file is read as a panel", { +test_that("an LD-meta row naming a GDS, VCF or PLINK1 file reads as a panel", { skip_if_not_installed("gdsfmt") skip_if_not_installed("GDSArray") - f <- .gh_makeLdMetaForGds() - on.exit(unlink(f), add = TRUE) - region <- "chr21:17513228-17592874" - expect_error( - GenotypeHandle(ldMeta = f, region = region), - "read as a genotype panel" - ) - panel <- readGenotypes(ldMeta = f, region = region) - expect_s4_class(panel, "RangedSummarizedExperiment") - expect_equal(dim(panel), c(349L, 100L)) - expect_equal(S4Vectors::metadata(panel)$genotypeSource$format, "gds") -}) - -test_that("an LD-meta row naming a .vcf.gz file is read as a panel", { skip_if_not_installed("VariantAnnotation") - f <- .gh_makeLdMetaForVcf() - on.exit(unlink(f), add = TRUE) - region <- "chr21:17513228-17592874" - expect_error( - GenotypeHandle(ldMeta = f, region = region), - "read as a genotype panel" - ) - panel <- readGenotypes(ldMeta = f, region = region) - expect_equal(dim(panel), c(349L, 100L)) - expect_equal(S4Vectors::metadata(panel)$genotypeSource$format, "vcf") + skip_if_not_installed("PlinkMatrix") + region <- GenomicRanges::GRanges("chr21:17513228-17592874") + files <- c( + gds = gds_path, + vcf = vcf_path, + plink1 = paste0(plink_prefix, ".bed") + ) + for (format in names(files)) { + f <- .gh_makeLdMeta(files[[format]]) + on.exit(unlink(f), add = TRUE) + expect_error( + GenotypeHandle(ldMeta = f, block = region), + "read as a genotype panel", + info = format + ) + panel <- readGenotypes(ldMeta = f, block = region) + expect_s4_class(panel, "RangedSummarizedExperiment") + expect_equal(dim(panel), c(349L, 100L), info = format) + expect_equal( + S4Vectors::metadata(panel)$genotypeSource$format, + format, + info = format + ) + } }) test_that("an LD-meta row's file is read by the reader its format names", { @@ -296,67 +232,62 @@ test_that("an LD-meta row's file is read by the reader its format names", { ) }) -test_that("an LD-meta row naming a .bed is read as a PLINK1 panel", { - skip_if_not_installed("PlinkMatrix") - f <- .gh_makeLdMetaForBed() - on.exit(unlink(f), add = TRUE) - region <- "chr21:17513228-17592874" - panel <- readGenotypes(ldMeta = f, region = region) - expect_equal(dim(panel), c(349L, 100L)) - expect_equal(S4Vectors::metadata(panel)$genotypeSource$format, "plink1") - expect_error( - GenotypeHandle(ldMeta = f, region = region), - "read as a genotype panel" - ) -}) - test_that("GenotypeHandle ldMeta: dispatches to plink2 reader for .pgen path", { skip_if_not_installed("pgenlibr") - f <- .gh_makeLdMetaForPgen() + f <- .gh_makeLdMeta(paste0(plink_prefix, ".pgen")) on.exit(unlink(f), add = TRUE) - h <- GenotypeHandle(ldMeta = f, region = "chr21:17513228-17592874") + h <- GenotypeHandle( + ldMeta = f, + block = GenomicRanges::GRanges("chr21:17513228-17592874") + ) expect_s4_class(h, "GenotypeHandle") expect_equal(genotypeFormat(h), "plink2") }) test_that("GenotypeHandle ldMeta: .cor.xz payload is rejected (out of scope)", { - paths <- .gh_makeLdMetaForCor() - on.exit(unlink(c(paths$meta, paths$cor)), add = TRUE) + # findValidFilePath needs the target file to exist (otherwise it falls + # back to returning the meta-TSV path itself, which would dead-end the + # downstream format dispatch elsewhere). Materialize an empty .cor.xz so + # we exercise the proper "cor.xz payload" rejection branch. + corPath <- tempfile(fileext = ".cor.xz") + file.create(corPath) + meta <- .gh_makeLdMeta(corPath) + on.exit(unlink(c(meta, corPath)), add = TRUE) expect_error( - GenotypeHandle(ldMeta = paths$meta, region = "chr21:17513228-17592874"), + GenotypeHandle( + ldMeta = meta, + block = GenomicRanges::GRanges("chr21:17513228-17592874") + ), "points at a pre-computed correlation matrix" ) }) test_that("GenotypeHandle ldMeta: region with no covering row errors", { - f <- .gh_makeLdMetaForGds() + f <- .gh_makeLdMeta(gds_path) on.exit(unlink(f), add = TRUE) # The upstream helper emits "No data for chromosome ..." when nothing on # the region's chromosome exists in the meta TSV; either phrasing # indicates the same "region uncovered" failure mode. expect_error( - GenotypeHandle(ldMeta = f, region = "chr22:1-1000"), + GenotypeHandle( + ldMeta = f, + block = GenomicRanges::GRanges("chr22:1-1000") + ), "No data for chromosome|no LD-meta row covers" ) }) -# === Tests migrated from test_h2ClassesSumstats.R (GenotypeHandle) === - -test_that("GenotypeHandle constructs and validates correctly", { - obj <- new( - "GenotypeHandle", - path = "/tmp/test", - format = "plink2", - snpInfo = makeTestSnpInfo(), - nSamples = 100L, - sampleIds = paste0("sample_", 1:100), - pgenPtr = NULL +test_that("GenotypeHandle ldMeta: the window to look up is a GRanges", { + f <- .gh_makeLdMeta(gds_path) + on.exit(unlink(f), add = TRUE) + expect_error( + GenotypeHandle(ldMeta = f, block = "chr21:17513228-17592874"), + "`block` must be a GRanges" ) - expect_s4_class(obj, "GenotypeHandle") - expect_equal(genotypeFormat(obj), "plink2") - expect_true(methods::validObject(obj)) + expect_error(GenotypeHandle(ldMeta = f), "requires `block`") }) +# === Tests migrated from test_h2ClassesSumstats.R (GenotypeHandle) === test_that("GenotypeHandle refuses the formats it no longer reads", { for (fmt in c("vcf", "gds", "plink1")) { @@ -375,7 +306,7 @@ test_that("GenotypeHandle refuses the formats it no longer reads", { } }) -test_that("GenotypeHandle accepts all valid formats", { +test_that("GenotypeHandle constructs and validates every format it reads", { for (fmt in c("plink2", "bgen")) { obj <- new( "GenotypeHandle", @@ -386,47 +317,18 @@ test_that("GenotypeHandle accepts all valid formats", { sampleIds = character(), pgenPtr = NULL ) + expect_s4_class(obj, "GenotypeHandle") + expect_equal(genotypeFormat(obj), fmt) expect_true(methods::validObject(obj)) } }) - -test_that("GenotypeHandle rejects invalid format", { - expect_error( - methods::validObject( - new( - "GenotypeHandle", - path = "/tmp/test", - format = "zarr", - snpInfo = data.frame(), - nSamples = 0L, - sampleIds = character(), - pgenPtr = NULL - ) - ), - "format.*must be one of" - ) -}) - # =========================================================================== # One-file-per-chromosome (sharded) handle: constructor + validation. # genoMeta accepts a #chr,path meta file or a named chrom->path vector. -# Extraction routing for sharded handles is covered in test_genotypeIo.R. +# The named-vector handle is built and checked with its extraction routing +# in test_genotypeIo.R. # =========================================================================== -test_that("genoMeta (named vector) builds a sharded handle", { - skip_if_not_installed("pgenlibr") - h <- GenotypeHandle( - genoMeta = c( - "21" = file.path(test_data_dir, "test_variants.pgen"), - "22" = file.path(test_data_dir, "test_variants_chr22.pgen") - ) - ) - expect_s4_class(h, "GenotypeHandle") - expect_equal(genotypeFormat(h), "plink2") - expect_equal(sort(names(chromPaths(h))), c("21", "22")) - expect_equal(nrow(snpInfo(h)), 2L * 349L) -}) - test_that("genoMeta meta-file resolves payloads relative to its own directory", { skip_if_not_installed("pgenlibr") # A meta file living in test_data referencing payloads by basename only. @@ -441,7 +343,7 @@ test_that("genoMeta meta-file resolves payloads relative to its own directory", metafile ) h <- GenotypeHandle(genoMeta = metafile) - expect_equal(sort(names(chromPaths(h))), c("21", "22")) + expect_equal(sort(names(chromPaths(h))), c("chr21", "chr22")) expect_equal(nrow(snpInfo(h)), 2L * 349L) }) @@ -459,13 +361,13 @@ test_that(".parseChromMeta matches chrom/path columns by name (order- and extra- "22\t1\t9\t/abs/b.bed" )) ) - expect_equal(m1$chrom, c("21", "22")) + expect_equal(m1$chrom, c("chr21", "chr22")) expect_equal(m1$path, c("/abs/a.bed", "/abs/b.bed")) # reordered header (path first) + alias column names m2 <- pecotmr:::.parseChromMeta( mk(c("genotype\tchr", "/abs/a.bed\t21", "/abs/b.bed\t22")) ) - expect_equal(m2$chrom, c("21", "22")) + expect_equal(m2$chrom, c("chr21", "chr22")) expect_equal(m2$path, c("/abs/a.bed", "/abs/b.bed")) }) @@ -478,7 +380,7 @@ test_that(".parseChromMeta falls back to the first two columns when no alias hea m <- pecotmr:::.parseChromMeta( mk(c("foo\tbar", "21\t/abs/a.bed", "22\t/abs/b.bed")) ) - expect_equal(m$chrom, c("21", "22")) + expect_equal(m$chrom, c("chr21", "chr22")) expect_equal(m$path, c("/abs/a.bed", "/abs/b.bed")) }) @@ -595,16 +497,16 @@ test_that("genoMeta chroms reads only the requested shard", { ) full <- GenotypeHandle(genoMeta = meta) only21 <- GenotypeHandle(genoMeta = meta, chroms = "21") - expect_equal(names(chromPaths(only21)), "21") + expect_equal(names(chromPaths(only21)), "chr21") expect_equal(nrow(snpInfo(only21)), 349L) # chr21 is the first shard, so the kept rows/fileIdx match the full handle's. expect_equal(snpInfo(only21)$SNP, snpInfo(full)$SNP[1:349]) expect_equal(snpInfo(only21)$fileIdx, snpInfo(full)$fileIdx[1:349]) }) -test_that("genoMeta chroms canonicalises chromosome labels", { +test_that("genoMeta chroms reads chromosome labels in any style", { skip_if_not_installed("pgenlibr") - # "chr21" canonicalises to the panel's declared "21" shard. + # "chr21" names the shard the panel declares as "21". h <- GenotypeHandle( genoMeta = c( "21" = file.path(test_data_dir, "test_variants.pgen"), @@ -612,7 +514,7 @@ test_that("genoMeta chroms canonicalises chromosome labels", { ), chroms = "chr21" ) - expect_equal(names(chromPaths(h)), "21") + expect_equal(names(chromPaths(h)), "chr21") }) test_that("genoMeta chroms falls back to all shards when none match", { @@ -626,7 +528,7 @@ test_that("genoMeta chroms falls back to all shards when none match", { ), chroms = "9" ) - expect_equal(sort(names(chromPaths(h))), c("21", "22")) + expect_equal(sort(names(chromPaths(h))), c("chr21", "chr22")) }) test_that("genoMeta chroms skips a shard whose file does not exist", { @@ -638,7 +540,7 @@ test_that("genoMeta chroms skips a shard whose file does not exist", { "21" = "/no/such/chr21/prefix" ) h <- GenotypeHandle(genoMeta = meta, chroms = "22") - expect_equal(names(chromPaths(h)), "22") + expect_equal(names(chromPaths(h)), "chr22") expect_error(GenotypeHandle(genoMeta = meta, chroms = c("22", "21"))) }) @@ -840,21 +742,6 @@ test_that("show(GenotypeHandle) does not error", { # is test_variants' PLINK2 copy: 349 variants x 100 samples. # --------------------------------------------------------------------------- -.gh_pgenHandle <- function() { - skip_if_not_installed("pgenlibr") - readGenotypeHandle(paste0(plink_prefix, ".pgen")) -} - -test_that("extractBlockGenotypes answers an empty index without a reader", { - # A reader need not accept an empty request -- snpStats segfaulted on - # one when it read PLINK1 -- so none is ever made. - gh <- .gh_pgenHandle() - se <- extractBlockGenotypes(gh, snpIdx = integer(0)) - expect_s4_class(se, "SummarizedExperiment") - expect_equal(nrow(se), 0L) - expect_equal(ncol(se), nSamples(gh)) -}) - test_that("genotypeDelayedArray reports variants x samples", { # The Bioconductor assay orientation, which is the TRANSPOSE of # genotypes(). Backwards, this returns a plausible matrix and a @@ -922,17 +809,6 @@ test_that(".emptyGenotypeHandle empties the sample axis as well as the variants" expect_equal(lengths(dimnames(seed)), c(0L, 0L)) }) -test_that(".emptyLdRef drops both axes and the seed on an RSE sketch", { - # The seed carries every variant's metadata; an empty panel keeps none - # of it, only the record of what it was read from. - gh <- .gh_pgenHandle() - empty <- pecotmr:::.emptyLdRef(pecotmr:::.genotypeExperiment(gh)) - expect_equal(dim(empty), c(0L, 0L)) - expect_null(pecotmr:::.panelSeed(empty)) - expect_null(pecotmr:::.ldRefHandle(empty)) - expect_equal(pecotmr:::.ldRefFormat(empty), genotypeFormat(gh)) -}) - test_that("nothing is read until a block is actually touched", { # The point of the seed: a panel can be described without being read. gh <- .gh_pgenHandle() diff --git a/tests/testthat/test_genotypeIo.R b/tests/testthat/test_genotypeIo.R index 808b0e09..bca2d94d 100644 --- a/tests/testthat/test_genotypeIo.R +++ b/tests/testthat/test_genotypeIo.R @@ -10,195 +10,6 @@ test_that("readPvar reads real pvar file", { expect_true(all(res$chrom == "21")) }) -test_that("readBim dummy data works", { - example_path <- "test_data/protocol_example.genotype.bed" - res <- readBim(example_path) - expect_equal(colnames(res), c("chrom", "id", "gpos", "pos", "a1", "a0")) - expect_equal(nrow(res), 100) -}) - -test_that("findValidFilePath works", { - ref_path <- "test_data/protocol_example.genotype.bed" - expect_error( - pecotmr:::.findValidFilePath( - referenceFilePath = paste0(ref_path, "s"), - targetFilePath = "protocol_example.genotype.bamf" - ), - "Both reference and target file paths do not work. Tried paths: 'test_data/protocol_example.genotype.beds' and 'test_data/protocol_example.genotype.bamf'" - ) - expect_equal( - pecotmr:::.findValidFilePath( - referenceFilePath = ref_path, - targetFilePath = "abc" - ), - ref_path - ) - expect_equal( - pecotmr:::.findValidFilePath( - referenceFilePath = ref_path, - targetFilePath = "protocol_example.genotype.bim" - ), - "test_data/protocol_example.genotype.bim" - ) - expect_equal( - pecotmr:::.findValidFilePath( - referenceFilePath = ref_path, - targetFilePath = "test_data/protocol_example.genotype.bim" - ), - "test_data/protocol_example.genotype.bim" - ) -}) - -dummyGenoData <- function( - number_of_samples = 10, - number_of_snps = 10, - sample_start_id = 1, - number_missing = 10, - number_low_maf = 10, - number_zero_var = 10, - number_var_thresh = 10 -) { - set.seed(1) - # Create portion of Matrix with satisfactory values - X <- matrix( - sample(c(0, 1, 2), number_of_samples * number_of_snps, replace = TRUE), - nrow = number_of_samples, - ncol = number_of_snps - ) - # Create portion of Matrix that should get pruned - ## Missing Rate - if (number_missing > 0) { - X_missing <- rbind( - matrix( - sample( - c(0, 1, 2), - (number_of_samples - 3) * number_of_snps, - replace = TRUE - ), - nrow = number_of_samples - 3, - ncol = number_of_snps - ), - matrix( - rep(NA, 3 * number_of_snps), - nrow = 3, - ncol = number_of_snps - ) - ) - X <- cbind(X, X_missing) - } - ## MAF - if (number_low_maf > 0) { - X_maf <- matrix( - rep(0.1, number_of_samples * number_of_snps), - nrow = number_of_samples, - ncol = number_of_snps - ) - X <- cbind(X, X_maf) - } - ## Zero Variance - if (number_zero_var > 0) { - X_zerovar <- matrix( - rep(1, number_of_samples * number_of_snps), - nrow = number_of_samples, - ncol = number_of_snps - ) - X <- cbind(X, X_zerovar) - } - ## Variance Threshold, just one row - if (number_var_thresh > 0) { - X_varthresh <- matrix( - c(rep(1, (number_of_samples - 1)), 2), - nrow = number_of_samples, - ncol = 1 - ) - X <- cbind(X, X_varthresh) - } - colnames(X) <- paste0( - "chr1:", - seq( - 1000, - 1000 + - number_of_snps + - number_missing + - number_low_maf + - number_zero_var + - number_var_thresh - - 1 - ), - "_G_C" - ) - rownames(X) <- paste0( - "Sample_", - seq(sample_start_id, number_of_samples + sample_start_id - 1) - ) - return(X) -} - -dummyPhenoData <- function( - number_of_samples = 10, - number_of_phenotypes = 10, - randomize = FALSE, - sample_start_id = 1 -) { - # Create dummy phenotype bed file - # columns: Chrom, Start, End, Sample_1, Sample_2, ..., Sample_N - start_matrix <- matrix( - c( - rep("chr1", number_of_phenotypes), - seq(100, 100 + number_of_phenotypes - 1), - seq(101, 101 + number_of_phenotypes - 1) - ), - nrow = number_of_phenotypes, - ncol = 3 - ) - end_matrix <- matrix( - rnorm(number_of_samples * number_of_phenotypes), - nrow = number_of_phenotypes, - ncol = number_of_samples - ) - pheno_data <- cbind(start_matrix, end_matrix) - sample_ids <- paste0( - "Sample_", - seq(sample_start_id, number_of_samples + sample_start_id - 1) - ) - colnames(pheno_data) <- c("#chr", "start", "end", sample_ids) - colnames(end_matrix) <- sample_ids - if (randomize) { - end_matrix <- end_matrix[sample(nrow(end_matrix)), ] - } - pheno_data <- t(pheno_data) - pheno_data <- map(seq_len(ncol(pheno_data)), function(i) { - pheno_data[, i, drop = FALSE] - }) - return(pheno_data) -} - -dummyCovarData <- function( - number_of_samples = 10, - number_of_covars = 10, - row_na = FALSE, - randomize = FALSE, - sample_start_id = 1 -) { - covar <- matrix( - sample(1:20, number_of_samples * number_of_covars, replace = TRUE), - nrow = number_of_samples, - ncol = number_of_covars - ) - colnames(covar) <- paste0("Covar_", seq(1, number_of_covars)) - rownames(covar) <- paste0( - "Sample_", - seq(sample_start_id, number_of_samples + sample_start_id - 1) - ) - if (randomize) { - covar <- covar[sample(nrow(covar)), ] - } - if (row_na) { - covar[sample(length(covar), 1), seq_len(number_of_covars)] <- NA - } - return(covar) -} - test_that("Test loadGenotypeRegion", { res <- loadGenotypeRegion( "test_data/protocol_example.genotype" @@ -247,7 +58,7 @@ test_that("Test loadGenotypeRegion no indels", { test_that("Test loadGenotypeRegion with region", { res <- loadGenotypeRegion( "test_data/protocol_example.genotype", - region = "chr22:20689453-20845958" + which = GenomicRanges::GRanges("chr22:20689453-20845958") ) sample_ids <- read_delim( "test_data/protocol_example.genotype.fam", @@ -270,7 +81,7 @@ test_that("Test loadGenotypeRegion with region", { test_that("Test loadGenotypeRegion with region and no indels", { res <- loadGenotypeRegion( "test_data/protocol_example.genotype", - region = "chr22:20689453-20845958", + which = GenomicRanges::GRanges("chr22:20689453-20845958"), keepIndel = F ) bim_file <- read_delim( @@ -300,53 +111,24 @@ test_that("Test loadGenotypeRegion with region and no indels", { expect_equal(colnames(res), bim_file[!indels, ]$X2) }) -test_that("loadGenotypeRegion errors on missing genotype files", { - expect_error( - loadGenotypeRegion("/nonexistent/geno"), - "neither a genotype file nor a PLINK prefix" - ) -}) - # --- findStochasticMeta tests --- -test_that("findStochasticMeta finds generic sidecar from PLINK1 prefix", { - td <- test_path("test_data") - # test_harmonize_regions has .stochastic_meta.tsv alongside it - result <- pecotmr:::findStochasticMeta(file.path( - td, - "test_harmonize_regions" - )) - expect_true(!is.null(result)) - expect_true(grepl("\\.(afreq|stochastic_meta\\.tsv)$", result)) -}) - -test_that("findStochasticMeta finds sidecar from VCF path", { - td <- test_path("test_data") - result <- pecotmr:::findStochasticMeta(file.path( - td, - "test_harmonize_regions.vcf.gz" - )) - expect_true(!is.null(result)) - expect_true(grepl("\\.(afreq|stochastic_meta\\.tsv)$", result)) -}) - -test_that("findStochasticMeta finds sidecar from GDS path", { - td <- test_path("test_data") - result <- pecotmr:::findStochasticMeta(file.path( - td, - "test_harmonize_regions.gds" - )) - expect_true(!is.null(result)) - expect_true(grepl("\\.(afreq|stochastic_meta\\.tsv)$", result)) -}) - -test_that("findStochasticMeta finds the sidecar of a BGEN or .vcf.bgz file", { +test_that("findStochasticMeta finds the sidecar beside a file or prefix", { dir <- withr::local_tempdir() file.create(file.path(dir, "sketch.afreq")) - for (file in c("sketch.bgen", "sketch.vcf.bgz", "sketch.VCF.GZ")) { + files <- c( + "sketch", + "sketch.bgen", + "sketch.gds", + "sketch.vcf.gz", + "sketch.vcf.bgz", + "sketch.VCF.GZ" + ) + for (file in files) { expect_equal( pecotmr:::findStochasticMeta(file.path(dir, file)), - file.path(dir, "sketch.afreq") + file.path(dir, "sketch.afreq"), + info = file ) } }) @@ -381,6 +163,13 @@ test_that("readStochasticMeta reads afreq format", { expect_equal(colnames(result), c("id", "u_min", "u_max")) expect_equal(nrow(result), 8L) expect_true(all(grepl("^chr21_", result$id))) + # The generic sidecar beside it holds the same values. + generic <- pecotmr:::readStochasticMeta( + file.path(td, "test_harmonize_regions.stochastic_meta.tsv") + ) + expect_equal(result$id, generic$id) + expect_equal(result$u_min, generic$u_min) + expect_equal(result$u_max, generic$u_max) }) test_that("readStochasticMeta reads afreq.zst format", { @@ -408,30 +197,37 @@ test_that("findStochasticMeta prefers afreq over afreq.zst", { expect_true(grepl("\\.afreq$", result)) }) -test_that("readStochasticMeta auto-detects format from extension", { - td <- test_path("test_data") - # .afreq extension -> afreq parser - afreq_result <- pecotmr:::readStochasticMeta(file.path( - td, - "test_harmonize_regions.afreq" - )) - # .tsv extension -> generic parser - generic_result <- pecotmr:::readStochasticMeta( - file.path(td, "test_harmonize_regions.stochastic_meta.tsv") +test_that("readStochasticMeta reads a forced afreq file under any name", { + # The override reads the file it is given; it once appended .afreq to + # the name and read .afreq instead, so nothing came back. + src <- test_path("test_data", "test_harmonize_regions.afreq") + renamed <- file.path(withr::local_tempdir(), "sidecar.txt") + file.copy(src, renamed) + expect_equal( + pecotmr:::readStochasticMeta(renamed, format = "afreq"), + pecotmr:::readStochasticMeta(src) + ) + expect_named( + pecotmr:::readStochasticMeta(renamed, format = "afreq"), + c("id", "u_min", "u_max") ) - # Both should return the same u_min/u_max values - expect_equal(afreq_result$u_min, generic_result$u_min) - expect_equal(afreq_result$u_max, generic_result$u_max) - expect_equal(afreq_result$id, generic_result$id) }) test_that("readStochasticMeta respects format override", { - td <- test_path("test_data") - path <- file.path(td, "test_harmonize_regions.stochastic_meta.tsv") - # Explicit generic format should work - result <- pecotmr:::readStochasticMeta(path, format = "generic") - expect_equal(nrow(result), 8L) - expect_equal(colnames(result), c("id", "u_min", "u_max")) + # A generic id/u_min/u_max table saved under an .afreq name: left to its + # extension it goes to the PLINK2 .afreq reader, which cannot parse it. + generic <- test_path( + "test_data", + "test_harmonize_regions.stochastic_meta.tsv" + ) + path <- file.path(withr::local_tempdir(), "sidecar.afreq") + file.copy(generic, path) + expect_error(pecotmr:::readStochasticMeta(path), "#CHROM") + # Forcing "generic" reads it as the table it is. + expect_equal( + pecotmr:::readStochasticMeta(path, format = "generic"), + pecotmr:::readStochasticMeta(generic) + ) }) test_that("readStochasticMeta returns NULL for afreq without U_MIN/U_MAX", { @@ -473,7 +269,7 @@ test_that("loadGenotypeRegion applies stochastic inversion with explicit sidecar # Check the first variant's first sample manually raw <- loadGenotypeRegion( file.path(td, "protocol_example.genotype"), - region = "chr22:20689453-20845958" + which = GenomicRanges::GRanges("chr22:20689453-20845958") ) # protocol_example has no sidecar, so raw values are unchanged (integer dosages) expect_true(all(raw == round(raw), na.rm = TRUE)) @@ -506,40 +302,6 @@ test_that("readBim returns correct columns and types", { # .colocFilterCsByConcentration # =========================================================================== -test_that(".colocFilterCsByConcentration returns numeric index vector", { - set.seed(42) - n_L <- 5 - n_vars <- 20 - alpha_raw <- matrix(runif(n_L * n_vars), nrow = n_L) - alpha_norm <- t(apply(alpha_raw, 1, function(x) x / sum(x))) - - mockSusie <- list( - alpha = alpha_norm, - V = runif(n_L), - lbf_variable = matrix(rnorm(n_L * n_vars), nrow = n_L), - mu = matrix(rnorm(n_L * n_vars), nrow = n_L), - mu2 = matrix(abs(rnorm(n_L * n_vars)), nrow = n_L), - sets = list( - cs = list(L1 = c(1, 3, 5), L3 = c(2, 4)), - cs_index = c(1, 3) - ), - pip = colSums(alpha_norm), - niter = 100, - converged = TRUE - ) - - result <- pecotmr:::.colocFilterCsByConcentration( - mockSusie, - coverage = 0.5, - concentration = 0.5 - ) - expect_true(is.numeric(result)) -}) - -# =========================================================================== -# refVariantInfo -# =========================================================================== - # ---- invertMinmaxScaling ---- test_that("invertMinmaxScaling exactly recovers original U", { @@ -565,32 +327,15 @@ test_that("invertMinmaxScaling exactly recovers original U", { expect_equal(U_recovered, U_original, tolerance = 1e-12) }) -test_that("invertMinmaxScaling preserves correlation structure", { - set.seed(123) - n <- 200 - k <- 3 - # Simulate U = W'G (G is raw, not standardized, matching rss_ld_sketch) - G <- exec(cbind, !!!map(c(0.2, 0.4, 0.1), function(p) rbinom(n, 2, p))) - W <- matrix(rnorm(n * n, 0, 1 / sqrt(n)), n, n) - U_original <- crossprod(W, G) - - # Scale and invert - u_min <- apply(U_original, 2, min) - u_max <- apply(U_original, 2, max) - denom <- u_max - u_min - U_scaled <- sweep(sweep(U_original, 2, u_min, "-"), 2, denom, "/") * 2 - U_recovered <- invertMinmaxScaling(U_scaled, u_min, u_max) - - # Exact recovery - expect_equal(U_recovered, U_original, tolerance = 1e-12) -}) - test_that("invertMinmaxScaling handles monomorphic variant", { - X <- matrix(c(1.0, 1.0, 1.0, 0.5, 1.0, 1.5), ncol = 2) - u_min <- c(0.5, 0.0) - u_max <- c(0.5, 1.0) # first column is monomorphic - result <- invertMinmaxScaling(X, u_min, u_max) - expect_equal(ncol(result), 2) + # Column 1 is monomorphic (u_min == u_max). The sketch writer divides it + # by 1 instead of 0, which leaves it all 0, and inverting has to give its + # constant back rather than NaN. + U <- cbind(rep(0.5, 3), c(-1, 0, 3)) + u_min <- c(0.5, -1) + u_max <- c(0.5, 3) + X <- cbind(rep(0, 3), c(0, 0.5, 2)) # 2 * (U - u_min) / c(1, 4) + expect_equal(invertMinmaxScaling(X, u_min, u_max), U) }) test_that("invertMinmaxScaling errors on mismatched lengths", { @@ -602,12 +347,26 @@ test_that("invertMinmaxScaling errors on mismatched lengths", { }) # =========================================================================== -# refVariantInfo with PLINK2 fixture +# refVariantInfo # =========================================================================== +# refVariantInfo() through an LD-metadata file naming `source` for all of +# chr21, written into test_data so its relative path resolves, and removed +# once read. +.gioRefInfoViaMeta <- function(source, which) { + meta <- withr::local_tempfile( + tmpdir = test_path("test_data"), + fileext = ".tsv" + ) + writeLines(c("chrom\tstart\tend\tpath", str_c("21\t0\t0\t", source)), meta) + refVariantInfo(meta, which = which) +} + test_that("refVariantInfo reads a genotype file or prefix given directly", { # It used to read every source as LD metadata, so a direct path failed # whatever its format. + skip_if_not_installed("gdsfmt") + skip_if_not_installed("GDSArray") stem <- str_remove( system.file("extdata", "toy_ref.bed", package = "pecotmr"), "\\.bed$" @@ -616,155 +375,45 @@ test_that("refVariantInfo reads a genotype file or prefix given directly", { plink1 <- refVariantInfo(stem) expect_equal(nrow(plink1), nrow(bim)) expect_equal(plink1$pos, bim[[4L]]) - vcf <- refVariantInfo(test_path("test_data", "test_variants.vcf.gz")) - expect_equal(nrow(vcf), 349L) + gds <- refVariantInfo(test_path("test_data", "test_variants.gds")) + expect_equal(nrow(gds), 349L) }) -test_that("refVariantInfo returns variant info for PLINK2 source", { +test_that("refVariantInfo reads PLINK2, VCF and GDS sources via LD metadata", { skip_if_not_installed("pgenlibr") - meta_file <- file.path(test_path("test_data"), "ld_meta_refinfo_tmp.tsv") - on.exit(unlink(meta_file), add = TRUE) - writeLines(paste("chrom", "start", "end", "path", sep = "\t"), meta_file) - cat( - paste("21", "0", "0", "test_variants", sep = "\t"), - "\n", - file = meta_file, - append = TRUE - ) - result <- refVariantInfo(meta_file, region = "chr21:17513228-17592874") - expect_true(is.data.frame(result)) - expect_equal(nrow(result), 349L) - expect_true(all(c("chrom", "id", "pos", "A2", "A1") %in% names(result))) - # .afreq is present, so allele_freq should be populated - expect_true("allele_freq" %in% names(result)) - expect_true(all(result$allele_freq > 0 & result$allele_freq < 1)) -}) - -test_that("refVariantInfo filters by subregion", { - skip_if_not_installed("pgenlibr") - meta_file <- file.path( - test_path("test_data"), - "ld_meta_refinfo_sub_tmp.tsv" - ) - on.exit(unlink(meta_file), add = TRUE) - writeLines(paste("chrom", "start", "end", "path", sep = "\t"), meta_file) - cat( - paste("21", "0", "0", "test_variants", sep = "\t"), - "\n", - file = meta_file, - append = TRUE - ) - result <- refVariantInfo(meta_file, region = "chr21:17513228-17550000") - expect_true(nrow(result) < 349L) - expect_true(all(result$pos >= 17513228 & result$pos <= 17550000)) -}) - -test_that("refVariantInfo returns variant info for VCF source", { skip_if_not_installed("VariantAnnotation") - meta_file <- file.path( - test_path("test_data"), - "ld_meta_refinfo_vcf_tmp.tsv" - ) - on.exit(unlink(meta_file), add = TRUE) - writeLines(paste("chrom", "start", "end", "path", sep = "\t"), meta_file) - cat( - paste("21", "0", "0", "test_variants.vcf.gz", sep = "\t"), - "\n", - file = meta_file, - append = TRUE - ) - result <- suppressWarnings( - refVariantInfo(meta_file, region = "chr21:17513228-17592874") - ) - expect_true(is.data.frame(result)) - expect_equal(nrow(result), 349L) - expect_true(all(c("chrom", "id", "pos", "A2", "A1") %in% names(result))) - expect_true("allele_freq" %in% names(result)) - expect_true(all(result$allele_freq > 0 & result$allele_freq < 1)) -}) - -test_that("refVariantInfo returns variant info for GDS source", { skip_if_not_installed("SNPRelate") skip_if_not_installed("gdsfmt") - meta_file <- file.path( - test_path("test_data"), - "ld_meta_refinfo_gds_tmp.tsv" - ) - on.exit(unlink(meta_file), add = TRUE) - writeLines(paste("chrom", "start", "end", "path", sep = "\t"), meta_file) - cat( - paste("21", "0", "0", "test_variants.gds", sep = "\t"), - "\n", - file = meta_file, - append = TRUE - ) - result <- refVariantInfo(meta_file, region = "chr21:17513228-17592874") - expect_true(is.data.frame(result)) - expect_equal(nrow(result), 349L) - expect_true(all(c("chrom", "id", "pos", "A2", "A1") %in% names(result))) - expect_true("allele_freq" %in% names(result)) -}) - -test_that("refVariantInfo VCF filters by subregion", { - skip_if_not_installed("VariantAnnotation") - skip_if_not_installed("Rsamtools") - meta_file <- file.path( - test_path("test_data"), - "ld_meta_refinfo_vcf_sub_tmp.tsv" - ) - on.exit(unlink(meta_file), add = TRUE) - writeLines(paste("chrom", "start", "end", "path", sep = "\t"), meta_file) - cat( - paste("21", "0", "0", "test_variants.vcf.gz", sep = "\t"), - "\n", - file = meta_file, - append = TRUE - ) - result <- suppressWarnings( - refVariantInfo(meta_file, region = "chr21:17513228-17550000") - ) - expect_true(nrow(result) < 349L) - expect_true(all(result$pos >= 17513228 & result$pos <= 17550000)) -}) - -test_that("refVariantInfo returns consistent results across formats", { - skip_if_not_installed("pgenlibr") - skip_if_not_installed("SNPRelate") - skip_if_not_installed("gdsfmt") - region <- "chr21:17513228-17592874" - td <- test_path("test_data") - - meta_plink <- file.path(td, "ld_meta_refinfo_cmp_p2_tmp.tsv") - meta_gds <- file.path(td, "ld_meta_refinfo_cmp_gds_tmp.tsv") - on.exit( - { - unlink(meta_plink) - unlink(meta_gds) - }, - add = TRUE - ) - - for (f in c(meta_plink, meta_gds)) { - writeLines(paste("chrom", "start", "end", "path", sep = "\t"), f) + # A window over the first 8 of the 349 variants. PLINK2 reads the allele + # frequency from its .afreq sidecar, VCF and GDS from the dosages. + window <- GenomicRanges::GRanges("chr21:17513228-17515000") + sources <- c( + plink2 = "test_variants", + vcf = "test_variants.vcf.gz", + gds = "test_variants.gds" + ) + infos <- map(sources, .gioRefInfoViaMeta, which = window) + for (format in names(infos)) { + info <- infos[[format]] + expect_true(is.data.frame(info), info = format) + expect_true( + all( + c("chrom", "id", "pos", "A2", "A1", "allele_freq") %in% + names(info) + ), + info = format + ) + expect_true( + all(info$allele_freq > 0 & info$allele_freq < 1), + info = format + ) + expect_equal(nrow(info), 8L, info = format) + expect_true( + all(info$pos >= 17513228 & info$pos <= 17515000), + info = format + ) + expect_equal(info$pos, infos$plink2$pos, info = format) } - cat( - paste("21", "0", "0", "test_variants", sep = "\t"), - "\n", - file = meta_plink, - append = TRUE - ) - cat( - paste("21", "0", "0", "test_variants.gds", sep = "\t"), - "\n", - file = meta_gds, - append = TRUE - ) - - info_plink <- refVariantInfo(meta_plink, region = region) - info_gds <- refVariantInfo(meta_gds, region = region) - - expect_equal(nrow(info_plink), nrow(info_gds)) - expect_equal(info_plink$pos, info_gds$pos) }) # =========================================================================== @@ -794,13 +443,17 @@ test_that("readAfreq returns NULL when no afreq file exists", { expect_null(af) }) -test_that("readAfreq reads .afreq.zst file", { +test_that("readAfreq reads .afreq.zst in-process, preferring it to .afreq", { td <- test_path("test_data") - # test_harmonize_regions has both .afreq and .afreq.zst; readAfreq prefers .zst + # Empty PATH: no zstd (or any) CLI is reachable. archive decompresses the + # .zst in-process via libarchive, so the read must still succeed. + withr::local_envvar(PATH = "") + # test_harmonize_regions has both .afreq and .afreq.zst; readAfreq + # prefers the .zst. af <- readAfreq(file.path(td, "test_harmonize_regions")) expect_true(is.data.frame(af)) expect_true(all( - c("id", "A2", "A1", "alt_freq", "obs_ct") %in% colnames(af) + c("chrom", "id", "A2", "A1", "alt_freq", "obs_ct") %in% colnames(af) )) # This afreq has U_MIN/U_MAX columns expect_true(all(c("u_min", "u_max") %in% colnames(af))) @@ -808,14 +461,14 @@ test_that("readAfreq reads .afreq.zst file", { }) test_that("readAfreq reads plain .afreq with U_MIN/U_MAX", { - td <- test_path("test_data") - # Temporarily hide the .zst so readAfreq falls through to plain .afreq - zst_path <- file.path(td, "test_harmonize_regions.afreq.zst") - tmp_path <- paste0(zst_path, ".bak") - file.rename(zst_path, tmp_path) - on.exit(file.rename(tmp_path, zst_path), add = TRUE) - - af <- readAfreq(file.path(td, "test_harmonize_regions")) + # A copy with no .zst beside it, so readAfreq falls through to plain + # .afreq without the shared fixture being touched. + dir <- withr::local_tempdir() + file.copy( + test_path("test_data", "test_harmonize_regions.afreq"), + file.path(dir, "g.afreq") + ) + af <- readAfreq(file.path(dir, "g")) expect_true(is.data.frame(af)) expect_true(all(c("u_min", "u_max") %in% colnames(af))) expect_equal(nrow(af), 8L) @@ -884,8 +537,10 @@ test_that("matchVariantsToKeep returns all FALSE for non-matching variants", { # =========================================================================== test_that("matchVariantsToKeep works with single-column variant ID file", { + # The variant info is pecotmr's own (UCSC); the keep file may spell its + # chromosomes either way. vi <- data.frame( - chrom = c("1", "1", "1"), + chrom = c("chr1", "chr1", "chr1"), pos = c(100L, 200L, 300L), A2 = c("A", "C", "G"), A1 = c("G", "T", "A"), @@ -925,10 +580,10 @@ test_that("matchVariantsToKeep uses position-only matching when no alleles", { }) # =========================================================================== -# readGenotypes + extractblockgenotypes: plink2 tests (replacing load_plink2_data) +# readGenotypes + extractBlockGenotypes: plink2 tests # =========================================================================== -test_that("readGenotypes loads plink2 handle with all variants", { +test_that("readGenotypeHandle reads a plink2 fileset with all its variants", { skip_if_not_installed("pgenlibr") td <- test_path("test_data") handle <- readGenotypeHandle( @@ -936,6 +591,7 @@ test_that("readGenotypes loads plink2 handle with all variants", { format = "plink2" ) expect_s4_class(handle, "GenotypeHandle") + expect_equal(genotypeFormat(handle), "plink2") expect_equal(nSamples(handle), 100L) expect_equal(nrow(snpInfo(handle)), 349L) rse <- extractBlockGenotypes(handle, seq_len(nrow(snpInfo(handle)))) @@ -945,42 +601,6 @@ test_that("readGenotypes loads plink2 handle with all variants", { expect_equal(ncol(dosage), 100L) }) -test_that("loadGenotypeRegion filters by region for plink2", { - skip_if_not_installed("pgenlibr") - td <- test_path("test_data") - region <- "chr21:17513228-17550000" - result <- loadGenotypeRegion( - file.path(td, "test_variants"), - region = region - ) - expect_true(ncol(result) < 349L) -}) - -test_that("loadGenotypeRegion errors on empty region for plink2", { - skip_if_not_installed("pgenlibr") - td <- test_path("test_data") - expect_error( - loadGenotypeRegion( - file.path(td, "test_variants"), - region = "chr21:1-2" - ), - "No SNPs found", - class = "NoSnpsError" - ) -}) - -test_that("loadGenotypeRegion removes indels for plink2", { - skip_if_not_installed("pgenlibr") - td <- test_path("test_data") - full <- loadGenotypeRegion(file.path(td, "test_variants")) - filtered <- loadGenotypeRegion( - file.path(td, "test_variants"), - keepIndel = FALSE - ) - # test data has 36 indels - expect_equal(ncol(filtered), ncol(full) - 36L) -}) - test_that("loadGenotypeRegion filters by keep_variants_path for plink2", { skip_if_not_installed("pgenlibr") td <- test_path("test_data") @@ -1026,46 +646,6 @@ test_that("readGenotypes plink2 sample names match psam IIDs", { expect_equal(length(unique(sampleIds(handle))), 100L) }) -# ============================================================================= -# Removed during the post-S4-refactor cleanup -# ----------------------------------------------------------------------------- -# The following test blocks were deleted because the functions / classes they -# exercise were either removed outright or replaced by `.Deprecated()` no-op -# stubs in the S4 refactor (see R/fileUtils.R deprecation notices): -# -# * loadRegionalAssociationData -> use QtlDataset() -# * loadRegionalUnivariateData -> use QtlDataset() -# * loadRegionalRegressionData -> use QtlDataset() -# * loadRegionalMultivariateData -> use MultiStudyQtlDataset() -# * loadRegionalFunctionalData -> use QtlDataset() -# * loadMultitaskRegionalData -> use MultiStudyQtlDataset() -# * loadRssData -> use GwasSumStats() / QtlSumStats() + -# summaryStatsQc() -# * loadTwasWeights -> use TwasWeights() / twasWeightsRow() -# * regionDataToIndInput -> use QtlDataset() -# * regionDataToRssInput -> use QtlSumStats() / GwasSumStats() -# * phenoListToMat -> function removed (no replacement) -# -# Removed S4 classes (no longer constructible / inspectable): -# * RegionalData -# * MultivariateRegionalData -# * QcResult -# * AlleleQcResult -# -# Removed accessor / helper functions: -# * getrssinput, getlddata, getoutliernumber -# * rssBasicQc -> folded into summaryStatsQc() -# -# Removed pipeline wrappers (all `.Deprecated()` no-ops returning NULL): -# * colocWrapper, xqtlEnrichmentWrapper, colocPostProcessor, -# rssAnalysisPipeline -# -# No surgical renames were applied: the previous test file contained no -# references to `finemappingResult` / `FineMappingResult(variantNames=...)` or -# related identifiers, so no `$finemappingEntry` / -# `fineMappingRow(variantIds=...)` substitutions were necessary here. -# ============================================================================= - # Tests for genotype loading via readGenotypes + extractBlockGenotypes, # and the loadGenotypeRegion dispatcher. @@ -1074,26 +654,13 @@ test_data_dir <- test_path("test_data") plink_prefix <- file.path(test_data_dir, "test_variants") vcf_path <- file.path(test_data_dir, "test_variants.vcf.gz") gds_path <- file.path(test_data_dir, "test_variants.gds") -region_all <- "chr21:17513228-17592874" -region_sub <- "chr21:17513228-17550000" +# A window over the first 8 variants. +region_sub <- GenomicRanges::GRanges("chr21:17513228-17515000") # Expected dimensions n_samples <- 100L n_variants <- 349L -test_that("format detection supports dotted PLINK2 prefixes", { - tmp <- tempfile("plink2_dotted_prefix_") - prefix <- file.path(dirname(tmp), "ADSP.R4.EUR.chr21") - file.create( - paste0(prefix, ".pgen"), - paste0(prefix, ".pvar"), - paste0(prefix, ".psam") - ) - on.exit(unlink(paste0(prefix, c(".pgen", ".pvar", ".psam"))), add = TRUE) - - expect_equal(pecotmr:::.genotypePathFormat(prefix), "plink2") -}) - # Shared helper: validate the output structure from loadGenotypeRegion # (with returnVariantInfo=TRUE) checkGenotypeResult <- function( @@ -1125,215 +692,141 @@ checkGenotypeResult <- function( ) } -# --- readGenotypes: PLINK1 (PlinkMatrix) ------------------------------------- +# --- readGenotypes: PLINK1, VCF and GDS panels ------------------------------- -test_that("readGenotypes reads a PLINK1 fileset as a panel", { +test_that("readGenotypes reads PLINK1, VCF and GDS files as panels", { skip_if_not_installed("PlinkMatrix") - panel <- readGenotypes(plink1Prefix = plink_prefix) - expect_s4_class(panel, "RangedSummarizedExperiment") - expect_equal(dim(panel), c(n_variants, n_samples)) - expect_equal(S4Vectors::metadata(panel)$genotypeSource$format, "plink1") - expect_s4_class(pecotmr:::.panelSeed(panel), "GenotypeDosageSeed") - expect_null(pecotmr:::.ldRefHandle(panel)) -}) - -test_that("loadGenotypeRegion loads plink1 via dispatch", { - skip_if_not_installed("PlinkMatrix") - # Use .genotype suffix plink1 files tested elsewhere in test_file_utils - plink1_path <- file.path(test_data_dir, "protocol_example.genotype") - skip_if( - !file.exists(paste0(plink1_path, ".bed")), - "plink1 test fixture missing" - ) - result <- loadGenotypeRegion(plink1_path, returnVariantInfo = TRUE) - expect_true(is.list(result)) - expect_true(is.matrix(result$X)) -}) - -# --- readGenotypes: PLINK2 (pgenlibr) ---------------------------------------- - -test_that("readGenotypes creates plink2 handle", { - skip_if_not_installed("pgenlibr") - handle <- readGenotypeHandle(plink_prefix, format = "plink2") - expect_s4_class(handle, "GenotypeHandle") - expect_equal(genotypeFormat(handle), "plink2") - expect_equal(nSamples(handle), n_samples) - expect_equal(nrow(snpInfo(handle)), n_variants) -}) - -test_that("extractBlockGenotypes works for plink2", { - skip_if_not_installed("pgenlibr") - handle <- readGenotypeHandle(plink_prefix, format = "plink2") - rse <- extractBlockGenotypes(handle, seq_len(nrow(snpInfo(handle)))) - expect_s4_class(rse, "SummarizedExperiment") - dosage <- SummarizedExperiment::assay(rse, "dosage") - expect_equal(nrow(dosage), n_variants) - expect_equal(ncol(dosage), n_samples) -}) - -test_that("loadGenotypeRegion filters plink2 by region", { - skip_if_not_installed("pgenlibr") - result <- loadGenotypeRegion( - plink_prefix, - region = region_sub, - returnVariantInfo = TRUE - ) - checkGenotypeResult(result, expected_ncol = 134L, label = "plink2 region") - expect_true(all( - result$variant_info$pos >= 17513228 & - result$variant_info$pos <= 17550000 - )) -}) - -test_that("loadGenotypeRegion filters plink2 indels", { - skip_if_not_installed("pgenlibr") - result <- loadGenotypeRegion( - plink_prefix, - keepIndel = FALSE, - returnVariantInfo = TRUE - ) - expect_lt(ncol(result$X), n_variants) - expect_true(all(nchar(result$variant_info$A1) == 1)) - expect_true(all(nchar(result$variant_info$A2) == 1)) -}) - -test_that("loadGenotypeRegion errors on empty region for plink2", { - skip_if_not_installed("pgenlibr") - expect_error(loadGenotypeRegion(plink_prefix, region = "chr1:1-2")) -}) - -# --- readGenotypes: VCF (VariantAnnotation) ----------------------------------- - -test_that("readGenotypes reads a VCF as a panel over its own seed", { - skip_if_not_installed("VariantAnnotation") - panel <- readGenotypes(vcf_path) - expect_s4_class(panel, "RangedSummarizedExperiment") - expect_equal(dim(panel), c(n_variants, n_samples)) - # No handle: the panel reads through a GenotypeDosageSeed, and records - # where it came from itself. - expect_null(pecotmr:::.ldRefHandle(panel)) - expect_equal(S4Vectors::metadata(panel)$genotypeSource$format, "vcf") -}) - -test_that("loadGenotypeRegion loads VCF via dispatch", { - skip_if_not_installed("VariantAnnotation") - result <- suppressWarnings(loadGenotypeRegion( - vcf_path, - returnVariantInfo = TRUE - )) - checkGenotypeResult(result, label = "dispatch vcf") -}) - -test_that("loadGenotypeRegion filters VCF by region", { skip_if_not_installed("VariantAnnotation") - skip_if_not_installed("Rsamtools") - result <- suppressWarnings(loadGenotypeRegion( - vcf_path, - region = region_sub, - returnVariantInfo = TRUE - )) - checkGenotypeResult(result, expected_ncol = 134L, label = "vcf region") - expect_true(all( - result$variant_info$pos >= 17513228 & - result$variant_info$pos <= 17550000 - )) -}) - -test_that("loadGenotypeRegion filters VCF indels", { - skip_if_not_installed("VariantAnnotation") - result <- suppressWarnings(loadGenotypeRegion( - vcf_path, - keepIndel = FALSE, - returnVariantInfo = TRUE - )) - expect_lt(ncol(result$X), n_variants) - expect_true(all(nchar(result$variant_info$A1) == 1)) - expect_true(all(nchar(result$variant_info$A2) == 1)) -}) - -# --- readGenotypes: GDS (SNPRelate) ------------------------------------------- - -test_that("readGenotypes reads a GDS file as a panel over its own seed", { skip_if_not_installed("gdsfmt") skip_if_not_installed("GDSArray") - panel <- readGenotypes(gds_path) - expect_s4_class(panel, "RangedSummarizedExperiment") - expect_equal(dim(panel), c(n_variants, n_samples)) - expect_null(pecotmr:::.ldRefHandle(panel)) - expect_equal(S4Vectors::metadata(panel)$genotypeSource$format, "gds") + sources <- list( + plink1 = list(plink1Prefix = plink_prefix), + vcf = list(vcf_path), + gds = list(gds_path) + ) + for (format in names(sources)) { + panel <- exec(readGenotypes, !!!sources[[format]]) + expect_s4_class(panel, "RangedSummarizedExperiment") + expect_equal(dim(panel), c(n_variants, n_samples), info = format) + expect_equal( + S4Vectors::metadata(panel)$genotypeSource$format, + format, + info = format + ) + # No handle: the panel reads through its own GenotypeDosageSeed, and + # records where it came from itself. + expect_s4_class(pecotmr:::.panelSeed(panel), "GenotypeDosageSeed") + expect_null(pecotmr:::.ldRefHandle(panel), info = format) + } }) -test_that("loadGenotypeRegion loads GDS via dispatch", { +# --- loadGenotypeRegion ------------------------------------------------------- + +test_that("loadGenotypeRegion reads every format by its path, alike", { + skip_if_not_installed("PlinkMatrix") + skip_if_not_installed("pgenlibr") + skip_if_not_installed("VariantAnnotation") skip_if_not_installed("SNPRelate") skip_if_not_installed("gdsfmt") - result <- loadGenotypeRegion(gds_path, returnVariantInfo = TRUE) - checkGenotypeResult(result, label = "dispatch gds") + # A PLINK2 prefix, a PLINK1 .bed, a VCF and a GDS file of the same + # genotypes: each is told by its path and read to the same variants. + paths <- c( + plink2 = plink_prefix, + plink1 = paste0(plink_prefix, ".bed"), + vcf = vcf_path, + gds = gds_path + ) + loaded <- map(paths, loadGenotypeRegion, returnVariantInfo = TRUE) + for (format in names(paths)) { + checkGenotypeResult(loaded[[format]], label = format) + expect_equal( + loaded[[format]]$variant_info$pos, + loaded$plink2$variant_info$pos, + info = format + ) + } }) -test_that("loadGenotypeRegion filters GDS by region", { +test_that("loadGenotypeRegion filters each format to a region", { + skip_if_not_installed("pgenlibr") + skip_if_not_installed("VariantAnnotation") skip_if_not_installed("SNPRelate") skip_if_not_installed("gdsfmt") - result <- loadGenotypeRegion( - gds_path, - region = region_sub, - returnVariantInfo = TRUE - ) - checkGenotypeResult(result, expected_ncol = 134L, label = "gds region") - expect_true(all( - result$variant_info$pos >= 17513228 & - result$variant_info$pos <= 17550000 - )) + for (path in c(plink_prefix, vcf_path, gds_path)) { + result <- loadGenotypeRegion( + path, + which = region_sub, + returnVariantInfo = TRUE + ) + checkGenotypeResult(result, expected_ncol = 8L, label = path) + expect_true( + all( + result$variant_info$pos >= 17513228 & + result$variant_info$pos <= 17515000 + ), + info = path + ) + } }) -test_that("loadGenotypeRegion filters GDS indels", { +test_that("loadGenotypeRegion drops every format's indels", { + skip_if_not_installed("pgenlibr") + skip_if_not_installed("VariantAnnotation") skip_if_not_installed("SNPRelate") skip_if_not_installed("gdsfmt") - result <- loadGenotypeRegion( - gds_path, - keepIndel = FALSE, - returnVariantInfo = TRUE - ) - expect_lt(ncol(result$X), n_variants) - expect_true(all(nchar(result$variant_info$A1) == 1)) - expect_true(all(nchar(result$variant_info$A2) == 1)) + # The first 25 variants, 3 of them indels: a VCF is read a record at a + # time, so the filter is run over a window rather than the whole file. + window <- GenomicRanges::GRanges("chr21:17513228-17518122") + for (path in c(plink_prefix, vcf_path, gds_path)) { + result <- loadGenotypeRegion( + path, + which = window, + keepIndel = FALSE, + returnVariantInfo = TRUE + ) + expect_equal(ncol(result$X), 22L, info = path) + expect_true(all(nchar(result$variant_info$A1) == 1), info = path) + expect_true(all(nchar(result$variant_info$A2) == 1), info = path) + } }) -test_that("loadGenotypeRegion errors on empty region for GDS", { +test_that("loadGenotypeRegion errors on an empty region", { + skip_if_not_installed("pgenlibr") skip_if_not_installed("SNPRelate") skip_if_not_installed("gdsfmt") - expect_error(loadGenotypeRegion(gds_path, region = "chr1:1-2")) + # Off the panel's variants, or on a chromosome it does not hold. + for (path in c(plink_prefix, gds_path)) { + for (window in c("chr21:1-2", "chr1:1-2")) { + expect_error( + loadGenotypeRegion( + path, + which = GenomicRanges::GRanges(window) + ), + "No SNPs found", + class = "NoSnpsError", + info = str_c(path, " ", window) + ) + } + } }) -# --- Cross-format consistency ------------------------------------------------- - -test_that("all formats return same dimensions and positions via loadGenotypeRegion", { - skip_if_not_installed("PlinkMatrix") +test_that("loadGenotypeRegion returns matrix when returnVariantInfo=FALSE", { skip_if_not_installed("pgenlibr") - skip_if_not_installed("VariantAnnotation") - skip_if_not_installed("SNPRelate") + result <- loadGenotypeRegion(plink_prefix) + expect_true(is.matrix(result)) + expect_equal(nrow(result), n_samples) + expect_equal(ncol(result), n_variants) +}) - p2 <- loadGenotypeRegion(plink_prefix, returnVariantInfo = TRUE) - p1 <- loadGenotypeRegion( - paste0(plink_prefix, ".bed"), - returnVariantInfo = TRUE +test_that("loadGenotypeRegion errors on unrecognized format", { + expect_error( + loadGenotypeRegion("/nonexistent/file.xyz"), + "loadGenotypeRegion: .* is neither a genotype file nor a PLINK prefix" ) - vcf <- suppressWarnings(loadGenotypeRegion( - vcf_path, - returnVariantInfo = TRUE - )) - gds <- loadGenotypeRegion(gds_path, returnVariantInfo = TRUE) - - # Same dimensions - expect_equal(dim(p2$X), dim(p1$X)) - expect_equal(dim(p2$X), dim(vcf$X)) - expect_equal(dim(p2$X), dim(gds$X)) - - # Same positions - expect_equal(p2$variant_info$pos, p1$variant_info$pos) - expect_equal(p2$variant_info$pos, vcf$variant_info$pos) - expect_equal(p2$variant_info$pos, gds$variant_info$pos) }) +# --- Cross-format consistency ------------------------------------------------- + test_that("PLINK1 and PLINK2 readGenotypes return consistent alleles", { skip_if_not_installed("PlinkMatrix") skip_if_not_installed("pgenlibr") @@ -1351,55 +844,6 @@ test_that("PLINK1 and PLINK2 readGenotypes return consistent alleles", { ) }) -# --- loadGenotypeRegion (dispatch) ----------------------------------------- - -test_that("loadGenotypeRegion dispatches to VCF by extension", { - skip_if_not_installed("VariantAnnotation") - result <- suppressWarnings(loadGenotypeRegion( - vcf_path, - returnVariantInfo = TRUE - )) - checkGenotypeResult(result, label = "dispatch vcf") -}) - -test_that("loadGenotypeRegion dispatches to GDS by extension", { - skip_if_not_installed("SNPRelate") - skip_if_not_installed("gdsfmt") - result <- loadGenotypeRegion(gds_path, returnVariantInfo = TRUE) - checkGenotypeResult(result, label = "dispatch gds") -}) - -test_that("loadGenotypeRegion dispatches to PLINK2 by prefix", { - skip_if_not_installed("pgenlibr") - result <- loadGenotypeRegion(plink_prefix, returnVariantInfo = TRUE) - checkGenotypeResult(result, label = "dispatch plink2") -}) - -test_that("loadGenotypeRegion returns matrix when returnVariantInfo=FALSE", { - skip_if_not_installed("pgenlibr") - result <- loadGenotypeRegion(plink_prefix) - expect_true(is.matrix(result)) - expect_equal(nrow(result), n_samples) - expect_equal(ncol(result), n_variants) -}) - -test_that("loadGenotypeRegion applies region filter", { - skip_if_not_installed("pgenlibr") - result <- loadGenotypeRegion( - plink_prefix, - region = region_sub, - returnVariantInfo = TRUE - ) - expect_equal(ncol(result$X), 134L) -}) - -test_that("loadGenotypeRegion errors on unrecognized format", { - expect_error( - loadGenotypeRegion("/nonexistent/file.xyz"), - "loadGenotypeRegion: .* is neither a genotype file nor a PLINK prefix" - ) -}) - # =========================================================================== # Tests migrated from test_dataStructures.R (extractBlockGenotypes) # =========================================================================== @@ -1440,42 +884,6 @@ test_that("extractBlockGenotypes mean-imputes a missing call on request", { expect_equal(imputed[-2L, ], raw[-2L, ]) }) -# ============================================================================= -# adjustPips -# ============================================================================= - -# Build a minimal FineMappingRow with a known lbf_variable so PIP -# renormalization can be checked end-to-end. -.makeAdjustEntry <- function(vids, maxNumSingleEffects = 2L) { - p <- length(vids) - set.seed(11L) - lbf <- matrix( - rnorm(maxNumSingleEffects * p), - nrow = maxNumSingleEffects, - ncol = p - ) - colnames(lbf) <- vids - alpha <- lbfToAlpha(lbf) - pip <- as.numeric(1 - apply(1 - alpha, 2, prod)) - fineMappingRow( - variantIds = vids, - susieFit = list( - pip = pip, - alpha = alpha, - lbf_variable = lbf, - mu = matrix(0, maxNumSingleEffects, p), - X_column_scale_factors = rep(1, p) - ), - topLoci = data.frame( - variant_id = vids, - pip = pip, - betahat = rep(0, p), - sebetahat = rep(1, p), - stringsAsFactors = FALSE - ) - ) -} - # =========================================================================== # One-file-per-chromosome (sharded) handle: extraction routing. # extractBlockGenotypes() routes each region to its per-chromosome payload and @@ -1519,7 +927,7 @@ test_that("extractBlockGenotypes mean-imputes a missing call on request", { shard <- GenotypeHandle(genoMeta = c("21" = spec$p21, "22" = spec$p22)) expect_s4_class(shard, "GenotypeHandle") expect_equal(genotypeFormat(shard), genotypeFormat(ref21)) - expect_equal(sort(names(chromPaths(shard))), c("21", "22")) + expect_equal(sort(names(chromPaths(shard))), c("chr21", "chr22")) n21 <- nrow(snpInfo(ref21)) n22 <- nrow(snpInfo(ref22)) expect_equal(nrow(snpInfo(shard)), n21 + n22) @@ -1629,9 +1037,9 @@ test_that("genoMeta meta-file form matches the named-vector form", { # Coverage top-ups for R/genotypeIo.R: dispatch/handle error stops, empty- and # missing-chromosome block paths, format-specific extractor edge cases, the # GDS LD path, format detection / stem branches, resolvePlink2Paths -# validation, readAfreq zstd guard, readStochasticMeta validation, the plink1 -# refVariantInfo path with a multi-row region, and the non-integer-dosage -# warning in loadGenotypeRegion. +# validation, readStochasticMeta validation, the plink1 refVariantInfo path, +# a multi-range refVariantInfo region, and the non-integer dosages +# loadGenotypeRegion keeps without a sidecar. # =========================================================================== # --- readGenotypes dispatch + handle-constructor file-not-found stops -------- @@ -1672,6 +1080,16 @@ test_that("extractBlockGenotypes on a sharded handle handles an empty block", { expect_equal(colnames(dosage), sampleIds(shard)) }) +test_that("extractBlockGenotypes answers an empty index without a reader", { + # A reader need not accept an empty request -- snpStats segfaulted on + # one when it read PLINK1 -- so none is ever made. + gh <- .gh_pgenHandle() + se <- extractBlockGenotypes(gh, snpIdx = integer(0)) + expect_s4_class(se, "SummarizedExperiment") + expect_equal(nrow(se), 0L) + expect_equal(ncol(se), nSamples(gh)) +}) + test_that("sharded extraction errors for a chromosome with no payload", { skip_if_not_installed("pgenlibr") td <- test_path("test_data") @@ -1691,7 +1109,7 @@ test_that("sharded extraction errors for a chromosome with no payload", { ) }) -# --- .extractBlockPlink2: stale-pointer reopen path (lines 402-403) ---------- +# --- .extractBlockPlink2: stale-pointer reopen path -------------------------- test_that("plink2 extraction reopens a stale (deserialized) pgen pointer", { skip_if_not_installed("pgenlibr") @@ -1717,45 +1135,7 @@ test_that("plink2 extraction reopens a stale (deserialized) pgen pointer", { expect_equal(got, ref) }) -# --- computeLd on a panel: NULL guard, single-variant, general path ---------- - -test_that("computeLd on a GDS panel uses the in-memory path", { - # The native SNPRelate route is no longer chosen implicitly by format: - # it applies a different missing-data policy, so it is opt-in via - # onDisk = TRUE rather than a silent consequence of the panel's format. - skip_if_not_installed("gdsfmt") - skip_if_not_installed("GDSArray") - panel <- readGenotypes(test_path("test_data", "test_variants.gds")) - R <- computeLd(panel, snpIdx = 1:6, backend = "internal") - expect_equal(dim(R), c(6L, 6L)) - expect_true(all(is.finite(R))) - expect_false(anyNA(R)) - expect_equal(unname(diag(R)), rep(1, 6), tolerance = 1e-6) - expect_identical(rownames(R), rownames(panel)[1:6]) -}) - -test_that("computeLd returns identity for a single-variant block", { - skip_if_not_installed("pgenlibr") - td <- test_path("test_data") - handle <- readGenotypeHandle( - file.path(td, "test_variants"), - format = "plink2" - ) - R <- computeLd(handle, snpIdx = 1L, backend = "internal") - expect_equal(R, diag(1)) -}) - -test_that("computeLd on a panel computes via the general path", { - skip_if_not_installed("pgenlibr") - td <- test_path("test_data") - handle <- readGenotypeHandle( - file.path(td, "test_variants"), - format = "plink2" - ) - R <- computeLd(handle, snpIdx = 1:5, backend = "internal") - expect_equal(dim(R), c(5L, 5L)) - expect_equal(unname(diag(R)), rep(1, 5), tolerance = 1e-6) -}) +# --- computeLd on a panel: single-variant and general path ------------------ # --- genotype format detection ---------------------------------------------- @@ -1773,6 +1153,10 @@ test_that("a PLINK prefix is told by the PLINK file beside it", { pecotmr:::.genotypePathFormat(file.path(td, "test_variants")), "plink2" ) + # A dotted prefix's last part is not taken for an extension. + dotted <- file.path(withr::local_tempdir(), "ADSP.R4.EUR.chr21") + file.create(str_c(dotted, c(".pgen", ".pvar", ".psam"))) + expect_equal(pecotmr:::.genotypePathFormat(dotted), "plink2") # A GDS file is named by its own path, never by a stem beside it. stem <- tempfile("gioGdsStem_") file.create(paste0(stem, ".gds")) @@ -1873,26 +1257,6 @@ test_that("resolvePlink2Paths errors when .psam is missing", { ) }) -# --- readAfreq: .afreq.zst is read via archive, no external CLI -------------- - -test_that("readAfreq reads .afreq.zst without any external CLI", { - skip_if_not_installed("withr") - td <- test_path("test_data") - zdir <- tempfile("gioZst_") - dir.create(zdir) - file.copy( - file.path(td, "test_harmonize_regions.afreq.zst"), - file.path(zdir, "g.afreq.zst") - ) - # Empty PATH: no zstd (or any) CLI is reachable. archive decompresses the - # .zst in-process via libarchive, so the read must still succeed. - withr::local_envvar(PATH = "") - af <- readAfreq(file.path(zdir, "g")) - expect_true(is.data.frame(af)) - expect_equal(nrow(af), 8L) - expect_true(all(c("chrom", "id", "alt_freq") %in% colnames(af))) -}) - # --- readStochasticMeta: generic format missing required columns ------------- test_that("readStochasticMeta errors when generic file lacks required columns", { @@ -1924,7 +1288,7 @@ test_that("refVariantInfo reads variant info from a plink1 source", { expect_gt(nrow(info), 0L) }) -test_that("refVariantInfo applies a multi-row data.frame region filter", { +test_that("refVariantInfo applies a multi-range region filter", { skip_if_not_installed("pgenlibr") td <- test_path("test_data") meta_file <- file.path(td, "ld_meta_refinfo_multirow_tmp.tsv") @@ -1936,15 +1300,13 @@ test_that("refVariantInfo applies a multi-row data.frame region filter", { file = meta_file, append = TRUE ) - # A two-row region (both chr21) drives the multi-row branch of the filter - # loop; together the rows cover the full block. - region_df <- data.frame( - chrom = c("21", "21"), - start = c(17513228L, 17550001L), - end = c(17550000L, 17592874L), - stringsAsFactors = FALSE + # A two-range window (both chr21) drives the multi-range filter; together + # the ranges cover the full block. + twoRanges <- GenomicRanges::GRanges( + "21", + IRanges::IRanges(c(17513228L, 17550001L), c(17550000L, 17592874L)) ) - info <- refVariantInfo(meta_file, region = region_df) + info <- refVariantInfo(meta_file, which = twoRanges) expect_true(is.data.frame(info)) expect_equal(nrow(info), 349L) expect_true(all(info$pos >= 17513228 & info$pos <= 17592874)) @@ -2041,61 +1403,38 @@ test_that("extractBlockGenotypes honours request order (plink2)", { .gio_orderCheck("plink2", test_path("test_data", "test_variants")) }) -test_that("a PLINK1 panel honours request order", { +test_that("a PLINK1, GDS or delayed PLINK2 read honours request order", { # snpStats returned file order when it read PLINK1; the panel's seed - # reads each block in file order and lays it out as asked. + # reads each block in file order and lays it out as asked. DelayedArray + # hands the index straight to extract_array(), so a handle's delayed + # array inherits whatever the reader does. skip_if_not_installed("PlinkMatrix") - panel <- readGenotypes( - plink1Prefix = test_path("test_data", "test_variants") - ) - a <- SummarizedExperiment::assay(panel, "dosage") - perm <- c(4L, 1L, 6L, 2L, 5L, 3L) - expect_equal( - unname(as.matrix(a[perm, 1:4])), - unname(as.matrix(a[1:6, 1:4])[perm, , drop = FALSE]) - ) -}) - -test_that("a GDS panel honours request order", { skip_if_not_installed("gdsfmt") skip_if_not_installed("GDSArray") - panel <- readGenotypes(test_path("test_data", "test_variants.gds")) - a <- SummarizedExperiment::assay(panel, "dosage") - perm <- c(4L, 1L, 6L, 2L, 5L, 3L) - expect_equal( - unname(as.matrix(a[perm, 1:4])), - unname(as.matrix(a[1:6, 1:4])[perm, , drop = FALSE]) - ) -}) - -test_that("a delayed read honours request order too", { - # DelayedArray hands the index straight to extract_array(), so the seed - # inherits whatever the reader does. skip_if_not_installed("pgenlibr") - handle <- readGenotypeHandle( - test_path("test_data", "test_variants"), - format = "plink2" + stem <- test_path("test_data", "test_variants") + arrays <- list( + plink1 = SummarizedExperiment::assay( + readGenotypes(plink1Prefix = stem), + "dosage" + ), + gds = SummarizedExperiment::assay( + readGenotypes(str_c(stem, ".gds")), + "dosage" + ), + plink2 = genotypeDelayedArray( + readGenotypeHandle(stem, format = "plink2") + ) ) - a <- genotypeDelayedArray(handle) perm <- c(4L, 1L, 6L, 2L, 5L, 3L) - expect_equal( - unname(as.matrix(a[perm, 1:4])), - unname(as.matrix(a[1:6, 1:4])[perm, , drop = FALSE]) - ) -}) - -test_that("LD from a sketch does not depend on the request order", { - skip_if_not_installed("pgenlibr") - handle <- readGenotypeHandle( - test_path("test_data", "test_variants"), - format = "plink2" - ) - ids <- snpInfo(handle)$SNP[1:6] - shuffled <- ids[c(4L, 1L, 6L, 2L, 5L, 3L)] - sorted <- pecotmr:::.ldFromRef(handle, ids, label = "t") - mixed <- pecotmr:::.ldFromRef(handle, shuffled, label = "t") - expect_identical(rownames(mixed), shuffled) - expect_equal(sorted[ids, ids], mixed[ids, ids]) + for (format in names(arrays)) { + a <- arrays[[format]] + expect_equal( + unname(as.matrix(a[perm, 1:4])), + unname(as.matrix(a[1:6, 1:4])[perm, , drop = FALSE]), + info = format + ) + } }) test_that(".restoreRequestedOrder refuses a short block", { @@ -2107,70 +1446,6 @@ test_that(".restoreRequestedOrder refuses a short block", { ) }) -# --------------------------------------------------------------------------- -# computeLd(onDisk = TRUE): read the correlation off the GDS without ever -# materialising dosages. The dosage matrix scales with samples x variants -# while the result scales with variants^2, so on a wide panel the input dwarfs -# the output and keeping it on disk is what makes a big block feasible. -# --------------------------------------------------------------------------- - -test_that("onDisk LD matches the in-memory path on complete data", { - skip_if_not_installed("SNPRelate") - skip_if_not_installed("GDSArray") - handle <- readGenotypes(test_path("test_data", "test_variants.gds")) - idx <- c(4L, 1L, 6L, 2L, 5L, 3L) - onDisk <- computeLd( - handle, - snpIdx = idx, - backend = "snprelate", - onDisk = TRUE - ) - inMem <- computeLd(handle, snpIdx = idx) - # The fixture has no missing calls, which is the only regime where the - # two are meant to agree. - expect_equal(unname(onDisk), unname(inMem), tolerance = 1e-8) -}) - -test_that("onDisk LD labels and orders by the request", { - skip_if_not_installed("SNPRelate") - skip_if_not_installed("GDSArray") - handle <- readGenotypes(test_path("test_data", "test_variants.gds")) - idx <- c(4L, 1L, 6L, 2L, 5L, 3L) - R <- computeLd(handle, snpIdx = idx, backend = "snprelate", onDisk = TRUE) - # snpgdsLDMat() returns file order and labels nothing; both are corrected. - expect_identical( - rownames(R), - SummarizedExperiment::rowRanges(handle)$SNP[idx] - ) - expect_identical(colnames(R), rownames(R)) -}) - -test_that("onDisk LD is refused where it cannot be honoured", { - skip_if_not_installed("SNPRelate") - skip_if_not_installed("GDSArray") - skip_if_not_installed("PlinkMatrix") - gds <- readGenotypes(test_path("test_data", "test_variants.gds")) - plink <- readGenotypes( - plink1Prefix = test_path("test_data", "test_variants") - ) - expect_error( - computeLd(plink, backend = "snprelate", onDisk = TRUE), - "GDS-backed panel" - ) - expect_error( - computeLd(gds, backend = "internal", onDisk = TRUE), - "only available for" - ) - expect_error( - computeLd(matrix(1, 4, 3), backend = "snprelate", onDisk = TRUE), - "must be one" - ) - expect_error( - computeLd(gds, method = "gcta", backend = "snprelate", onDisk = TRUE), - "sample correlation" - ) -}) - test_that("ordering uses FILE position, not the snpInfo row number", { # A row-subset handle's snpInfo rows are no longer file positions, so # sorting the request by row number would ask the backend for the wrong @@ -2256,17 +1531,6 @@ test_that("a panel answers panel questions without the handle", { expect_true(all(is_in(c("SNP", "A1", "A2"), cn))) }) -test_that("computeLd accepts the panel readGenotypes returns", { - skip_if_not_installed("PlinkMatrix") - panel <- readGenotypes( - test_path("test_data", "test_variants"), - format = "plink1" - ) - R <- computeLd(panel, snpIdx = 1:5) - expect_equal(dim(R), c(5L, 5L)) - expect_equal(unname(diag(R)), rep(1, 5), tolerance = 1e-8) -}) - test_that("readGenotypes names a panel by keyword when path is missing", { # GenotypeHandle is internal now, so its source vocabulary (prefixes, # explicit triplets, genoMeta) has to stay reachable from the public @@ -2366,7 +1630,7 @@ test_that("a legacy handle without fileIdx is not subset", { format = "plink2", snpInfo = data.frame( SNP = c("a", "b", "c"), - CHR = "1", + CHR = "chr1", BP = 1:3, A1 = "A", A2 = "G", @@ -2422,7 +1686,7 @@ test_that("block extraction rejects a format it has no reader for", { format = "plink2", snpInfo = data.frame( SNP = "a", - CHR = "1", + CHR = "chr1", BP = 1L, A1 = "A", A2 = "G", @@ -2552,7 +1816,7 @@ test_that("a BGEN file's variants read as pecotmr's convention", { expect_equal(genotypeFormat(handle), "bgen") expect_equal(si$A2, rep("A", 5L)) expect_equal(si$A1, rep("G", 5L)) - expect_equal(si$CHR, rep("1", 5L)) + expect_equal(si$CHR, rep("chr1", 5L)) expect_equal(si$SNP, c("chr1:100:A:G", sprintf("rs%d", 1:4))) expect_equal(si$BP, 100L * (1:5)) }) @@ -2785,9 +2049,15 @@ test_that("a BGEN file serves every genotype route", { c("#chr\tstart\tend\tpath", str_c("chr1\t1\t10000\t", fx$path)), meta ) - viaMeta <- readGenotypes(ldMeta = meta, region = "chr1:1-10000") + viaMeta <- readGenotypes( + ldMeta = meta, + block = GenomicRanges::GRanges("chr1:1-10000") + ) expect_equal(unname(.bgenPanelDosage(viaMeta)), want, tolerance = 1e-12) - loaded <- loadGenotypeRegion(fx$path, region = "chr1:1-10000") + loaded <- loadGenotypeRegion( + fx$path, + which = GenomicRanges::GRanges("chr1:1-10000") + ) expect_equal(unname(loaded), want, tolerance = 1e-12) expect_equal( refVariantInfo(fx$path)$pos, @@ -2849,10 +2119,6 @@ test_that("the BGEN dosage kernel reads any ploidy and allele count", { samples3 <- c("s1", "s2", "s3") -.dose <- function(panel) { - unname(as.matrix(SummarizedExperiment::assay(panel, "dosage"))) -} - # A GDS file built node by node with gdsfmt, of root format `fileFormat` # (NULL records none), by `build(gds)`. .writeTestGds <- function(fileFormat, build) { @@ -3123,19 +2389,6 @@ test_that("a PLINK1 panel reads the dosages snpStats reads", { ) }) -test_that("a PLINK1 panel cut to a few variants keeps only those", { - # Its seed is cut with it, so a saved panel carries the kept variants' - # metadata only, and reads them back from the file. - skip_if_not_installed("PlinkMatrix") - panel <- readGenotypes(plink1Prefix = plink_prefix) - cut <- pecotmr:::.panelSubsetRows(panel, c(3L, 10L, 200L)) - expect_equal(dim(pecotmr:::.panelSeed(cut)), c(3L, n_samples)) - expect_equal(.dose(cut), .dose(panel)[c(3L, 10L, 200L), ]) - saved <- tempfile(fileext = ".rds") - saveRDS(cut, saved) - expect_equal(.dose(readRDS(saved)), .dose(cut)) -}) - # ---- Per-chromosome sets --------------------------------------------------- test_that("a per-chromosome VCF, GDS or PLINK1 set stacks into one panel", { @@ -3148,14 +2401,24 @@ test_that("a per-chromosome VCF, GDS or PLINK1 set stacks into one panel", { one21 <- readGenotypes(p21) one22 <- readGenotypes(p22) stacked <- readGenotypes(genoMeta = c("21" = p21, "22" = p22)) - expect_equal(dim(stacked), c(nrow(one21) + nrow(one22), ncol(one21))) - expect_equal(.dose(stacked), rbind(.dose(one21), .dose(one22))) + n21 <- nrow(one21) + expect_equal(dim(stacked), c(n21 + nrow(one22), ncol(one21))) + expect_equal(rownames(stacked), c(rownames(one21), rownames(one22))) + # A VCF is read a record at a time, so the dosages are compared on + # each shard's first, second and last rows, either side of the join. + rows21 <- c(1L, 2L, n21) + rows22 <- c(1L, 2L, nrow(one22)) + dose22 <- .dose(one22[rows22, ]) + expect_equal( + .dose(stacked[c(rows21, n21 + rows22), ]), + rbind(.dose(one21[rows21, ]), dose22) + ) source <- S4Vectors::metadata(stacked)$genotypeSource # A PLINK1 file is recorded by its stem, as a PLINK prefix is. recorded <- str_remove(normalizePath(c(p21, p22)), "\\.bed$") expect_equal( source$chromPaths, - c("21" = recorded[[1L]], "22" = recorded[[2L]]) + c(chr21 = recorded[[1L]], chr22 = recorded[[2L]]) ) # A stacked panel has no single seed to read through. expect_null(pecotmr:::.panelSeed(stacked)) @@ -3164,7 +2427,8 @@ test_that("a per-chromosome VCF, GDS or PLINK1 set stacks into one panel", { genoMeta = c("21" = p21, "22" = p22), chroms = "22" ) - expect_equal(.dose(only22), .dose(one22)) + expect_equal(rownames(only22), rownames(one22)) + expect_equal(.dose(only22[rows22, ]), dose22) } }) diff --git a/tests/testthat/test_h2Annotations.R b/tests/testthat/test_h2Annotations.R index 5fd8199f..53d0606f 100644 --- a/tests/testthat/test_h2Annotations.R +++ b/tests/testthat/test_h2Annotations.R @@ -1,8 +1,4 @@ -# Tests migrated from test_h2ClassesSumstats.R - -# === Tests migrated from test_h2ClassesSumstats.R (h2Annotations) === - -test_that(".annot_detect_format() detects bigwig, bed, ldsc_annot", { +test_that(".annotDetectFormat() detects bigwig, bed, ldsc_annot", { detect <- pecotmr:::.annotDetectFormat expect_equal(detect("path/to/file.bw"), "bigwig") @@ -15,10 +11,10 @@ test_that(".annot_detect_format() detects bigwig, bed, ldsc_annot", { }) # ============================================================================= -# .read_bed_annotation (h2Annotations.R) +# .readBedAnnotation (h2Annotations.R) # ============================================================================= -test_that(".read_bed_annotation returns correct binary overlap vector", { +test_that(".readBedAnnotation returns correct binary overlap vector", { skip_if_not_installed("rtracklayer") bed_content <- paste( @@ -51,7 +47,7 @@ test_that(".read_bed_annotation returns correct binary overlap vector", { }) -test_that(".read_bed_annotation returns all zeros when no overlaps", { +test_that(".readBedAnnotation returns all zeros when no overlaps", { skip_if_not_installed("rtracklayer") bed_content <- "chr1\t100\t200\tregion1" @@ -70,10 +66,10 @@ test_that(".read_bed_annotation returns all zeros when no overlaps", { }) # ============================================================================= -# .read_ldsc_annot (h2Annotations.R) +# .readLdscAnnot (h2Annotations.R) # ============================================================================= -test_that(".read_ldsc_annot reads annotation column and matches SNPs", { +test_that(".readLdscAnnot reads annotation column and matches SNPs", { annot_df <- data.frame( CHR = c(1, 1, 1, 1), BP = c(100, 200, 300, 400), @@ -105,7 +101,7 @@ test_that(".read_ldsc_annot reads annotation column and matches SNPs", { }) -test_that(".read_ldsc_annot returns 0 for unmatched SNP positions", { +test_that(".readLdscAnnot returns 0 for unmatched SNP positions", { annot_df <- data.frame( CHR = c(1, 1), BP = c(100, 200), @@ -135,7 +131,7 @@ test_that(".read_ldsc_annot returns 0 for unmatched SNP positions", { }) -test_that(".read_ldsc_annot errors when annotation column not found", { +test_that(".readLdscAnnot errors when annotation column not found", { annot_df <- data.frame( CHR = c(1), BP = c(100), @@ -166,7 +162,7 @@ test_that(".read_ldsc_annot errors when annotation column not found", { }) -test_that(".read_ldsc_annot handles chr-prefixed CHR column", { +test_that(".readLdscAnnot handles chr-prefixed CHR column", { annot_df <- data.frame( CHR = c("chr1", "chr1"), BP = c(100, 200), @@ -195,10 +191,10 @@ test_that(".read_ldsc_annot handles chr-prefixed CHR column", { }) # ============================================================================= -# readannotations method (h2Annotations.R) +# readAnnotations method (h2Annotations.R) # ============================================================================= -test_that("readannotations errors when paths is not named", { +test_that("readAnnotations errors when path is not named", { snp_gr <- GenomicRanges::GRanges( seqnames = "chr1", ranges = IRanges::IRanges(start = 100, width = 1) @@ -206,12 +202,12 @@ test_that("readannotations errors when paths is not named", { expect_error( readAnnotations(c("/some/file.bed"), snp_gr), - "paths.*must be a named" + "path.*must be a named" ) }) -test_that("readannotations with BED file creates AnnotationMatrix", { +test_that("readAnnotations with BED file creates AnnotationMatrix", { skip_if_not_installed("rtracklayer") bed_content <- "chr1\t100\t500\tregion1" @@ -240,7 +236,7 @@ test_that("readannotations with BED file creates AnnotationMatrix", { }) -test_that("readannotations with LDSC annot file creates AnnotationMatrix", { +test_that("readAnnotations with LDSC annot file creates AnnotationMatrix", { annot_df <- data.frame( CHR = c(1, 1, 1), BP = c(100, 200, 300), @@ -273,7 +269,7 @@ test_that("readannotations with LDSC annot file creates AnnotationMatrix", { }) -test_that("readannotations uses provided annotation_meta", { +test_that("readAnnotations uses the provided annotationMeta", { annot_df <- data.frame( CHR = c(1, 1), BP = c(100, 200), @@ -314,7 +310,7 @@ test_that("readannotations uses provided annotation_meta", { }) -test_that("readannotations with multiple files creates multi-column matrix", { +test_that("readAnnotations with multiple files creates multi-column matrix", { # Two LDSC annot files annot_df1 <- data.frame( CHR = c(1, 1), @@ -429,9 +425,3 @@ test_that(".readLdscAnnot errors when CHR/BP columns are absent", { "must contain CHR and BP columns" ) }) - -# ============================================================================= -# readsumstats edge cases (h2_sumstats.R) -# ============================================================================= - -# ============================================================================= diff --git a/tests/testthat/test_h2EstimationWrappers.R b/tests/testthat/test_h2EstimationWrappers.R index 579243da..a0f481d3 100644 --- a/tests/testthat/test_h2EstimationWrappers.R +++ b/tests/testthat/test_h2EstimationWrappers.R @@ -4,6 +4,42 @@ context("h2_estimate_wrappers") # Helper functions to build test S4 objects # =========================================================================== +# Two baseline annotations (binary and continuous) and one candidate over the +# variants of `ref`. +.h2PanelAnnotations <- function(ref) { + set.seed(11) + p <- length(ref) + mat <- cbind( + coding = rbinom(p, 1, 0.3), + cons = runif(p), + cand = rbinom(p, 1, 0.2) + ) + AnnotationMatrix( + mat, + GenomicRanges::granges(ref, use.mcols = FALSE), + data.frame( + name = colnames(mat), + tier = c("baseline", "baseline", "candidate"), + type = c("binary", "continuous", "binary") + ), + genome = "hg19" + ) +} + +# GWAS z-scores over the fixture's blocks with heritability `h2`: +# z = sqrt(n) R beta + e, e ~ N(0, R), block by block. +.h2PanelZ <- function(ld, n, h2, seed = 3) { + set.seed(seed) + M <- sum(map_int(ld, length)) + list_c(map(ld, function(x) { + R <- ldMatrix(x) + beta <- rnorm(nrow(R), sd = sqrt(h2 / M)) + e <- eigen(R, symmetric = TRUE) + noise <- e$vectors %*% (sqrt(pmax(e$values, 0)) * rnorm(nrow(R))) + as.vector(sqrt(n) * R %*% beta + noise) + })) +} + makeTestEigenRef <- function(nSnps = 20, nBlocks = 2) { snps_per_block <- nSnps / nBlocks blocks_gr <- GenomicRanges::GRanges( @@ -126,72 +162,22 @@ makeTestAnnotations <- function(nSnps = 20) { AnnotationMatrix(annot_mat, snp_ranges, annotation_meta, genome = "hg19") } -makeTestH2Estimate <- function(with_enrichment = TRUE) { - enrich <- if (with_enrichment) { - data.frame( - annotation = c("annot1", "annot2"), - tau = c(1e-7, 2e-7), - tauSe = c(5e-8, 6e-8), - enrichment = c(2.0, 3.0), - enrichmentSe = c(0.5, 0.7), - enrichmentP = c(0.01, 0.001), - propH2 = c(0.3, 0.5), - propSnps = c(0.15, 0.17), - stringsAsFactors = FALSE - ) - } else { - NULL - } - - set.seed(55) - annotationJackknifeCoefs <- if (with_enrichment) { - matrix( - rnorm(20), - nrow = 10, - ncol = 2, - dimnames = list(NULL, c("annot1", "annot2")) - ) - } else { - NULL - } - - new( - "H2Estimate", - estimate = 0.3, - estimateSe = 0.05, - intercept = 1.01, - interceptSe = 0.02, - localBlocks = NULL, - enrichment = enrich, - annotationJackknifeCoefs = annotationJackknifeCoefs, - scoreStats = NULL, - method = "lder", - nSnps = 100L, - traitName = "test" - ) -} - # =========================================================================== -# .validate_method_ref (internal) +# .validateMethodRef (internal) # =========================================================================== -test_that(".validate_method_ref errors when method='lder' but ref is LdScore", { - score_ref <- makeTestScoreRef() - expect_error( - pecotmr:::.validateMethodRef("lder", score_ref), - "requires an LdEigen" - ) -}) - -test_that(".validate_method_ref errors when method='hdl' but ref is LdScore", { +test_that(".validateMethodRef errors when lder or hdl is given an LdScore", { score_ref <- makeTestScoreRef() - expect_error( - pecotmr:::.validateMethodRef("hdl", score_ref), - "requires an LdEigen" - ) + for (method in c("lder", "hdl")) { + expect_error( + pecotmr:::.validateMethodRef(method, score_ref), + "requires an LdEigen", + info = method + ) + } }) -test_that(".validate_method_ref errors when method='gldsc' but ref is LdEigen", { +test_that(".validateMethodRef errors when method='gldsc' but ref is LdEigen", { eigen_ref <- makeTestEigenRef() expect_error( pecotmr:::.validateMethodRef("gldsc", eigen_ref), @@ -199,7 +185,7 @@ test_that(".validate_method_ref errors when method='gldsc' but ref is LdEigen", ) }) -test_that(".validate_method_ref returns TRUE for valid combinations", { +test_that(".validateMethodRef returns TRUE for valid combinations", { eigen_ref <- makeTestEigenRef() score_ref <- makeTestScoreRef() @@ -212,18 +198,13 @@ test_that(".validate_method_ref returns TRUE for valid combinations", { # computeLdScores for LdEigen # =========================================================================== -test_that("computeLdScores LdEigen returns matrix with base_l2 column", { +test_that("computeLdScores LdEigen returns a non-negative base_l2 column", { eigen_ref <- makeTestEigenRef() result <- computeLdScores(eigen_ref) expect_true(is.matrix(result)) expect_equal(ncol(result), 1) expect_equal(colnames(result), "base_l2") expect_equal(nrow(result), length(eigen_ref)) -}) - -test_that("computeLdScores LdEigen base LD scores are non-negative", { - eigen_ref <- makeTestEigenRef() - result <- computeLdScores(eigen_ref) expect_true(all(result[, "base_l2"] >= 0)) }) @@ -233,15 +214,8 @@ test_that("computeLdScores LdEigen with annotations returns base + annotation co result <- computeLdScores(eigen_ref, annotations = annot) expect_true(is.matrix(result)) # base_l2 + 2 annotation columns - expect_equal(ncol(result), 3) expect_equal(nrow(result), length(eigen_ref)) -}) - -test_that("computeLdScores LdEigen annotation column names match", { - eigen_ref <- makeTestEigenRef() - annot <- makeTestAnnotations() - result <- computeLdScores(eigen_ref, annotations = annot) expect_equal(colnames(result), c("base_l2", "annot_A", "annot_B")) }) @@ -419,84 +393,6 @@ test_that("computeLdScores LdScore with annotations but no ld_matrix_list errors ) }) -# =========================================================================== -# H2Estimate accessors -# =========================================================================== - -test_that("getlocal returns the local slot", { - local_df <- data.frame( - blockId = 1:3, - h2Local = c(0.1, 0.15, 0.05), - h2LocalSe = c(0.02, 0.03, 0.01), - stringsAsFactors = FALSE - ) - h2_obj <- new( - "H2Estimate", - estimate = 0.3, - estimateSe = 0.05, - intercept = 1.0, - interceptSe = 0.01, - localBlocks = local_df, - enrichment = NULL, - annotationJackknifeCoefs = NULL, - scoreStats = NULL, - method = "lder", - nSnps = 100L, - traitName = "test" - ) - expect_identical(localH2Blocks(h2_obj), local_df) -}) - -test_that("getenrichment returns the enrichment slot", { - h2_obj <- makeTestH2Estimate(with_enrichment = TRUE) - result <- stratifiedHeritabilityEnrichment(h2_obj) - expect_true(is.data.frame(result)) - expect_equal(result$annotation, c("annot1", "annot2")) -}) - -test_that("getscorestats returns the scoreStats slot", { - scoreStats <- list( - z = c(1.5, -0.8), - R = diag(2), - annotationNames = c("a1", "a2") - ) - h2_obj <- new( - "H2Estimate", - estimate = 0.3, - estimateSe = 0.05, - intercept = 1.0, - interceptSe = 0.01, - localBlocks = NULL, - enrichment = NULL, - annotationJackknifeCoefs = NULL, - scoreStats = scoreStats, - method = "lder", - nSnps = 100L, - traitName = "test" - ) - expect_identical(scoreStats(h2_obj), scoreStats) -}) - -test_that("accessors return NULL when slots are NULL", { - h2_obj <- new( - "H2Estimate", - estimate = 0.3, - estimateSe = 0.05, - intercept = 1.0, - interceptSe = 0.01, - localBlocks = NULL, - enrichment = NULL, - annotationJackknifeCoefs = NULL, - scoreStats = NULL, - method = "lder", - nSnps = 100L, - traitName = "test" - ) - expect_null(localH2Blocks(h2_obj)) - expect_null(stratifiedHeritabilityEnrichment(h2_obj)) - expect_null(scoreStats(h2_obj)) -}) - # =========================================================================== # h2EstimateToSldscTrait # =========================================================================== @@ -617,22 +513,29 @@ makeTestSumstatsForRef <- function( } # =========================================================================== -# estimateh2 end-to-end tests +# estimateH2 end-to-end tests # =========================================================================== -test_that("estimateh2 with method='lder' returns H2Estimate with correct slots", { +test_that("estimateH2 returns an H2Estimate for lder, gldsc and hdl", { eigen_ref <- makeTestEigenRef() - ss <- makeTestSumstatsForRef(eigen_ref) - result <- estimateH2(ss, eigen_ref, method = "lder") - - expect_s4_class(result, "H2Estimate") - expect_true(is.numeric(heritabilityEstimate(result))) - expect_true(is.numeric(heritabilityEstimateSe(result))) - expect_true(is.numeric(heritabilityIntercept(result))) - expect_true(is.numeric(heritabilityInterceptSe(result))) - expect_equal(methodNames(result), "lder") - expect_equal(nSnps(result), nSnps(ss)) - expect_equal(traitNames(result), "test") + refs <- list( + lder = eigen_ref, + gldsc = makeTestScoreRef(with_ld_matrices = TRUE), + hdl = eigen_ref + ) + for (method in names(refs)) { + ss <- makeTestSumstatsForRef(refs[[method]]) + result <- estimateH2(ss, refs[[method]], method = method) + + expect_true(is(result, "H2Estimate"), info = method) + expect_true(is.numeric(heritabilityEstimate(result)), info = method) + expect_true(is.numeric(heritabilityEstimateSe(result)), info = method) + expect_true(is.numeric(heritabilityIntercept(result)), info = method) + expect_true(is.numeric(heritabilityInterceptSe(result)), info = method) + expect_equal(methodNames(result), method, info = method) + expect_equal(nSnps(result), nSnps(ss), info = method) + expect_equal(traitNames(result), "test", info = method) + } }) # =========================================================================== @@ -747,7 +650,10 @@ test_that("unstratified S-LDSC runs without the per-block LD matrices", { # LdScore is enough, which is why it is the cheap option. noMat <- makeTestScoreRef(with_ld_matrices = FALSE) ss <- makeTestSumstatsForRef(noMat) - expect_error(estimateH2(ss, noMat, method = "gldsc"), "each LD block's LD") + expect_error( + estimateH2(ss, noMat, method = "gldsc"), + "g-LDSC needs each LD block's LD" + ) res <- estimateH2(ss, noMat, method = "sldsc") expect_s4_class(res, "H2Estimate") expect_equal(methodNames(res), "sldsc") @@ -955,16 +861,17 @@ test_that("buildLdScore(keepLdMatrices = FALSE) is rejected by g-LDSC", { test_that("estimateH2 accepts a chr-prefix difference between the two sides", { ref <- makeTestEigenRef() ss <- makeTestSumstatsForRef(ref) - # makeTestSumstatsForRef already strips the prefix ("1" vs "chr1"), - # so this pins that the check normalizes rather than rejects it. + # makeTestSumstatsForRef builds the entry on bare names ("1" vs the + # reference's "chr1"); the constructor reads them in UCSC style, so the + # two sides meet exactly. expect_equal( as.character(GenomicRanges::seqnames(sumStats(ss)))[[1]], - "1" + "chr1" ) expect_s4_class(estimateH2(ss, ref, method = "lder"), "H2Estimate") }) -test_that("estimateh2 with var_y correction runs without error", { +test_that("estimateH2 with a varY correction runs without error", { eigen_ref <- makeTestEigenRef() ss <- makeTestSumstatsForRef( eigen_ref, @@ -978,36 +885,6 @@ test_that("estimateh2 with var_y correction runs without error", { expect_true(is.numeric(heritabilityEstimate(result))) }) -test_that("estimateh2 with method='gldsc' returns H2Estimate", { - score_ref <- makeTestScoreRef(with_ld_matrices = TRUE) - ss <- makeTestSumstatsForRef(score_ref) - result <- estimateH2(ss, score_ref, method = "gldsc") - - expect_s4_class(result, "H2Estimate") - expect_true(is.numeric(heritabilityEstimate(result))) - expect_true(is.numeric(heritabilityEstimateSe(result))) - expect_equal(methodNames(result), "gldsc") - expect_equal(nSnps(result), nSnps(ss)) - expect_equal(traitNames(result), "test") -}) - -test_that("estimateh2 with method='hdl' returns H2Estimate", { - eigen_ref <- makeTestEigenRef() - ss <- makeTestSumstatsForRef(eigen_ref) - # HDL likelihood optimization on tiny test data produces NaN warnings - # from log() on negative sigma2 during search; these are harmless. - suppressWarnings( - result <- estimateH2(ss, eigen_ref, method = "hdl") - ) - - expect_s4_class(result, "H2Estimate") - expect_true(is.numeric(heritabilityEstimate(result))) - expect_true(is.numeric(heritabilityEstimateSe(result))) - expect_equal(methodNames(result), "hdl") - expect_equal(nSnps(result), nSnps(ss)) - expect_equal(traitNames(result), "test") -}) - # =========================================================================== # computeLdScores for LdScore WITH annotations # =========================================================================== @@ -1037,11 +914,6 @@ test_that(".jackknifeSeFromLoo is zero when every LOO estimate is equal", { expect_equal(pecotmr:::.jackknifeSeFromLoo(rep(2, 5)), 0) }) -test_that(".jackknifeSeFromLoo is positive when the LOO estimates vary", { - set.seed(42) - expect_gt(pecotmr:::.jackknifeSeFromLoo(rnorm(10, mean = 5, sd = 0.5)), 0) -}) - test_that(".jackknifeSeFromLoo equals the pseudo-value jackknife", { # The delete-one form sqrt((n - 1) / n * sum((loo - mean)^2)) and the # pseudo-value form sqrt(var(n * full - (n - 1) * loo) / n) are the same @@ -1061,7 +933,7 @@ test_that(".jackknifeSeFromLoo equals the pseudo-value jackknife", { # computeBaselineEnrichment # ============================================================================= -test_that("computeBaselineEnrichment returns correct structure", { +test_that("computeBaselineEnrichment computes enrichment and propSnps", { M <- 100 baseline_mat <- matrix(0, nrow = M, ncol = 2) baseline_mat[1:50, 1] <- 1 @@ -1091,45 +963,7 @@ test_that("computeBaselineEnrichment returns correct structure", { ) expect_named(res, expected_cols) expect_equal(nrow(res), 2) -}) - -test_that("computeBaselineEnrichment computes enrichment = tau * M / h2", { - M <- 100 - baseline_mat <- matrix(0, nrow = M, ncol = 2) - baseline_mat[1:50, 1] <- 1 - baseline_mat[, 2] <- 1 - tau <- c(0.01, 0.005) - tauSe <- c(0.002, 0.001) - h2 <- 0.5 - annot_names <- c("annot1", "base") - res <- pecotmr:::computeBaselineEnrichment( - tau, - tauSe, - NULL, - baseline_mat, - annot_names, - h2 - ) expect_equal(res$enrichment, tau * M / h2) -}) - -test_that("computeBaselineEnrichment computes propSnps correctly", { - M <- 100 - baseline_mat <- matrix(0, nrow = M, ncol = 2) - baseline_mat[1:50, 1] <- 1 - baseline_mat[, 2] <- 1 - tau <- c(0.01, 0.005) - tauSe <- c(0.002, 0.001) - h2 <- 0.5 - annot_names <- c("annot1", "base") - res <- pecotmr:::computeBaselineEnrichment( - tau, - tauSe, - NULL, - baseline_mat, - annot_names, - h2 - ) expect_equal(res$propSnps, c(0.5, 1.0)) }) @@ -1161,10 +995,10 @@ test_that("computeBaselineEnrichment uses jackknife blocks when provided", { }) # ============================================================================= -# standardize_tau_star +# standardizeTauStar # ============================================================================= -test_that("standardize_tau_star computes tauStar = tau * sd_annot * M_ref / h2g", { +test_that("standardizeTauStar computes tauStar = tau * sdAnnot * MRef / h2g", { tau <- c(0.01, 0.02) sd_annot <- c(0.5, 0.3) M_ref <- 1000L @@ -1183,11 +1017,13 @@ test_that("standardize_tau_star computes tauStar = tau * sd_annot * M_ref / h2g" h2g ) expected <- tau * sd_annot * M_ref / h2g + expect_true(is.list(res)) + expect_named(res, c("tauStar", "tauStarSe")) expect_equal(res$tauStar, expected) expect_length(res$tauStarSe, 2) }) -test_that("standardize_tau_star errors when h2g == 0", { +test_that("standardizeTauStar errors when h2g == 0", { expect_error( pecotmr:::standardizeTauStar( c(0.01), @@ -1200,7 +1036,7 @@ test_that("standardize_tau_star errors when h2g == 0", { ) }) -test_that("standardize_tau_star errors when tau and sd_annot differ in length", { +test_that("standardizeTauStar errors when tau and sdAnnot differ in length", { expect_error( pecotmr:::standardizeTauStar( c(0.01, 0.02), @@ -1213,34 +1049,11 @@ test_that("standardize_tau_star errors when tau and sd_annot differ in length", ) }) -test_that("standardize_tau_star returns list with tauStar and tauStarSe", { - tau <- c(0.01) - sd_annot <- c(0.5) - M_ref <- 1000L - h2g <- 0.4 - annotationJackknifeCoefs <- matrix( - rnorm(5, mean = 0.01, sd = 0.001), - nrow = 5, - ncol = 1 - ) - res <- pecotmr:::standardizeTauStar( - tau, - annotationJackknifeCoefs, - sd_annot, - M_ref, - h2g - ) - expect_true(is.list(res)) - expect_named(res, c("tauStar", "tauStarSe")) - expect_length(res$tauStar, 1) - expect_length(res$tauStarSe, 1) -}) - # ============================================================================= -# meta_random_effects +# .rmaMeta # ============================================================================= -test_that("meta_random_effects returns all NA with k=0", { +test_that(".rmaMeta returns all NA with k=0", { res <- pecotmr:::.rmaMeta(numeric(0), numeric(0)) expect_true(is.na(res$mean)) expect_true(is.na(res$se)) @@ -1249,14 +1062,14 @@ test_that("meta_random_effects returns all NA with k=0", { expect_true(is.na(res$Q)) }) -test_that("meta_random_effects with k=1 returns input values", { +test_that(".rmaMeta with k=1 returns input values", { res <- pecotmr:::.rmaMeta(5.0, 1.0) expect_equal(res$mean, 5.0) expect_equal(res$se, 1.0) expect_equal(res$tau2, 0) }) -test_that("meta_random_effects with identical means gives tau2=0", { +test_that(".rmaMeta with identical means gives tau2=0", { means <- rep(3.0, 5) ses <- rep(1.0, 5) res <- pecotmr:::.rmaMeta(means, ses) @@ -1264,20 +1077,7 @@ test_that("meta_random_effects with identical means gives tau2=0", { expect_equal(res$mean, 3.0) }) -test_that("meta_random_effects returns correct structure", { - set.seed(42) - means <- rnorm(5, mean = 2, sd = 0.5) - ses <- rep(0.5, 5) - res <- pecotmr:::.rmaMeta(means, ses) - expect_true(is.list(res)) - expect_named(res, c("mean", "se", "tau2", "I2", "Q")) - expect_true(res$se > 0) - expect_true(res$I2 >= 0 && res$I2 <= 1) - expect_true(res$Q >= 0) - expect_true(res$tau2 >= 0) -}) - -test_that("meta_random_effects errors with non-positive ses", { +test_that(".rmaMeta errors with non-positive ses", { expect_error( pecotmr:::.rmaMeta(c(1, 2), c(1, 0)), "all ses must be positive and finite" @@ -1288,11 +1088,16 @@ test_that("meta_random_effects errors with non-positive ses", { ) }) -test_that("meta_random_effects known DerSimonian-Laird example", { +test_that(".rmaMeta defaults to DL and matches a known example", { # Three studies with known values means <- c(0.5, 0.8, 0.3) ses <- c(0.2, 0.3, 0.15) res <- pecotmr:::.rmaMeta(means, ses) + expect_equal(res, pecotmr:::.rmaMeta(means, ses, method = "DL")) + expect_true(is.list(res)) + expect_named(res, c("mean", "se", "tau2", "I2", "Q")) + # metafor reports I2 as a percentage; .rmaMeta rescales it to [0, 1]. + expect_true(res$I2 >= 0 && res$I2 <= 1) # Fixed-effect weights w_fe <- 1 / ses^2 @@ -1310,6 +1115,29 @@ test_that("meta_random_effects known DerSimonian-Laird example", { expect_equal(res$se, se_re) }) +test_that(".rmaMeta runs REML through metafor, differing from DL", { + set.seed(3) + m <- rnorm(8, sd = 1.5) + s <- abs(rnorm(8)) + 0.3 + reml <- pecotmr:::.rmaMeta(m, s, method = "REML") + expect_true(all(c("mean", "se", "tau2", "I2", "Q") %in% names(reml))) + expect_true(reml$I2 >= 0 && reml$I2 <= 1) + # REML tau2 generally differs from DL tau2 on heterogeneous data + expect_false(isTRUE(all.equal(reml$tau2, pecotmr:::.rmaMeta(m, s)$tau2))) +}) + +test_that(".rmaMeta falls back to DL when REML does not converge", { + # metafor's iterative estimators can fail to converge on small / degenerate + # inputs; .rmaMeta must still return a finite fit (via the DL fallback). + set.seed(1) + for (i in seq_len(25)) { + m <- rnorm(sample(3:8, 1L)) + s <- abs(rnorm(length(m))) + 0.1 + r <- suppressWarnings(pecotmr:::.rmaMeta(m, s, method = "REML")) + expect_true(is.finite(r$mean) && is.finite(r$se)) + } +}) + # ============================================================================= # snpsPerBlock # ============================================================================= @@ -1415,10 +1243,8 @@ test_that("checkGenomeBuild works with AnnotationMatrix", { expect_true(pecotmr:::checkGenomeBuild(am, ld_blocks)) }) -# Tests for heritability estimation methods: -# lderUnivariate (h2Lder.R) -# gldscUnivariate (h2Gldsc.R) -# hdlUnivariate (h2Hdl.R) +# Tests for the heritability estimators lderUnivariate, gldscUnivariate and +# hdlUnivariate. set.seed(42) @@ -1527,441 +1353,6 @@ simulateH2Data <- function( ) } -# Annotation helper: all-ones baseline so the eigenvalue-score column is -# simply the eigenvalue itself (avoids singularity with few blocks), plus -# one candidate annotation for score-statistic testing. -makeTestAnnotations <- function(n_snps) { - set.seed(99) - snp_gr <- GenomicRanges::GRanges( - seqnames = rep("chr1", n_snps), - ranges = IRanges::IRanges( - start = seq(50, by = 100, length.out = n_snps), - width = 1L - ) - ) - # All-ones baseline (behaves like the unstratified intercept) - base_col <- rep(1, n_snps) - # Binary candidate: random 30% - cand_col <- rbinom(n_snps, 1, 0.3) - mat <- cbind(base_col, cand_col) - meta <- data.frame( - name = c("baseline1", "candidate1"), - tier = c("baseline", "candidate"), - type = c("binary", "binary"), - stringsAsFactors = FALSE - ) - AnnotationMatrix(mat, snp_gr, meta, genome = "hg19") -} - -# Pre-compute shared test data -dat <- simulateH2Data() - -# ============================================================================= -# LDER tests (h2Lder.R) -# ============================================================================= - -test_that("lderUnivariate returns correct structure", { - res <- pecotmr:::lderUnivariate(dat$z, dat$n, dat$eigen_ref) - expect_type(res, "list") - expect_true(all( - c( - "h2", - "h2Se", - "intercept", - "interceptSe", - "local", - "enrichment", - "annotationJackknifeCoefs", - "scoreStats" - ) %in% - names(res) - )) -}) - -test_that("lderUnivariate h2 is finite and in reasonable range", { - res <- pecotmr:::lderUnivariate(dat$z, dat$n, dat$eigen_ref) - expect_true(is.finite(res$h2)) - expect_true(res$h2 > -0.5 && res$h2 < 1.0) -}) - -test_that("lderUnivariate h2Se is positive", { - res <- pecotmr:::lderUnivariate(dat$z, dat$n, dat$eigen_ref) - expect_true(is.finite(res$h2Se)) - expect_true(res$h2Se > 0) -}) - -test_that("lderUnivariate intercept is near zero for well-calibrated data", { - # In LDER the intercept parameter a represents confounding deviation: - # the model is E[chi2Rot - 1] = n * h2/M * d + n * a - # so a ~ 0 when there is no confounding. - res <- pecotmr:::lderUnivariate(dat$z, dat$n, dat$eigen_ref) - expect_true(is.finite(res$intercept)) - expect_true(abs(res$intercept) < 0.01) -}) - -test_that("lderUnivariate with local = TRUE returns local data.frame", { - res <- pecotmr:::lderUnivariate(dat$z, dat$n, dat$eigen_ref, local = TRUE) - expect_true(is.data.frame(res$local)) - expect_true("h2Local" %in% colnames(res$local)) -}) - -test_that("lderUnivariate without annotations returns NULL enrichment", { - res <- pecotmr:::lderUnivariate(dat$z, dat$n, dat$eigen_ref) - expect_null(res$enrichment) -}) - -# ============================================================================= -# gLDSC tests (h2Gldsc.R) -# ============================================================================= - -test_that("gldscUnivariate returns correct structure", { - res <- pecotmr:::gldscUnivariate(dat$z, dat$n, dat$ld_score_ref) - expect_type(res, "list") - expect_true(all( - c( - "h2", - "h2Se", - "intercept", - "interceptSe", - "local", - "enrichment", - "annotationJackknifeCoefs", - "scoreStats" - ) %in% - names(res) - )) -}) - -test_that("gldscUnivariate h2 is finite", { - res <- pecotmr:::gldscUnivariate(dat$z, dat$n, dat$ld_score_ref) - expect_true(is.finite(res$h2)) -}) - -test_that("gldscUnivariate h2Se is positive", { - res <- pecotmr:::gldscUnivariate(dat$z, dat$n, dat$ld_score_ref) - expect_true(is.finite(res$h2Se)) - expect_true(res$h2Se > 0) -}) - -test_that("gldscUnivariate with local = TRUE returns per-block local h2", { - res <- pecotmr:::gldscUnivariate( - dat$z, - dat$n, - dat$ld_score_ref, - local = TRUE - ) - expect_true(is.data.frame(res$local)) - expect_true(all( - c("blockId", "h2Local", "h2LocalSe") %in% colnames(res$local) - )) -}) - -# ============================================================================= -# HDL tests (h2Hdl.R) -# ============================================================================= - -test_that("hdlUnivariate returns correct structure", { - res <- pecotmr:::hdlUnivariate(dat$z, dat$n, dat$eigen_ref) - expect_type(res, "list") - expect_true(all( - c( - "h2", - "h2Se", - "intercept", - "interceptSe", - "local", - "enrichment", - "annotationJackknifeCoefs", - "scoreStats" - ) %in% - names(res) - )) -}) - -test_that("hdlUnivariate h2 is finite", { - res <- pecotmr:::hdlUnivariate(dat$z, dat$n, dat$eigen_ref) - expect_true(is.finite(res$h2)) -}) - -test_that("hdlUnivariate h2Se is positive", { - res <- pecotmr:::hdlUnivariate(dat$z, dat$n, dat$eigen_ref) - expect_true(is.finite(res$h2Se)) - expect_true(res$h2Se > 0) -}) - -test_that("hdlUnivariate with local = TRUE returns local data.frame", { - res <- pecotmr:::hdlUnivariate(dat$z, dat$n, dat$eigen_ref, local = TRUE) - expect_true(is.data.frame(res$local)) - expect_true("h2Local" %in% colnames(res$local)) -}) - -# ============================================================================= -# Annotation tests (using LDER with more blocks for numerical stability) -# ============================================================================= - -# Use 5 blocks and 500 SNPs for annotation tests to avoid singular matrices -dat_annot <- simulateH2Data(n_snps = 500, nBlocks = 5) - -test_that("lderUnivariate with annotations returns enrichment data.frame", { - annot <- makeTestAnnotations(dat_annot$n_snps) - res <- pecotmr:::lderUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot - ) - expect_true(is.data.frame(res$enrichment)) -}) - -test_that("lder enrichment has correct columns", { - annot <- makeTestAnnotations(dat_annot$n_snps) - res <- pecotmr:::lderUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot - ) - expected_cols <- c( - "annotation", - "tau", - "tauSe", - "enrichment", - "enrichmentSe", - "enrichmentP", - "propH2", - "propSnps" - ) - expect_true(all(expected_cols %in% colnames(res$enrichment))) -}) - -test_that("lder with annotations returns annotationJackknifeCoefs matrix", { - annot <- makeTestAnnotations(dat_annot$n_snps) - res <- pecotmr:::lderUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot - ) - expect_true(is.matrix(res$annotationJackknifeCoefs)) - # nBlocks rows (5 blocks in the annotation test data) - expect_equal(nrow(res$annotationJackknifeCoefs), 5L) -}) - -test_that("lder with annotations returns scoreStats list", { - annot <- makeTestAnnotations(dat_annot$n_snps) - res <- pecotmr:::lderUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot - ) - expect_type(res$scoreStats, "list") - expect_true(all(c("z", "R") %in% names(res$scoreStats))) -}) - -# ============================================================================= -# HDL annotation tests (h2Hdl.R stratified paths) -# ============================================================================= - -test_that("hdlUnivariate with annotations returns enrichment data.frame with correct columns", { - set.seed(123) - annot <- makeTestAnnotations(dat_annot$n_snps) - res <- pecotmr:::hdlUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot - ) - expect_true(is.data.frame(res$enrichment)) - expected_cols <- c( - "annotation", - "tau", - "tauSe", - "enrichment", - "enrichmentSe", - "enrichmentP", - "propH2", - "propSnps" - ) - expect_true(all(expected_cols %in% colnames(res$enrichment))) - # Should have one row per baseline annotation - expect_equal(nrow(res$enrichment), 1L) # 1 baseline annotation - # Values should be finite - expect_true(all(is.finite(res$enrichment$tau))) - expect_true(all(is.finite(res$enrichment$enrichment))) -}) - -test_that("hdlUnivariate with annotations returns annotationJackknifeCoefs matrix", { - set.seed(124) - annot <- makeTestAnnotations(dat_annot$n_snps) - res <- pecotmr:::hdlUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot - ) - expect_true(is.matrix(res$annotationJackknifeCoefs)) - # nBlocks rows (5 blocks in dat_annot) - expect_equal(nrow(res$annotationJackknifeCoefs), 5L) - # Number of columns matches baseline annotation count - expect_equal(ncol(res$annotationJackknifeCoefs), 1L) - # Values should be finite - expect_true(all(is.finite(res$annotationJackknifeCoefs))) -}) - -test_that("hdlUnivariate with annotations and local = TRUE returns local data.frame", { - set.seed(125) - annot <- makeTestAnnotations(dat_annot$n_snps) - res <- pecotmr:::hdlUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot, - local = TRUE - ) - expect_true(is.data.frame(res$local)) - expect_true("h2Local" %in% colnames(res$local)) - expect_true("h2LocalSe" %in% colnames(res$local)) - expect_true("blockId" %in% colnames(res$local)) - # Should have one row per block - expect_equal(nrow(res$local), 5L) -}) - -test_that("hdlUnivariate with annotations returns scoreStats with z and R", { - set.seed(126) - annot <- makeTestAnnotations(dat_annot$n_snps) - res <- pecotmr:::hdlUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot - ) - expect_type(res$scoreStats, "list") - expect_true(all(c("z", "R") %in% names(res$scoreStats))) - # z should have length = number of candidate annotations (1) - expect_length(res$scoreStats$z, 1L) - expect_true(is.finite(res$scoreStats$z[1])) - # R should be a matrix - expect_true(is.matrix(res$scoreStats$R)) - expect_equal(dim(res$scoreStats$R), c(1L, 1L)) - # annotationNames should be present - expect_true("annotationNames" %in% names(res$scoreStats)) - expect_equal(res$scoreStats$annotationNames, "candidate1") -}) - -# ============================================================================= -# gLDSC annotation tests (h2Gldsc.R stratified paths) -# ============================================================================= - -# gLDSC annotation helper: use a spatially varying baseline instead of -# all-ones, because computeldscores with an all-ones baseline produces -# LD scores identical to the base L2 column, making the design matrix -# singular. A half-on/half-off baseline avoids collinearity. -makeGldscAnnotations <- function(n_snps) { - set.seed(77) - snp_gr <- GenomicRanges::GRanges( - seqnames = rep("chr1", n_snps), - ranges = IRanges::IRanges( - start = seq(50, by = 100, length.out = n_snps), - width = 1L - ) - ) - # Spatially structured baseline: first half = 1, second half = 0 - base_col <- as.numeric(seq_len(n_snps) <= n_snps / 2) - # Binary candidate: random 30% - cand_col <- rbinom(n_snps, 1, 0.3) - mat <- cbind(base_col, cand_col) - meta <- data.frame( - name = c("baseline1", "candidate1"), - tier = c("baseline", "candidate"), - type = c("binary", "binary"), - stringsAsFactors = FALSE - ) - AnnotationMatrix(mat, snp_gr, meta, genome = "hg19") -} - -test_that("gldscUnivariate with annotations returns enrichment data.frame", { - set.seed(200) - annot <- makeGldscAnnotations(dat_annot$n_snps) - res <- pecotmr:::gldscUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$ld_score_ref, - annotations = annot - ) - expect_true(is.data.frame(res$enrichment)) - expected_cols <- c( - "annotation", - "tau", - "tauSe", - "enrichment", - "enrichmentSe", - "enrichmentP", - "propH2", - "propSnps" - ) - expect_true(all(expected_cols %in% colnames(res$enrichment))) - # Should have one row per baseline annotation - expect_equal(nrow(res$enrichment), 1L) - # Values should be finite - expect_true(all(is.finite(res$enrichment$tau))) - expect_true(all(is.finite(res$enrichment$enrichment))) -}) - -test_that("gldscUnivariate with annotations returns annotationJackknifeCoefs matrix", { - set.seed(201) - annot <- makeGldscAnnotations(dat_annot$n_snps) - res <- pecotmr:::gldscUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$ld_score_ref, - annotations = annot - ) - expect_true(is.matrix(res$annotationJackknifeCoefs)) - # gldsc jackknife uses 200 blocks by default; with 500 SNPs the actual - # number of unique blocks equals ceil(500/ceil(500/200)) = 200 - expect_true(nrow(res$annotationJackknifeCoefs) > 0) - # Number of columns matches baseline annotation count - expect_equal(ncol(res$annotationJackknifeCoefs), 1L) - # Values should be finite (allow some NAs from edge blocks) - expect_true(any(is.finite(res$annotationJackknifeCoefs))) -}) - -test_that("gldscUnivariate with annotations returns scoreStats", { - set.seed(202) - annot <- makeGldscAnnotations(dat_annot$n_snps) - res <- pecotmr:::gldscUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$ld_score_ref, - annotations = annot - ) - expect_type(res$scoreStats, "list") - expect_true(all(c("z", "R") %in% names(res$scoreStats))) - # z should have length = number of candidate annotations (1) - expect_length(res$scoreStats$z, 1L) - expect_true(is.finite(res$scoreStats$z[1])) - # R should be a matrix - expect_true(is.matrix(res$scoreStats$R)) - expect_equal(dim(res$scoreStats$R), c(1L, 1L)) - # annotationNames should be present - expect_true("annotationNames" %in% names(res$scoreStats)) - expect_equal(res$scoreStats$annotationNames, "candidate1") -}) - -# =========================================================================== -# Coverage-gap tests (appended) -# -# Targets the specific uncovered branches in R/h2EstimationWrappers.R: -# checkGenomeBuild (unknown type), .rmaMeta (length mismatch), .fglsSolve -# (diagonal path), .gldscLocal (fine-grained blocks), .hdlLocal (p<3 and -# tau=NULL), .lderLocalH2 (small block + baseline path), .hdlSeFisher- -# Stratified / .hdlJackknifeTau (lambda>0 + singular fallback), the -# multi-candidate (cor) and no-candidate (NULL) paths of the stratified -# score-statistic helpers, h2EstimateToSldscTrait (unnamed -# annotationJackknifeCoefs), and the multi-study estimateH2 dispatch error. -# =========================================================================== - # Flexible annotation builder: one baseline column (all-ones or spatial # half-on/half-off) plus `nCand` random binary candidate columns. makeCoverageAnnot <- function( @@ -2013,130 +1404,208 @@ makeCoverageAnnot <- function( AnnotationMatrix(mat, snp_gr, meta, genome = "hg19") } -# --------------------------------------------------------------------------- -# checkGenomeBuild — unknown object type branch -# --------------------------------------------------------------------------- +# The three estimators, each with the reference it reads and the baseline +# its annotations take. An all-ones baseline makes the LDER and HDL +# eigenvalue-score column the eigenvalue itself; for g-LDSC it would repeat +# the base LD score column and leave the design singular, so g-LDSC takes a +# half-on/half-off baseline instead. +.h2Runs <- list( + lder = list( + fn = pecotmr:::lderUnivariate, + ref = "eigen_ref", + baseline = "ones" + ), + gldsc = list( + fn = pecotmr:::gldscUnivariate, + ref = "ld_score_ref", + baseline = "spatial" + ), + hdl = list( + fn = pecotmr:::hdlUnivariate, + ref = "eigen_ref", + baseline = "ones" + ) +) + +# Run `method` on the simulated data `d`, passing `...` to the estimator. +.h2Run <- function(method, d, ...) { + run <- .h2Runs[[method]] + run$fn(d$z, d$n, d[[run$ref]], ...) +} -test_that("checkGenomeBuild errors on an unrecognized object type", { - expect_error( - pecotmr:::checkGenomeBuild(list(genome = "hg19")), - "Unknown object type" +# Annotations over `d`'s variants for `method`, with `nCand` candidates. +.h2RunAnnot <- function(method, d, nCand) { + makeCoverageAnnot( + d$n_snps, + baseline = .h2Runs[[method]]$baseline, + nCand = nCand ) -}) +} -# --------------------------------------------------------------------------- -# .rmaMeta — length-mismatch error -# --------------------------------------------------------------------------- +# Pre-compute shared test data +dat <- simulateH2Data() +# Five blocks and 500 SNPs for the annotation tests, so that the stratified +# designs are not singular. +dat_annot <- simulateH2Data(n_snps = 500, nBlocks = 5) -test_that(".rmaMeta errors when means and ses differ in length", { - expect_error( - pecotmr:::.rmaMeta(c(1, 2), c(1, 2, 3)), - "must have the same length" - ) +# ============================================================================= +# Unstratified estimates +# ============================================================================= + +test_that("each univariate estimator returns a finite h2 and a positive SE", { + fields <- c( + "h2", + "h2Se", + "intercept", + "interceptSe", + "local", + "enrichment", + "annotationJackknifeCoefs", + "scoreStats" + ) + for (method in names(.h2Runs)) { + res <- .h2Run(method, dat) + expect_true(is.list(res), info = method) + expect_true(all(fields %in% names(res)), info = method) + expect_true(is.finite(res$h2), info = method) + expect_true(res$h2 > -0.5 && res$h2 < 1.0, info = method) + expect_true(is.finite(res$h2Se), info = method) + expect_true(res$h2Se > 0, info = method) + # Without annotations there is no enrichment to report. + expect_null(res$enrichment, info = method) + } }) -test_that("lderUnivariate with annotations and local = TRUE returns local h2", { - annot <- makeCoverageAnnot(dat_annot$n_snps, baseline = "ones", nCand = 1L) - res <- pecotmr:::lderUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot, - local = TRUE - ) - expect_true(is.data.frame(res$local)) - expect_true("h2Local" %in% colnames(res$local)) - expect_equal(nrow(res$local), 5L) +test_that("lderUnivariate intercept is near zero for well-calibrated data", { + # In LDER the intercept parameter a represents confounding deviation: + # the model is E[chi2Rot - 1] = n * h2/M * d + n * a + # so a ~ 0 when there is no confounding. + res <- pecotmr:::lderUnivariate(dat$z, dat$n, dat$eigen_ref) + expect_true(is.finite(res$intercept)) + expect_true(abs(res$intercept) < 0.01) }) +test_that("each univariate estimator with local = TRUE returns per-block h2", { + for (method in names(.h2Runs)) { + res <- .h2Run(method, dat, local = TRUE) + expect_true(is.data.frame(res$local), info = method) + expect_true( + all(c("blockId", "h2Local", "h2LocalSe") %in% colnames(res$local)), + info = method + ) + } +}) -# --------------------------------------------------------------------------- -# Stratified score helpers — multiple-candidate (cor) branch -# --------------------------------------------------------------------------- +# ============================================================================= +# Stratified estimates +# ============================================================================= -test_that("lderUnivariate with 2 candidates returns a 2x2 score correlation", { - annot <- makeCoverageAnnot(dat_annot$n_snps, baseline = "ones", nCand = 2L) - res <- pecotmr:::lderUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot +test_that("each univariate estimator reports enrichment and score statistics", { + expected_cols <- c( + "annotation", + "tau", + "tauSe", + "enrichment", + "enrichmentSe", + "enrichmentP", + "propH2", + "propSnps" ) - expect_length(res$scoreStats$z, 2L) - expect_equal(dim(res$scoreStats$R), c(2L, 2L)) + for (method in names(.h2Runs)) { + annot <- .h2RunAnnot(method, dat_annot, 1L) + res <- .h2Run(method, dat_annot, annotations = annot) + # One enrichment row per baseline annotation + expect_true(is.data.frame(res$enrichment), info = method) + expect_true( + all(expected_cols %in% colnames(res$enrichment)), + info = method + ) + expect_equal(nrow(res$enrichment), 1L, info = method) + expect_true(all(is.finite(res$enrichment$tau)), info = method) + expect_true(all(is.finite(res$enrichment$enrichment)), info = method) + # One jackknife row per LD block (5), one column per baseline + # annotation + jk <- res$annotationJackknifeCoefs + expect_true(is.matrix(jk), info = method) + expect_equal(dim(jk), c(5L, 1L), info = method) + expect_true(all(is.finite(jk)), info = method) + # One score z per candidate annotation + ss <- res$scoreStats + expect_true(is.list(ss), info = method) + expect_true(all(c("z", "R") %in% names(ss)), info = method) + expect_equal(length(ss$z), 1L, info = method) + expect_true(is.finite(ss$z[1]), info = method) + expect_true(is.matrix(ss$R), info = method) + expect_equal(dim(ss$R), c(1L, 1L), info = method) + expect_equal(ss$annotationNames, "cand1", info = method) + } }) -test_that("hdlUnivariate with 2 candidates returns a 2x2 score correlation", { - annot <- makeCoverageAnnot(dat_annot$n_snps, baseline = "ones", nCand = 2L) - suppressWarnings( - res <- pecotmr:::hdlUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot +test_that("each estimator with annotations and local = TRUE gives local h2", { + for (method in names(.h2Runs)) { + annot <- .h2RunAnnot(method, dat_annot, 1L) + res <- .h2Run(method, dat_annot, annotations = annot, local = TRUE) + expect_true(is.data.frame(res$local), info = method) + expect_true( + all(c("blockId", "h2Local", "h2LocalSe") %in% colnames(res$local)), + info = method ) - ) - expect_length(res$scoreStats$z, 2L) - expect_equal(dim(res$scoreStats$R), c(2L, 2L)) + # One row per block + expect_equal(nrow(res$local), 5L, info = method) + } }) -test_that("gldscUnivariate with 2 candidates returns a 2x2 score correlation", { - annot <- makeCoverageAnnot( - dat_annot$n_snps, - baseline = "spatial", - nCand = 2L - ) - res <- pecotmr:::gldscUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$ld_score_ref, - annotations = annot - ) - expect_length(res$scoreStats$z, 2L) - expect_equal(dim(res$scoreStats$R), c(2L, 2L)) +# --------------------------------------------------------------------------- +# Stratified score helpers — multiple-candidate (cor) branch +# --------------------------------------------------------------------------- + +test_that("each estimator with 2 candidates returns a 2x2 score correlation", { + for (method in names(.h2Runs)) { + annot <- .h2RunAnnot(method, dat_annot, 2L) + res <- .h2Run(method, dat_annot, annotations = annot) + expect_equal(length(res$scoreStats$z), 2L, info = method) + expect_equal(dim(res$scoreStats$R), c(2L, 2L), info = method) + } }) # --------------------------------------------------------------------------- # Stratified score helpers — no-candidate (NULL scoreStats) branch # --------------------------------------------------------------------------- -test_that("lderUnivariate with baseline-only annotations yields NULL scoreStats", { - annot <- makeCoverageAnnot(dat_annot$n_snps, baseline = "ones", nCand = 0L) - res <- pecotmr:::lderUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot - ) - expect_null(res$scoreStats) +test_that("each estimator with baseline-only annotations has NULL scoreStats", { + for (method in names(.h2Runs)) { + annot <- .h2RunAnnot(method, dat_annot, 0L) + res <- .h2Run(method, dat_annot, annotations = annot) + expect_null(res$scoreStats, info = method) + } }) -test_that("hdlUnivariate with baseline-only annotations yields NULL scoreStats", { - annot <- makeCoverageAnnot(dat_annot$n_snps, baseline = "ones", nCand = 0L) - suppressWarnings( - res <- pecotmr:::hdlUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$eigen_ref, - annotations = annot - ) +# =========================================================================== +# Error branches and degenerate inputs: an unknown object type for the +# genome check, mismatched .rmaMeta lengths, and unnamed jackknife +# coefficients for h2EstimateToSldscTrait. +# =========================================================================== + +# --------------------------------------------------------------------------- +# checkGenomeBuild — unknown object type branch +# --------------------------------------------------------------------------- + +test_that("checkGenomeBuild errors on an unrecognized object type", { + expect_error( + pecotmr:::checkGenomeBuild(list(genome = "hg19")), + "Unknown object type" ) - expect_null(res$scoreStats) }) -test_that("gldscUnivariate with baseline-only annotations yields NULL scoreStats", { - annot <- makeCoverageAnnot( - dat_annot$n_snps, - baseline = "spatial", - nCand = 0L - ) - res <- pecotmr:::gldscUnivariate( - dat_annot$z, - dat_annot$n, - dat_annot$ld_score_ref, - annotations = annot +# --------------------------------------------------------------------------- +# .rmaMeta — length-mismatch error +# --------------------------------------------------------------------------- + +test_that(".rmaMeta errors when means and ses differ in length", { + expect_error( + pecotmr:::.rmaMeta(c(1, 2), c(1, 2, 3)), + "must have the same length" ) - expect_null(res$scoreStats) }) # --------------------------------------------------------------------------- @@ -2156,42 +1625,6 @@ test_that("h2EstimateToSldscTrait assigns category names to unnamed annotationJa expect_equal(result$nBlocks, 10L) }) -# --------------------------------------------------------------------------- -# estimateH2 dispatch — `study` required for a multi-study collection -# --------------------------------------------------------------------------- - -test_that("estimateH2 errors when study is omitted for a multi-study collection", { - eigen_ref <- makeTestEigenRef() - n_snps <- length(eigen_ref) - set.seed(321) - df <- data.frame( - SNP = names(eigen_ref), - CHR = sub( - "^chr", - "", - as.character(GenomicRanges::seqnames(eigen_ref)) - ), - BP = GenomicRanges::start(eigen_ref), - A1 = as.character(S4Vectors::mcols(eigen_ref)$A1), - A2 = as.character(S4Vectors::mcols(eigen_ref)$A2), - Z = rnorm(n_snps), - N = rep(50000, n_snps), - stringsAsFactors = FALSE - ) - gr <- .dfToGwasGr(df) - ss2 <- GwasSumStats( - studyName = c("studyA", "studyB"), - entry = list(gr, gr), - genome = "hg19", - ldReference = makeTestGwasGenotypeHandle(), - varY = NA_real_ - ) - expect_error( - estimateH2(ss2, eigen_ref, method = "lder"), - "is required when" - ) -}) - # =========================================================================== # Deterministic h2 recovery + regression tests (correctness validation) # @@ -2199,8 +1632,8 @@ test_that("estimateH2 errors when study is omitted for a multi-study collection" # a KNOWN heritability, using fixed seeds so every run is deterministic and # self-contained (no dependence on the original LDER/gLDSC/HDL packages). # Recovery tests check the mean estimate recovers the true h2; the stored means -# pin the known-input -> known-output values. Behavioral tests lock in the -# nRef / inSample wiring and the g-LDSC bug fixes. +# pin the known-input -> known-output values. A behavioral test locks in the +# LDER inSample wiring. # =========================================================================== # AR(1) LD blocks + a chol-based per-block MVN simulator for the standard @@ -2289,13 +1722,17 @@ test_that("estimateH2 errors when study is omitted for a multi-study collection" AnnotationMatrix(mat, gr, meta, genome = "hg19") } +# The HDL recovery tests use 10 blocks rather than 30: HDL refits once per +# block for its jackknife, so its cost grows with the square of the block +# count, and on 10 blocks the mean estimate still lands well inside the +# tolerances. test_that("hdlUnivariate recovers a known h2 (deterministic, seed = 1)", { - d <- .h2RecoveryRefs() + d <- .h2RecoveryRefs(nBlocks = 10L) uni <- rep(0.4 / d$M, d$M) set.seed(1) ests <- replicate(30, hdlUnivariate(d$simZ(uni), d$N, d$eigenRef)$h2) expect_lt(abs(mean(ests) - 0.4), 0.05) # recovers true h2 = 0.4 - expect_equal(mean(ests), 0.405, tolerance = 0.04) # stored known output + expect_equal(mean(ests), 0.395, tolerance = 0.04) # stored known output }) test_that("lderUnivariate recovers a known h2 (deterministic, seed = 1)", { @@ -2317,12 +1754,12 @@ test_that("gldscUnivariate recovers a known h2 (deterministic, seed = 1)", { }) test_that("hdlUnivariate recovers partitioned h2 (block-separable annots)", { - d <- .h2RecoveryRefs() + d <- .h2RecoveryRefs(nBlocks = 10L) annot <- .h2RecoveryAnnot(d$M, d$M / 2) perSnp <- ifelse(seq_len(d$M) <= d$M / 2, 0.6 / d$M, 0.2 / d$M) M_a <- c(d$M / 2, d$M / 2) set.seed(1) - h2 <- rowMeans(replicate(20, { + h2 <- rowMeans(replicate(15, { r <- hdlUnivariate(d$simZ(perSnp), d$N, d$eigenRef, annotations = annot) r$enrichment$tau * M_a })) @@ -2347,24 +1784,6 @@ test_that("gldscUnivariate recovers enrichment direction (annotA > annotB)", { expect_lt(e[2], 0.8) # annotB depleted }) -test_that("HDL uses the finite-reference correction (nRef changes h2)", { - d <- .h2RecoveryRefs() - set.seed(1) - z <- d$simZ(rep(0.4 / d$M, d$M)) - refBig <- d$eigenRef - refSmall <- d$eigenRef - refSmall@nSamples <- 2000L - h2Big <- hdlUnivariate(z, d$N, refBig)$h2 - # nRef = 2000 against this N is exactly the regime where the - # finite-reference term dominates, so the fit lands on its bound and says - # so. That is the behaviour under test, not noise to be ignored. - expect_warning( - h2Small <- hdlUnivariate(z, d$N, refSmall)$h2, - "sits at the top of its range" - ) - expect_gt(abs(h2Big - h2Small), 0.05) -}) - test_that("LDER uses the in-sample vs out-of-sample weight switch", { d <- .h2RecoveryRefs() set.seed(1) @@ -2378,22 +1797,8 @@ test_that("LDER uses the in-sample vs out-of-sample weight switch", { ))) }) -test_that("gLDSC requires full LD matrices and gives a positive jackknife SE", { - noMat <- makeTestScoreRef(with_ld_matrices = FALSE) - ss <- makeTestSumstatsForRef(noMat) - expect_error( - estimateH2(ss, noMat, method = "gldsc"), - "g-LDSC needs each LD block's LD" - ) - d <- .h2RecoveryRefs() - set.seed(1) - res <- gldscUnivariate(d$simZ(rep(0.4 / d$M, d$M)), d$N, d$scoreRef) - expect_true(is.finite(res$h2Se)) - expect_gt(res$h2Se, 0) -}) - -# The two S-LDSC recovery checks live here rather than with the rest of the -# S-LDSC block because they need .h2RecoveryRefs(), defined just above. +# The S-LDSC checks below live here rather than with the rest of the S-LDSC +# block because they need .h2RecoveryRefs(), defined just above. # S-LDSC is a genome-scale method: real analyses regress over ~1M variants. # Every reference in this suite is a few thousand, and at that size the # intercept is not identifiable -- an unweighted OLS on the same data also @@ -2555,12 +1960,17 @@ test_that("S-LDSC recovers enrichment direction for one annotation", { e <- eigen(b$R, symmetric = TRUE) list(values = e$values, vectors = e$vectors, snpIdx = b$snpIdx) }) + # The frozen table holds the blocks 1-based, as they were always read. + ldBlocks <- GenomicRanges::GRanges( + fx$ldBlocks$chrom, + IRanges::IRanges(fx$ldBlocks$start, fx$ldBlocks$end) + ) list( score = LdScore( snpInfo = fx$snpInfo, ldScores = matrix(base, ncol = 1, dimnames = list(NULL, "base_l2")), ldScoreWeights = base, - ldBlocks = fx$ldBlocks, + ldBlocks = ldBlocks, nSamples = nSamples, genome = fx$genome, ldMatrixList = blocks @@ -2568,7 +1978,7 @@ test_that("S-LDSC recovers enrichment direction for one annotation", { eigen = LdEigen( snpInfo = fx$snpInfo, eigenList = eigens, - ldBlocks = fx$ldBlocks, + ldBlocks = ldBlocks, nSamples = nSamples, genome = fx$genome ) @@ -3114,3 +2524,36 @@ test_that("the DL fallback carries metaArgs too", { expect_equal(seen[[2]]$method, "DL") expect_true(all(map_dbl(seen, "level") == 90)) }) + +test_that("estimateH2 reads a study split across LD blocks as one study", { + ref <- makeTestEigenRef() + ss <- makeTestSumstatsForRef(ref) + gr <- sumStats(ss) + mid <- GenomicRanges::start(gr)[[10L]] + split <- GwasSumStats( + studyName = "test", + entry = list(gr), + genome = "hg19", + ldReference = makeTestGwasGenotypeHandle(), + region = GenomicRanges::GRanges( + as.character(GenomicRanges::seqnames(gr))[[1L]], + IRanges::IRanges(c(1L, mid + 1L), c(mid, .Machine$integer.max)) + ) + ) + expect_equal(nrow(split), 2L) + expect_equal( + heritabilityEstimate(estimateH2(split, ref, method = "lder")), + heritabilityEstimate(estimateH2(ss, ref, method = "lder")) + ) + # Two studies still need one named. + two <- GwasSumStats( + studyName = c("a", "b"), + entry = list(gr, gr), + genome = "hg19", + ldReference = makeTestGwasGenotypeHandle() + ) + expect_error( + estimateH2(two, ref, method = "lder"), + "`studyName` is required when the GwasSumStats has 2 studies" + ) +}) diff --git a/tests/testthat/test_jointEngine.R b/tests/testthat/test_jointEngine.R index 448f993f..a3432f08 100644 --- a/tests/testthat/test_jointEngine.R +++ b/tests/testthat/test_jointEngine.R @@ -62,7 +62,7 @@ ... ) { vids <- colnames(dataX) - fineMappingRow( + FineMappingRow( variantIds = vids, susieFit = list(method = method, cond = conditionIdx), topLoci = data.frame( @@ -218,7 +218,7 @@ test_that(".runJointCell: cross-context FM uses the per-fold mr.mash CV prior", samplePartition = sp, foldFits = list(fold_1 = fp, fold_2 = fp) ) - twEntry <- twasWeightsRow( + twEntry <- TwasWeightsRow( variantIds = c("chr1:100:A:G", "chr1:200:A:G"), weights = c(0.1, 0.2), methodFits = fp, @@ -253,7 +253,7 @@ test_that(".runJointCell: cross-context FM uses the per-fold mr.mash CV prior", verbose = 1, mvPrior = NULL, mvPriorCv = NULL, - numThreads = 1, + BPPARAM = BiocParallel::SerialParam(), seed = NULL ) { captured <<- list( @@ -315,7 +315,7 @@ test_that(".runJointCell: cross-context FM uses the per-fold mr.mash CV prior", ncol(Y), dimnames = list(colnames(X), colnames(Y)) ) - e <- twasWeightsRow( + e <- TwasWeightsRow( variantIds = colnames(X), weights = W, methodFits = .je_fakeMrmashFit() @@ -603,9 +603,10 @@ test_that("fitJointGroup(SumStats, Twas): real mr.mash-rss keys stat$n (regressi # errored in sqrt(nVec) on genuine summary-statistic input. This drives the # unmocked fitter end to end. set.seed(1) - p <- 30L + # Small enough that the real mr.mash.rss fit stays quick. + p <- 10L K <- 2L - nObs <- 400L + nObs <- 100L X <- matrix(rnorm(nObs * p), nObs, p) colnames(X) <- sprintf("chr1:%d:A:G", 100L * seq_len(p)) R <- cor(X) @@ -1074,10 +1075,9 @@ test_that(".runJointCell: composed/sumstats (context+trait vary) -> per-tuple ro }) # ---- SR-TWAS ensemble layer (.twasEnsembleLayer) ---------------------------- -# The ensemble orchestration formerly inside .twasWeightsPipelineMatrix is now a -# LAYER ON TOP of per-method fitting: per condition, read each method's retained -# out-of-fold CV predictions + weights + R^2, drop methods below the cutoff -# (needs >= 2), and stack via `ensembleWeights` per context. +# The ensemble is a LAYER ON TOP of per-method fitting: per condition, read each +# method's retained out-of-fold CV predictions + weights + R^2, drop methods +# below the cutoff (needs >= 2), and stack via `ensembleWeights` per context. .je_ensGroup <- function(n = 40L, nCond = 2L) { samp <- paste0("s", seq_len(n)) @@ -1112,7 +1112,7 @@ test_that(".runJointCell: composed/sumstats (context+trait vary) -> per-tuple ro pr <- predCor * Y[, r] + rnorm(nrow(Y), sd = 0.3) names(pr) <- rownames(Y) rsq <- stats::cor(Y[, r], pr)^2 - twasWeightsRow( + TwasWeightsRow( variantIds = vars, weights = rnorm(length(vars)), cvResult = list( @@ -1183,7 +1183,7 @@ test_that(".twasEnsembleLayer: < 2 methods pass the R^2 cutoff -> NULL (skip)", expect_true(all(map_lgl(ens, is.null))) }) -# ---- engine twas fitter: orchestration absorbed from .twasWeightsPipelineMatrix +# ---- engine twas fitter (fitJointGroup on a TwasJointPipeline) -------------- test_that("fitJointGroup(twas): leakage warning when a full-data mr.mash prior is reused across folds", { set.seed(3) @@ -1444,7 +1444,7 @@ test_that(".enumCrossContextIndividual: one group per trait in >= 2 contexts", { ) { if (tid == "G2") { return(NULL) - } # skip branch (461) + } # skip branch X <- matrix( 0, 4, @@ -1557,7 +1557,7 @@ test_that(".enumCrossTraitIndividual: one group per context with >= 2 traits + p ) { if (cx == "c2") { return(NULL) - } # skip branch (511) + } # skip branch X <- matrix( 0, 4, @@ -1717,6 +1717,40 @@ test_that(".enumComposedIndividual: study not in scope / NULL xy -> empty", { ) # xy NULL }) +test_that(".enumTopPcIndividual enumerates only the studies in scope", { + # Reached through .jointDispatchTable, which covr cannot see, so called + # directly here. + data(qtlDatasetExample) + qd <- qtlDatasetExample + expect_identical( + pecotmr:::.enumTopPcIndividual(qd, list(studies = "other")), + list() + ) + seen <- list() + local_mocked_bindings( + .enumTopPcForContext = function( + cx, + data, + scope, + args, + studyName, + phenotypeFilter + ) { + seen[[cx]] <<- list(study = studyName, filter = phenotypeFilter) + list(cx) + }, + .package = "pecotmr" + ) + scope <- list(studies = "study1", contexts = list(study1 = c("a", "b"))) + expect_identical( + pecotmr:::.enumTopPcIndividual(qd, scope), + list("a", "b") + ) + expect_identical(seen$a$study, "study1") + # The joint engine's own phenotype QC when the run supplied none. + expect_identical(seen$a$filter$naAction, "drop") +}) + test_that(".enumUnivariateIndividual: one 1-condition group per (context, trait)", { scope <- list( studies = "S", @@ -1726,12 +1760,12 @@ test_that(".enumUnivariateIndividual: one 1-condition group per (context, trait) samp <- paste0("s", 1:5) local_mocked_bindings( studyName = function(data) "S", - molecularTraits = function(data, contexts) .je_mkSe(c("G1", "G2")), + .qtlContextSe = function(data, context) .je_mkSe(c("G1", "G2")), .fmResidPheno = function( data, contexts, traitId, - naAction = "drop", + phenotypeFilter = NULL, ... ) { matrix(0, 5, 1, dimnames = list(samp, traitId)) @@ -1768,12 +1802,12 @@ test_that(".enumUnivariateIndividual: too few shared samples skips the tuple", { ) local_mocked_bindings( studyName = function(data) "S", - molecularTraits = function(data, contexts) .je_mkSe("G1"), + .qtlContextSe = function(data, context) .je_mkSe("G1"), .fmResidPheno = function( data, contexts, traitId, - naAction = "drop", + phenotypeFilter = NULL, ... ) { matrix(0, 1, 1, dimnames = list("s1", traitId)) @@ -1851,7 +1885,7 @@ test_that(".enumComposedSumstats: NULL group index and singleton blocks skip", { list(studies = "S") ), 0L - ) # gi NULL (646) + ) # gi NULL local_mocked_bindings( .jointRowsLdRef = function(data, rows, label) NULL, .enumerateComposedSumstatGroups = function(spec, data, scope) { @@ -1873,7 +1907,7 @@ test_that(".enumComposedSumstats: NULL group index and singleton blocks skip", { args = list(axes = c("context", "trait")) ), 0L - ) # < 2 gIdx (649) + ) # < 2 gIdx }) # ============================================================================= @@ -2214,7 +2248,7 @@ test_that(".twasEnsembleLayer: entries lacking CV predictions are skipped", { g <- .je_ensGroup(nCond = 1L) good <- .je_ensEntries(g, 0.85) # A method whose entry carries no CV predictions -> contributes nothing. - noCv <- list(twasWeightsRow( + noCv <- list(TwasWeightsRow( variantIds = colnames(.jgX(g)), weights = rnorm(ncol(.jgX(g))), cvResult = NULL @@ -2322,9 +2356,9 @@ test_that(".jointTwasCvResult: NULL cv and empty/absent payloads degrade gracefu foldFits = list(fold_1 = list(other = 1)) ) out <- pecotmr:::.jointTwasCvResult(cv, "mrmash") - expect_null(out$predictions) # pickByBase empty (252) - expect_null(out$foldFits) # all-NULL ffKey (260) - # A method token absent from a non-empty prediction list -> NULL (255). + expect_null(out$predictions) # pickByBase empty + expect_null(out$foldFits) # all-NULL ffKey + # A method token absent from a non-empty prediction list -> NULL. cv2 <- list( samplePartition = NULL, prediction = list(lasso_predicted = matrix(0, 1, 1)), @@ -2412,7 +2446,7 @@ test_that(".twasGroupArgs: takes the CV partition from the fine-mapping CV when .package = "pecotmr" ) out <- pecotmr:::.twasGroupArgs(g, pipe, list(fineMappingResult = "FMR")) - expect_identical(out$samplePartition, sp) # line 692 + expect_identical(out$samplePartition, sp) }) test_that(".runJointCell: a token whose fitter returns NULL is skipped", { @@ -2422,7 +2456,7 @@ test_that(".runJointCell: a token whose fitter returns NULL is skipped", { fitJointGroup = function(...) NULL, .package = "pecotmr" ) - expect_null(pecotmr:::.runJointCell(cell, pipe, NULL, NULL, "mvsusie")) # 755 + expect_null(pecotmr:::.runJointCell(cell, pipe, NULL, NULL, "mvsusie")) }) test_that(".runJointSpecs: region mode without traitId restricts scoped traits to the locus", { @@ -2430,7 +2464,7 @@ test_that(".runJointSpecs: region mode without traitId restricts scoped traits t region <- GenomicRanges::GRanges("chr1", IRanges::IRanges(1, 100)) captured <- NULL local_mocked_bindings( - # S2 has no scoped contexts -> the region-restriction loop skips it (873). + # S2 has no scoped contexts -> the region-restriction loop skips it. .fmResolveSpecScope = function(spec, data, contexts, traitIds) { list( studies = c("S", "S2"), @@ -2438,7 +2472,7 @@ test_that(".runJointSpecs: region mode without traitId restricts scoped traits t traits = list(S = c("g1", "g2"), S2 = "g9") ) }, - molecularTraits = function(data, contexts) .je_mkSe(c("g1", "g2")), + .qtlContextSe = function(data, context) .je_mkSe(c("g1", "g2")), .fmTraitsInRegion = function(se, traits, region) { captured <<- traits "g1" @@ -2457,7 +2491,7 @@ test_that(".runJointSpecs: region mode without traitId restricts scoped traits t args = list(region = region) ) expect_null(res) # empty cell -> NULL - expect_equal(captured, c("g1", "g2")) # 871-875 ran + expect_equal(captured, c("g1", "g2")) # the restriction ran }) @@ -2503,8 +2537,8 @@ test_that(".runJointSpecs: region mode without traitId restricts scoped traits t test_that("traitPos comes from the QtlSumStats traitPos column", { ss <- .je_ssWithTraitPos() - g1 <- pecotmr:::.traitPosFor(ss, "brain", "G1") - g2 <- pecotmr:::.traitPosFor(ss, "brain", "G2") + g1 <- pecotmr:::.traitPosFor(ss, "S", "brain", "G1") + g2 <- pecotmr:::.traitPosFor(ss, "S", "brain", "G2") expect_s4_class(g1, "GRanges") expect_equal(GenomicRanges::start(g1), 500L) expect_equal(GenomicRanges::start(g2), 900L) @@ -2514,37 +2548,72 @@ test_that("traitPos comes from the QtlSumStats traitPos column", { test_that("traitPos is NULL when the sumstats cannot supply one", { ss <- .je_ssWithTraitPos() - expect_null(pecotmr:::.traitPosFor(ss, "brain", "absentTrait")) - expect_null(pecotmr:::.traitPosFor(ss, "absentContext", "G1")) + expect_null(pecotmr:::.traitPosFor(ss, "S", "brain", "absentTrait")) + expect_null(pecotmr:::.traitPosFor(ss, "S", "absentContext", "G1")) + expect_null(pecotmr:::.traitPosFor(ss, "absentStudy", "brain", "G1")) # A collection with no traitPos column at all. data(qtlSumStatsExample) expect_false(is_in("traitPos", colnames(qtlSumStatsExample))) expect_null(pecotmr:::.traitPosFor( qtlSumStatsExample, + as.character(qtlSumStatsExample$study)[[1L]], as.character(qtlSumStatsExample$context)[[1L]], as.character(qtlSumStatsExample$trait)[[1L]] )) }) +test_that("each study keeps its own anchors for a shared (context, trait)", { + # Two studies carry brain:G1 at different positions and spans; a row + # named by its study gets that study's, not the first study's. + ss <- QtlSumStats( + studyName = c("S1", "S2"), + context = c("brain", "brain"), + trait = c("G1", "G1"), + entry = list( + .je_mkSsEntry("chr1", c(100L, 200L)), + .je_mkSsEntry("chr1", c(300L, 400L)) + ), + genome = "hg38", + traitPos = GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(500L, 900L), width = 1L) + ) + ) + tp <- pecotmr:::.anchorVector( + ss, + c("S2", "S1"), + c("brain", "brain"), + c("G1", "G1"), + kind = "traitPos" + ) + expect_equal(GenomicRanges::start(tp), c(900L, 500L)) + rg <- pecotmr:::.fitRegionFor(ss, "S2", "brain", "G1") + expect_equal( + c(GenomicRanges::start(rg), GenomicRanges::end(rg)), + c(300L, 400L) + ) +}) + test_that("the fit region of a QtlSumStats row is its variant span", { # Sumstats carry no cis-window, so the fitted span IS the region -- # deliberately different from traitPos (500) above. ss <- .je_ssWithTraitPos() - r <- pecotmr:::.fitRegionFor(ss, "brain", "G1") + r <- pecotmr:::.fitRegionFor(ss, "S", "brain", "G1") expect_s4_class(r, "GRanges") expect_equal(GenomicRanges::start(r), 100L) expect_equal(GenomicRanges::end(r), 200L) - expect_null(pecotmr:::.fitRegionFor(ss, "brain", "absentTrait")) + expect_null(pecotmr:::.fitRegionFor(ss, "S", "brain", "absentTrait")) }) test_that("the fit region of a QtlDataset row is traitPos +/- the cis window", { data(qtlDatasetExample) qd <- qtlDatasetExample cx <- contexts(qd)[[1L]] - tr <- rownames(molecularTraits(qd, contexts = cx))[[1L]] - tp <- pecotmr:::.traitPosFor(qd, cx, tr) - bare <- pecotmr:::.fitRegionFor(qd, cx, tr) - wide <- pecotmr:::.fitRegionFor(qd, cx, tr, cisWindow = 1e5) + tr <- rownames(molecularTraits(qd, context = cx)[[cx]])[[1L]] + st <- studyName(qd) + tp <- pecotmr:::.traitPosFor(qd, st, cx, tr) + bare <- pecotmr:::.fitRegionFor(qd, st, cx, tr) + wide <- pecotmr:::.fitRegionFor(qd, st, cx, tr, cisWindow = 1e5) # With no window the region collapses onto the trait position. expect_equal(GenomicRanges::start(bare), GenomicRanges::start(tp)) # With one it is symmetric about it. @@ -2559,14 +2628,15 @@ test_that("the anchors are NULL for a trait the dataset does not carry", { data(qtlDatasetExample) qd <- qtlDatasetExample cx <- contexts(qd)[[1L]] - expect_null(pecotmr:::.traitPosFor(qd, cx, "absentTrait")) - expect_null(pecotmr:::.traitPosFor(qd, "absentContext", "anything")) - expect_null(pecotmr:::.fitRegionFor(qd, cx, "absentTrait")) + st <- studyName(qd) + expect_null(pecotmr:::.traitPosFor(qd, st, cx, "absentTrait")) + expect_null(pecotmr:::.traitPosFor(qd, st, "absentContext", "anything")) + expect_null(pecotmr:::.fitRegionFor(qd, st, cx, "absentTrait")) }) test_that("the anchors are NULL for an unsupported input class", { - expect_null(pecotmr:::.traitPosFor(42, "a", "b")) - expect_null(pecotmr:::.fitRegionFor(42, "a", "b")) + expect_null(pecotmr:::.traitPosFor(42, "s", "a", "b")) + expect_null(pecotmr:::.fitRegionFor(42, "s", "a", "b")) }) @@ -2588,7 +2658,7 @@ test_that("a sumstats entry with no variants has no fit region", { entry = list(emptyEntry), genome = "hg38" ) - expect_null(pecotmr:::.fitRegionFor(ss, "brain", "G0")) + expect_null(pecotmr:::.fitRegionFor(ss, "S", "brain", "G0")) }) test_that("slicing a CV result to one condition tolerates absent payloads", { @@ -2630,12 +2700,14 @@ test_that("the anchor vector keeps traitPos and region distinct", { ss <- .je_ssWithTraitPos() region <- pecotmr:::.anchorVector( ss, + c("S", "S"), c("brain", "brain"), c("G1", "G2"), kind = "region" ) anchors <- pecotmr:::.anchorVector( ss, + c("S", "S"), c("brain", "brain"), c("G1", "G2"), kind = "traitPos" @@ -2845,7 +2917,7 @@ test_that(".jointTwasCv prefers per-call CV settings over the config", { weightMethods, fitRetention, maxNumVariants, - numThreads, + BPPARAM, dataDrivenPriorMatricesCv, verbose, seed @@ -2913,8 +2985,14 @@ test_that(".enumUnivariateIndividual reads a region instead of a cis window", { ) local_mocked_bindings( studyName = function(data) "S1", - molecularTraits = function(data, contexts) phenotypes, - .fmResidPheno = function(data, contexts, traitId, naAction, ...) { + .qtlContextSe = function(data, context) phenotypes, + .fmResidPheno = function( + data, + contexts, + traitId, + phenotypeFilter, + ... + ) { matrix(1, 2L, 1L, dimnames = list(c("s1", "s2"), "t1")) }, .fmResidGeno = function( @@ -2942,11 +3020,11 @@ test_that(".enumUnivariateIndividual reads a region instead of a cis window", { pecotmr:::.enumUnivariateIndividual( NULL, scope, - list(region = "chr1:1-1000") + list(region = GenomicRanges::GRanges("chr1:1-1000")) ) # An explicit region replaces the trait-anchored cis window entirely -- # neither traitId nor cisWindow is passed down. - expect_equal(seen$region, "chr1:1-1000") + expect_equal(seen$region, GenomicRanges::GRanges("chr1:1-1000")) expect_null(seen$cisWindow) expect_null(seen$traitId) }) @@ -3158,7 +3236,7 @@ test_that(".twasEnsembleCollect answers empty parts when no token contributes", expect_identical(out$rsq, c()) }) -test_that(".jointAfForGroup resolves allele frequencies for an individual group", { +test_that(".jointAfForGroup is NULL without a QtlDataset or individual group", { data(qtlDatasetExample) X <- matrix( c(0, 1, 2, 1, 2, 0), @@ -3173,7 +3251,8 @@ test_that(".jointAfForGroup resolves allele frequencies for an individual group" ) # Not a QtlDataset -> no af rather than an error. expect_null(.jointAfForGroup(NULL, g)) - # A SumStats group has no design matrix to take frequencies from. + # Anything but an individual group has no design matrix to read + # frequencies from. expect_null(.jointAfForGroup(qtlDatasetExample, "not a group")) }) @@ -3242,7 +3321,6 @@ test_that(".jointMrmashRssWeights passes the caller's mr.mash options", { coverage = 0.95, crossValidationParam = list( folds = 2, - numThreads = 1, fitFullData = FALSE ) ) @@ -3389,7 +3467,7 @@ test_that(".jointGroupSelect drops pairs a per-context traitId leaves out", { entry = list(gr, gr), genome = "hg19", ldReference = refs, - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) } diff --git a/tests/testthat/test_jointSpecification.R b/tests/testthat/test_jointSpecification.R index d4292aa9..c1623eb9 100644 --- a/tests/testthat/test_jointSpecification.R +++ b/tests/testthat/test_jointSpecification.R @@ -12,7 +12,7 @@ format = "plink2", snpInfo = data.frame( SNP = paste0("rs", seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -105,6 +105,10 @@ ) } +# The default dataset, built on first use and shared by the parser tests +# that only read its names. +delayedAssign(".jsQd", .js_makeQtlDataset()) + # ----------------------------------------------------------------------------- # Scope helpers # ----------------------------------------------------------------------------- @@ -156,12 +160,13 @@ test_that(".sp* helpers: MultiStudyQtlDataset combines individual + sumstats", { # ----------------------------------------------------------------------------- test_that("parseJointSpecification: NULL returns empty list", { - qd <- .js_makeQtlDataset() + qd <- .jsQd expect_equal(pecotmr:::parseJointSpecification(NULL, qd), list()) + expect_silent(pecotmr:::parseJointSpecification(NULL, qd)) }) test_that("parseJointSpecification: auto-wraps a single char vector", { - qd <- .js_makeQtlDataset() + qd <- .jsQd out <- pecotmr:::parseJointSpecification("context", qd) expect_equal(length(out), 1L) expect_equal(out[[1L]]$axes, "context") @@ -169,7 +174,7 @@ test_that("parseJointSpecification: auto-wraps a single char vector", { }) test_that("parseJointSpecification: accepts a list of specs", { - qd <- .js_makeQtlDataset() + qd <- .jsQd out <- pecotmr:::parseJointSpecification( list("context", c("context", "trait")), qd @@ -190,7 +195,7 @@ test_that("parseJointSpecification: accepts scope-restricted spec", { }) test_that("parseJointSpecification: rejects unknown axes", { - qd <- .js_makeQtlDataset() + qd <- .jsQd expect_error( pecotmr:::parseJointSpecification(c("context", "bogus"), qd), "unknown axes" @@ -198,7 +203,7 @@ test_that("parseJointSpecification: rejects unknown axes", { }) test_that("parseJointSpecification: rejects duplicate axes", { - qd <- .js_makeQtlDataset() + qd <- .jsQd expect_error( pecotmr:::parseJointSpecification(c("context", "context"), qd), "duplicate axes" @@ -206,7 +211,7 @@ test_that("parseJointSpecification: rejects duplicate axes", { }) test_that("parseJointSpecification: rejects unknown scope keys", { - qd <- .js_makeQtlDataset() + qd <- .jsQd expect_error( pecotmr:::parseJointSpecification( list(list(axes = "context", scope = list(bogus = "x"))), @@ -228,7 +233,7 @@ test_that("parseJointSpecification: rejects scope values absent from data", { }) test_that("parseJointSpecification: rejects unknown spec elements", { - qd <- .js_makeQtlDataset() + qd <- .jsQd expect_error( pecotmr:::parseJointSpecification( list(list(axes = "context", scope = NULL, bogus = "x")), @@ -243,7 +248,7 @@ test_that("parseJointSpecification: rejects unknown spec elements", { # ----------------------------------------------------------------------------- test_that("parseContexts: NULL passes through", { - qd <- .js_makeQtlDataset() + qd <- .jsQd expect_null(pecotmr:::parseContexts(NULL, qd)) }) @@ -289,7 +294,7 @@ test_that("parseContexts: list form fills unmentioned studies with defaults", { # ----------------------------------------------------------------------------- test_that("parseTraitIds: NULL passes through", { - qd <- .js_makeQtlDataset() + qd <- .jsQd expect_null(pecotmr:::parseTraitIds(NULL, qd)) }) @@ -333,28 +338,6 @@ test_that("parseTraitIds: doubly-nested study->context validates per context", { # Pipeline-level wiring: jointSpecification accepted on all three methods # ----------------------------------------------------------------------------- -test_that("fineMappingPipeline(QtlDataset): trait-axis joint dispatcher is wired", { - # Cross-trait dispatcher is now wired; calling it on a fake genotype - # handle errors when the genotype extractor tries to open its .pgen file. - # The point of this test is to verify the dispatcher is invoked (not - # the stub error), so we check that the error comes from the genotype - # I/O layer rather than the jointSpec wiring. - qd <- .js_makeQtlDataset( - studyName = "A", - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) - expect_error( - fineMappingPipeline( - qd, - methods = "mvsusie", - cisWindow = 1000L, - jointSpecification = "trait" - ), - "File does not exist" - ) -}) - test_that("fineMappingPipeline(QtlDataset): composed joint dispatcher is wired", { # Composed dispatcher accepts axes = c("context", "trait") for individual- # level input. On the fake fixture the genotype I/O fails when the @@ -410,17 +393,6 @@ test_that("fineMappingPipeline(QtlDataset): study-axis on individual data errors ) }) -test_that("fineMappingPipeline(QtlDataset): NULL jointSpec is the default", { - qd <- .js_makeQtlDataset( - studyName = "A", - contexts = "brain", - traits = "ENSG_A" - ) - expect_silent( - pecotmr:::parseJointSpecification(NULL, qd) - ) -}) - test_that("fineMappingPipeline(QtlDataset): invalid jointSpec errors before fit", { qd <- .js_makeQtlDataset(studyName = "A") expect_error( @@ -434,23 +406,6 @@ test_that("fineMappingPipeline(QtlDataset): invalid jointSpec errors before fit" ) }) -test_that("twasWeightsPipeline(QtlDataset): cross-trait joint dispatcher is wired", { - qd <- .js_makeQtlDataset( - studyName = "A", - contexts = "brain", - traits = c("ENSG_A", "ENSG_B") - ) - expect_error( - twasWeightsPipeline( - qd, - methods = "mrmash", - cisWindow = 1000L, - jointSpecification = "trait" - ), - "File does not exist" - ) -}) - test_that("twasWeightsPipeline(QtlDataset): study-axis on individual data errors", { qd <- .js_makeQtlDataset( studyName = "A", @@ -468,32 +423,11 @@ test_that("twasWeightsPipeline(QtlDataset): study-axis on individual data errors ) }) -test_that("twasWeightsPipeline(QtlSumStats): non-NULL jointSpec errors", { - ss <- .js_makeQtlSumStats( - studies = c("X", "Y"), - contexts = "DLPFC", - traits = "ENSG_A" - ) - # qcInfo is empty; the QC assertion fires BEFORE jointSpec parsing. - expect_error( - twasWeightsPipeline( - ss, - methods = "susie", - jointSpecification = "context" - ), - "QC" - ) -}) - -test_that("twasWeightsPipeline(MultiStudyQtlDataset): method exists", { - expect_true(existsMethod("twasWeightsPipeline", "MultiStudyQtlDataset")) -}) - # ============================================================================ # Joint dispatchers (merged from former tests/testthat/test_jointDispatchers.R) # ============================================================================ -context("joint dispatchers (fineMappingDispatcher / twasDispatcher)") +context("joint dispatchers (fineMappingPipeline / twasWeightsPipeline)") # ============================================================================ # Strategy: each joint-dispatcher function is exercised by driving @@ -514,7 +448,7 @@ context("joint dispatchers (fineMappingDispatcher / twasDispatcher)") format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -601,7 +535,7 @@ context("joint dispatchers (fineMappingDispatcher / twasDispatcher)") entry = map(seq_len(nrow(rows)), function(.) makeGr()), genome = "hg19", ldReference = .jd_makeHandle(), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) } @@ -653,7 +587,7 @@ context("joint dispatchers (fineMappingDispatcher / twasDispatcher)") if (is.null(vids)) { vids <- "chr1:1200:A:G" } - fineMappingRow( + FineMappingRow( variantIds = vids, susieFit = list(method = method, payload = fit), topLoci = data.frame( @@ -695,7 +629,7 @@ context("joint dispatchers (fineMappingDispatcher / twasDispatcher)") } # ============================================================================= -# fineMappingDispatcher: QtlSumStats +# fineMappingPipeline joint dispatch: QtlSumStats # ============================================================================= test_that("fineMappingPipeline(QtlSumStats): jointSpec='context' fits one joint per (study, trait)", { @@ -871,7 +805,7 @@ test_that("fineMappingPipeline(QtlSumStats): composed jointSpec rejects fsusie", }) # ============================================================================= -# twasDispatcher: QtlDataset +# twasWeightsPipeline joint dispatch: QtlDataset # ============================================================================= .jd_makeSe <- function(traits = c("t1", "t2"), n_samples = 30L, starts = NULL) { @@ -993,23 +927,6 @@ test_that("twasWeightsPipeline(QtlDataset): jointSpec='trait' fits mr.mash per c expect_true("jointTraits" %in% pecotmr:::.tupleColumnNames(res)) }) -test_that("twasWeightsPipeline(QtlDataset): study-axis fails on individual data", { - qd <- .jd_makeQtlDataset( - studyName = "Q1", - contexts = c("c1", "c2"), - traits = "t1" - ) - expect_error( - twasWeightsPipeline( - qd, - methods = "mrmash", - cisWindow = 1000L, - jointSpecification = "study" - ), - "requires sumstats input" - ) -}) - test_that("twasWeightsPipeline(QtlDataset): composed jointSpec axes=c('context','trait') fits", { qd <- .jd_makeQtlDataset( studyName = "Q1", @@ -1053,7 +970,7 @@ test_that("twasWeightsPipeline(QtlDataset): composed jointSpec including 'study' }) # ============================================================================= -# twasDispatcher: QtlSumStats +# twasWeightsPipeline joint dispatch: QtlSumStats # ============================================================================= test_that("twasWeightsPipeline(QtlSumStats): jointSpec='context' fits mr.mash.rss per (study, trait)", { @@ -1240,7 +1157,7 @@ test_that(".sp* helpers: unsupported class raises a labelled error", { # ----------------------------------------------------------------------------- test_that("parseJointSpecification: malformed inputs error", { - qd <- .js_makeQtlDataset() + qd <- .jsQd expect_error(pecotmr:::parseJointSpecification(42, qd), "must be NULL") expect_error( pecotmr:::parseJointSpecification(list(list(scope = NULL)), qd), @@ -1282,7 +1199,7 @@ test_that("parseContexts: malformed inputs error", { "non-empty character vector" ) expect_error(pecotmr:::parseContexts(list("brain"), qd), "named list") # unnamed - expect_error(pecotmr:::parseContexts(42, qd), "must be NULL") + expect_error(pecotmr:::parseContexts(42, qd), "`contexts` must be NULL") }) test_that("parseContexts: vector form refuses a context no study has", { @@ -1302,7 +1219,7 @@ test_that("parseTraitIds: malformed inputs error", { traits = c("ENSG1", "ENSG2") ) expect_error(pecotmr:::parseTraitIds(character(0), qd), "non-empty") - expect_error(pecotmr:::parseTraitIds(42, qd), "must be NULL") + expect_error(pecotmr:::parseTraitIds(42, qd), "`traitId` must be NULL") expect_error(pecotmr:::parseTraitIds(list("ENSG1"), qd), "named by study") expect_error( pecotmr:::parseTraitIds(list(nope = "ENSG1"), qd), @@ -1449,6 +1366,57 @@ test_that(".sumStatsRowsSelected applies study and per-context selections", { ) }) +test_that("a study's selected traits follow traitId, else region", { + # .js_makeSe places ENSG1 at chr1:100-149 and ENSG2 at chr1:200-249. + qd <- .js_makeQtlDataset(studyName = "A") + sel <- function(cx, traitId = NULL, region = NULL) { + pecotmr:::.contextSelectedTraits(cx, qd, traitId, region) + } + expect_equal(sel("brain"), c("ENSG1", "ENSG2")) + expect_equal(sel("brain", traitId = c("ENSG2", "ENSG9")), "ENSG2") + # A selection that leaves the context out keeps all of its traits. + expect_equal( + sel("liver", traitId = list(A = list(brain = "ENSG1"))), + c("ENSG1", "ENSG2") + ) + # region picks traits only when no trait was named at all. + nearEnsg1 <- GenomicRanges::GRanges("chr1:120-130") + expect_equal(sel("brain", region = nearEnsg1), "ENSG1") + expect_equal(sel("brain", traitId = "ENSG2", region = nearEnsg1), "ENSG2") + has <- function(contexts = NULL, traitId = NULL, region = NULL) { + pecotmr:::.studyHasSelectedTraits(qd, contexts, traitId, region) + } + expect_true(has(traitId = "ENSG1")) + expect_false(has(traitId = "ENSG9")) + expect_false(has(region = GenomicRanges::GRanges("chr1:5000-6000"))) + # None of the study's contexts selected leaves it no trait either. + expect_false(has(contexts = list(A = character(0)))) + expect_true(has(contexts = list(A = "liver"), traitId = "ENSG2")) +}) + +test_that("a multi-study run is refused only when no component has a trait", { + msqd <- MultiStudyQtlDataset( + qtlDatasets = list(A = .js_makeQtlDataset(studyName = "A")), + sumStats = .js_makeQtlSumStats(studies = "ssA") + ) + check <- function(traitId) { + pecotmr:::.msAssertTraitsSelected( + msqd, + list(contexts = NULL, traitId = traitId, region = NULL), + "aPipeline" + ) + } + # A trait the individual-level study carries, or one only the summary + # statistics carry: either is enough. + expect_silent(check("ENSG1")) + expect_silent(check("ENSG3")) + expect_error( + check("ENSG9"), + "aPipeline(MultiStudyQtlDataset): no traits selected.", + fixed = TRUE + ) +}) + # ----------------------------------------------------------------------------- # .buildJointSumstatZMatrix: SNP-order mismatch error # ----------------------------------------------------------------------------- @@ -1462,7 +1430,7 @@ test_that(".buildJointSumstatZMatrix: a mismatched SNP order across entries erro ) calls <- 0L local_mocked_bindings( - as.data.frame = function(x, studyName, context, trait, require, ...) { + .sumStatsDf = function(x, studyName, context, trait, require, ...) { calls <<- calls + 1L vid <- if (calls == 1L) { c("chr1:100:A:G", "chr1:200:A:G") @@ -1497,7 +1465,7 @@ test_that(".buildIndividualCrossContextXy: skips when a trait spans < 2 contexts se1 <- .js_makeSe(traits = "g1") # g1 present se0 <- .js_makeSe(traits = "other") # g1 absent local_mocked_bindings( - molecularTraits = function(data, contexts) { + .qtlContextSe = function(data, context) { if (identical(contexts, "c1")) se1 else se0 }, .package = "pecotmr" @@ -1517,7 +1485,7 @@ test_that(".buildIndividualCrossContextXy: region path + complete-case skip", { samp <- paste0("s", 1:6) region <- GenomicRanges::GRanges("chr1", IRanges::IRanges(1, 10000)) local_mocked_bindings( - molecularTraits = function(data, contexts) se, + .qtlContextSe = function(data, context) se, .fmResidGeno = function( x, contexts, @@ -1556,7 +1524,7 @@ test_that(".buildIndividualCrossContextXy: region path + complete-case skip", { test_that(".buildIndividualCrossContextXy: too few shared samples skips", { se <- .js_makeSe(traits = "g1", samples = paste0("s", 1:6)) local_mocked_bindings( - molecularTraits = function(data, contexts) se, + .qtlContextSe = function(data, context) se, .fmResidGeno = function( x, contexts, @@ -1590,10 +1558,15 @@ test_that(".buildIndividualCrossContextXy: too few shared samples skips", { ))) }) -test_that(".fmTraitsInRegion: filters traits by phenotype overlap with the region", { +test_that(".fmTraitsInRegion keeps overlapping traits; NULL keeps all", { se <- .js_makeSe(traits = c("g1", "g2")) # g1@~100, g2@~200 region <- GenomicRanges::GRanges("chr1", IRanges::IRanges(90, 160)) expect_equal(pecotmr:::.fmTraitsInRegion(se, c("g1", "g2"), region), "g1") + both <- GenomicRanges::GRanges("chr1", IRanges::IRanges(90, 260)) + expect_setequal( + pecotmr:::.fmTraitsInRegion(se, c("g1", "g2"), both), + c("g1", "g2") + ) expect_equal( pecotmr:::.fmTraitsInRegion(se, c("g1", "g2"), NULL), c("g1", "g2") @@ -1605,7 +1578,7 @@ test_that(".buildIndividualCrossTraitXy: skip branches (< 2 traits, region, comp samp <- paste0("s", 1:6) # < 2 scoped traits in the context -> NULL. local_mocked_bindings( - molecularTraits = function(data, contexts) se2, + .qtlContextSe = function(data, context) se2, .package = "pecotmr" ) expect_null(suppressMessages(pecotmr:::.buildIndividualCrossTraitXy( @@ -1619,7 +1592,7 @@ test_that(".buildIndividualCrossTraitXy: skip branches (< 2 traits, region, comp ))) # region path + < 2 complete cases. local_mocked_bindings( - molecularTraits = function(data, contexts) se2, + .qtlContextSe = function(data, context) se2, .fmResidGeno = function( x, contexts, @@ -1659,7 +1632,7 @@ test_that(".buildComposedIndividualXy: skip branches and single-context wrap", { scope <- list(contexts = list(S = "c1"), traits = list(S = c("g1", "g2"))) # Single context: YresList wrap branch, then a valid 2-tuple build. local_mocked_bindings( - molecularTraits = function(data, contexts) se, + .qtlContextSe = function(data, context) se, .fmResidGeno = function( x, contexts, @@ -1693,7 +1666,7 @@ test_that(".buildComposedIndividualXy: skip branches and single-context wrap", { # < 2 tuples -> NULL. scope1 <- list(contexts = list(S = "c1"), traits = list(S = "g1")) local_mocked_bindings( - molecularTraits = function(data, contexts) { + .qtlContextSe = function(data, context) { .js_makeSe(traits = "g1") }, .package = "pecotmr" @@ -1754,7 +1727,7 @@ test_that(".fmSynthesizeJointSpec: trait wins over context; single/single -> emp # ----------------------------------------------------------------------------- .js_fmEntry <- function(vid = "chr1:100:A:G") { - fineMappingRow( + FineMappingRow( variantIds = vid, susieFit = list(), topLoci = data.frame( @@ -1800,7 +1773,7 @@ test_that(".twasMergeResultsByKey: merges per-region TwasWeights entries", { context = "c1", trait = "t1", method = "lasso", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = "chr1:100:A:G", weights = 0.5 )) @@ -1842,8 +1815,8 @@ test_that(".twasDispatchJointSpecsQtlDataset: two region blocks are merged by ke trait = c("t1", "t1"), method = c("mrmash", "mrmash"), entry = list( - twasWeightsRow(variantIds = "chr1:100:A:G", weights = 0.5), - twasWeightsRow(variantIds = "chr1:100:A:G", weights = 0.5) + TwasWeightsRow(variantIds = "chr1:100:A:G", weights = 0.5), + TwasWeightsRow(variantIds = "chr1:100:A:G", weights = 0.5) ) ) } @@ -1963,7 +1936,7 @@ test_that(".twasDispatchJointSpecsMultiStudy: routes components + sumstats and r context = "c1", trait = "t1", method = "mrmash", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = "chr1:100:A:G", weights = 0.5 )) @@ -1973,7 +1946,7 @@ test_that(".twasDispatchJointSpecsMultiStudy: routes components + sumstats and r context = "c1", trait = "t1", method = "mrmash", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = "chr1:100:A:G", weights = 0.5 )), @@ -2020,8 +1993,8 @@ test_that(".twasDispatchJointSpecsMultiStudy: study spec, no sumStats -> message }) # ============================================================================ -# Mop-up: remaining .sp* empties, parseContexts unnamed list, validate no-op, -# X/Y builder skip paths, region-missing keys in merges, FM multi-region merge. +# Mop-up: remaining .sp* empties, X/Y builder skip paths, region-missing keys +# in merges, FM multi-region merge. # ============================================================================ test_that(".sp* QtlDataset: mismatched study / absent context return empty", { @@ -2030,15 +2003,15 @@ test_that(".sp* QtlDataset: mismatched study / absent context return empty", { contexts = "brain", traits = c("g1", "g2") ) - expect_equal(pecotmr:::.spListContexts(qd, "wrong"), character(0)) # 59 - expect_equal(pecotmr:::.spListTraits(qd, studyName = "wrong"), character(0)) # 93 - expect_equal(pecotmr:::.spListTraits(qd, context = "nope"), character(0)) # 98 + expect_equal(pecotmr:::.spListContexts(qd, "wrong"), character(0)) + expect_equal(pecotmr:::.spListTraits(qd, studyName = "wrong"), character(0)) + expect_equal(pecotmr:::.spListTraits(qd, context = "nope"), character(0)) }) test_that(".buildIndividualCrossTraitXy: disjoint X/Y samples skip the context", { se <- .js_makeSe(traits = c("g1", "g2"), samples = paste0("s", 1:6)) local_mocked_bindings( - molecularTraits = function(data, contexts) se, + .qtlContextSe = function(data, context) se, .fmResidGeno = function( x, contexts, @@ -2067,7 +2040,7 @@ test_that(".buildIndividualCrossTraitXy: disjoint X/Y samples skip the context", verbose = 1, label = "X", studyName = "S" - ))) # 730 + ))) }) test_that(".buildComposedIndividualXy: disjoint samples / missing trait col / NA rows skip", { @@ -2077,9 +2050,9 @@ test_that(".buildComposedIndividualXy: disjoint samples / missing trait col / NA contexts = list(S = c("c1", "c2")), traits = list(S = c("g1", "g2")) ) - # (a) disjoint X samples -> < 2 common -> NULL (774). + # (a) disjoint X samples -> < 2 common -> NULL. local_mocked_bindings( - molecularTraits = function(data, contexts) se, + .qtlContextSe = function(data, context) se, .fmResidGeno = function( x, contexts, @@ -2117,10 +2090,10 @@ test_that(".buildComposedIndividualXy: disjoint samples / missing trait col / NA cisWindow = 1000L, verbose = 1, label = "X" - ))) # 774 - # (b) one context's Y lacks the trait column -> tuple skipped -> < 2 yCols (779/785). + ))) + # (b) one context's Y lacks the trait column -> tuple skipped -> < 2 yCols. local_mocked_bindings( - molecularTraits = function(data, contexts) se, + .qtlContextSe = function(data, context) se, .fmResidGeno = function( x, contexts, @@ -2151,10 +2124,10 @@ test_that(".buildComposedIndividualXy: disjoint samples / missing trait col / NA cisWindow = 1000L, verbose = 1, label = "X" - ))) # 779/785 - # (c) two valid columns but < 2 complete rows (NA) -> NULL (788). + ))) + # (c) two valid columns but < 2 complete rows (NA) -> NULL. local_mocked_bindings( - molecularTraits = function(data, contexts) se, + .qtlContextSe = function(data, context) se, .fmResidGeno = function( x, contexts, @@ -2195,7 +2168,7 @@ test_that(".buildComposedIndividualXy: disjoint samples / missing trait col / NA cisWindow = 1000L, verbose = 1, label = "X" - ))) # 788 + ))) }) test_that(".fmMergeResultsByKey: a key missing from a later region contributes nothing", { @@ -2223,7 +2196,7 @@ test_that(".fmMergeResultsByKey: a key missing from a later region contributes n ) out <- pecotmr:::.fmMergeResultsByKey(list(twoRow, oneRow)) expect_equal(nrow(out), 2L) - expect_equal(seen, 3L) # 2 for c1 row + 1 for c2 row (849 else) + expect_equal(seen, 3L) # 2 for c1 row + 1 for c2 row }) test_that(".fmDispatchJointSpecsQtlDataset: two region blocks are merged", { @@ -2258,7 +2231,7 @@ test_that(".fmDispatchJointSpecsQtlDataset: two region blocks are merged", { list(data = qd, verbose = 0, xRegions = list(r1, r2)) ) expect_s4_class(res, "QtlFineMappingResult") - expect_equal(nrow(res), 2L) # 907-910 + expect_equal(nrow(res), 2L) # the two region blocks merged by key }) test_that(".fmDispatchJointSpecsQtlDataset: a single region returns directly; all-NULL -> NULL", { @@ -2284,7 +2257,7 @@ test_that(".fmDispatchJointSpecsQtlDataset: a single region returns directly; al list(), list(data = qd, verbose = 0, cisWindow = 1000L, xRegions = list(NULL)) ) - expect_identical(out, res1) # length-1 short-circuit (909) + expect_identical(out, res1) # length-1 short-circuit local_mocked_bindings( .fmDispatchJointSpecRegion = function(...) NULL, .package = "pecotmr" @@ -2294,7 +2267,7 @@ test_that(".fmDispatchJointSpecsQtlDataset: a single region returns directly; al "mvsusie", list(), list(data = qd, verbose = 0, cisWindow = 1000L, xRegions = list(NULL)) - )) # all-NULL (908) + )) # all-NULL }) test_that(".twasMergeResultsByKey: a key absent from a later region contributes nothing", { @@ -2304,8 +2277,8 @@ test_that(".twasMergeResultsByKey: a key absent from a later region contributes trait = c("t1", "t1"), method = c("lasso", "lasso"), entry = list( - twasWeightsRow(variantIds = "chr1:100:A:G", weights = 0.1), - twasWeightsRow(variantIds = "chr1:200:A:G", weights = 0.2) + TwasWeightsRow(variantIds = "chr1:100:A:G", weights = 0.1), + TwasWeightsRow(variantIds = "chr1:200:A:G", weights = 0.2) ) ) oneRow <- TwasWeights( @@ -2313,13 +2286,13 @@ test_that(".twasMergeResultsByKey: a key absent from a later region contributes context = "c1", trait = "t1", method = "lasso", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = "chr1:100:A:G", weights = 0.1 )) ) out <- pecotmr:::.twasMergeResultsByKey(list(twoRow, oneRow), c("rA", "rB")) - expect_equal(nrow(out), 2L) # 1063 else-branch + expect_equal(nrow(out), 2L) # c2 kept from the first region }) test_that(".twasMergedEntryAt concatenates one key's entry across regions", { @@ -2363,6 +2336,8 @@ test_that(".mergeEntryForKey gives NULL for a region lacking the tuple", { summaryStatsQc(qtlSumStatsMulticontextExample) )) } +# Built once on first use: summaryStatsQc() dominates these tests. +delayedAssign(".bjzSs", .bjz_qcd()) # @noRd .bjz_build <- function(ss, ...) { @@ -2377,14 +2352,14 @@ test_that(".mergeEntryForKey gives NULL for a region lacking the tuple", { } test_that(".buildJointSumstatZMatrix filters nothing by default", { - ss <- .bjz_qcd() + ss <- .bjzSs jz <- .bjz_build(ss) expect_equal(length(jz$variantIds), sum(lengths(ss)) / nrow(ss)) expect_equal(ncol(jz$Z), nrow(ss)) }) test_that(".buildJointSumstatZMatrix drops panel-rare variants", { - ss <- .bjz_qcd() + ss <- .bjzSs full <- .bjz_build(ss) tight <- .bjz_build(ss, mafCutoff = 0.2) expect_lt(length(tight$variantIds), length(full$variantIds)) @@ -2395,7 +2370,7 @@ test_that(".buildJointSumstatZMatrix drops panel-rare variants", { }) test_that(".buildJointSumstatZMatrix agrees with .panelVariantFilter", { - ss <- .bjz_qcd() + ss <- .bjzSs ids <- .bjz_build(ss)$variantIds for (cut in c(0.05, 0.2)) { expect_equal( @@ -2414,7 +2389,7 @@ test_that(".buildJointSumstatZMatrix keeps Z aligned to its ids", { # Each context's own frame is narrowed to the filtered set before the # shared-SNP-order check; otherwise that check fires on a length mismatch # the filter itself created. - ss <- .bjz_qcd() + ss <- .bjzSs full <- .bjz_build(ss) tight <- .bjz_build(ss, mafCutoff = 0.2) expect_equal(rownames(tight$Z), tight$variantIds) @@ -2424,7 +2399,7 @@ test_that(".buildJointSumstatZMatrix keeps Z aligned to its ids", { }) test_that(".buildJointSumstatZMatrix honours a missingness cutoff", { - ss <- .bjz_qcd() + ss <- .bjzSs expect_lt( length(.bjz_build(ss, imissCutoff = 0)$variantIds), length(.bjz_build(ss)$variantIds) @@ -2439,3 +2414,78 @@ test_that(".msFoldStudyResults answers NULL when every fold is empty", { expect_null(pecotmr:::.msFoldStudyResults(list(), NULL)) expect_null(pecotmr:::.msFoldStudyResults(list(NULL, NULL), NULL)) }) + +test_that("the joint builders read phenotypes under the run's phenotype QC", { + # The cross-context, cross-trait and composed assemblies each read their + # phenotypes through .fmResidPheno(); the run's resolved filter has to + # reach it, or a joint fit would ignore the QC every other fit applies. + seen <- list() + samp <- c("s1", "s2", "s3") + se <- SummarizedExperiment::SummarizedExperiment( + assays = list(e = matrix(0, 2, 3, dimnames = list(c("t1", "t2"), samp))) + ) + local_mocked_bindings( + .crossContextPerTrait = function(...) c("c1", "c2"), + .crossTraitTooFew = function(...) FALSE, + .qtlContextSe = function(data, context) se, + .buildResidGeno = function(...) { + matrix(0, 3, 1, dimnames = list(samp, "v1")) + }, + .fmResidPheno = function( + data, + contexts, + traitId, + phenotypeFilter, + ... + ) { + seen[[length(seen) + 1L]] <<- phenotypeFilter + NULL + }, + .crossContextAssemble = function(...) "cc", + .crossTraitAssemble = function(...) "ct", + .package = "pecotmr" + ) + pf <- list(naAction = "impute", outlierAction = "drop") + common <- list( + residualizationParam = ResidualizationParam(), + genotypeFilter = pecotmr:::.qtlResolveFilter(), + phenotypeFilter = pf + ) + pecotmr:::.buildIndividualCrossContextXy( + NULL, + "t1", + c("c1", "c2"), + 1e5, + 0, + "lbl", + residualizationParam = common$residualizationParam, + genotypeFilter = common$genotypeFilter, + phenotypeFilter = pf + ) + pecotmr:::.buildIndividualCrossTraitXy( + NULL, + "c1", + c("t1", "t2"), + 1e5, + 0, + "lbl", + "S", + residualizationParam = common$residualizationParam, + genotypeFilter = common$genotypeFilter, + phenotypeFilter = pf + ) + pecotmr:::.composedResidualized( + NULL, + c("c1", "c2"), + c("t1", "t2"), + 1e5, + NULL, + common$residualizationParam, + common$genotypeFilter, + pf + ) + expect_length(seen, 3L) + for (got in seen) { + expect_identical(got, pf) + } +}) diff --git a/tests/testthat/test_ld.R b/tests/testthat/test_ld.R index 4712ff93..ff0c62df 100644 --- a/tests/testthat/test_ld.R +++ b/tests/testthat/test_ld.R @@ -1,112 +1,6 @@ context("LD") library(tidyverse) -# Helper: build an LdData S4 object from variant IDs and optional correlation matrix -makeTestLdData <- function(variant_ids, R = NULL, blockMetadata = NULL) { - if (is.null(R)) { - p <- length(variant_ids) - R <- diag(p) - rownames(R) <- colnames(R) <- variant_ids - } - ref_panel <- pecotmr:::parseVariantId(variant_ids) - ref_panel$variant_id <- variant_ids - variants_gr <- pecotmr:::.refPanelToGranges(ref_panel) - if (is.null(blockMetadata)) { - blockMetadata <- data.frame( - blockId = 1L, - chrom = as.character(ref_panel$chrom[1]), - blockStart = min(ref_panel$pos), - blockEnd = max(ref_panel$pos), - size = length(variant_ids), - startIdx = 1L, - endIdx = length(variant_ids), - stringsAsFactors = FALSE - ) - } - LdData( - correlation = R, - variants = variants_gr, - blockMetadata = blockMetadata - ) -} - -generateDummyData <- function() { - region <- data.frame( - chrom = "chr1", - start = c(1000), - end = c(1190) - ) - meta_df <- data.frame( - chrom = "chr1", - start = c(1000, 1200, 1400, 1600, 1800), - end = c(1200, 1400, 1600, 1800, 2000), - path = c( - "./test_data/LD_block_1.chr1_1000_1200.float16.txt.xz,./test_data/LD_block_1.chr1_1000_1200.float16.bim", - "./test_data/LD_block_2.chr1_1200_1400.float16.txt.xz,./test_data/LD_block_2.chr1_1200_1400.float16.bim", - "./test_data/LD_block_3.chr1_1400_1600.float16.txt.xz,./test_data/LD_block_3.chr1_1400_1600.float16.bim", - "./test_data/LD_block_4.chr1_1600_1800.float16.txt.xz,./test_data/LD_block_4.chr1_1600_1800.float16.bim", - "./test_data/LD_block_5.chr1_1800_2000.float16.txt.xz,./test_data/LD_block_5.chr1_1800_2000.float16.bim" - ) - ) - return(list(region = region, meta = meta_df)) -} - -# Generate a wider region that spans multiple blocks for partition testing -generateMultiBlockData <- function() { - region <- data.frame( - chrom = "chr1", - start = c(1000), - end = c(1500) - ) - meta_df <- data.frame( - chrom = "chr1", - start = c(1000, 1200, 1400, 1600, 1800), - end = c(1200, 1400, 1600, 1800, 2000), - path = c( - "./test_data/LD_block_1.chr1_1000_1200.float16.txt.xz,./test_data/LD_block_1.chr1_1000_1200.float16.bim", - "./test_data/LD_block_2.chr1_1200_1400.float16.txt.xz,./test_data/LD_block_2.chr1_1200_1400.float16.bim", - "./test_data/LD_block_3.chr1_1400_1600.float16.txt.xz,./test_data/LD_block_3.chr1_1400_1600.float16.bim", - "./test_data/LD_block_4.chr1_1600_1800.float16.txt.xz,./test_data/LD_block_4.chr1_1600_1800.float16.bim", - "./test_data/LD_block_5.chr1_1800_2000.float16.txt.xz,./test_data/LD_block_5.chr1_1800_2000.float16.bim" - ) - ) - return(list(region = region, meta = meta_df)) -} - -# LdData stores block metadata as a GRanges, and the block internals read it -# as one (mcols via `$`, blocks via `[` and length()). The fixtures below are -# index-only tables, so a span is synthesised from whatever they carry -- the -# merge and validation logic reads chrom, size and the index range, not the -# span. -.ld_bmGr <- function(df) { - has <- function(n) n %in% names(df) - st <- if (has("blockStart")) { - df$blockStart - } else if (has("startIdx")) { - df$startIdx - } else { - rep(1L, nrow(df)) - } - en <- if (has("blockEnd")) { - df$blockEnd - } else if (has("endIdx")) { - df$endIdx - } else { - rep(1L, nrow(df)) - } - gr <- GenomicRanges::GRanges( - seqnames = as.character(df$chrom), - ranges = IRanges::IRanges(start = as.integer(st), end = as.integer(en)) - ) - keep <- intersect(c("blockId", "size", "startIdx", "endIdx"), names(df)) - S4Vectors::mcols(gr) <- S4Vectors::DataFrame( - as.data.frame(df[, keep, drop = FALSE]) - ) - gr -} - -# ---- partitionLdMatrix ---- - # ---- orderDedupRegions ---- test_that("orderDedupRegions removes duplicate regions", { @@ -134,24 +28,15 @@ test_that("orderDedupRegions orders and deduplicates across chromosomes", { expect_true(all(diff(result$start[result$chrom == result$chrom[1]]) >= 0)) }) -test_that("orderDedupRegions strips chr prefix", { - df <- data.frame( - chrom = c("chr1", "chr2"), - start = c(100, 200), - end = c(200, 300) - ) - result <- pecotmr:::orderDedupRegions(df) - expect_equal(result$chrom, c("1", "2")) # normalized to a bare string, not integer -}) - test_that("orderDedupRegions sorts X/Y/MT after autosomes and keeps chrom a string", { df <- data.frame( - chrom = c("chrX", "chr2", "chr1", "chrMT"), + chrom = c("chrX", "chr2", "chr1", "chrM"), start = c(1L, 1L, 1L, 1L), end = c(2L, 2L, 2L, 2L) ) result <- pecotmr:::orderDedupRegions(df) - expect_equal(result$chrom, c("1", "2", "X", "MT")) # genomic order, not NA-collapsed + # Genomic order, not alphabetical and not NA-collapsed. + expect_equal(result$chrom, c("chr1", "chr2", "chrX", "chrM")) expect_type(result$chrom, "character") }) @@ -247,18 +132,6 @@ test_that("extractFilePaths errors on missing column", { ) }) -# ---- partitionLdMatrix: different chromosomes ---- - -# ---- extractLdForRegion ---- - -# ---- createLdMatrix ---- - -# ---- validateBlockStructure ---- - -# ---- mergeBlocks ---- - -# ---- canMerge ---- - # =========================================================================== # checkLd (regularize_ld) # =========================================================================== @@ -342,49 +215,27 @@ test_that("checkLd eigenfix does nothing when matrix is already PD", { # =========================================================================== geno_test_data_dir <- test_path("test_data") -geno_region_all <- "chr21:17513228-17592874" - -test_that("resolveLdSource detects PLINK2 from metadata", { - meta_file <- file.path(geno_test_data_dir, "ld_meta_resolve_p2_tmp.tsv") - on.exit(unlink(meta_file), add = TRUE) - writeLines(paste("chrom", "start", "end", "path", sep = "\t"), meta_file) - cat( - paste("21", "0", "0", "test_variants", sep = "\t"), - "\n", - file = meta_file, - append = TRUE - ) - result <- pecotmr:::resolveLdSource(meta_file) - expect_equal(result$type, "plink2") - expect_equal(result$metaPath, meta_file) -}) - -test_that("resolveLdSource detects VCF from metadata", { - meta_file <- file.path(geno_test_data_dir, "ld_meta_resolve_vcf_tmp.tsv") - on.exit(unlink(meta_file), add = TRUE) - writeLines(paste("chrom", "start", "end", "path", sep = "\t"), meta_file) - cat( - paste("21", "0", "0", "test_variants.vcf.gz", sep = "\t"), - "\n", - file = meta_file, - append = TRUE - ) - result <- pecotmr:::resolveLdSource(meta_file) - expect_equal(result$type, "vcf") -}) - -test_that("resolveLdSource detects GDS from metadata", { - meta_file <- file.path(geno_test_data_dir, "ld_meta_resolve_gds_tmp.tsv") - on.exit(unlink(meta_file), add = TRUE) - writeLines(paste("chrom", "start", "end", "path", sep = "\t"), meta_file) - cat( - paste("21", "0", "0", "test_variants.gds", sep = "\t"), - "\n", - file = meta_file, - append = TRUE - ) - result <- pecotmr:::resolveLdSource(meta_file) - expect_equal(result$type, "gds") +geno_region_all <- GenomicRanges::GRanges("chr21:17513228-17592874") + +test_that("resolveLdSource tells the format of the genotypes metadata names", { + # One row per chromosome naming its genotype file or PLINK prefix, + # resolved beside the metadata file. + rows <- c( + plink2 = "21\t0\t0\ttest_variants", + vcf = "21\t0\t0\ttest_variants.vcf.gz", + gds = "21\t0\t0\ttest_variants.gds", + plink1 = "22\t0\t0\tprotocol_example.genotype" + ) + for (format in names(rows)) { + meta_file <- withr::local_tempfile( + tmpdir = geno_test_data_dir, + fileext = ".tsv" + ) + writeLines(c("chrom\tstart\tend\tpath", rows[[format]]), meta_file) + result <- pecotmr:::resolveLdSource(meta_file) + expect_equal(result$type, format, info = format) + expect_equal(result$metaPath, meta_file, info = format) + } }) test_that("resolveLdSource tells a file's format as readGenotypes does", { @@ -443,22 +294,6 @@ test_that("resolveLdSource errors on missing file", { ) }) -test_that("resolveLdSource errors on 0:0 sentinel with non-genotype path", { - meta_file <- file.path(geno_test_data_dir, "ld_meta_resolve_bad_tmp.tsv") - on.exit(unlink(meta_file), add = TRUE) - writeLines(paste("chrom", "start", "end", "path", sep = "\t"), meta_file) - cat( - paste("21", "0", "0", "nonexistent_prefix", sep = "\t"), - "\n", - file = meta_file, - append = TRUE - ) - expect_error( - pecotmr:::resolveLdSource(meta_file), - "does not resolve to genotype files" - ) -}) - # =========================================================================== # resolveGenotypePathForRegion # =========================================================================== @@ -493,23 +328,20 @@ test_that("resolveGenotypePathForRegion errors on missing chromosome", { ) }) -# =========================================================================== -# resolveLdSource: PLINK1 detection -# =========================================================================== - -test_that("resolveLdSource detects PLINK1 from metadata", { - skip_if_not_installed("snpStats") - meta_file <- file.path(geno_test_data_dir, "ld_meta_resolve_p1_tmp.tsv") - on.exit(unlink(meta_file), add = TRUE) - writeLines(paste("chrom", "start", "end", "path", sep = "\t"), meta_file) - cat( - paste("22", "0", "0", "protocol_example.genotype", sep = "\t"), - "\n", - file = meta_file, - append = TRUE +test_that("resolveGenotypePathForRegion takes a window on one chromosome", { + # A per-chromosome meta names one file per chromosome, so a window over + # two cannot resolve to one path; and a window is a GRanges, not a string. + expect_error( + pecotmr:::resolveGenotypePathForRegion( + "unused.tsv", + GenomicRanges::GRanges(c("chr21:1-10", "chr22:1-10")) + ), + "`region` spans chromosomes chr21, chr22" + ) + expect_error( + pecotmr:::resolveGenotypePathForRegion("unused.tsv", "chr21:1-10"), + "`region` must be a GRanges" ) - result <- pecotmr:::resolveLdSource(meta_file) - expect_equal(result$type, "plink1") }) # =========================================================================== @@ -540,7 +372,10 @@ test_that("regionalLdMeta returns correct file paths for single block", { ) ) writeLines(lines, meta_file) - result <- pecotmr:::regionalLdMeta(meta_file, "chr1:1050-1150") + result <- pecotmr:::regionalLdMeta( + meta_file, + GenomicRanges::GRanges("chr1:1050-1150") + ) expect_true(is.list(result)) expect_true(length(result$intersections$LD_file_paths) >= 1) # All returned paths should exist @@ -576,64 +411,11 @@ test_that("regionalLdMeta spans multiple blocks for wide region", { ) ) writeLines(lines, meta_file) - result <- pecotmr:::regionalLdMeta(meta_file, "chr1:1000-1500") - expect_true(length(result$intersections$LD_file_paths) >= 2) -}) - -# =========================================================================== -# dropCollinearColumns: strategy variants -# =========================================================================== - -test_that("dropCollinearColumns variance strategy removes lowest-variance column", { - set.seed(42) - X <- matrix(rnorm(100 * 4), 100, 4) - colnames(X) <- c("a", "b", "c", "d") - # Make column "c" have near-zero variance - X[, "c"] <- X[1, "c"] - result <- pecotmr:::dropCollinearColumns( - X, - c("b", "c", "d"), - strategy = "variance" - ) - expect_false("c" %in% colnames(result)) - expect_equal(ncol(result), 3L) -}) - -test_that("dropCollinearColumns responseCorrelation strategy works", { - set.seed(42) - X <- matrix(rnorm(100 * 3), 100, 3) - colnames(X) <- c("a", "b", "c") - y <- X[, "a"] + rnorm(100, sd = 0.1) # y correlates strongly with "a" - result <- pecotmr:::dropCollinearColumns( - X, - c("a", "b", "c"), - strategy = "responseCorrelation", - response = y - ) - # Should keep "a" (highest |cor| with response) and remove one of b/c - expect_true("a" %in% colnames(result)) - expect_equal(ncol(result), 2L) -}) - -test_that("dropCollinearColumns responseCorrelation errors without response", { - X <- matrix(1:12, 4, 3) - colnames(X) <- c("a", "b", "c") - expect_error( - pecotmr:::dropCollinearColumns( - X, - c("a", "b"), - strategy = "responseCorrelation" - ), - "response must be supplied" + result <- pecotmr:::regionalLdMeta( + meta_file, + GenomicRanges::GRanges("chr1:1000-1500") ) -}) - -test_that("dropCollinearColumns with single problematic column removes it", { - X <- matrix(rnorm(40), 10, 4) - colnames(X) <- c("a", "b", "c", "d") - result <- pecotmr:::dropCollinearColumns(X, "b", strategy = "correlation") - expect_false("b" %in% colnames(result)) - expect_equal(ncol(result), 3L) + expect_true(length(result$intersections$LD_file_paths) >= 2) }) # =========================================================================== @@ -754,7 +536,7 @@ test_that("ldClumpByScore errors on mismatched chr/pos length", { # ldPruneByCorrelation: verbose paths # =========================================================================== -test_that("ldPruneByCorrelation verbose reports pruning", { +test_that("ldPruneByCorrelation reports pruning only when verbose", { # Create matrix with correlated columns set.seed(42) base <- rnorm(100) @@ -766,6 +548,7 @@ test_that("ldPruneByCorrelation verbose reports pruning", { rnorm(100) ) colnames(X) <- sprintf("chr1:%d:A:G", 100L * (1:5)) + expect_silent(ldPruneByCorrelation(X, corThres = 0.5)) expect_message( ldPruneByCorrelation(X, corThres = 0.5, verbose = TRUE), "pruned" @@ -783,46 +566,6 @@ test_that("ldPruneByCorrelation verbose reports no pruning", { ) }) -# ============================================================================= -# loadLdMatrix duplicate variant removal -# ============================================================================= - -test_that("loadLdMatrix dedup removes duplicated variants from result", { - # Simulate what loadLdMatrix does after calling the backend: a result with - # duplicated ldVariants should have duplicates removed. - # We test the dedup logic by constructing a mock result and verifying - # the internal dedup code path via the exported function's contract. - # Since we can't easily call the real function without data, test the dedup - # behavior directly on the result structure. - mat <- matrix(1:16, nrow = 4, ncol = 4) - variants <- c( - "chr1:100:A:G", - "chr1:200:C:T", - "chr1:100:A:G", - "chr1:300:T:A" - ) - ref <- data.frame( - chrom = c(1, 1, 1, 1), - pos = c(100, 200, 100, 300), - A2 = c("A", "C", "A", "T"), - A1 = c("G", "T", "G", "A") - ) - - # Apply the same dedup logic used in loadLdMatrix - dup_idx <- which(duplicated(variants)) - expect_equal(dup_idx, 3L) - - variants_clean <- variants[-dup_idx] - mat_clean <- mat[-dup_idx, -dup_idx, drop = FALSE] - ref_clean <- ref[-dup_idx, , drop = FALSE] - - expect_equal(length(variants_clean), 3) - expect_equal(nrow(mat_clean), 3) - expect_equal(ncol(mat_clean), 3) - expect_equal(nrow(ref_clean), 3) - expect_false(any(duplicated(variants_clean))) -}) - test_data_dir <- test_path("test_data") library(testthat) @@ -841,6 +584,7 @@ test_that("ldPruneByCorrelation removes highly correlated columns", { result <- ldPruneByCorrelation(X, corThres = 0.9) expect_true(ncol(result$X.new) < p) expect_equal(length(result$filter.id), ncol(result$X.new)) + expect_true(all(result$filter.id %in% seq_len(p))) }) test_that("ldPruneByCorrelation keeps all columns when uncorrelated", { @@ -852,6 +596,7 @@ test_that("ldPruneByCorrelation keeps all columns when uncorrelated", { result <- ldPruneByCorrelation(X, corThres = 0.99) expect_equal(ncol(result$X.new), p) expect_equal(result$filter.id, seq_len(p)) + expect_equal(colnames(result$X.new), colnames(X)) }) test_that("ldPruneByCorrelation preserves colnames for single remaining column", { @@ -891,28 +636,6 @@ test_that("ldPruneByCorrelation strict threshold removes at least as many as len expect_true(ncol(result_strict$X.new) <= ncol(result_lenient$X.new)) }) -test_that("ldPruneByCorrelation preserves colnames when no columns deleted", { - set.seed(42) - n <- 100 - p <- 3 - X <- matrix(rnorm(n * p), nrow = n) - colnames(X) <- c("snp_a", "snp_b", "snp_c") - result <- ldPruneByCorrelation(X, corThres = 0.999) - expect_equal(colnames(result$X.new), colnames(X)) -}) - -test_that("ldPruneByCorrelation is silent by default, chatty with verbose", { - set.seed(1) - X <- matrix(rnorm(100), 20, 5) - colnames(X) <- sprintf("chr1:%d:A:G", 100L * (1:5)) - X[, 2] <- X[, 1] + rnorm(20, sd = 1e-3) - expect_silent(ldPruneByCorrelation(X, corThres = 0.9)) - expect_message( - ldPruneByCorrelation(X, corThres = 0.9, verbose = TRUE), - "ldPruneByCorrelation" - ) -}) - # =========================================================================== # dropCollinearColumns # =========================================================================== @@ -920,7 +643,7 @@ test_that("ldPruneByCorrelation is silent by default, chatty with verbose", { # dropCollinearColumns and enforceDesignFullRank are unexported helpers; # access them via pecotmr::: in these tests. -test_that("dropCollinearColumns returns X unchanged when problematicCols is empty", { +test_that("dropCollinearColumns returns X unchanged with no candidates", { X <- matrix(rnorm(100), nrow = 20, ncol = 5) colnames(X) <- sprintf("chr1:%d:A:G", 100L * (1:5)) result <- pecotmr:::dropCollinearColumns( @@ -928,7 +651,7 @@ test_that("dropCollinearColumns returns X unchanged when problematicCols is empt problematicCols = character(0), strategy = "correlation" ) - expect_equal(ncol(result), 5) + expect_identical(result, X) }) test_that("dropCollinearColumns removes single problematic column", { @@ -959,31 +682,40 @@ test_that("dropCollinearColumns variance strategy removes lowest variance column expect_false("low_var" %in% colnames(result)) }) -test_that("dropCollinearColumns correlation strategy with two columns removes one", { +test_that("dropCollinearColumns correlation drops one of two candidates", { set.seed(42) X <- matrix(rnorm(100), nrow = 20, ncol = 5) colnames(X) <- sprintf("chr1:%d:A:G", 100L * (1:5)) + candidates <- c("chr1:100:A:G", "chr1:200:A:G") result <- pecotmr:::dropCollinearColumns( X, - problematicCols = c("chr1:100:A:G", "chr1:200:A:G"), + problematicCols = candidates, strategy = "correlation" ) - expect_equal(ncol(result), 4) + # Which of the two goes is a random pick, but it is always one of them, + # and every other column comes through untouched. + dropped <- setdiff(colnames(X), colnames(result)) + expect_length(dropped, 1L) + expect_true(is_in(dropped, candidates)) + expect_identical(result, X[, colnames(X) != dropped]) }) -test_that("dropCollinearColumns correlation strategy with 3+ cols removes highest sum", { +test_that("dropCollinearColumns correlation drops the highest-sum candidate", { set.seed(42) n <- 50 X <- matrix(rnorm(n * 4), nrow = n, ncol = 4) colnames(X) <- sprintf("chr1:%d:A:G", 100L * (1:4)) - X[, 2] <- X[, 1] + rnorm(n, sd = 0.01) - X[, 3] <- X[, 1] + rnorm(n, sd = 0.01) + # chr1:200 is built from both of the other candidates, which are + # independent of each other, so its sum of |cor| with them is the + # largest by a wide margin. It sits mid-list, so neither the first nor + # the last candidate would pass for it. + X[, 2] <- X[, 1] + X[, 3] + rnorm(n, sd = 0.1) result <- pecotmr:::dropCollinearColumns( X, problematicCols = c("chr1:100:A:G", "chr1:200:A:G", "chr1:300:A:G"), strategy = "correlation" ) - expect_equal(ncol(result), 3) + expect_identical(result, X[, -2L]) }) test_that("dropCollinearColumns responseCorrelation strategy removes lowest |cor| with response", { @@ -1011,7 +743,7 @@ test_that("dropCollinearColumns errors on responseCorrelation without response", problematicCols = c("chr1:100:A:G", "chr1:200:A:G"), strategy = "responseCorrelation" ), - "response" + "response must be supplied" ) }) @@ -1055,17 +787,6 @@ test_that("dropCollinearColumns is silent by default", { # enforceDesignFullRank (unexported) # =========================================================================== -test_that("enforceDesignFullRank returns full-rank matrix when already full rank", { - set.seed(42) - n <- 50 - X <- matrix(rnorm(n * 3), nrow = n, ncol = 3) - colnames(X) <- sprintf("chr1:%d:A:G", 100L * (1:3)) - C <- matrix(rnorm(n * 2), nrow = n, ncol = 2) - result <- enforceDesignFullRank(X = X, C = C, strategy = "correlation") - expect_true(is.matrix(result)) - expect_true(ncol(result) >= 1) -}) - test_that("enforceDesignFullRank handles rank-deficient design via correlation fallback", { set.seed(42) n <- 50 @@ -1102,43 +823,7 @@ test_that("enforceDesignFullRank is silent by default", { # ldClumpByScore # =========================================================================== -test_that("ldClumpByScore skips clumping on single-column input", { - skip_if_not_installed("bigsnpr") - skip_if_not_installed("bigstatsr") - set.seed(1) - X <- matrix(rbinom(100, 2, 0.3), 100, 1) - colnames(X) <- "chr1:100:A:G" - keep <- ldClumpByScore(X, score = 1.0, chr = 1L, pos = 100L, r2 = 0.2) - expect_equal(keep, 1L) -}) - -test_that("ldClumpByScore validates input lengths", { - skip_if_not_installed("bigsnpr") - skip_if_not_installed("bigstatsr") - set.seed(1) - X <- matrix(rbinom(100 * 3, 2, 0.3), 100, 3) - colnames(X) <- paste0("chr1:", seq_len(3) * 1000, ":A:G") - expect_error( - ldClumpByScore( - X, - score = 1:2, - chr = rep(1L, 3), - pos = seq_len(3) * 1000L - ), - "score" - ) - expect_error( - ldClumpByScore( - X, - score = 1:3, - chr = rep(1L, 2), - pos = seq_len(3) * 1000L - ), - "chr.*Must have length 3" - ) -}) - -test_that("ldClumpByScore returns indices on real data", { +test_that("ldClumpByScore drops the lower-scoring copy of a perfect-LD pair", { skip_if_not_installed("bigsnpr") skip_if_not_installed("bigstatsr") set.seed(1) @@ -1161,72 +846,58 @@ test_that("ldClumpByScore returns indices on real data", { # Tests migrated from test_misc.R (computeLd + .findValidFilePath*) # =========================================================================== +# The fixtures sit in test_data, which R CMD check copies with the tests, +# unlike the package root's own files. +.ldBed <- test_path("test_data", "protocol_example.genotype.bed") + test_that("findValidFilePath returns target when it exists directly", { - pkg_root <- normalizePath( - file.path(test_path(), "..", ".."), - mustWork = TRUE - ) - target <- file.path(pkg_root, "DESCRIPTION") - ref <- file.path(pkg_root, "NAMESPACE") - skip_if_not( - file.exists(target) && file.exists(ref), - "Package root files not found" - ) + target <- test_path("test_data", "protocol_example.genotype.bim") result <- pecotmr:::.findValidFilePath( - referenceFilePath = ref, + referenceFilePath = .ldBed, targetFilePath = target ) expect_equal(result, target) }) test_that("findValidFilePath constructs path from reference directory", { - pkg_root <- normalizePath( - file.path(test_path(), "..", ".."), - mustWork = TRUE - ) - ref <- file.path(pkg_root, "NAMESPACE") - skip_if_not(file.exists(ref), "NAMESPACE not found") result <- pecotmr:::.findValidFilePath( - referenceFilePath = ref, - targetFilePath = "DESCRIPTION" + referenceFilePath = .ldBed, + targetFilePath = "protocol_example.genotype.bim" + ) + expect_equal( + result, + test_path("test_data", "protocol_example.genotype.bim") ) - expect_true(file.exists(result)) - expect_true(grepl("DESCRIPTION$", result)) }) test_that("findValidFilePath errors when both paths are invalid", { expect_error( pecotmr:::.findValidFilePath( referenceFilePath = "/nonexistent/dir/ref.txt", - targetFilePath = "/nonexistent/target.txt" + targetFilePath = "target.txt" + ), + str_c( + "Both reference and target file paths do not work. Tried paths: ", + "'/nonexistent/dir/ref.txt' and '/nonexistent/dir/target.txt'" ), - "Both reference and target file paths do not work" + fixed = TRUE ) }) test_that("findValidFilePath returns reference when target is invalid but reference exists", { - pkg_root <- normalizePath( - file.path(test_path(), "..", ".."), - mustWork = TRUE - ) - ref <- file.path(pkg_root, "DESCRIPTION") - skip_if_not(file.exists(ref), "DESCRIPTION not found") result <- pecotmr:::.findValidFilePath( - referenceFilePath = ref, + referenceFilePath = .ldBed, targetFilePath = "/totally/bogus/path.txt" ) - expect_equal(result, ref) + expect_equal(result, .ldBed) }) test_that("findValidFilePaths resolves multiple targets", { - pkg_root <- normalizePath( - file.path(test_path(), "..", ".."), - mustWork = TRUE - ) - ref <- file.path(pkg_root, "NAMESPACE") - skip_if_not(file.exists(ref), "NAMESPACE not found") - targets <- c("DESCRIPTION", "NAMESPACE") - result <- pecotmr:::.findValidFilePaths(ref, targets) + targets <- c( + "protocol_example.genotype.bim", + "protocol_example.genotype.fam" + ) + result <- pecotmr:::.findValidFilePaths(.ldBed, targets) expect_length(result, 2) expect_true(all(file.exists(result))) }) @@ -1299,29 +970,6 @@ test_that("computeLd population method handles column with all NA", { expect_equal(R[2, 4], 0) }) -test_that("computeLd with larger matrix (100 SNPs) is fast and valid", { - set.seed(99) - X <- matrix(sample(0:2, 5000, replace = TRUE), nrow = 50, ncol = 100) - colnames(X) <- paste0("rs", 1:100) - - R <- computeLd(X, method = "sample") - expect_equal(dim(R), c(100L, 100L)) - expect_equal(unname(diag(R)), rep(1, 100)) - expect_true(isSymmetric(R)) - expect_true(all(R >= -1 & R <= 1)) -}) - -test_that("computeLd population method with larger matrix is valid", { - set.seed(99) - X <- matrix(sample(0:2, 5000, replace = TRUE), nrow = 50, ncol = 100) - colnames(X) <- paste0("rs", 1:100) - - R <- computeLd(X, method = "population") - expect_equal(dim(R), c(100L, 100L)) - expect_equal(unname(diag(R)), rep(1, 100)) - expect_true(isSymmetric(R)) -}) - test_that("computeLd with perfectly correlated SNPs returns correlation of 1", { set.seed(42) col1 <- sample(0:2, 50, replace = TRUE) @@ -1333,17 +981,6 @@ test_that("computeLd with perfectly correlated SNPs returns correlation of 1", { expect_equal(R[2, 1], 1.0, tolerance = 1e-10) }) -test_that("computeLd population method with trim_samples trims correctly", { - set.seed(42) - X <- matrix(sample(0:2, 33, replace = TRUE), nrow = 11, ncol = 3) - colnames(X) <- paste0("rs", 1:3) - - R_trimmed <- computeLd(X, method = "population", trimSamples = TRUE) - expect_equal(dim(R_trimmed), c(3L, 3L)) - R_full <- computeLd(X, method = "population", trimSamples = FALSE) - expect_equal(dim(R_full), c(3L, 3L)) -}) - test_that("computeLd with two monomorphic SNPs produces 0 off-diagonal", { X <- matrix(c(rep(1, 50), rep(2, 50)), nrow = 50, ncol = 2) colnames(X) <- c("mono1", "mono2") @@ -1380,18 +1017,6 @@ test_that("computeLd with heavy missingness still produces valid matrix", { expect_equal(unname(diag(R_pop)), rep(1, 5)) }) -test_that("computeLd with NA genotypes and sample method", { - set.seed(42) - X <- matrix(sample(0:2, 200, replace = TRUE), nrow = 50) - X[1, 1] <- NA - X[5, 3] <- NA - colnames(X) <- paste0("rs", 1:4) - - R <- computeLd(X, method = "sample") - expect_true(all(!is.na(R))) - expect_equal(unname(diag(R)), rep(1, 4)) -}) - test_that("computeLd errors on NULL input", { expect_error(computeLd(NULL), "X must be provided") }) @@ -1454,19 +1079,9 @@ test_that("computeLd gcta preserves column names", { }) # ============================================================================= -# waldTestPval +# computeLd: trimSamples and shrinkage # ============================================================================= -test_that("computeLd sample method without Rfast falls back to cor", { - set.seed(42) - X <- matrix(sample(0:2, 100, replace = TRUE), nrow = 20, ncol = 5) - colnames(X) <- paste0("snp", 1:5) - R <- computeLd(X, method = "sample") - expect_equal(dim(R), c(5, 5)) - expect_equal(as.numeric(diag(R)), rep(1, 5)) - expect_true(all(abs(R) <= 1)) -}) - test_that("computeLd with gcta method and trim_samples", { set.seed(42) # 21 samples -> trimmed to 20 (multiple of 4) @@ -1484,6 +1099,8 @@ test_that("computeLd population method with trim_samples", { R <- computeLd(X, method = "population", trimSamples = TRUE) expect_equal(dim(R), c(5, 5)) expect_equal(as.numeric(diag(R)), rep(1, 5)) + # 21 samples trim to the first 20, a multiple of four. + expect_equal(R, computeLd(X[1:20, ], method = "population")) }) test_that("computeLd with shrinkage > 0", { @@ -1500,13 +1117,51 @@ test_that("computeLd with shrinkage > 0", { expect_equal(off_diag_s, 0.9 * off_diag_no) }) +test_that("computeLd on a GDS panel uses the in-memory path", { + # The native SNPRelate route is no longer chosen implicitly by format: + # it applies a different missing-data policy, so it is opt-in via + # onDisk = TRUE rather than a silent consequence of the panel's format. + skip_if_not_installed("gdsfmt") + skip_if_not_installed("GDSArray") + panel <- readGenotypes(test_path("test_data", "test_variants.gds")) + R <- computeLd(panel, snpIdx = 1:6, backend = "internal") + expect_equal(dim(R), c(6L, 6L)) + expect_true(all(is.finite(R))) + expect_false(anyNA(R)) + expect_equal(unname(diag(R)), rep(1, 6), tolerance = 1e-6) + expect_identical(rownames(R), rownames(panel)[1:6]) +}) + +test_that("computeLd returns identity for a single-variant block", { + skip_if_not_installed("pgenlibr") + td <- test_path("test_data") + handle <- readGenotypeHandle( + file.path(td, "test_variants"), + format = "plink2" + ) + R <- computeLd(handle, snpIdx = 1L, backend = "internal") + expect_equal(R, diag(1)) +}) + +test_that("computeLd on a panel computes via the general path", { + skip_if_not_installed("pgenlibr") + td <- test_path("test_data") + handle <- readGenotypeHandle( + file.path(td, "test_variants"), + format = "plink2" + ) + R <- computeLd(handle, snpIdx = 1:5, backend = "internal") + expect_equal(dim(R), c(5L, 5L)) + expect_equal(unname(diag(R)), rep(1, 5), tolerance = 1e-6) +}) + # ============================================================================= # Additional coverage: findIntersectionRows / regionalLdMeta edge cases # ============================================================================= test_that("findIntersectionRows errors when region falls in a coverage gap", { # Chromosome exists but there is a gap between the two blocks; after - # clamping, no single row covers the query start -> stop (line 33). + # clamping, no single row covers the query start -> error. gd <- data.frame(chrom = c(1, 1), start = c(100, 300), end = c(150, 350)) expect_error( pecotmr:::findIntersectionRows(gd, 1, 200, 250), @@ -1530,10 +1185,13 @@ test_that("regionalLdMeta handles whole-chromosome 0:0 sentinel rows", { file = meta_file, append = TRUE ) - result <- pecotmr:::regionalLdMeta(meta_file, "chr1:1000-1190") + result <- pecotmr:::regionalLdMeta( + meta_file, + GenomicRanges::GRanges("chr1:1000-1190") + ) expect_true(length(result$intersections$LD_file_paths) >= 1) expect_true(all(file.exists(result$intersections$LD_file_paths))) - # 0:0 sentinel row should have had its end set to Inf internally (line 103) + # 0:0 sentinel row should have had its end set to Inf internally expect_true(is.infinite(max(result$ldMetaData$end))) }) @@ -1551,10 +1209,10 @@ test_that("regionalLdMeta validates complete coverage when required", { ) ) writeLines(lines, meta_file) - # Region fully inside block 1 -> validateSelectedRegion passes (line 122) + # Region fully inside block 1 -> validateSelectedRegion passes result <- pecotmr:::regionalLdMeta( meta_file, - "chr1:1050-1150", + GenomicRanges::GRanges("chr1:1050-1150"), completeCoverageRequired = TRUE ) expect_true(length(result$intersections$LD_file_paths) >= 1) @@ -1629,18 +1287,6 @@ test_that(".ldFromRef matches non-prefixed ids to a chr-prefixed panel", { expect_equal(rownames(m), req) # caller's labels preserved }) -test_that(".ldFromRef is unchanged when request and panel share a convention", { - skip_if_not_installed("pgenlibr") - h <- readGenotypeHandle( - file.path(geno_test_data_dir, "test_variants"), - format = "plink2" - ) - pid <- as.character(snpInfo(h)$SNP) - m <- pecotmr:::.ldFromRef(h, pid[1:3]) - expect_equal(dim(m), c(3L, 3L)) - expect_equal(rownames(m), pid[1:3]) -}) - test_that(".ldFromRef still errors on a variant absent after reconciling", { skip_if_not_installed("pgenlibr") h <- readGenotypeHandle( @@ -1676,7 +1322,7 @@ test_that(".ldFromRef rejects an ldReference that is not a genotype panel", { format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * seq_len(snpN)), - CHR = rep("1", snpN), + CHR = rep("chr1", snpN), BP = seq(100L, by = 100L, length.out = snpN), A1 = rep("A", snpN), A2 = rep("G", snpN), @@ -1773,11 +1419,11 @@ test_that(".ldFromRef leaves LD untouched when every allele agrees", { .package = "pecotmr" ) ids <- c("chr1:200:A:G", "chr1:400:A:G") - expect_equal( - pecotmr:::.ldFromRef(h, ids), - pecotmr:::.ldFromRef(h, ids), - tolerance = 1e-12 - ) + # The sample correlation of the very dosages the panel serves for those + # variants: with no allele to flip, no sign may change. + served <- .lds_mockExtractor()(h, c(2L, 4L)) + direct <- cor(t(SummarizedExperiment::assay(served, "dosage"))) + expect_equal(pecotmr:::.ldFromRef(h, ids), direct, tolerance = 1e-12) }) test_that(".ldFromRef errors on a variant the panel does not carry", { @@ -1835,7 +1481,7 @@ test_that(".requireMatchingLdRefs accepts panels trimmed differently", { # surviving variant set. The panels overlap but are not identical. si <- data.frame( SNP = c("1:100:A:G", "1:200:C:T", "1:300:G:A", "1:400:T:C"), - CHR = rep("1", 4L), + CHR = rep("chr1", 4L), BP = c(100L, 200L, 300L, 400L), A1 = c("A", "C", "G", "T"), A2 = c("G", "T", "A", "C"), @@ -1869,7 +1515,7 @@ test_that(".requireMatchingLdRefs errors when panels share no variant", { mkSi <- function(bp) { data.frame( SNP = str_c("1:", bp, ":A:G"), - CHR = rep("1", length(bp)), + CHR = rep("chr1", length(bp)), BP = as.integer(bp), A1 = rep("A", length(bp)), A2 = rep("G", length(bp)), @@ -1901,7 +1547,7 @@ test_that(".requireMatchingLdRefs errors when panels share no variant", { test_that(".requireMatchingLdRefs errors on a different sample set", { si <- data.frame( SNP = "1:100:A:G", - CHR = "1", + CHR = "chr1", BP = 100L, A1 = "A", A2 = "G", @@ -1929,17 +1575,16 @@ test_that(".requireMatchingLdRefs errors on a different sample set", { ) }) -test_that(".requireMatchingLdRefs tolerates a chr-prefix-only difference", { +test_that(".requireMatchingLdRefs tolerates chr-prefixed SNP labels", { si1 <- data.frame( SNP = c("1:100:A:G", "1:200:C:T"), - CHR = c("1", "1"), + CHR = c("chr1", "chr1"), BP = c(100L, 200L), A1 = c("A", "C"), A2 = c("G", "T"), stringsAsFactors = FALSE ) si2 <- si1 - si2$CHR <- c("chr1", "chr1") si2$SNP <- c("chr1:100:A:G", "chr1:200:C:T") # same panel, chr-prefixed mk <- function(si) { new( @@ -2287,43 +1932,6 @@ test_that("computeLd errors when a non-internal backend is paired with non-sampl ) }) -# The Rfast-absent fallback branches (computeLd's `R <- cor(X_imp)` and -# ldPruneByCorrelation's `cor.X <- cor(X)`) are reachable by mocking the *base* -# `requireNamespace` (so it reports Rfast missing) for the duration of the call. -test_that("ldPruneByCorrelation and computeLd fall back to base cor() when Rfast is absent", { - # Captured BEFORE the rebinding: inside the mock, `base::requireNamespace` - # resolves to the mock itself, so delegating through it recurses. - realRequireNamespace <- base::requireNamespace - with_mocked_bindings( - { - set.seed(1) - X <- matrix(rnorm(50 * 4), 50, 4) - colnames(X) <- paste0("s", 1:4) - pruned <- ldPruneByCorrelation(X, corThres = 0.9) # hits cor(X) at ld.R:1207 - R <- computeLd(X, method = "sample", backend = "internal") # hits cor(X_imp) at ld.R:1816 - expect_true(is.list(pruned)) - expect_true(all(c("X.new", "filter.id") %in% names(pruned))) - expect_equal(dim(R), c(4L, 4L)) - expect_equal(unname(diag(R)), rep(1, 4), tolerance = 1e-8) - expect_true(isSymmetric(unname(R))) - # base cor() fallback must agree with the direct base computation. - expect_equal(unname(R), unname(cor(X)), tolerance = 1e-10) - }, - requireNamespace = function(package, ...) { - if (identical(package, "Rfast")) { - FALSE - } else { - realRequireNamespace(package, ...) - } - }, - .package = "base" - ) -}) - -# ============================================================================= -# detectVariantConvention — uncovered line 586 -# ============================================================================= - # --------------------------------------------------------------------------- # .panelVariantStats / .panelVariantFilter # @@ -2733,19 +2341,6 @@ test_that("panel allele frequencies are computed per variant", { expect_equal(st$maf, pmin(st$af, 1 - st$af)) }) -test_that("panel variant filtering is a no-op without a panel or variants", { - # Both early exits return the caller's ids unchanged: with no panel there - # is nothing to filter against, and with no variants nothing to filter. - expect_equal( - pecotmr:::.panelVariantFilter(NULL, c("v1", "v2")), - c("v1", "v2") - ) - expect_equal( - pecotmr:::.panelVariantFilter(NULL, character(0)), - character(0) - ) -}) - # =========================================================================== # Empty sketches, the .afreq fast path, and design rank # =========================================================================== @@ -2761,7 +2356,7 @@ test_that("emptying a sketch clears both axes", { format = "plink2", snpInfo = data.frame( SNP = c("a", "b"), - CHR = "1", + CHR = "chr1", BP = 1:2, A1 = "A", A2 = "G", @@ -2777,17 +2372,50 @@ test_that("emptying a sketch clears both axes", { expect_equal(length(pecotmr:::sampleIds(e)), 0L) }) +test_that(".emptyLdRef drops the seed, not just the rows", { + # A panel carries its handle twice: as rowRanges and inside the dosage + # assay's DelayedArray seed. Dropping rows alone leaves the seed holding + # the whole panel, which is the weight this exists to shed. + h <- .sk_panel() + e <- .emptyLdRef(h) + expect_equal(nrow(e), 0L) + expect_null(.panelSeed(e)) + expect_lt( + length(serialize(e, NULL)), + length(serialize(h, NULL)) / 2 + ) +}) + +test_that(".emptyLdRef is NULL-safe and idempotent", { + expect_null(.emptyLdRef(NULL)) + e <- .emptyLdRef(.sk_panel()) + expect_equal(nrow(.emptyLdRef(e)), 0L) +}) + +test_that(".emptyLdRef drops both axes and the seed on an RSE sketch", { + # The seed carries every variant's metadata; an empty panel keeps none + # of it, only the record of what it was read from. + gh <- .gh_pgenHandle() + empty <- pecotmr:::.emptyLdRef(pecotmr:::.genotypeExperiment(gh)) + expect_equal(dim(empty), c(0L, 0L)) + expect_null(pecotmr:::.panelSeed(empty)) + expect_null(pecotmr:::.ldRefHandle(empty)) + expect_equal(pecotmr:::.ldRefFormat(empty), genotypeFormat(gh)) +}) + test_that("a missing or malformed afreq sidecar degrades to no frequencies", { # The sidecar is optional; a bad one must not take the whole filter down, # it just falls back to reading dosage. expect_null(pecotmr:::.panelAfreqTable("/nonexistent/prefix")) + prefix <- file.path(withr::local_tempdir(), "panel") + sidecar <- str_c(prefix, ".afreq") h <- new( "GenotypeHandle", - path = "/tmp/x", + path = prefix, format = "plink2", snpInfo = data.frame( SNP = c("a", "b"), - CHR = "1", + CHR = "chr1", BP = 1:2, A1 = "A", A2 = "G", @@ -2800,6 +2428,32 @@ test_that("a missing or malformed afreq sidecar degrades to no frequencies", { ) # No sidecar beside the file: nothing to read, in any format. expect_null(.pvfAfreqMaf(h, c("a", "b"))) + # A well-formed sidecar there is read ... + writeLines( + c( + "#CHROM\tID\tREF\tALT\tALT_FREQS\tOBS_CT", + "1\ta\tG\tA\t0.1\t4", + "1\tb\tG\tA\t0.8\t4" + ), + sidecar + ) + expect_equal(.pvfAfreqMaf(h, c("a", "b")), c(0.1, 0.2)) + # ... and a malformed one degrades to no frequencies: one without + # ALT_FREQS, which the reader refuses, or one that is not a table. + writeLines( + c( + "#CHROM\tID\tREF\tALT\tOBS_CT", + "1\ta\tG\tA\t4", + "1\tb\tG\tA\t4" + ), + sidecar + ) + expect_error(readAfreq(prefix), "ALT_FREQS") + expect_null(pecotmr:::.panelAfreqTable(prefix)) + expect_null(.pvfAfreqMaf(h, c("a", "b"))) + writeLines("not an afreq file", sidecar) + expect_null(pecotmr:::.panelAfreqTable(prefix)) + expect_null(.pvfAfreqMaf(h, c("a", "b"))) }) test_that("collinear design columns are reported, full-rank ones are not", { @@ -2827,50 +2481,6 @@ test_that("computeLd refuses snpIdx against an already-materialized block", { ) }) -# =========================================================================== -# Block-indexed sources and LdData subsetting -# =========================================================================== - -# --------------------------------------------------------------------------- -# LdData narrowing and materialization: each genotype source shape (matrix, -# handle + snpIdx, mixture list) narrows differently, and only the matrix -# shape can be materialized. -# --------------------------------------------------------------------------- - -.ldcov_gr <- function(variant_ids, af = NULL) { - rp <- pecotmr:::parseVariantId(variant_ids) - rp$variant_id <- variant_ids - if (!is.null(af)) { - rp$allele_freq <- af - } - pecotmr:::.refPanelToGranges(rp) -} - -.ldcov_bm <- function(n) { - data.frame( - blockId = 1L, - chrom = "chr1", - blockStart = 100, - blockEnd = 100 * n, - size = n, - startIdx = 1L, - endIdx = n, - stringsAsFactors = FALSE - ) -} - -.ldcov_handle <- function() { - new( - "GenotypeHandle", - path = "/tmp/test", - format = "plink2", - snpInfo = data.frame(), - nSamples = 0L, - sampleIds = character(), - pgenPtr = NULL - ) -} - test_that(".ldRefMatchIds returns bare ids when alleles are absent", { gr <- GenomicRanges::GRanges( "chr1", @@ -2888,26 +2498,16 @@ test_that(".ldRefMatchIds returns bare ids when alleles are absent", { ) }) -test_that(".panelVariantFilter is a no-op without a sketch", { - v <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A") - # An active cutoff still cannot filter anything with no panel to read - # frequencies from. - expect_equal( - pecotmr:::.panelVariantFilter( - NULL, - v, - PanelFilterParam(mafCutoff = 0.01) - ), - v - ) - expect_equal( - pecotmr:::.panelVariantFilter( - NULL, - character(0), - PanelFilterParam(mafCutoff = 0.01) - ), - character(0) - ) +test_that(".ldRefMatchIds repairs tag ids and leaves clean labels alone", { + h <- .ssQ_makeHandleVid() # ids chr1:100:G:A .. chr1:800:G:A, A1=A A2=G + h@snpInfo$SNP[h@snpInfo$BP == 200L] <- "chr1:200:INS:A" + ids <- pecotmr:::.ldRefMatchIds(h) + # the tag id is re-rendered from the panel's own A2/A1 columns ... + expect_equal(ids[2L], "chr1:200:G:A") + # ... and every other label is untouched. + expect_equal(ids[-2L], pecotmr:::.ldRefVariantIds(h)[-2L]) + # the raw accessor still answers the panel FILE's label (.afreq keys on it) + expect_equal(pecotmr:::.ldRefVariantIds(h)[2L], "chr1:200:INS:A") }) test_that(".panelVariantFilter is a no-op when nothing matches the panel", { @@ -3070,21 +2670,91 @@ test_that("computeLd(onDisk) applies shrinkage toward the identity", { ) }) -# --------------------------------------------------------------------------- -# .ldInfoBlock: an `ldInfo` row names the LD matrix, and the variant metadata -# is either named alongside it or auto-detected from the LD path. -# --------------------------------------------------------------------------- +test_that("onDisk LD matches the in-memory path on complete data", { + skip_if_not_installed("SNPRelate") + skip_if_not_installed("GDSArray") + handle <- readGenotypes(test_path("test_data", "test_variants.gds")) + idx <- c(4L, 1L, 6L, 2L, 5L, 3L) + onDisk <- computeLd( + handle, + snpIdx = idx, + backend = "snprelate", + onDisk = TRUE + ) + inMem <- computeLd(handle, snpIdx = idx) + # The fixture has no missing calls, which is the only regime where the + # two are meant to agree. + expect_equal(unname(onDisk), unname(inMem), tolerance = 1e-8) +}) + +test_that("onDisk LD labels and orders by the request", { + skip_if_not_installed("SNPRelate") + skip_if_not_installed("GDSArray") + handle <- readGenotypes(test_path("test_data", "test_variants.gds")) + idx <- c(4L, 1L, 6L, 2L, 5L, 3L) + R <- computeLd(handle, snpIdx = idx, backend = "snprelate", onDisk = TRUE) + # snpgdsLDMat() returns file order and labels nothing; both are corrected. + expect_identical( + rownames(R), + SummarizedExperiment::rowRanges(handle)$SNP[idx] + ) + expect_identical(colnames(R), rownames(R)) +}) + +test_that("onDisk LD is refused where it cannot be honoured", { + skip_if_not_installed("SNPRelate") + skip_if_not_installed("GDSArray") + skip_if_not_installed("PlinkMatrix") + gds <- readGenotypes(test_path("test_data", "test_variants.gds")) + plink <- readGenotypes( + plink1Prefix = test_path("test_data", "test_variants") + ) + expect_error( + computeLd(plink, backend = "snprelate", onDisk = TRUE), + "GDS-backed panel" + ) + expect_error( + computeLd(gds, backend = "internal", onDisk = TRUE), + "only available for" + ) + expect_error( + computeLd(matrix(1, 4, 3), backend = "snprelate", onDisk = TRUE), + "must be one" + ) + expect_error( + computeLd(gds, method = "gcta", backend = "snprelate", onDisk = TRUE), + "sample correlation" + ) +}) -test_that(".panelAfreqMaf returns NULL when no sidecar exists at all", { +test_that("LD from a sketch does not depend on the request order", { skip_if_not_installed("pgenlibr") - # This plink2 fixture ships without an .afreq, so every shard's table is - # absent -- distinct from the partial-sidecar case above. handle <- readGenotypeHandle( - test_path("test_data/test_variants_chr22"), + test_path("test_data", "test_variants"), format = "plink2" ) - expect_equal(pecotmr:::genotypeFormat(handle), "plink2") - expect_null(.pvfAfreqMaf(handle, as.character(snpInfo(handle)$SNP))) + ids <- snpInfo(handle)$SNP[1:6] + shuffled <- ids[c(4L, 1L, 6L, 2L, 5L, 3L)] + sorted <- pecotmr:::.ldFromRef(handle, ids, label = "t") + mixed <- pecotmr:::.ldFromRef(handle, shuffled, label = "t") + expect_identical(rownames(mixed), shuffled) + expect_equal(sorted[ids, ids], mixed[ids, ids]) +}) + +test_that("a PLINK1 panel cut to a few variants keeps only those", { + # Its seed is cut with it, so a saved panel carries the kept variants' + # metadata only, and reads them back from the file. + skip_if_not_installed("PlinkMatrix") + panel <- readGenotypes( + plink1Prefix = test_path("test_data", "test_variants") + ) + cut <- pecotmr:::.panelSubsetRows(panel, c(3L, 10L, 200L)) + # 100 samples in the panel + expect_equal(dim(pecotmr:::.panelSeed(cut)), c(3L, 100L)) + expect_equal(.dose(cut), .dose(panel)[c(3L, 10L, 200L), ]) + saved <- tempfile(fileext = ".rds") + saveRDS(cut, saved) + expect_equal(.dose(readRDS(saved)), .dose(cut)) }) test_that("ldReference cross-checks are no-ops when a side has no variants", { @@ -3165,26 +2835,6 @@ test_that("ldPruneByCorrelation forwards methodArgs to SNPRelate", { expect_equal(seen$ld.threshold, 0.9) }) -test_that(".panelCutoffs answers NULL for a filter that keeps everything", { - expect_null(pecotmr:::.panelCutoffs(PanelFilterParam())) - expect_equal( - pecotmr:::.panelCutoffs(PanelFilterParam(mafCutoff = 0.01))$mafCutoff, - 0.01 - ) -}) - -test_that("a stochastic sketch's real sample count comes from its .afreq", { - skip_if_not_installed("pgenlibr") - # 100 pseudo-samples, and an .afreq that carries U_MIN / U_MAX (so the - # panel is a stochastic sketch) with OBS_CT 100: 50 real people. A MAC - # cutoff and DENTIST's truncation rank count those, not the columns. - panel <- readGenotypes( - file.path(geno_test_data_dir, "test_harmonize_regions.pgen") - ) - expect_equal(pecotmr:::.ldRefNSamples(panel), 100L) - expect_equal(pecotmr:::.ldRefRealNSamples(panel), 50L) -}) - # ============================================================================= # The LD reference dispatch: a genotype panel and an LdMatrix answer alike # ============================================================================= @@ -3344,6 +2994,10 @@ test_that("a stochastic sketch records its real size and frequencies", { skip_if_not_installed("pgenlibr") sketch <- .ldrefSketch() expect_true(pecotmr:::.ldRefIsProjection(sketch)) + # 100 pseudo-samples, and an .afreq that carries U_MIN / U_MAX (so the + # panel is a stochastic sketch) with OBS_CT 100: 50 real people. A MAC + # cutoff and DENTIST's truncation rank count those, not the columns. + expect_equal(pecotmr:::.ldRefNSamples(sketch), 100L) expect_identical(pecotmr:::.ldRefRealNSamples(sketch), 50L) # 1 / (1/50 + 1/100): the noise of the real samples and of the # projection's 100 pseudo-samples together. @@ -3699,4 +3353,155 @@ test_that(".overlapsOnShared compares ranges on the chromosomes both have", { far <- GenomicRanges::GRanges("chr3", IRanges::IRanges(100L, width = 1L)) expect_silent(none <- pecotmr:::.overlapsOnShared(q, far)) expect_identical(none, c(FALSE, FALSE)) + # Strand says nothing about where a variant or a block sits. + minus <- GenomicRanges::GRanges( + "chr2", + IRanges::IRanges(105L, width = 1L), + strand = "-" + ) + plus <- GenomicRanges::`strand<-`(q, value = "+") + expect_identical(pecotmr:::.overlapsOnShared(plus, minus), c(FALSE, TRUE)) +}) + +test_that(".locusRanges keeps where ranges sit and the build, nothing else", { + gr <- GenomicRanges::GRanges( + c("chr1", "chrM"), + IRanges::IRanges(c(100L, 5L), width = 1L), + strand = c("+", "-"), + SNP = c("a", "b") + ) + GenomeInfoDb::genome(gr) <- "hg19" + out <- pecotmr:::.locusRanges(gr) + expect_identical( + as.character(GenomicRanges::seqnames(out)), + c("chr1", "chrM") + ) + expect_identical(as.character(GenomicRanges::strand(out)), c("*", "*")) + expect_identical(ncol(S4Vectors::mcols(out)), 0L) + expect_identical(unname(GenomeInfoDb::genome(out)), c("hg19", "hg19")) +}) + +test_that("ranges on two genome builds refuse to meet", { + q <- GenomicRanges::GRanges("chr1", IRanges::IRanges(100L, width = 10L)) + s <- GenomicRanges::GRanges("chr1", IRanges::IRanges(105L, width = 1L)) + GenomeInfoDb::genome(q) <- "hg19" + GenomeInfoDb::genome(s) <- "hg38" + expect_error(pecotmr:::.overlapsOnShared(q, s), "incompatible genomes") +}) + +test_that(".rowsSharedLdRef returns the rows' one reference or refuses", { + a <- .ldr_ldm() + qss <- .ldr_qss(list(a, .ldr_ldm(rho = 0.5), a)) + expect_identical(pecotmr:::.rowsSharedLdRef(qss, c(1L, 3L), "rows"), a) + expect_error( + pecotmr:::.rowsSharedLdRef(qss, 1:2, "these rows"), + "these rows use 2 different LD references" + ) +}) + +# =========================================================================== +# On a real genotype panel: checkLd, ldClumpByScore, enforceDesignFullRank, +# filterVariantsByLdReference +# =========================================================================== + +# Fixtures: 100 samples x 349 variants on chr21 +plink_prefix <- test_path("test_data", "test_variants") + +# The panel's genotype matrix and variant info +loadTestGenotype <- function() { + loadGenotypeRegion(plink_prefix, returnVariantInfo = TRUE) +} + +# --- checkLd ---------------------------------------------------------------- + +test_that("checkLd reports a rank-deficient sample LD matrix as PSD", { + skip_if_not_installed("pgenlibr") + X <- loadTestGenotype()$X + # 100 samples cap the rank at 99 of 349 variants. + R <- computeLd(X, method = "sample") + result <- checkLd(R) + expect_true(is.list(result)) + expect_false(result$isPd) + expect_true(result$isPsd) + expect_equal(result$methodApplied, "none") + # min eigenvalue may be near-zero (numerically PSD, not strictly PD) + expect_true(result$minEigenvalue > -1e-7) + expect_true(result$nNegative == 0) + expect_true(is.finite(result$conditionNumber)) +}) + +# --- ldClumpByScore ------------------------------------------------------- + +test_that("ldClumpByScore takes UCSC chromosome labels on a real panel", { + skip_if_not_installed("pgenlibr") + skip_if_not_installed("bigsnpr") + skip_if_not_installed("bigstatsr") + geno <- loadTestGenotype() + set.seed(42) + score <- runif(ncol(geno$X)) + # UCSC labels (chr21) are taken as they are. + chr <- geno$variant_info$chrom + pos <- geno$variant_info$pos + keep <- ldClumpByScore( + geno$X, + score = score, + chr = chr, + pos = pos, + r2 = 0.2 + ) + expect_true(is.integer(keep)) + expect_true(length(keep) > 0) + expect_true(length(keep) <= ncol(geno$X)) + expect_true(all(keep %in% seq_len(ncol(geno$X)))) +}) + +# --- enforceDesignFullRank ------------------------------------------------ + +test_that("enforceDesignFullRank handles genotype matrix with covariates", { + skip_if_not_installed("pgenlibr") + X <- loadTestGenotype()$X + # Create a simple covariate matrix (e.g., first 2 PCs of X) + pca <- prcomp(X, rank. = 2) + C <- pca$x + result <- enforceDesignFullRank(X, C, strategy = "correlation") + expect_true(is.matrix(result)) + expect_equal(nrow(result), nrow(X)) + # Should produce full-rank design + full_design <- cbind(1, result, C) + expect_equal(qr(full_design)$rank, ncol(full_design)) +}) + +# --- filterVariantsByLdReference ----------------------------------------- + +test_that("filterVariantsByLdReference filters via a PLINK metadata file", { + skip_if_not_installed("pgenlibr") + geno <- loadTestGenotype() + vi <- geno$variant_info + variant_ids <- paste0(vi$chrom, ":", vi$pos, ":", vi$A2, ":", vi$A1) + fake_ids <- c("21:999999:A:G", "21:888888:C:T") + all_ids <- c(variant_ids, fake_ids) + + # Create a metadata TSV in the same directory as the PLINK files + # so the relative path resolves correctly + meta_file <- file.path(test_data_dir, "ld_meta_tmp.tsv") + on.exit(unlink(meta_file), add = TRUE) + writeLines( + paste("chrom", "start", "end", "path", sep = "\t"), + meta_file + ) + cat( + paste("21", "0", "0", "test_variants", sep = "\t"), + "\n", + file = meta_file, + append = TRUE + ) + + result <- suppressMessages( + filterVariantsByLdReference(all_ids, meta_file, keepIndel = TRUE) + ) + expect_true(is.list(result)) + expect_true(length(result$data) <= length(all_ids)) + expect_true(length(result$idx) == length(result$data)) + # Fake variants should be filtered out + expect_true(length(result$data) <= length(variant_ids)) }) diff --git a/tests/testthat/test_manifestLoaders.R b/tests/testthat/test_manifestLoaders.R index 55531c74..9bbfcf94 100644 --- a/tests/testthat/test_manifestLoaders.R +++ b/tests/testthat/test_manifestLoaders.R @@ -14,8 +14,11 @@ ) } +# Read once and shared: the panel is a value, and some forty tests take one. +.toyLdRefPanel <- readGenotypes(plink1Prefix = .toyRefPrefix()) + .toyLdRef <- function() { - readGenotypes(plink1Prefix = .toyRefPrefix()) + .toyLdRefPanel } # A small GWAS sumstats data.frame over real toy_ref chr22 variants. @@ -200,7 +203,7 @@ test_that("loadGwasSumStatsFromManifest builds from a data.frame manifest", { c("SNP", "A1", "A2", "Z", "N") %in% colnames(S4Vectors::mcols(obj[[1L]])) )) - expect_equal(length(qcInfo(obj)), 0L) # loaders run no QC + expect_equal(length(qcOptions(obj)), 0L) # loaders run no QC }) test_that("loadGwasSumStatsFromManifest reads a file and reconciles genome", { @@ -262,22 +265,27 @@ test_that("tabix-indexed text honours the region", { tsv <- .writeSumstatsTsv(.toyGwasDf(5), file.path(tmp, "s.tsv")) gz <- Rsamtools::bgzip(tsv, dest = paste0(tsv, ".gz"), overwrite = TRUE) Rsamtools::indexTabix(gz, seq = 1L, start = 2L, end = 2L, comment = "#") - df <- pecotmr:::.readSumStatsText(gz, "22:14560000-14565000", NULL, "lbl") + df <- pecotmr:::.readSumStatsText( + gz, + GenomicRanges::GRanges("22:14560000-14565000"), + NULL, + "lbl" + ) expect_equal(nrow(df), 2L) # first two variants only expect_true(all(df$pos >= 14560000 & df$pos <= 14565000)) }) -test_that("plain-text region is ignored with a warning", { +test_that("plain text cannot narrow a read to the region", { tmp <- withr::local_tempdir() tsv <- .writeSumstatsTsv(.toyGwasDf(5), file.path(tmp, "s.tsv")) expect_warning( df <- pecotmr:::.readSumStatsText( tsv, - "22:14560000-14565000", + GenomicRanges::GRanges("22:14560000-14565000"), NULL, "lbl" ), - "region ignored" + "the whole file is read" ) expect_equal(nrow(df), 5L) }) @@ -382,6 +390,48 @@ test_that(".resolveSumstatCols derives the Wald z from beta/se", { expect_true(all(c("BETA", "SE") %in% colnames(out))) # beta/se still attached }) +test_that("an af: key is directional AF; a maf: key is directionless", { + # Same source column, different declaration -> different meaning. + a <- suppressWarnings(.resolveSumstatCols( + .afm_df("effect_allele_frequency", 0.8), + .afm_cm(af = "effect_allele_frequency"), + "af" + )) + expect_equal(a$AF, 0.8) + expect_false("MAF" %in% names(a)) + b <- suppressWarnings(.resolveSumstatCols( + .afm_df("effect_allele_frequency", 0.8), + .afm_cm(maf = "effect_allele_frequency"), + "maf" + )) + expect_false("AF" %in% names(b)) + expect_equal(b$MAF, 0.8) +}) + +test_that("an undeclared af warns distinctly and yields no AF column", { + expect_warning( + out <- .resolveSumstatCols( + .afm_df("maf", 0.2), + .afm_cm(maf = "maf"), + "undeclared" + ), + "no effect-allele frequency declared" + ) + expect_false("AF" %in% names(out)) +}) + +test_that("a declared-but-unusable af warns with a different message", { + # Distinct from "undeclared": this is a data problem, not a mapping one. + expect_warning( + .resolveSumstatCols( + .afm_df("eaf", NA_real_), + .afm_cm(af = "eaf"), + "missing" + ), + "declared but its values are all missing" + ) +}) + test_that(".resolveSumstatCols keeps a supplied z over beta/se", { df <- .toyGwasDf(4) df$beta <- rep(99, 4) @@ -748,6 +798,42 @@ test_that("loadQtlSumStatsFromManifest errors when a tuple has no N source", { path } +test_that("a phenotype BED's chromosomes are read in UCSC style", { + tmp <- withr::local_tempdir() + path <- file.path(tmp, "ncbi.bed") + readr::write_tsv( + data.frame( + `#chr` = c("22", "MT"), + start = c(10L, 20L), + end = c(11L, 21L), + gene_id = c("gA", "gB"), + S1 = c(1, 2), + check.names = FALSE + ), + path + ) + rr <- pecotmr:::.readPhenotypeBed(path)$rr + expect_identical( + as.character(GenomicRanges::seqnames(rr)), + c("chr22", "chrM") + ) + expect_identical(GenomeInfoDb::seqlevelsStyle(rr), "UCSC") +}) + +test_that("a manifest's BED-style ranges are read in UCSC style", { + df <- data.frame( + chrom = c("22", "chrX"), + start = c(0L, 10L), + end = c(5L, 20L) + ) + gr <- pecotmr:::.manifestRanges(df, "start", "end", "QTL", "window") + expect_identical( + as.character(GenomicRanges::seqnames(gr)), + c("chr22", "chrX") + ) + expect_identical(GenomicRanges::start(gr), c(1L, 11L)) +}) + test_that("loadQtlDatasetFromManifest builds a single-study dataset", { tmp <- withr::local_tempdir() bed <- .writePhenoBed(file.path(tmp, "ctxA.bed")) @@ -799,7 +885,7 @@ test_that("loadMultiStudyQtlDatasetFromManifest builds from >=2 studies", { msd <- loadMultiStudyQtlDatasetFromManifest(manifest) expect_s4_class(msd, "MultiStudyQtlDataset") expect_true(methods::validObject(msd)) - expect_equal(sort(names(qtlDatasets(msd))), c("study1", "study2")) + expect_equal(sort(names(msd)), c("study1", "study2")) }) test_that("loadMultiStudyQtlDatasetFromManifest attaches a summary study", { @@ -828,7 +914,7 @@ test_that("loadMultiStudyQtlDatasetFromManifest attaches a summary study", { ) expect_true(methods::validObject(msd)) expect_s4_class(msd@sumStats, "QtlSumStats") - expect_equal(names(qtlDatasets(msd)), "study1") + expect_equal(names(msd), "study1") }) # =========================================================================== @@ -905,7 +991,7 @@ test_that(".readGenotypePath reads a VCF as a panel", { test_that(".resolveLdRef accepts a genoMeta vector or path, rejects junk", { sharded <- pecotmr:::.resolveLdRef(c("22" = .toyRefPrefix())) expect_s4_class(sharded, "RangedSummarizedExperiment") - expect_true("22" %in% names(pecotmr:::.ldRefChromPaths(sharded))) + expect_true("chr22" %in% names(pecotmr:::.ldRefChromPaths(sharded))) expect_s4_class( pecotmr:::.resolveLdRef(.toyRefPrefix()), "RangedSummarizedExperiment" @@ -934,12 +1020,12 @@ test_that(".materializeLdRef and .resolveGenotypes take a panel too", { ) }) -test_that(".entriesChroms collects canonical chromosomes across entries", { +test_that(".entriesChroms collects the chromosomes across entries", { a <- pecotmr:::.dfToEntryGranges(.toyGwasDf(3)) # chr22 b <- .toyGwasDf(2) b$chrom <- "1" b <- pecotmr:::.dfToEntryGranges(b) - expect_setequal(pecotmr:::.entriesChroms(list(a, b)), c("22", "1")) + expect_setequal(pecotmr:::.entriesChroms(list(a, b)), c("chr22", "chr1")) expect_equal(pecotmr:::.entriesChroms(list()), character(0)) expect_equal(pecotmr:::.entriesChroms(list(NULL)), character(0)) }) @@ -954,7 +1040,7 @@ test_that(".materializeLdRef passes a handle through, restricts shards", { spec <- c("22" = .toyRefPrefix(), "21" = "/no/such/chr21/prefix") restricted <- pecotmr:::.materializeLdRef(spec, "22") expect_s4_class(restricted, "RangedSummarizedExperiment") - expect_equal(names(pecotmr:::.ldRefChromPaths(restricted)), "22") + expect_equal(names(pecotmr:::.ldRefChromPaths(restricted)), "chr22") expect_error(pecotmr:::.materializeLdRef(spec, c("22", "21"))) }) @@ -1036,7 +1122,7 @@ test_that(".checkLdContainment warns when the sketch has no variant metadata", { nSamples = 0L, sampleIds = character(), pgenPtr = NULL, - chromPaths = c("22" = "/p") + chromPaths = c(chr22 = "/p") ) gr <- pecotmr:::.dfToEntryGranges(.toyGwasDf(3)) expect_warning( @@ -1049,21 +1135,6 @@ test_that(".checkLdContainment warns when the sketch has no variant metadata", { # Coverage: region coercion and column-mapping errors # =========================================================================== -test_that(".asGRegion coerces strings, GRanges, and data.frames", { - gr <- GenomicRanges::GRanges("22", IRanges::IRanges(1, 100)) - expect_identical(pecotmr:::.asGRegion(gr), gr) - fromStr <- pecotmr:::.asGRegion("22:1-100") - expect_equal(GenomicRanges::start(fromStr), 1L) - fromDf <- pecotmr:::.asGRegion(data.frame( - chrom = "22", - start = 1, - end = 100 - )) - expect_equal(as.character(GenomicRanges::seqnames(fromDf)), "22") - expect_error(pecotmr:::.asGRegion("not-a-region"), "chr:start-end") - expect_error(pecotmr:::.asGRegion(42L), "chr:start-end") -}) - test_that(".readColumnMapping errors on bad inputs", { tmp <- withr::local_tempdir() expect_error( @@ -1132,7 +1203,7 @@ test_that("loadQtlSumStatsFromManifest attaches varY and honours region", { manifest, genome = "hg38", ldReference = .toyLdRef(), - region = data.frame(chrom = "22", start = 1, end = 5e7) + which = GenomicRanges::GRanges("22:1-50000000") )) expect_equal(as.numeric(obj$varY), 1.7) }) @@ -1247,7 +1318,8 @@ test_that("QtlDataset builder errors on inconsistent per-context paths", { samples = "study1", n = 5, dropSs = FALSE, - dropEs = FALSE + dropEs = FALSE, + reference = NULL ) { pos <- c(14560203, 14564328, 14850625, 14870204, 14878387)[seq_len(n)] ids <- c( @@ -1274,6 +1346,7 @@ test_that("QtlDataset builder errors on inconsistent per-context paths", { ) meta <- c( "##fileformat=VCFv4.2", + if (!is.null(reference)) str_c("##reference=", reference), unname(hdrFor[tags]), "##contig=", paste( @@ -1350,6 +1423,54 @@ test_that("loadGwasSumStatsFromManifest reads a GWAS-VCF (A1=ALT, Z=ES/SE)", { expect_equal(mc$N, rep(10000, 5)) }) +test_that("a GWAS-VCF's recorded build stands in for a missing genome", { + skip_if_not_installed("VariantAnnotation") + tmp <- withr::local_tempdir() + vcf <- .writeGwasVcf(file.path(tmp, "study1.vcf"), reference = "hg38") + manifest <- data.frame(study = "study1", sumStatsPath = vcf) + obj <- suppressWarnings( + loadGwasSumStatsFromManifest(manifest, ldReference = .toyLdRef()) + ) + expect_equal(unique(unname(GenomeInfoDb::genome(obj))), "hg38") + # A build that contradicts the file's is refused, not taken. + expect_error( + suppressWarnings(loadGwasSumStatsFromManifest( + manifest, + genome = "hg19", + ldReference = .toyLdRef() + )), + "`genome` is 'hg19', but the GWAS-VCF files record 'hg38'" + ) +}) + +test_that("the given build and the VCFs' recorded ones reconcile", { + f <- pecotmr:::.manifestBuild + expect_equal(f("hg38", character(0), "f"), "hg38") + expect_equal(f("hg38", "hg38", "f"), "hg38") + expect_error( + f(NULL, c("hg19", "hg38"), "f"), + "record different genome builds \\(hg19, hg38\\)" + ) + expect_error(f(NULL, character(0), "f"), "`genome` must be provided") +}) + +test_that("only a manifest's VCF paths are read for a build", { + skip_if_not_installed("VariantAnnotation") + tmp <- withr::local_tempdir() + df <- data.frame( + sumStatsPath = c( + .writeGwasVcf(file.path(tmp, "a.vcf"), reference = "hg38"), + .writeGwasVcf(file.path(tmp, "b.vcf")), + file.path(tmp, "c.tsv") + ) + ) + expect_equal(pecotmr:::.manifestVcfBuilds(df, tmp), "hg38") + expect_equal( + pecotmr:::.manifestVcfBuilds(df[3L, , drop = FALSE], tmp), + character(0) + ) +}) + test_that("GWAS-VCF sample selection is enforced for multi-sample files", { skip_if_not_installed("VariantAnnotation") tmp <- withr::local_tempdir() @@ -1388,23 +1509,65 @@ test_that("GWAS-VCF sample selection is enforced for multi-sample files", { ) }) -test_that("GWAS-VCF without SS errors", { +test_that("GWAS-VCF without SS, or without ES/SE, errors", { skip_if_not_installed("VariantAnnotation") tmp <- withr::local_tempdir() - vcf <- .writeGwasVcf(file.path(tmp, "noss.vcf"), dropSs = TRUE) - manifest <- data.frame( - study = "study1", - sumStatsPath = vcf, - stringsAsFactors = FALSE - ) - expect_error( - suppressWarnings(loadGwasSumStatsFromManifest( - manifest, - genome = "hg38", - ldReference = .toyLdRef() - )), - "SS" - ) + # Each case drops fields the reader needs; the error names them. + cases <- list(SS = list(dropSs = TRUE), `ES and SE` = list(dropEs = TRUE)) + for (field in names(cases)) { + vcf <- exec( + .writeGwasVcf, + tempfile(tmpdir = tmp, fileext = ".vcf"), + !!!cases[[field]] + ) + manifest <- data.frame( + study = "study1", + sumStatsPath = vcf, + stringsAsFactors = FALSE + ) + expect_error( + suppressWarnings(loadGwasSumStatsFromManifest( + manifest, + genome = "hg38", + ldReference = .toyLdRef() + )), + field, + info = field + ) + } +}) + +# Drop the ES and SE subfields from one record (or leave a header line as-is). +# @noRd +.ezDropEsSe <- function(line) { + if (!str_starts(line, "chr1")) { + return(line) + } + fields <- str_split(line, "\t")[[1L]] + keys <- str_split(fields[[9L]], ":")[[1L]] + values <- str_split(fields[[10L]], ":")[[1L]] + keep <- !is_in(keys, c("ES", "SE")) + fields[[9L]] <- str_flatten(keys[keep], ":") + fields[[10L]] <- str_flatten(values[keep], ":") + str_flatten(fields, "\t") +} + +test_that("a z-only GWAS-VCF reads without ES and SE", { + # Reading EZ was missing altogether, so a file whose ES/SE were derived + # upstream from z either lost that fact or, with no ES/SE at all, was + # refused outright. + skip_if_not_installed("VariantAnnotation") + out <- withr::local_tempfile(fileext = ".vcf") + writeGwasVcf(.ezss(TRUE), out) + lines <- readLines(out) + lines <- lines[!str_detect(lines, "^##FORMAT== 0" + "unused argument" ) + expect_error(GenotypeFilterParam(mafCutoff = -1), "mafCutoff.*is not >= 0") expect_error( - loadQtlDatasetFromManifest( - data.frame(), - genotypeFilterParam = GenotypeFilterParam(keepIndel = NA) - ), + GenotypeFilterParam(keepIndel = NA), "keepIndel.*May not be NA" ) - # A bare list cannot be checked, so it is refused outright. expect_error( - loadQtlDatasetFromManifest( - data.frame(), - genotypeFilterParam = list(mafCutoff = 0.01) - ), - "must be built with GenotypeFilterParam" + GenotypeFilterParam(xvarCutoff = -1), + "xvarCutoff.*is not >= 0" ) + # A bare list cannot be checked, so a run refuses it outright. expect_error( - loadQtlDatasetFromManifest( - data.frame(), - scaleResiduals = c(TRUE, TRUE) - ), - "scaleResiduals.*Must have length 1" + pecotmr:::.qtlResolveFilter(list(mafCutoff = 0.01)), + "must be built with GenotypeFilterParam" ) expect_error( loadQtlDatasetFromManifest(data.frame(), studyName = 1L), @@ -1882,13 +2067,6 @@ test_that("manifest loaders guard the QtlDataset pass-through arguments", { ), "minLdOverlapWarn.*is not <= 1" ) - expect_error( - loadMultiStudyQtlDatasetFromManifest( - data.frame(), - genotypeFilterParam = GenotypeFilterParam(xvarCutoff = -1) - ), - "xvarCutoff.*is not >= 0" - ) }) # --------------------------------------------------------------------------- @@ -1931,7 +2109,7 @@ test_that("manifest loaders guard the QtlDataset pass-through arguments", { test_that("a directional AF survives the GWAS-VCF round trip", { skip_if_not_installed("VariantAnnotation") out <- withr::local_tempfile(fileext = ".vcf") - exportToVcf(.afvcf_sumstats(), out) + writeGwasVcf(.afvcf_sumstats(), out) back <- .readSumStatsVcf(out, NULL, NULL, NULL, "x") # Unfolded, and under its own name -- 0.8 is an ALT frequency above 0.5, # which is exactly the case folding destroys. @@ -1944,7 +2122,7 @@ test_that("a directional AF survives the GWAS-VCF round trip", { test_that("a GWAS-VCF with no AF has neither AF nor a folded one", { skip_if_not_installed("VariantAnnotation") out <- withr::local_tempfile(fileext = ".vcf") - exportToVcf(.afvcf_sumstats(af = NULL), out) + writeGwasVcf(.afvcf_sumstats(af = NULL), out) back <- .readSumStatsVcf(out, NULL, NULL, NULL, "x") expect_false(is_in("AF", names(back))) expect_false(is_in("MAF", names(back))) @@ -1953,7 +2131,7 @@ test_that("a GWAS-VCF with no AF has neither AF nor a folded one", { test_that("an explicit formatMapping still redirects the AF slot", { skip_if_not_installed("VariantAnnotation") out <- withr::local_tempfile(fileext = ".vcf") - exportToVcf(.afvcf_sumstats(), out) + writeGwasVcf(.afvcf_sumstats(), out) # Reading the spec's AF field into the MAF slot on purpose: the caller # says this file's AF is not to be trusted as directional. back <- .readSumStatsVcf( @@ -1966,3 +2144,108 @@ test_that("an explicit formatMapping still redirects the AF slot", { expect_false(is_in("AF", names(back))) expect_equal(as.numeric(back$MAF), c(0.2, 0.3)) }) + +test_that("a manifest's BED-style columns give each row its window", { + gwasTsv <- system.file( + "extdata", + "manifests", + "protocol_example.twas.gwas_sumstats.chr22.tsv.gz", + package = "pecotmr" + ) + ldStem <- file.path( + system.file("extdata", "ld_reference", "chr22", package = "pecotmr"), + "protocol_example.LD.chr22" + ) + mf <- data.frame( + study = "g1", + sumStatsPath = gwasTsv, + chrom = "chr22", + start = 9999999L, + end = 19000000L + ) + g <- suppressWarnings(loadGwasSumStatsFromManifest( + manifest = mf, + genome = "hg38", + ldReference = ldStem + )) + # The start is 0-based, as in BED. + expect_identical(as.character(g$region), "chr22:10000000-19000000") + expect_true(g$regionGiven) + expect_error( + loadGwasSumStatsFromManifest( + manifest = mf, + genome = "hg38", + ldReference = ldStem, + which = GenomicRanges::GRanges("chr22:1-2") + ), + "cannot give them too" + ) + # A QTL row may also give its trait's position, on its `chrom`. + qmf <- data.frame( + study = "s1", + context = "c", + trait = "t", + sumStatsPath = gwasTsv, + chrom = "chr22", + start = 9999999L, + end = 19000000L, + traitStart = 15527999L, + traitEnd = 15528000L + ) + q <- suppressWarnings(loadQtlSumStatsFromManifest( + manifest = qmf, + genome = "hg38", + ldReference = ldStem + )) + expect_identical(as.character(q$region), "chr22:10000000-19000000") + expect_true(q$regionGiven) + expect_identical(as.character(q$traitPos), "chr22:15528000") + # A QTL tuple has one window. + expect_error( + loadQtlSumStatsFromManifest( + manifest = qmf[, 1:4], + genome = "hg38", + ldReference = ldStem, + which = GenomicRanges::GRanges(c("chr22:1-10", "chr22:20-30")) + ), + "must be one window" + ) + # A window needs all three columns, on every row. + expect_error( + loadGwasSumStatsFromManifest( + manifest = mf[, c("study", "sumStatsPath", "start", "end")], + genome = "hg38", + ldReference = ldStem + ), + "missing chrom" + ) + holes <- rbind( + mf, + data.frame( + study = "g2", + sumStatsPath = gwasTsv, + chrom = "chr22", + start = NA, + end = 19000000L + ) + ) + expect_error( + loadGwasSumStatsFromManifest( + manifest = holes, + genome = "hg38", + ldReference = ldStem + ), + "row(s) 2 leave their window empty", + fixed = TRUE + ) +}) + +test_that(".matchRegionSeqnames reads the windows a file holds, once", { + gr <- GenomicRanges::GRanges( + c("chr22", "chr22", "chr3"), + IRanges::IRanges(c(1L, 50L, 1L), c(100L, 200L, 10L)) + ) + m <- pecotmr:::.matchRegionSeqnames(gr, c("22", "21")) + expect_identical(as.character(m), "22:1-200") + expect_null(pecotmr:::.matchRegionSeqnames(gr[3L], "22")) +}) diff --git a/tests/testthat/test_mashPipeline.R b/tests/testthat/test_mashPipeline.R index 868f8f68..b5897921 100644 --- a/tests/testthat/test_mashPipeline.R +++ b/tests/testthat/test_mashPipeline.R @@ -1,8 +1,7 @@ # ============================================================================= -# Tests for utility helpers exported from R/mashPipeline.R that don't -# require mashr / flashier installs: -# sanitizeMashData, makePairwiseContrastCol, sliceMashData, -# metaAnalysisPerCondition +# Tests for R/mashPipeline.R: the mash pipeline and its extracted building +# blocks, the contrast and feature-score helpers, and the input preparation +# that turns SumStats / fine-mapping objects into mash matrices. # Fixtures for the input-preparation tests, moved here with them. @@ -20,7 +19,7 @@ format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * seq_len(nSnp)), - CHR = "1", + CHR = "chr1", BP = seq(100L, by = 100L, length.out = nSnp), A1 = "A", A2 = "G", @@ -49,7 +48,7 @@ entry = entries, genome = "hg19", ldReference = gh, - qcInfo = list(prebuilt = "synthetic") + qcOptions = list(prebuilt = "synthetic") ) } @@ -60,7 +59,7 @@ format = "plink2", snpInfo = data.frame( SNP = "chr1:100:A:G", - CHR = "1", + CHR = "chr1", BP = 100L, A1 = "A", A2 = "G", @@ -123,12 +122,12 @@ ) } vids <- paste0("chr1:", 100 * seq_len(6), ":A:G") - e1 <- fineMappingRow( + e1 <- FineMappingRow( variantIds = vids, susieFit = list(x = 1), topLoci = mkTL(c(0.5, -1, 6.0, 0.2, 1.1, -0.3), c(3, 2)) ) - e2 <- fineMappingRow( + e2 <- FineMappingRow( variantIds = vids, susieFit = list(x = 1), topLoci = mkTL(c(-0.4, 0.7, 0.1, 5.0, -1.2, 0.6), c(4, 5)) @@ -142,6 +141,71 @@ ) } +# The mash fixture and the fits several tests only read, each built on first +# use and then shared. Every mash() call forces three garbage collections +# (mashr times each step with system.time()), which costs far more than the +# fit itself, so repeated fits are what made this file slow. +delayedAssign(".mpSs", mashFixture()) +# The default component set, and the default prior refined from it. +delayedAssign( + ".mpDefaultComps", + suppressMessages(suppressWarnings(mashCovarianceComponents( + list(strong = .mpSs), + alpha = 0, + vhat = diag(3), + nPcs = 2L, + setSeed = 1L + ))) +) +delayedAssign( + ".mpDefaultPrior", + suppressMessages(suppressWarnings(mashPriorCovariances( + list(strong = .mpSs), + alpha = 0, + vhat = diag(3), + nPcs = 2L, + setSeed = 1L + ))) +) +# The whole pipeline: null-based Vhat, then the default prior chain. +delayedAssign( + ".mpSimpleFull", + suppressMessages(suppressWarnings(mashPipeline( + list(strong = .mpSs, random = .mpSs, null = .mpSs), + alpha = 0, + residualCorrelationMethod = "simple", + setSeed = 1L + ))) +) +# mashPipeline with the tiny prior under each residual-correlation setup the +# residualCorrelationMethod tests compare. evaluate_promise() keeps the +# messages a run emits next to its result. +.mpVhatRun <- function(partitions, ...) { + evaluate_promise(mashPipeline( + set_names(rep(list(.mpSs), length(partitions)), partitions), + alpha = 0, + ..., + prior = MashPriorParam(priorCovariances = mashTinyPrior()), + setSeed = 1L + )) +} +delayedAssign(".mpVhatWithNull", .mpVhatRun(c("strong", "random", "null"))) +delayedAssign(".mpVhatWithoutNull", .mpVhatRun(c("strong", "random"))) +delayedAssign( + ".mpVhatIdentity", + .mpVhatRun( + c("strong", "random", "null"), + residualCorrelationMethod = "identity" + ) +) +delayedAssign( + ".mpVhatSimple", + .mpVhatRun( + c("strong", "random", "null"), + residualCorrelationMethod = "simple" + ) +) + # ============================================================================= # --------------------------------------------------------------------------- @@ -471,7 +535,7 @@ test_that("fitMashContrast: 3-tested-conditions yields deviation + pairwise cont test_that("mashPipeline runs end-to-end on qtlSumStatsMulticontextExample", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs # Use the same fixture for strong/random; nPcs <= ncol - 1 (3 contexts). res <- suppressMessages(suppressWarnings( mashPipeline( @@ -631,7 +695,7 @@ test_that("mashPipeline coerces a SimpleList before validating its names", { test_that("mashPipeline rejects priorCovariances not a non-empty named list", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs vhat <- diag(3) # Empty list. expect_error( @@ -662,7 +726,7 @@ test_that("mashPipeline rejects priorCovariances not a non-empty named list", { test_that("mashPipeline rejects priorCovariances with wrong dimensions", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs vhat <- diag(3) expect_error( suppressMessages(suppressWarnings( @@ -680,7 +744,7 @@ test_that("mashPipeline rejects priorCovariances with wrong dimensions", { test_that("mashPipeline passes supplied residualCorrelation + priorCovariances through", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs vhat <- diag(3) U0 <- list(identity = diag(3), effectA = diag(c(1, 0, 0))) res <- suppressMessages(suppressWarnings( @@ -706,18 +770,10 @@ test_that("mashPipeline passes supplied residualCorrelation + priorCovariances t test_that("mashPipeline estimates Vhat from a null set and defaults nPcs", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() # `residualCorrelationMethod = "simple"` runs # estimate_null_correlation_simple on the null set; leaving nPcs NULL # exercises the `nPcs <- ncol(Bhat) - 1` default in the cov_* chain. - res <- suppressMessages(suppressWarnings( - mashPipeline( - list(strong = ss, random = ss, null = ss), - alpha = 0, - residualCorrelationMethod = "simple", - setSeed = 1L - ) - )) + res <- .mpSimpleFull expect_named(res, c("U", "w")) expect_gt(length(res$U), 0L) expect_true(all(map_lgl( @@ -738,116 +794,46 @@ test_that("mashPipeline estimates Vhat from a null set and defaults nPcs", { test_that("the default is identity regardless of which partitions are given", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() - prior <- mashTinyPrior() # The default must not depend on data shape -- that was the old silent # behaviour this argument replaced. `w` is what carries the evidence: it # is fitted against V, so an identical `w` across the three calls is the # same V reaching mash() each time. (`U` is the supplied prior passed # through, so comparing it would prove nothing here.) - withNull <- suppressMessages(suppressWarnings(mashPipeline( - list(strong = ss, random = ss, null = ss), - alpha = 0, - prior = MashPriorParam(priorCovariances = prior), - setSeed = 1L - ))) - withoutNull <- suppressMessages(suppressWarnings(mashPipeline( - list(strong = ss, random = ss), - alpha = 0, - prior = MashPriorParam(priorCovariances = prior), - setSeed = 1L - ))) - explicit <- suppressMessages(suppressWarnings(mashPipeline( - list(strong = ss, random = ss, null = ss), - alpha = 0, - residualCorrelationMethod = "identity", - prior = MashPriorParam(priorCovariances = prior), - setSeed = 1L - ))) - expect_equal(withNull$w, withoutNull$w) - expect_equal(withNull$w, explicit$w) + withNull <- .mpVhatWithNull$result + expect_equal(withNull$w, .mpVhatWithoutNull$result$w) + expect_equal(withNull$w, .mpVhatIdentity$result$w) }) test_that("an unused null partition is reported", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() # Assembling a null set and still getting identity is more often an # oversight than an intent, so it must not pass silently. - expect_message( - suppressWarnings(mashPipeline( - list(strong = ss, random = ss, null = ss), - alpha = 0, - prior = MashPriorParam(priorCovariances = mashTinyPrior()), - setSeed = 1L - )), - "does not use it" - ) + expect_match(.mpVhatWithNull$messages, "does not use it", all = FALSE) # Naming identity explicitly does not change that the set is unused. - expect_message( - suppressWarnings(mashPipeline( - list(strong = ss, random = ss, null = ss), - alpha = 0, - residualCorrelationMethod = "identity", - prior = MashPriorParam(priorCovariances = mashTinyPrior()), - setSeed = 1L - )), - "'null' partition" - ) + expect_match(.mpVhatIdentity$messages, "'null' partition", all = FALSE) }) test_that("no unused-null notice when there is nothing to ignore", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() - noNull <- function() { - suppressWarnings(mashPipeline( - list(strong = ss, random = ss), - alpha = 0, - prior = MashPriorParam(priorCovariances = mashTinyPrior()), - setSeed = 1L - )) - } - expect_no_message(noNull(), message = "'null' partition") + expect_false(any(grepl("'null' partition", .mpVhatWithoutNull$messages))) # Nor when the null set is actually being consumed. - usesNull <- function() { - suppressWarnings(mashPipeline( - list(strong = ss, random = ss, null = ss), - alpha = 0, - residualCorrelationMethod = "simple", - prior = MashPriorParam(priorCovariances = mashTinyPrior()), - setSeed = 1L - )) - } - expect_no_message(usesNull(), message = "does not use it") + expect_false(any(grepl("does not use it", .mpVhatSimple$messages))) }) test_that("mashPipeline honours a data-driven residualCorrelationMethod", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() - sl <- list(strong = ss, random = ss, null = ss) - prior <- mashTinyPrior() - identityFit <- suppressMessages(suppressWarnings(mashPipeline( - sl, - alpha = 0, - residualCorrelationMethod = "identity", - prior = MashPriorParam(priorCovariances = prior), - setSeed = 1L - ))) - simpleFit <- suppressMessages(suppressWarnings(mashPipeline( - sl, - alpha = 0, - residualCorrelationMethod = "simple", - prior = MashPriorParam(priorCovariances = prior), - setSeed = 1L - ))) # A different V has to move the fit, or the argument is not reaching it. - expect_false(isTRUE(all.equal(identityFit$w, simpleFit$w))) + expect_false(isTRUE(all.equal( + .mpVhatIdentity$result$w, + .mpVhatSimple$result$w + ))) }) test_that("mashPipeline rejects an unknown residualCorrelationMethod", { - ss <- mashFixture() + ss <- .mpSs expect_error( mashPipeline( list(strong = ss, random = ss), @@ -860,7 +846,7 @@ test_that("mashPipeline rejects an unknown residualCorrelationMethod", { test_that("a method needing a partition it lacks errors through mashPipeline", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs expect_error( mashPipeline( list(strong = ss, random = ss), @@ -874,7 +860,7 @@ test_that("a method needing a partition it lacks errors through mashPipeline", { test_that("a supplied residualCorrelation wins over the method", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs # 'simple' would error without a null set; the supplied matrix means the # estimator is never consulted. res <- suppressMessages(suppressWarnings(mashPipeline( @@ -894,7 +880,7 @@ test_that("a supplied residualCorrelation wins over the method", { test_that("mashResidualCorrelation(identity) is an identity of the right size", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs v <- mashResidualCorrelation( list(strong = ss), alpha = 0, @@ -906,7 +892,7 @@ test_that("mashResidualCorrelation(identity) is an identity of the right size", test_that("mashResidualCorrelation(simple) returns a null correlation matrix", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs v <- suppressMessages(suppressWarnings( mashResidualCorrelation( list(strong = ss, null = ss), @@ -921,7 +907,7 @@ test_that("mashResidualCorrelation(simple) returns a null correlation matrix", { test_that("mashResidualCorrelation(simple) errors without a null entry", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs expect_error( mashResidualCorrelation( list(strong = ss), @@ -934,7 +920,7 @@ test_that("mashResidualCorrelation(simple) errors without a null entry", { test_that("mashResidualCorrelation(simpleSpecific) returns a null correlation", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs v <- suppressMessages(suppressWarnings( mashResidualCorrelation( list(strong = ss, null = ss), @@ -949,7 +935,7 @@ test_that("mashResidualCorrelation(simpleSpecific) returns a null correlation", test_that("mashResidualCorrelation(corshrink) returns a 3x3 correlation matrix", { skip_if_not_installed("mashr") skip_if_not_installed("CorShrink") - ss <- mashFixture() + ss <- .mpSs v <- suppressMessages(suppressWarnings( mashResidualCorrelation( list(strong = ss, null = ss), @@ -963,7 +949,7 @@ test_that("mashResidualCorrelation(corshrink) returns a 3x3 correlation matrix", test_that("mashResidualCorrelation(mle) refines V against a supplied prior", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs v <- suppressMessages(suppressWarnings( mashResidualCorrelation( list(strong = ss, random = ss), @@ -971,7 +957,8 @@ test_that("mashResidualCorrelation(mle) refines V against a supplied prior", { method = "mle", priorCovariances = list(identity = diag(3)), nSubset = 100L, - maxIter = 3L, + # One EM refinement: each iteration is another mash() fit. + maxIter = 1L, setSeed = 1L ) )) @@ -980,7 +967,7 @@ test_that("mashResidualCorrelation(mle) refines V against a supplied prior", { test_that("mashResidualCorrelation errors when a method's inputs are missing", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs expect_error( mashResidualCorrelation( list(strong = ss), @@ -1008,16 +995,7 @@ test_that("mashResidualCorrelation errors when a method's inputs are missing", { test_that("mashPriorCovariances computes the default (all-but-udr) prior", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() - pc <- suppressMessages(suppressWarnings( - mashPriorCovariances( - list(strong = ss), - alpha = 0, - vhat = diag(3), - nPcs = 2L, - setSeed = 1L - ) - )) + pc <- .mpDefaultPrior expect_named(pc, c("U", "w", "loglik")) expect_gt(length(pc$U), 0L) expect_true(all(map_lgl( @@ -1028,10 +1006,10 @@ test_that("mashPriorCovariances computes the default (all-but-udr) prior", { expect_null(pc$loglik) }) -test_that("mashPriorCovariances passes a supplied prior through unchanged", { +test_that("mashPriorCovariances passes a given prior through, either shape", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs U0 <- list(identity = diag(3), effectA = diag(c(1, 0, 0))) pc <- suppressMessages(suppressWarnings( mashPriorCovariances( @@ -1043,12 +1021,24 @@ test_that("mashPriorCovariances passes a supplied prior through unchanged", { )) expect_identical(pc$U, U0) expect_equal(sum(pc$w), 1, tolerance = 1e-6) + # A mashPriorCovariances()-shaped list(U, w, loglik) is unwrapped to the + # same prior and fits the same weights. + wrapped <- suppressMessages(suppressWarnings( + mashPriorCovariances( + list(strong = ss), + alpha = 0, + vhat = diag(3), + priorCovariances = list(U = U0, w = NULL, loglik = NULL) + ) + )) + expect_equal(names(wrapped$U), names(pc$U)) + expect_equal(wrapped$w, pc$w) }) test_that("mashPriorCovariances validates a supplied prior", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs expect_error( suppressMessages(suppressWarnings( mashPriorCovariances( @@ -1076,7 +1066,7 @@ test_that("mashPriorCovariances validates a supplied prior", { test_that("mashPriorCovariances(flashNonneg) adds components vs flash-only", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs base <- suppressMessages(suppressWarnings( mashPriorCovariances( list(strong = ss), @@ -1087,28 +1077,24 @@ test_that("mashPriorCovariances(flashNonneg) adds components vs flash-only", { setSeed = 1L ) )) - wide <- suppressMessages(suppressWarnings( - mashPriorCovariances( - list(strong = ss), - alpha = 0, - vhat = diag(3), - components = c("canonical", "pca", "flash", "flashNonneg"), - nPcs = 2L, - setSeed = 1L - ) - )) - expect_gt(length(wide$U), length(base$U)) + # The shared default prior is this same call with flashNonneg added. + expect_identical( + eval(formals(mashPriorCovariances)$components), + c("canonical", "pca", "flash", "flashNonneg") + ) + expect_gt(length(.mpDefaultPrior$U), length(base$U)) }) test_that("mashPriorCovariances engine 'ud' (udr) produces U + weights", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") skip_if_not_installed("udr") - ss <- mashFixture() - # A toy-sized udr config: `n_unconstrained` dominates the cost, and the default - # (50, sized for many-condition data) is pathological on a 3-condition fixture - # (it drove a 5+ minute fit). 2 unconstrained matrices suffice to exercise the - # udr path. + ss <- .mpSs + # A toy-sized udr config: `n_unconstrained` dominates the cost, and the + # default (50, sized for many-condition data) is pathological on a + # 3-condition fixture (it drove a 5+ minute fit). 2 unconstrained + # matrices suffice to exercise the udr path, and on the beta scale each + # update iteration is slow, so a few iterations do too. pc <- suppressMessages(suppressWarnings( mashPriorCovariances( list(strong = ss), @@ -1116,7 +1102,7 @@ test_that("mashPriorCovariances engine 'ud' (udr) produces U + weights", { vhat = diag(3), engine = CovUdrOptions( init = UdInitOptions(n_unconstrained = 2L), - fit = UdFitOptions(maxiter = 20L) + fit = UdFitOptions(maxiter = 5L) ), setSeed = 1L ) @@ -1129,11 +1115,33 @@ test_that("mashPriorCovariances engine 'ud' (udr) produces U + weights", { expect_equal(sum(pc$w), 1, tolerance = 1e-6) }) +test_that("the udr engine runs on the z scale, where udr picks TED", { + skip_if_not_installed("mashr") + skip_if_not_installed("udr") + # The companion to the alpha = 0 udr run in test_mashPipeline.R: on the + # beta scale pecotmr pins the update, so only here does udr choose. + pc <- suppressMessages(suppressWarnings( + mashPriorCovariances( + list(strong = .mwSs), + alpha = 1, + vhat = diag(3), + engine = CovUdrOptions( + init = UdInitOptions(n_unconstrained = 2L), + fit = UdFitOptions(maxiter = 20L) + ), + setSeed = 1L + ) + )) + expect_gt(length(pc$U), 0L) + expect_true(all(map_lgl(pc$U, function(m) all(dim(m) == c(3L, 3L))))) + expect_equal(sum(pc$w), 1, tolerance = 1e-6) +}) + test_that("mashPriorCovariances TED update errors clearly on non-i.i.d. data", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") skip_if_not_installed("udr") - ss <- mashFixture() + ss <- .mpSs expect_error( suppressMessages(suppressWarnings( mashPriorCovariances( @@ -1153,7 +1161,7 @@ test_that("mashPriorCovariances TED update errors clearly on non-i.i.d. data", { test_that("mashPriorCovariances rejects an unknown component", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs expect_error( mashPriorCovariances( list(strong = ss), @@ -1172,7 +1180,7 @@ test_that("mashPriorCovariances rejects an unknown component", { test_that("mashCovarianceComponents builds a single requested component", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs fl <- suppressMessages(suppressWarnings( mashCovarianceComponents( list(strong = ss), @@ -1191,7 +1199,7 @@ test_that("mashCovarianceComponents builds a single requested component", { test_that("a requested component that yields nothing returns an empty list", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs # flashier legitimately finds no factors on weak data. c(NULL, NULL) is # NULL, so the collapse used to leak a NULL out of a function documented # to return a named list -- length()/names()/c() then behave differently @@ -1215,7 +1223,7 @@ test_that("a requested component that yields nothing returns an empty list", { test_that("mashCovarianceComponents default builds all non-udr components", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs one <- suppressMessages(suppressWarnings( mashCovarianceComponents( list(strong = ss), @@ -1225,40 +1233,16 @@ test_that("mashCovarianceComponents default builds all non-udr components", { setSeed = 1L ) )) - all4 <- suppressMessages(suppressWarnings( - mashCovarianceComponents( - list(strong = ss), - alpha = 0, - vhat = diag(3), - nPcs = 2L, - setSeed = 1L - ) - )) - expect_gt(length(all4), length(one)) + expect_gt(length(.mpDefaultComps), length(one)) }) test_that("mashCovarianceComponents feeds mashPriorCovariances (same components)", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() - comps <- suppressMessages(suppressWarnings( - mashCovarianceComponents( - list(strong = ss), - alpha = 0, - vhat = diag(3), - nPcs = 2L, - setSeed = 1L - ) - )) - prior <- suppressMessages(suppressWarnings( - mashPriorCovariances( - list(strong = ss), - alpha = 0, - vhat = diag(3), - nPcs = 2L, - setSeed = 1L - ) - )) + ss <- .mpSs + # Both built with the same settings: the default components, nPcs = 2. + comps <- .mpDefaultComps + prior <- .mpDefaultPrior # Canonical components are structural hypotheses and reach the prior # unrefined, so their names survive verbatim. The data-driven ones are # replaced by their Extreme Deconvolution refinements (mashr names those @@ -1286,7 +1270,7 @@ test_that("mashCovarianceComponents feeds mashPriorCovariances (same components) test_that("mashCovarianceComponents rejects unknown components", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs expect_error( mashCovarianceComponents( list(strong = ss), @@ -1300,16 +1284,8 @@ test_that("mashCovarianceComponents rejects unknown components", { test_that("mashPriorCovariances refines supplied priorComponents (pipeline mode)", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() - comps <- suppressMessages(suppressWarnings( - mashCovarianceComponents( - list(strong = ss), - alpha = 0, - vhat = diag(3), - nPcs = 2L, - setSeed = 1L - ) - )) + ss <- .mpSs + comps <- .mpDefaultComps pr <- suppressMessages(suppressWarnings( mashPriorCovariances( list(strong = ss), @@ -1331,7 +1307,7 @@ test_that("mashPriorCovariances refines supplied priorComponents (pipeline mode) test_that("mashPriorCovariances validates priorComponents", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs expect_error( mashPriorCovariances( list(strong = ss), @@ -1345,15 +1321,9 @@ test_that("mashPriorCovariances validates priorComponents", { test_that("mashPipeline result == composing the two extracted building blocks", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() - full <- suppressMessages(suppressWarnings( - mashPipeline( - list(strong = ss, random = ss, null = ss), - alpha = 0, - residualCorrelationMethod = "simple", - setSeed = 1L - ) - )) + ss <- .mpSs + # The pipeline on (strong, random, null) with Vhat method "simple". + full <- .mpSimpleFull # Same seed discipline mashPipeline uses: seed once, then delegate with # setSeed = NULL so the RNG stream stays continuous. set.seed(1L) @@ -1375,11 +1345,6 @@ test_that("mashPipeline result == composing the two extracted building blocks", expect_equal(full$w, prior$w) }) -# --------------------------------------------------------------------------- -# mashModelFit + mashPosterior — the fit -> posterior chain (mash_fit / -# mash_posterior). A tiny 2-component prior keeps these fast. -# --------------------------------------------------------------------------- - # --------------------------------------------------------------------------- # Prior-shape normalisation (.mashAsUlist) # @@ -1405,32 +1370,9 @@ test_that(".mashAsUlist does not mistake a covariance named U for the wrapper", expect_equal(pecotmr:::.mashAsUlist(ulist), ulist) }) -test_that("mashPriorCovariances accepts either shape for its two prior args", { - skip_if_not_installed("mashr") - ss <- mashFixture() - sl <- list(strong = ss, random = ss) - ulist <- list(identity = diag(3), effectA = diag(c(1, 0, 0))) - wrapped <- list(U = ulist, w = NULL, loglik = NULL) - - bare <- suppressMessages(suppressWarnings(mashPriorCovariances( - sl, - alpha = 0, - vhat = diag(3), - priorCovariances = ulist - ))) - wrap <- suppressMessages(suppressWarnings(mashPriorCovariances( - sl, - alpha = 0, - vhat = diag(3), - priorCovariances = wrapped - ))) - expect_equal(names(wrap$U), names(bare$U)) - expect_equal(wrap$w, bare$w) -}) - test_that("fitMashContrast consumes a mashPosterior result", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs post <- suppressMessages(suppressWarnings( mashPosterior(.mashTestModel(ss), ss, alpha = 0, vhat = diag(3)) )) @@ -1443,60 +1385,9 @@ test_that("fitMashContrast consumes a mashPosterior result", { }) # --------------------------------------------------------------------------- -# .rmaMeta: thin metafor::rma adapter (DL default; REML/ML/... pass through) +# metaAnalysisPerCondition # --------------------------------------------------------------------------- -test_that(".rmaMeta: DL is the default and reshapes the metafor fit", { - set.seed(1) - m <- rnorm(6) - s <- abs(rnorm(6)) + 0.2 - expect_equal( - pecotmr:::.rmaMeta(m, s), - pecotmr:::.rmaMeta(m, s, method = "DL") - ) - out <- pecotmr:::.rmaMeta(m, s) - expect_true(all(c("mean", "se", "tau2", "I2", "Q") %in% names(out))) - expect_true(out$I2 >= 0 && out$I2 <= 1) # metafor's % rescaled to [0,1] -}) - -test_that(".rmaMeta: DL matches the closed-form DerSimonian-Laird", { - means <- c(0.5, 0.8, 0.3) - ses <- c(0.2, 0.3, 0.15) - res <- pecotmr:::.rmaMeta(means, ses) - wFe <- 1 / ses^2 - muFe <- sum(wFe * means) / sum(wFe) - Q <- sum(wFe * (means - muFe)^2) - tau2 <- max(0, (Q - 2) / (sum(wFe) - sum(wFe^2) / sum(wFe))) - wRe <- 1 / (ses^2 + tau2) - expect_equal(res$Q, Q, tolerance = 1e-6) - expect_equal(res$tau2, tau2, tolerance = 1e-6) - expect_equal(res$mean, sum(wRe * means) / sum(wRe), tolerance = 1e-6) - expect_equal(res$se, sqrt(1 / sum(wRe)), tolerance = 1e-6) -}) - -test_that(".rmaMeta: non-DL estimator (REML) runs via metafor and differs from DL", { - set.seed(3) - m <- rnorm(8, sd = 1.5) - s <- abs(rnorm(8)) + 0.3 - reml <- pecotmr:::.rmaMeta(m, s, method = "REML") - expect_true(all(c("mean", "se", "tau2", "I2", "Q") %in% names(reml))) - expect_true(reml$I2 >= 0 && reml$I2 <= 1) - # REML tau2 generally differs from DL tau2 on heterogeneous data - expect_false(isTRUE(all.equal(reml$tau2, pecotmr:::.rmaMeta(m, s)$tau2))) -}) - -test_that(".rmaMeta: non-DL estimator falls back to DL on non-convergence (never errors)", { - # metafor's iterative estimators can fail to converge on small / degenerate - # inputs; .rmaMeta must still return a finite fit (via the DL fallback). - set.seed(1) - for (i in seq_len(25)) { - m <- rnorm(sample(3:8, 1L)) - s <- abs(rnorm(length(m))) + 0.1 - r <- suppressWarnings(pecotmr:::.rmaMeta(m, s, method = "REML")) - expect_true(is.finite(r$mean) && is.finite(r$se)) - } -}) - test_that("metaAnalysisPerCondition: threads metaMethod (DL default unchanged)", { es <- matrix( rnorm(12), @@ -1707,7 +1598,7 @@ test_that("mashPosteriorContrast: empty frame when every feature is dropped", { test_that("mashResidualCorrelation(mle): errors without a 'random' entry", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs expect_error( mashResidualCorrelation(list(strong = ss), alpha = 0, method = "mle"), "requires a 'random' entry" @@ -1716,7 +1607,7 @@ test_that("mashResidualCorrelation(mle): errors without a 'random' entry", { test_that("mashResidualCorrelation accepts a SimpleList sumStatsList", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs V <- suppressMessages(suppressWarnings( mashResidualCorrelation( S4Vectors::SimpleList(null = ss), @@ -1729,7 +1620,7 @@ test_that("mashResidualCorrelation accepts a SimpleList sumStatsList", { test_that("mashCovarianceComponents: SimpleList input + default (NULL) vhat", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs cc <- suppressMessages(suppressWarnings( mashCovarianceComponents( S4Vectors::SimpleList(strong = ss), @@ -1743,7 +1634,7 @@ test_that("mashCovarianceComponents: SimpleList input + default (NULL) vhat", { test_that("mashPriorCovariances: SimpleList input (canonical only)", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs pc <- suppressMessages(suppressWarnings( mashPriorCovariances( S4Vectors::SimpleList(strong = ss), @@ -1865,7 +1756,7 @@ test_that("MashPriorParam takes only a MashComponentParam for components", { test_that("mashPriorCovariances takes components as names or a record", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs byRecord <- suppressMessages(suppressWarnings( mashPriorCovariances( list(strong = ss), @@ -1884,7 +1775,7 @@ test_that("mashPriorCovariances takes components as names or a record", { test_that("engine 'none' leaves the data-driven components unrefined", { skip_if_not_installed("mashr") skip_if_not_installed("flashier") - ss <- mashFixture() + ss <- .mpSs raw <- suppressMessages(suppressWarnings( mashPriorCovariances( list(strong = ss), @@ -1904,7 +1795,7 @@ test_that("engine 'none' leaves the data-driven components unrefined", { test_that("mashPriorCovariances rejects an unknown engine", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mpSs expect_error( mashPriorCovariances( list(strong = ss), @@ -2283,32 +2174,6 @@ test_that("filterInvalidSummaryStat z path handles NULL strong component", { expect_true(!is.null(result$random$z)) }) -test_that("filterMixtureComponents removes zero matrices", { - U <- list( - comp1 = matrix( - c(1, 0, 0, 2), - 2, - 2, - dimnames = list(c("A", "B"), c("A", "B")) - ), - comp2 = matrix( - c(0, 0, 0, 0), - 2, - 2, - dimnames = list(c("A", "B"), c("A", "B")) - ), - A = matrix( - c(3, 0, 0, 4), - 2, - 2, - dimnames = list(c("A", "B"), c("A", "B")) - ) - ) - w <- c(comp1 = 0.5, comp2 = 0.3, A = 0.2) - result <- filterMixtureComponents(c("A", "B"), U, w) - expect_false("comp2" %in% names(result$U)) -}) - test_that("filterMixtureComponents removes matrices below weight cutoff", { U <- list( comp1 = matrix( @@ -2344,29 +2209,7 @@ test_that("filterMixtureComponents errors on missing conditions", { ) }) -test_that("filterMixtureComponents removes components named as filtered conditions", { - U <- list( - comp1 = matrix( - c(1, 0, 0, 0, 2, 0, 0, 0, 3), - 3, - 3, - dimnames = list(c("A", "B", "C"), c("A", "B", "C")) - ), - C = matrix( - c(4, 0, 0, 0, 5, 0, 0, 0, 6), - 3, - 3, - dimnames = list(c("A", "B", "C"), c("A", "B", "C")) - ) - ) - w <- c(comp1 = 0.6, C = 0.4) - result <- filterMixtureComponents(c("A", "B"), U, w) - expect_false("C" %in% names(result$U)) - expect_equal(nrow(result$U$comp1), 2) - expect_equal(ncol(result$U$comp1), 2) -}) - -test_that("filterMixtureComponents renormalizes weights to preserve original sum", { +test_that("filterMixtureComponents drops zero matrices, renormalizes weights", { U <- list( comp1 = matrix( c(1, 0, 0, 2), @@ -2551,28 +2394,6 @@ test_that("mergeMashData uses one_data when res_data element has zero rows", { expect_true(nrow(result$random) >= 3) }) -test_that("mashRandNullSample with z scores returns random and null", { - set.seed(42) - dat <- list( - z = data.frame( - cond1 = c(5, 0.1, 0.2, 0.3, 0.5, 6, 0.1, 0.2, 0.4, 0.3), - cond2 = c(0.2, 0.3, 0.1, 0.5, 0.4, 0.1, 0.3, 0.2, 0.1, 0.5) - ) - ) - result <- mashRandNullSample( - dat, - nRandom = 5, - nNull = 3, - excludeCondition = c(), - seed = 123 - ) - expect_type(result, "list") - expect_true("random" %in% names(result)) - expect_true("null" %in% names(result)) - expect_true("z" %in% names(result$random)) - expect_equal(nrow(result$random$z), 5) -}) - test_that("mashRandNullSample with seed is reproducible", { dat <- list( z = data.frame( @@ -2648,29 +2469,6 @@ test_that("mashRandNullSample warns when not enough null data", { expect_equal(length(result$null), 0) }) -test_that("mashRandNullSample with bhat/sbhat processes random and null samples", { - dat <- list( - bhat = data.frame( - cond1 = c(0.1, 0.05, 0.02, 0.01, 0.03), - cond2 = c(0.02, 0.01, 0.03, 0.05, 0.04) - ), - sbhat = data.frame( - cond1 = c(0.1, 0.1, 0.1, 0.1, 0.1), - cond2 = c(0.1, 0.1, 0.1, 0.1, 0.1) - ) - ) - result <- mashRandNullSample( - dat, - nRandom = 3, - nNull = 3, - excludeCondition = c(), - seed = 42 - ) - expect_equal(ncol(result$random$bhat), 2) - expect_equal(nrow(result$random$bhat), 3) - expect_true(length(result$null) > 0) -}) - test_that("mashRandNullSample errors when excludeCondition not found (z path)", { dat <- list( z = data.frame(cond1 = 1:5, cond2 = 1:5) @@ -2685,6 +2483,17 @@ test_that("mashRandNullSample errors when excludeCondition not found (z path)", ), "excludeCondition are not present" ) + # A numeric index is not a column name, even where it is a valid position. + expect_error( + mashRandNullSample( + dat, + nRandom = 3, + nNull = 2, + excludeCondition = 2, + seed = 42 + ), + "excludeCondition are not present" + ) }) test_that("mashRandNullSample errors when excludeCondition not found (bhat path)", { @@ -2702,6 +2511,17 @@ test_that("mashRandNullSample errors when excludeCondition not found (bhat path) ), "excludeCondition are not present" ) + # A numeric index is not a column name, even where it is a valid position. + expect_error( + mashRandNullSample( + dat, + nRandom = 3, + nNull = 2, + excludeCondition = 2, + seed = 42 + ), + "excludeCondition are not present" + ) }) test_that("mashRandNullSample drops excluded condition by column name", { @@ -2724,7 +2544,7 @@ test_that("mashRandNullSample drops excluded condition by column name", { expect_false("cond3" %in% colnames(result$random$z)) }) -test_that("mashRandNullSample extracts null data with z scores when enough null variants exist", { +test_that("mashRandNullSample draws random and null samples from z scores", { dat <- list( z = data.frame( cond1 = c(0.1, 0.3, 0.2, 0.5, 0.4, 0.1, 0.3, 0.2, 0.5, 0.4), @@ -2745,7 +2565,7 @@ test_that("mashRandNullSample extracts null data with z scores when enough null expect_equal(nrow(result$random$z), 5) }) -test_that("mashRandNullSample null data capped at available null variants", { +test_that("mashRandNullSample caps both samples at the available rows", { dat <- list( z = data.frame( cond1 = c(0.1, 0.2, 0.3), @@ -2754,16 +2574,17 @@ test_that("mashRandNullSample null data capped at available null variants", { ) result <- mashRandNullSample( dat, - nRandom = 2, + nRandom = 100, nNull = 100, excludeCondition = c(), seed = 42 ) + expect_equal(nrow(result$random$z), 3) expect_true(length(result$null) > 0) expect_equal(nrow(result$null$z), 3) }) -test_that("mashRandNullSample extracts null data with bhat/sbhat when enough null variants", { +test_that("mashRandNullSample draws random and null samples from bhat/sbhat", { dat <- list( bhat = data.frame( cond1 = c(0.01, 0.02, 0.01, 0.03, 0.02, 0.01), @@ -2781,6 +2602,7 @@ test_that("mashRandNullSample extracts null data with bhat/sbhat when enough nul excludeCondition = c(), seed = 42 ) + expect_equal(dim(result$random$bhat), c(3L, 2L)) expect_true("null" %in% names(result)) expect_true("bhat" %in% names(result$null)) expect_true("sbhat" %in% names(result$null)) @@ -2788,149 +2610,6 @@ test_that("mashRandNullSample extracts null data with bhat/sbhat when enough nul expect_equal(nrow(result$null$sbhat), 4) }) -test_that("mashRandNullSample excludeCondition with numeric index errors on z path", { - dat <- list( - z = data.frame( - cond1 = c(0.1, 0.2, 0.3, 0.4, 0.5), - cond2 = c(0.5, 0.4, 0.3, 0.2, 0.1), - cond3 = c(0.3, 0.3, 0.3, 0.3, 0.3) - ) - ) - expect_error( - mashRandNullSample( - dat, - nRandom = 3, - nNull = 2, - excludeCondition = 3, - seed = 42 - ), - "excludeCondition are not present" - ) -}) - -test_that("mashRandNullSample excludeCondition with numeric index errors on bhat path", { - dat <- list( - bhat = data.frame( - cond1 = c(0.01, 0.02, 0.01, 0.03, 0.02), - cond2 = c(0.02, 0.01, 0.03, 0.01, 0.02), - cond3 = c(0.01, 0.01, 0.01, 0.01, 0.01) - ), - sbhat = data.frame( - cond1 = c(0.1, 0.1, 0.1, 0.1, 0.1), - cond2 = c(0.1, 0.1, 0.1, 0.1, 0.1), - cond3 = c(0.1, 0.1, 0.1, 0.1, 0.1) - ) - ) - expect_error( - mashRandNullSample( - dat, - nRandom = 3, - nNull = 2, - excludeCondition = 3, - seed = 42 - ), - "excludeCondition are not present" - ) -}) - -test_that("mashRandNullSample caps random sample at available rows", { - dat <- list( - z = data.frame( - cond1 = c(0.1, 0.2, 0.3), - cond2 = c(0.2, 0.1, 0.3) - ) - ) - result <- mashRandNullSample( - dat, - nRandom = 100, - nNull = 2, - excludeCondition = c(), - seed = 42 - ) - expect_equal(nrow(result$random$z), 3) -}) - -test_that("filterMixtureComponents filters zero matrices", { - U <- list( - mat1 = matrix( - c(1, 0.5, 0.5, 1), - 2, - 2, - dimnames = list(c("A", "B"), c("A", "B")) - ), - mat2 = matrix(0, 2, 2, dimnames = list(c("A", "B"), c("A", "B"))), - mat3 = matrix( - c(0.8, 0.3, 0.3, 0.9), - 2, - 2, - dimnames = list(c("A", "B"), c("A", "B")) - ) - ) - w <- c(mat1 = 0.5, mat2 = 0.3, mat3 = 0.2) - conditions_to_keep <- c("A", "B") - - result <- filterMixtureComponents(conditions_to_keep, U, w) - - # mat2 should be removed (all zeros) - expect_true(!"mat2" %in% names(result$U)) - # weights should be rescaled to maintain sum - expect_equal(sum(result$w), sum(w), tolerance = 1e-10) -}) - -test_that("filterMixtureComponents removes low weight components", { - U <- list( - mat1 = matrix( - c(1, 0.5, 0.5, 1), - 2, - 2, - dimnames = list(c("A", "B"), c("A", "B")) - ), - mat2 = matrix( - c(0.8, 0.3, 0.3, 0.9), - 2, - 2, - dimnames = list(c("A", "B"), c("A", "B")) - ) - ) - w <- c(mat1 = 0.999, mat2 = 0.00001) # mat2 below default cutoff - conditions_to_keep <- c("A", "B") - - result <- filterMixtureComponents(conditions_to_keep, U, w, wCutoff = 1e-04) - expect_true(!"mat2" %in% names(result$U)) -}) - -test_that("filterMixtureComponents errors on missing condition", { - U <- list( - mat1 = matrix( - c(1, 0.5, 0.5, 1), - 2, - 2, - dimnames = list(c("A", "B"), c("A", "B")) - ) - ) - w <- c(mat1 = 1.0) - expect_error( - filterMixtureComponents(c("A", "C"), U, w), - "not found in matrix" - ) -}) - -test_that("filterMixtureComponents subsets conditions", { - U <- list( - mat1 = matrix( - c(1, 0.5, 0.2, 0.5, 1, 0.3, 0.2, 0.3, 1), - 3, - 3, - dimnames = list(c("A", "B", "C"), c("A", "B", "C")) - ) - ) - w <- c(mat1 = 1.0) - - result <- filterMixtureComponents(c("A", "B"), U, w) - expect_equal(nrow(result$U[[1]]), 2) - expect_equal(ncol(result$U[[1]]), 2) -}) - test_that(".mashSumStatsToMatrices: auto picks BETA+SE when present", { ss <- .mssm_makeQtlSumStats(function(i, n) { list( @@ -3032,11 +2711,20 @@ test_that(".mashObjectMatrices errors when marginal effects lack the required co method = "susie", entry = list(.sc_makeFineMappingRow(3)) ) - # Force a marginal-effects table with no `context` column (as an mv/f-SuSiE + # Force marginal effects with no `context` column (as an mv/f-SuSiE # result trimmed of marginal sumstats would yield): mash cannot pivot it. testthat::local_mocked_bindings( marginalEffects = function(x, ...) { - data.frame(variant_id = "v", beta = 1, se = 1) + # mcols set apart: `se =` passed to GRanges() would partially + # match its `seqnames` formal. + S4Vectors::`mcols<-`( + GenomicRanges::GRanges("chr1:100"), + value = S4Vectors::DataFrame( + variant_id = "chr1:100:A:G", + beta = 1, + se = 1 + ) + ) }, .package = "pecotmr" ) @@ -3148,7 +2836,7 @@ test_that(".mashSumStatsToMatrices fills missing variants with bhat=0 / sbhat=10 format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * (1:5)), - CHR = "1", + CHR = "chr1", BP = seq(100L, by = 100L, length.out = 5L), A1 = "A", A2 = "G", @@ -3187,7 +2875,7 @@ test_that(".mashSumStatsToMatrices fills missing variants with bhat=0 / sbhat=10 ), genome = "hg19", ldReference = gh, - qcInfo = list(prebuilt = "synthetic") + qcOptions = list(prebuilt = "synthetic") ) out <- pecotmr:::.mashSumStatsToMatrices(ss, "strong", inputScale = "auto") expect_equal(dim(out$b), c(5L, 2L)) @@ -3208,7 +2896,7 @@ test_that(".mashSumStatsToMatrices disambiguates rownames across (study, trait) format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * (1:3)), - CHR = "1", + CHR = "chr1", BP = c(100L, 200L, 300L), A1 = "A", A2 = "G", @@ -3248,7 +2936,7 @@ test_that(".mashSumStatsToMatrices disambiguates rownames across (study, trait) ), genome = "hg19", ldReference = gh, - qcInfo = list(prebuilt = "synthetic") + qcOptions = list(prebuilt = "synthetic") ) out <- pecotmr:::.mashSumStatsToMatrices(ss, "strong", inputScale = "auto") # 3 variants per block × 2 blocks = 6 rows @@ -3270,7 +2958,7 @@ test_that(".mashSumStatsToMatrices errors when entry lacks SNP mcol", { format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * (1:3)), - CHR = "1", + CHR = "chr1", BP = c(100L, 200L, 300L), A1 = "A", A2 = "G", @@ -3299,7 +2987,7 @@ test_that(".mashSumStatsToMatrices errors when entry lacks SNP mcol", { entry = list(gr), genome = "hg19", ldReference = gh, - qcInfo = list(prebuilt = "synthetic") + qcOptions = list(prebuilt = "synthetic") ) expect_error( pecotmr:::.mashSumStatsToMatrices(ss, "strong", inputScale = "auto"), @@ -3315,7 +3003,7 @@ test_that(".mashSumStatsToMatrices on GwasSumStats: studies become columns", { format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * (1:3)), - CHR = "1", + CHR = "chr1", BP = c(100L, 200L, 300L), A1 = "A", A2 = "G", @@ -3353,7 +3041,7 @@ test_that(".mashSumStatsToMatrices on GwasSumStats: studies become columns", { ), genome = "hg19", ldReference = gh, - qcInfo = list(prebuilt = "synthetic") + qcOptions = list(prebuilt = "synthetic") ) out <- pecotmr:::.mashSumStatsToMatrices(ss, "strong", inputScale = "auto") expect_equal(ncol(out$b), 2L) @@ -3389,7 +3077,7 @@ test_that(".mashSumStatsToMatrices errors when SumStats has empty QC info", { format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * (1:3)), - CHR = "1", + CHR = "chr1", BP = c(100L, 200L, 300L), A1 = "A", A2 = "G", @@ -3418,7 +3106,7 @@ test_that(".mashSumStatsToMatrices errors when SumStats has empty QC info", { entry = list(gr), genome = "hg19", ldReference = gh, - qcInfo = list() + qcOptions = list() ) # empty QC info expect_error( pecotmr:::.mashSumStatsToMatrices(ss, "strong"), @@ -3433,7 +3121,7 @@ test_that(".mashSumStatsToMatrices errors when SumStats has zero entries", { format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * (1:3)), - CHR = "1", + CHR = "chr1", BP = c(100L, 200L, 300L), A1 = "A", A2 = "G", @@ -3451,7 +3139,7 @@ test_that(".mashSumStatsToMatrices errors when SumStats has zero entries", { genome = "hg19", ldReference = gh, varY = numeric(0), - qcInfo = list(prebuilt = "synthetic") + qcOptions = list(prebuilt = "synthetic") ) expect_error( pecotmr:::.mashSumStatsToMatrices(ss, "strong"), @@ -3507,8 +3195,12 @@ test_that("qtlSumStatsFromZMatrix: decodes chrom/pos from ids, synthesises when e <- sumStats(qss, studyName = "s1", context = "ctx", trait = "mash") expect_equal(GenomicRanges::start(e)[1], 250L) # decoded expect_true(GenomicRanges::start(e)[2] >= 1L) # synthetic fallback - # un-parseable chrom falls back to chr1 (never NA) - expect_false(any(is.na(as.character(GenomicRanges::seqnames(e))))) + # un-parseable chrom falls back to chr1 (never NA), and a decoded one is + # spelled in UCSC style like it + expect_identical( + as.character(GenomicRanges::seqnames(e)), + c("chr1", "chr1") + ) # SNP ids are carried through unchanged expect_equal(S4Vectors::mcols(e)$SNP, rownames(z)) }) @@ -3519,7 +3211,7 @@ test_that("qtlSumStatsFromZMatrix: NULL rownames get synthetic variant ids", { expect_equal(S4Vectors::mcols(qss[[1]])$SNP, c("var1", "var2")) }) -test_that("qtlSumStatsFromZMatrix: placeholders and pass-through qcInfo are set", { +test_that("qtlSumStatsFromZMatrix: placeholders and pass-through qcOptions", { z <- matrix(rnorm(6), nrow = 3, dimnames = list(NULL, c("x", "y"))) qss <- qtlSumStatsFromZMatrix( z, @@ -3534,8 +3226,10 @@ test_that("qtlSumStatsFromZMatrix: placeholders and pass-through qcInfo are set" expect_equal(unique(mc$A1), "T") expect_equal(unique(mc$A2), "C") expect_equal(unique(mc$N), 500L) - expect_equal(qcInfo(qss)$role, "strong") - expect_equal(length(qcInfo(qss)$entryAudit), 2L) # one slot per context + expect_equal(qcOptions(qss)$role, "strong") + # No QC has run: the audit names one row per context and records nothing. + expect_equal(nrow(qcInfo(qss)), 2L) + expect_null(mcols(qss)$qcAudit) }) test_that("qtlSumStatsFromZMatrix: columns can map to traits or context x trait pairs", { @@ -3661,7 +3355,7 @@ test_that("qtlSumStatsFromBetaMatrix: NULL rownames -> synthetic ids; placeholde expect_equal(mc$SNP, c("var1", "var2")) expect_equal(unique(mc$A1), "T") expect_equal(unique(mc$N), 500L) - expect_equal(qcInfo(qss)$role, "strong") + expect_equal(qcOptions(qss)$role, "strong") }) test_that("mashInput: QtlSumStats path returns the flat b/s/z + XtX contract", { @@ -3731,12 +3425,12 @@ test_that("mashInput: a fine-mapping result with no credible set: no strong", { stringsAsFactors = FALSE ) } - e1 <- fineMappingRow( + e1 <- FineMappingRow( variantIds = vids, susieFit = list(x = 1), topLoci = noCsTL(rnorm(6)) ) - e2 <- fineMappingRow( + e2 <- FineMappingRow( variantIds = vids, susieFit = list(x = 1), topLoci = noCsTL(rnorm(6)) @@ -3890,7 +3584,7 @@ test_that(".qtlSumStatsFromMatrix synthesises coords for unparseable ids", { expect_equal(GenomicRanges::start(gr), c(1L, 2L)) }) -test_that("mashWrapper: argument guards fire", { +test_that("mash data filters and merge: argument guards fire", { expect_error( filterInvalidSummaryStat("not-a-list"), "datList.*Must be of type 'list'" @@ -3938,3 +3632,81 @@ test_that(".mashFilterZ leaves a list with no z-carrying partition alone", { datList <- list(other = list(bhat = matrix(1))) expect_identical(pecotmr:::.mashFilterZ(datList, 0.5, NULL), datList) }) + +# =========================================================================== +# A GWAS study split across rows +# =========================================================================== + +test_that("mash reads each study once however many rows it spans", { + gr <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(100L * (1:6), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = sprintf("chr1:%d:A:G", 100L * (1:6)), + A1 = "A", + A2 = "G", + Z = c(3, -1, 0.5, 2, -2.5, 1), + N = 1000L + ) + gss <- GwasSumStats( + studyName = c("g1", "g2"), + entry = list(gr, gr), + genome = "hg19", + qcOptions = list(step1 = "ok"), + region = GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(1L, 351L), c(350L, 1000L)) + ) + ) + expect_equal(nrow(gss), 4L) + reads <- 0L + original <- pecotmr:::.mashRowDf + local_mocked_bindings( + .mashRowDf = function(...) { + reads <<- reads + 1L + original(...) + }, + .package = "pecotmr" + ) + mats <- pecotmr:::.mashSumStatsToMatrices(gss, "probe", inputScale = "z") + # One read per study, each stitching both of its rows. + expect_identical(reads, 2L) + # And the matrices are the unsplit studies'. + whole <- GwasSumStats( + studyName = c("g1", "g2"), + entry = list(gr, gr), + genome = "hg19", + qcOptions = list(step1 = "ok") + ) + expect_equal( + mats, + pecotmr:::.mashSumStatsToMatrices(whole, "probe", inputScale = "z") + ) +}) + +test_that("a GWAS fine-mapping result's conditions are its studies", { + block <- function(studyName, offset) { + list(study = studyName, entry = .sc_makeFineMappingRow(3, offset)) + } + rows <- list( + block("g1", 0L), + block("g1", 10000L), + block("g2", 0L), + block("g2", 10000L) + ) + fmr <- GwasFineMappingResult( + studyName = map_chr(rows, "study"), + method = rep("susie", 4L), + entry = map(rows, "entry"), + blockId = rep(c("chr1_1_5000", "chr1_5001_20000"), 2L) + ) + mats <- pecotmr:::.mashFmrMatrices(fmr, coverage = 0.95) + expect_identical(colnames(mats$b), c("g1", "g2")) + expect_equal(nrow(mats$b), 6L) + # Set 1 of each block is its own set, so each block contributes a lead. + expect_identical( + rownames(mats$b)[mats$strongRows], + c("chr1:100:A:G", "chr1:10100:A:G") + ) +}) diff --git a/tests/testthat/test_mashWrapper.R b/tests/testthat/test_mashWrapper.R index cb2e6fc6..b83f0e1d 100644 --- a/tests/testthat/test_mashWrapper.R +++ b/tests/testthat/test_mashWrapper.R @@ -1,83 +1,21 @@ context("mash_wrapper") # =========================================================================== -# filterInvalidSummaryStat +# mashModelFit / mashPosterior and the mashr / udr engine-argument +# constructors (R/mashWrapper.R) # =========================================================================== -# =========================================================================== -# filterMixtureComponents -# =========================================================================== - -# =========================================================================== -# mergeMashData -# =========================================================================== - -# =========================================================================== -# mashRandNullSample -# =========================================================================== - -# mashPipeline integration tests were removed in the S4 refactor: the -# legacy matrix-list input (strong.b/strong.s/random.b/random.s/null.b/null.s) -# is no longer accepted. The new API takes a named list of QtlSumStats / -# GwasSumStats objects, which is non-trivial to mock without exercising the -# full SumStats QC pipeline. Cover mashPipeline behavior end-to-end via the -# pipeline-level integration tests instead. - -# === Tests migrated from test_mrmashWrapper.R (filterMixtureComponents) === - -# =========================================================================== -# Tests from test_misc_round3.R (mrmashWrapper coverage boost) -# =========================================================================== - -# ========================================================================= -# mrmashWrapper.R: computeW0 (lines 284-298) -# ========================================================================= - -# =========================================================================== -# .mashSumStatsToMatrices — inputScale resolution -# =========================================================================== - -# =========================================================================== -# .mashObjectMatrices / .mashObjectPartitions -# =========================================================================== - -# =========================================================================== -# .mashSumStatsToMatrices — matrix assembly behaviour (NA fill, -# rowname disambiguation, multi-context shape) on the bundled fixture -# and on hand-built partial-coverage data. -# =========================================================================== - -# =========================================================================== -# .mashSumStatsToMatrices — GwasSumStats path + input-validation errors -# =========================================================================== - -# =========================================================================== -# mergeMashData — oneData-empty branch (returns resData unchanged) -# =========================================================================== - -# =========================================================================== -# qtlSumStatsFromZMatrix -# =========================================================================== - -# =========================================================================== -# qtlSumStatsFromBetaMatrix (beta-scale sibling of qtlSumStatsFromZMatrix) -# =========================================================================== - -# =========================================================================== -# mashInput (unified strong/random/null assembly from S4 objects) -# =========================================================================== +delayedAssign(".mwModel", .mashTestModel(.mwSs)) test_that("mashModelFit returns a fitted mash model", { skip_if_not_installed("mashr") - ss <- mashFixture() - m <- .mashTestModel(ss) - expect_s3_class(m, "mash") - expect_false(is.null(m$fitted_g)) + expect_s3_class(.mwModel, "mash") + expect_false(is.null(.mwModel$fitted_g)) }) test_that("mashModelFit validates the prior and the fitOn entry", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mwSs expect_error( mashModelFit(list(random = ss), alpha = 0, priorCovariances = list()), "non-empty named list" @@ -94,27 +32,23 @@ test_that("mashModelFit validates the prior and the fitOn entry", { test_that("mashModelFit accepts either prior shape and fits identically", { skip_if_not_installed("mashr") - ss <- mashFixture() + # .mwModel is the fit of this same prior given as a bare list. ulist <- list(identity = diag(3), effectA = diag(c(1, 0, 0))) wrapped <- list(U = ulist, w = NULL, loglik = NULL) - - fit <- function(prior) { - suppressMessages(suppressWarnings(mashModelFit( - list(random = ss), - alpha = 0, - priorCovariances = prior, - vhat = diag(3), - setSeed = 1L - ))) - } - expect_equal(fit(wrapped)$loglik, fit(ulist)$loglik) + fit <- suppressMessages(suppressWarnings(mashModelFit( + list(random = .mwSs), + alpha = 0, + priorCovariances = wrapped, + vhat = diag(3), + setSeed = 1L + ))) + expect_equal(fit$loglik, .mwModel$loglik) }) test_that("mashPosterior returns posterior matrices with covariance", { skip_if_not_installed("mashr") - ss <- mashFixture() post <- suppressMessages(suppressWarnings( - mashPosterior(.mashTestModel(ss), ss, alpha = 0, vhat = diag(3)) + mashPosterior(.mwModel, .mwSs, alpha = 0, vhat = diag(3)) )) expect_true(all( c("PosteriorMean", "PosteriorSD", "lfsr", "PosteriorCov") %in% @@ -126,11 +60,10 @@ test_that("mashPosterior returns posterior matrices with covariance", { test_that("mashPosterior outputPosteriorCov = FALSE omits PosteriorCov", { skip_if_not_installed("mashr") - ss <- mashFixture() post <- suppressMessages(suppressWarnings( mashPosterior( - .mashTestModel(ss), - ss, + .mwModel, + .mwSs, alpha = 0, vhat = diag(3), outputPosteriorCov = FALSE @@ -142,11 +75,11 @@ test_that("mashPosterior outputPosteriorCov = FALSE omits PosteriorCov", { test_that("mashPosterior(excludeCondition) drops the condition from model + output", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mwSs conds <- colnames(.mashSumStatsToMatrices(ss, "strong")$b) post <- suppressMessages(suppressWarnings( mashPosterior( - .mashTestModel(ss), + .mwModel, ss, alpha = 0, vhat = diag(3), @@ -159,11 +92,10 @@ test_that("mashPosterior(excludeCondition) drops the condition from model + outp test_that("mashPosterior errors on an unknown excludeCondition", { skip_if_not_installed("mashr") - ss <- mashFixture() expect_error( mashPosterior( - .mashTestModel(ss), - ss, + .mwModel, + .mwSs, alpha = 0, vhat = diag(3), excludeCondition = "not_a_condition" @@ -174,7 +106,7 @@ test_that("mashPosterior errors on an unknown excludeCondition", { test_that("mashModelFit: SimpleList input + default (NULL) vhat", { skip_if_not_installed("mashr") - ss <- mashFixture() + ss <- .mwSs m <- suppressMessages(suppressWarnings( mashModelFit( S4Vectors::SimpleList(random = ss), @@ -188,8 +120,8 @@ test_that("mashModelFit: SimpleList input + default (NULL) vhat", { test_that("mashPosterior: default (NULL) vhat and excludeCondition dropping every condition", { skip_if_not_installed("mashr") - ss <- mashFixture() - model <- .mashTestModel(ss) + ss <- .mwSs + model <- .mwModel conds <- colnames(.mashSumStatsToMatrices(ss, "strong")$b) # NULL vhat path: omit vhat so mashPosterior fills the identity default. post <- suppressMessages(suppressWarnings(mashPosterior( @@ -315,10 +247,13 @@ test_that("the mash constructors carry their pecotmr defaults", { expect_length(MashOptions(), 0L) }) -test_that("mashDataArgs reaches mashr::mash_set_data", { +test_that("mashDataArgs and mashArgs reach mashr::mash_set_data and mash", { skip_if_not_installed("mashr") - seen <- NULL - real <- mashr::mash_set_data + # One recorded fit serves both bundles: each mash() call is costly. + dataSeen <- NULL + mashSeen <- NULL + realData <- mashr::mash_set_data + realMash <- mashr::mash ss <- mashFixture(20L) suppressMessages(suppressWarnings(with_mocked_bindings( mashModelFit( @@ -327,61 +262,38 @@ test_that("mashDataArgs reaches mashr::mash_set_data", { priorCovariances = mashTinyPrior(), vhat = diag(3), mashDataArgs = MashDataOptions(zero_Shat_reset = 0.5), + mashArgs = MashOptions(nullweight = 7, verbose = FALSE), setSeed = 1L ), mash_set_data = function(...) { - seen <<- list(...) - real(...) + dataSeen <<- list(...) + realData(...) }, - .package = "mashr" - ))) - expect_equal(seen$zero_Shat_reset, 0.5) - # The pecotmr default rides along unless the caller overrides it. - expect_equal(seen$zero_Bhat_Shat_reset, 1000) -}) - -test_that("mashArgs reaches mashr::mash", { - skip_if_not_installed("mashr") - seen <- NULL - real <- mashr::mash - ss <- mashFixture(20L) - suppressMessages(suppressWarnings(with_mocked_bindings( - mashModelFit( - list(random = ss), - alpha = 0, - priorCovariances = mashTinyPrior(), - vhat = diag(3), - mashArgs = MashOptions(nullweight = 7, verbose = FALSE), - setSeed = 1L - ), mash = function(...) { - seen <<- list(...) - real(...) + mashSeen <<- list(...) + realMash(...) }, .package = "mashr" ))) - expect_equal(seen$nullweight, 7) - expect_false(seen$verbose) + expect_equal(dataSeen$zero_Shat_reset, 0.5) + # The pecotmr default rides along unless the caller overrides it. + expect_equal(dataSeen$zero_Bhat_Shat_reset, 1000) + expect_equal(mashSeen$nullweight, 7) + expect_false(mashSeen$verbose) # The entry point keeps owning outputlevel and the data/prior pair. - expect_equal(seen$outputlevel, 4L) + expect_equal(mashSeen$outputlevel, 4L) }) test_that("mashPosterior forwards posteriorArgs", { skip_if_not_installed("mashr") seen <- NULL real <- mashr::mash_compute_posterior_matrices - ss <- mashFixture(20L) - model <- suppressMessages(suppressWarnings(mashModelFit( - list(random = ss), - alpha = 0, - priorCovariances = mashTinyPrior(), - vhat = diag(3), - setSeed = 1L - ))) + # Built before the mock is in place, so only mashPosterior is recorded. + model <- .mwModel suppressMessages(suppressWarnings(with_mocked_bindings( mashPosterior( model, - ss, + .mwSs, alpha = 0, vhat = diag(3), posteriorArgs = MashPosteriorOptions(pi_thresh = 1e-8) @@ -395,29 +307,6 @@ test_that("mashPosterior forwards posteriorArgs", { expect_equal(seen$pi_thresh, 1e-8) }) -test_that("the udr engine runs on the z scale, where udr picks TED", { - skip_if_not_installed("mashr") - skip_if_not_installed("udr") - # The companion to the alpha = 0 run above: both existing udr tests were - # on the beta scale, so the branch that lets udr choose was unexercised. - ss <- mashFixture() - pc <- suppressMessages(suppressWarnings( - mashPriorCovariances( - list(strong = ss), - alpha = 1, - vhat = diag(3), - engine = CovUdrOptions( - init = UdInitOptions(n_unconstrained = 2L), - fit = UdFitOptions(maxiter = 20L) - ), - setSeed = 1L - ) - )) - expect_gt(length(pc$U), 0L) - expect_true(all(map_lgl(pc$U, function(m) all(dim(m) == c(3L, 3L))))) - expect_equal(sum(pc$w), 1, tolerance = 1e-6) -}) - test_that("UdFitOptions checks unconstrained.update's value, not just its name", { skip_if_not_installed("udr") # udr validates the NAME but not the value: compute_penalty() is two diff --git a/tests/testthat/test_overlapTopLoci.R b/tests/testthat/test_overlapTopLoci.R index 73c43694..38132470 100644 --- a/tests/testthat/test_overlapTopLoci.R +++ b/tests/testthat/test_overlapTopLoci.R @@ -25,7 +25,7 @@ context("overlapTopLoci") ) } .ot_entry <- function(tl) { - fineMappingRow( + FineMappingRow( variantIds = tl$variant_id, susieFit = list(fake = TRUE), topLoci = tl @@ -70,6 +70,7 @@ test_that("overlapTopLoci joins QTL x GWAS with allele-aware matching + sign-fli ) ov <- overlapTopLoci(qtl, gwas, signalCutoff = 0) + expect_s4_class(ov, "GRanges") # variant key kept once; every other column prefixed qtl_ / gwas_ cols <- names(S4Vectors::mcols(ov)) @@ -82,11 +83,12 @@ test_that("overlapTopLoci joins QTL x GWAS with allele-aware matching + sign-fli # per-context QTL rows preserved expect_setequal(unique(ov$qtl_context), c("ctx1", "ctx2")) - # v1 unflipped: gwas beta unchanged (+0.6); v2 swapped: sign-flipped (-0.5) + # v1 unflipped: gwas posterior effect unchanged (+0.6); v2 swapped: + # sign-flipped (-0.5) v1 <- ov[ov$variant_id == "chr1:100:A:G", ] v2 <- ov[ov$variant_id == "chr1:200:A:G", ] - expect_true(all(abs(v1$gwas_beta - 0.60) < 1e-9)) - expect_true(all(abs(v2$gwas_beta + 0.50) < 1e-9)) + expect_equal(v1$gwas_posterior_effect, c(0.60, 0.60)) + expect_equal(v2$gwas_posterior_effect, c(-0.50, -0.50)) # af complemented on the swapped variant (0.7 -> 0.3), untouched otherwise expect_true(all(abs(v2$gwas_af - 0.30) < 1e-9)) expect_true(all(abs(v1$gwas_af - 0.20) < 1e-9)) @@ -160,36 +162,3 @@ test_that("overlapTopLoci returns an empty merge when a side has no signal", { # the empty result is still ranges (.overlapToGRanges empty guard) expect_s4_class(df, "GRanges") }) - -test_that("overlapTopLoci returns a GRanges of the shared variants", { - q <- .ot_entry(.ot_tl( - c("chr1:100:A:G", "chr1:200:A:G"), - A1 = c("G", "G"), - A2 = c("A", "A"), - pm = c(0.3, 0.4), - af = c(0.3, 0.4) - )) - g <- .ot_entry(.ot_tl( - "chr1:100:A:G", - A1 = "G", - A2 = "A", - pm = 0.6, - af = 0.2 - )) - qtl <- QtlFineMappingResult( - studyName = "s", - context = "c", - trait = "t", - method = "susie", - entry = list(q) - ) - gwas <- GwasFineMappingResult( - studyName = "g", - method = "susie", - entry = list(g) - ) - gr <- overlapTopLoci(qtl, gwas, signalCutoff = 0) - expect_s4_class(gr, "GRanges") - expect_equal(length(gr), 1L) - expect_true("gwas_posterior_effect" %in% names(S4Vectors::mcols(gr))) -}) diff --git a/tests/testthat/test_pvalCombineWrappers.R b/tests/testthat/test_pvalCombineWrappers.R index 2e50f16e..4a022ec1 100644 --- a/tests/testthat/test_pvalCombineWrappers.R +++ b/tests/testthat/test_pvalCombineWrappers.R @@ -13,16 +13,6 @@ test_that("waldTestPval: returns two-sided p-values matching stats::pt", { expect_equal(res, expected) }) -test_that("waldTestPval: returns 1 when beta is zero", { - expect_equal(waldTestPval(0, 0.1, 50), 1, tolerance = 1e-12) -}) - -test_that("waldTestPval: is vectorised over beta/se", { - res <- waldTestPval(c(1, 2, 3), c(0.5, 0.5, 0.5), 100) - expect_length(res, 3) - expect_true(all(res > 0 & res <= 1)) -}) - # =========================================================================== # pvalAcat (internal) # =========================================================================== @@ -51,6 +41,7 @@ test_that("pvalAcat: clips very-near-1 p-values to 0.99", { test_that("pvalAcat: small p-values produce small combined p", { combined <- pecotmr:::pvalAcat(rep(1e-6, 5)) + expect_gt(combined, 0) expect_lt(combined, 1e-5) }) @@ -312,7 +303,7 @@ test_that("combinePValues dispatches aSPU and GATES", { }) # =========================================================================== -# Tests migrated from test_misc.R (p-value combiners + waldTestPval) +# pvalHmp # =========================================================================== test_that("pvalHmp returns valid p-value", { @@ -321,26 +312,13 @@ test_that("pvalHmp returns valid p-value", { result <- pecotmr:::pvalHmp(pvals) expect_true(is.numeric(result)) expect_true(result >= 0 && result <= 1) - # The harmonic mean is L/sum(1/p) where L = length(unique(pvals)) - L <- length(unique(pvals)) - HMP <- L / sum(1 / pvals) - # Result should be based on pLandau(1/HMP, ...) and be smaller than the arithmetic mean + # pLandau's tail at 1 / HMP, HMP = L / sum(1 / p): for these inputs it + # sits below both their arithmetic mean and the largest of them. expect_true(result < mean(pvals)) - # Verify the result is less than the smallest individual p-value is not required, - # but it should be in a reasonable range relative to the harmonic mean expect_true(result < 0.1) }) -test_that("pvalHmp uses unique p-values only", { - skip_if_not_installed("harmonicmeanp") - pvals <- c(0.01, 0.01, 0.05, 0.05, 0.3) - result <- pecotmr:::pvalHmp(pvals) - expect_true(is.numeric(result)) - expect_true(result >= 0 && result <= 1) -}) - - test_that("pvalHmp errors when package not available", { skip_if( requireNamespace("harmonicmeanp", quietly = TRUE), @@ -353,26 +331,6 @@ test_that("pvalHmp errors when package not available", { # pvalAcat # ============================================================================= -test_that("pvalAcat returns single p-value unchanged", { - expect_equal(pecotmr:::pvalAcat(0.05), 0.05) -}) - - -test_that("pvalAcat combines multiple p-values", { - pvals <- c(0.001, 0.01, 0.1) - combined <- pecotmr:::pvalAcat(pvals) - expect_true(combined > 0 && combined < 1) -}) - - -test_that("pvalAcat with very small p-values does not return NA", { - result <- pecotmr:::pvalAcat(c(1e-10, 1e-8, 1e-6)) - expect_true(is.numeric(result)) - expect_true(!is.na(result)) - expect_true(result > 0 && result <= 1) -}) - - test_that("pvalAcat with all large p-values returns large combined p-value", { result <- pecotmr:::pvalAcat(c(0.8, 0.9, 0.95)) expect_true(is.numeric(result)) @@ -380,48 +338,10 @@ test_that("pvalAcat with all large p-values returns large combined p-value", { }) -test_that("pvalAcat uses asymptotic approximation for p < 1e-15", { - # p-values below 1e-15 use 1/(p*pi) instead of tan() - result <- pecotmr:::pvalAcat(c(1e-20, 1e-18, 0.01)) - expect_true(is.numeric(result)) - expect_true(result > 0 && result < 1) - expect_false(is.na(result)) -}) - # ============================================================================= # pvalPoolr # ============================================================================= -test_that("pvalPoolr fisher method returns valid p-value", { - skip_if_not_installed("poolr") - pvals <- c(0.01, 0.05, 0.1) - R <- diag(3) - result <- pecotmr:::pvalPoolr(pvals, method = "fisher", R = R) - expect_true(is.numeric(result)) - expect_true(result > 0 && result < 1) -}) - - -test_that("pvalPoolr stouffer method returns valid p-value", { - skip_if_not_installed("poolr") - pvals <- c(0.01, 0.05, 0.1) - R <- diag(3) - result <- pecotmr:::pvalPoolr(pvals, method = "stouffer", R = R) - expect_true(is.numeric(result)) - expect_true(result > 0 && result < 1) -}) - - -test_that("pvalPoolr invchisq method returns valid p-value", { - skip_if_not_installed("poolr") - pvals <- c(0.01, 0.05, 0.1) - R <- diag(3) - result <- pecotmr:::pvalPoolr(pvals, method = "invchisq", R = R) - expect_true(is.numeric(result)) - expect_true(result > 0 && result < 1) -}) - - test_that("generalized poolr tests reduce to the plain ones when independent", { # With R = I the generalized adjustment must give the unadjusted test. # poolr reads R as the covariance of each test's transformed statistic, @@ -435,6 +355,32 @@ test_that("generalized poolr tests reduce to the plain ones when independent", { expect_equal(pecotmr:::pvalPoolr(p, "invchisq", R), poolr::invchisq(p)$p) }) +test_that("pvalPoolr runs poolr's empirical adjustment for every test", { + # poolr names the running test from its own call; with the function + # object inlined into the call it could not, and every empirical + # adjustment failed inside poolr. + skip_if_not_installed("poolr") + p <- c(0.01, 0.2, 0.5) + R <- diag(3) + R[1, 2] <- R[2, 1] <- 0.3 + direct <- list( + fisher = function() poolr::fisher(p, adjust = "empirical", R = R), + stouffer = function() poolr::stouffer(p, adjust = "empirical", R = R), + invchisq = function() poolr::invchisq(p, adjust = "empirical", R = R) + ) + for (method in names(direct)) { + set.seed(1) + got <- pecotmr:::pvalPoolr( + p, + method, + R, + PoolrOptions(adjust = "empirical") + ) + set.seed(1) + expect_equal(got, direct[[method]]()$p, info = method) + } +}) + test_that(".poolrDependence converts R for the adjustment poolr runs", { skip_if_not_installed("poolr") R <- 0.6^abs(outer(1:4, 1:4, "-")) @@ -481,66 +427,6 @@ test_that("pvalPoolr errors on unknown method", { # pvalGbj # ============================================================================= -test_that("pvalGbj gbj method returns valid p-value", { - skip_if_not_installed("GBJ") - z <- c(2.5, 1.8, 3.0) - R <- diag(3) - result <- pecotmr:::pvalGbj(z, R, method = "gbj") - expect_true(is.numeric(result)) - expect_true(result >= 0 && result <= 1) -}) - - -test_that("pvalGbj hc method returns valid p-value", { - skip_if_not_installed("GBJ") - z <- c(2.5, 1.8, 3.0) - R <- diag(3) - result <- pecotmr:::pvalGbj(z, R, method = "hc") - expect_true(is.numeric(result)) - expect_true(result >= 0 && result <= 1) -}) - - -test_that("pvalGbj minp method returns valid p-value", { - skip_if_not_installed("GBJ") - z <- c(2.5, 1.8, 3.0) - R <- diag(3) - result <- pecotmr:::pvalGbj(z, R, method = "minp") - expect_true(is.numeric(result)) - expect_true(result >= 0 && result <= 1) -}) - - -test_that("pvalGbj bj method returns valid p-value", { - skip_if_not_installed("GBJ") - z <- c(2.5, 1.8, 3.0) - R <- diag(3) - result <- pecotmr:::pvalGbj(z, R, method = "bj") - expect_true(is.numeric(result)) - expect_true(result >= 0 && result <= 1) -}) - - -test_that("pvalGbj ghc method returns valid p-value", { - skip_if_not_installed("GBJ") - z <- c(2.5, 1.8, 3.0) - R <- diag(3) - result <- pecotmr:::pvalGbj(z, R, method = "ghc") - expect_true(is.numeric(result)) - expect_true(result >= 0 && result <= 1) -}) - - -test_that("pvalGbj gbj_omni method returns valid p-value", { - skip_if_not_installed("GBJ") - z <- c(2.5, 1.8, 3.0) - R <- diag(3) - result <- pecotmr:::pvalGbj(z, R, method = "gbj_omni") - expect_true(is.numeric(result)) - expect_true(result >= 0 && result <= 1) -}) - - test_that("pvalGbj errors on unknown method", { skip_if_not_installed("GBJ") expect_error( @@ -553,27 +439,6 @@ test_that("pvalGbj errors on unknown method", { # pvalAspu # ============================================================================= -test_that("pvalAspu aspu method returns valid p-value", { - skip_if_not_installed("aSPU") - set.seed(42) - z <- c(2.5, 1.8, 3.0) - R <- diag(3) - result <- pecotmr:::pvalAspu(zScores = z, R = R, method = "aspu") - expect_true(is.numeric(result)) - expect_true(result >= 0 && result <= 1) -}) - - -test_that("pvalAspu gates method returns valid p-value", { - skip_if_not_installed("aSPU") - pvals <- c(0.01, 0.05, 0.1) - R <- diag(3) - result <- pecotmr:::pvalAspu(pvals = pvals, R = R, method = "gates") - expect_true(is.numeric(result)) - expect_true(result >= 0 && result <= 1) -}) - - test_that("pvalAspu errors on unknown method", { skip_if_not_installed("aSPU") expect_error( @@ -582,49 +447,9 @@ test_that("pvalAspu errors on unknown method", { ) }) -# ============================================================================= -# ============================================================================= -# findValidFilePath and findValidFilePaths -# ============================================================================= - -test_that("waldTestPval computes correct p-values", { - pval <- waldTestPval(beta = 5, se = 1, n = 100) - expect_true(pval < 0.001) - - pval_zero <- waldTestPval(beta = 0, se = 1, n = 100) - expect_equal(pval_zero, 1.0, tolerance = 1e-10) -}) - - -test_that("waldTestPval handles vector inputs", { - betas <- c(0, 1, 2, 5) - ses <- c(1, 1, 1, 1) - pvals <- waldTestPval(betas, ses, n = 100) - expect_length(pvals, 4) - expect_true(pvals[1] > pvals[4]) -}) - - -test_that("waldTestPval is symmetric in beta sign", { - pval_pos <- waldTestPval(beta = 3, se = 1, n = 50) - pval_neg <- waldTestPval(beta = -3, se = 1, n = 50) - expect_equal(pval_pos, pval_neg, tolerance = 1e-10) -}) - - -test_that("waldTestPval with very large beta gives p near 0", { - pval <- waldTestPval(beta = 100, se = 1, n = 1000) - expect_true(pval < 1e-10) -}) - - -test_that("waldTestPval with very large se gives p near 1", { - pval <- waldTestPval(beta = 1, se = 1000, n = 100) - expect_true(pval > 0.99) -}) # ============================================================================= -# parseRegion +# Argument guards # ============================================================================= test_that("pvalCombine: argument guards fire", { @@ -757,7 +582,10 @@ test_that("combinePValues forwards each method's options to its engine", { ), stouffer = function(...) { seen <<- list(...) - real(...) + # Called by its own name: poolr's empirical adjustment reads + # which test it is from its call. + stouffer <- real + stouffer(...) }, .package = "poolr" ) diff --git a/tests/testthat/test_qtlAssociationPostprocess.R b/tests/testthat/test_qtlAssociationPostprocess.R index 24eabd86..4cbebd1f 100644 --- a/tests/testthat/test_qtlAssociationPostprocess.R +++ b/tests/testthat/test_qtlAssociationPostprocess.R @@ -1,85 +1,15 @@ context("qtlAssociationPostprocess") -# A deterministic per-gene QtlSumStats: one row per gene carrying the regional -# summary as row columns (p_beta / beta shapes / n_variants), each entry a -# per-variant GRanges (P / af / tss_distance / tes_distance). Deterministic so -# qvalue::qvalue sees a stable p-value distribution. -# drop row columns to omit (e.g. "n_variants", "p_beta", beta shapes), -# for the required-column / missing-input error paths. -# withQvalue attach a per-variant `qvalue` mcol (needed by the qvalue SNP -# significance query), with v1 tracking the gene signal. -# emptyIdx gene indices whose entry is an empty GRanges (no p-values), for -# the "skip genes with no variants" branch. -# naShapeIdx gene indices given an NA beta_shape1 (so qbeta -> NA nominal -# threshold), for the "skip genes with an NA threshold" branch. -# Column counts and the p_beta distribution are unchanged from the base -# fixture, so qvalue::qvalue still estimates pi0 on its default path. -.qapFixture <- function( - nVar = 50L, - nVarFilt = 30L, - drop = character(), - withQvalue = FALSE, - emptyIdx = integer(0), - naShapeIdx = integer(0) -) { - # 6 strong signal p_beta + a deterministic uniform null (ppoints) so - # qvalue::qvalue estimates pi0 on its default path (no fallback needed). - pBeta <- c(10^(-c(8, 7, 6, 5, 4, 3)), stats::ppoints(54)) - G <- length(pBeta) - entries <- map(seq_len(G), function(i) { - if (i %in% emptyIdx) { - return(GenomicRanges::GRanges()) - } # no variants - k <- 4L - pv <- c(pBeta[i] / 5, 0.2, 0.5, 0.8) # min tracks the gene signal - gr <- GenomicRanges::GRanges( - "chr1", - IRanges::IRanges( - start = seq(1000L, by = 50L, length.out = k), - width = 1L - ) - ) - mc <- S4Vectors::DataFrame( - SNP = paste0("g", i, "_v", seq_len(k)), - A1 = "A", - A2 = "G", - P = pv, - af = c(0.30, 0.20, 0.005, 0.40), # v3 fails MAF 0.01 - tss_distance = c(0L, 500L, 900000L, 2000000L), # v4 outside 1Mb cis - tes_distance = c(0L, 500L, 900000L, 2000000L) - ) - if (withQvalue) { - mc$qvalue <- c(pBeta[i] / 5, 0.30, 0.60, 0.90) - } - S4Vectors::mcols(gr) <- mc - gr - }) - shape1 <- rep(1, G) - shape1[naShapeIdx] <- NA_real_ - extra <- list( - n_variants = rep(nVar, G), - n_variants_filtered = rep(nVarFilt, G), - p_beta = pBeta, - beta_shape1 = shape1, - beta_shape2 = rep(200, G) - ) - args <- list( - study = rep("s", G), - context = rep("brain", G), - trait = paste0("g", seq_len(G)), - entry = entries, - genome = "hg19", - extraCols = extra[setdiff(names(extra), drop)] - ) - exec(QtlSumStats, !!!args[setdiff(names(args), drop)]) +# The shared fixture without the named row columns, for the required-column / +# missing-input error paths: dropping a column is a cheap mcols edit, where a +# rebuild costs as much as the test itself. +.qapWithout <- function(cols) { + x <- .qapDefaultFixture + kept <- setdiff(colnames(S4Vectors::mcols(x)), cols) + S4Vectors::mcols(x) <- S4Vectors::mcols(x)[, kept, drop = FALSE] + x } -# The default fixture is 60 genes of GRanges + mcols and costs ~0.5s to build, -# which is most of this file's runtime when every test rebuilds it. S4 objects -# are copy-on-modify, so one shared instance is safe; tests needing a variant -# still call .qapFixture() with arguments. -.qapDefaultFixture <- .qapFixture() - test_that("qtlAssociationPostprocess enriches with package-computed columns", { x <- .qapDefaultFixture r <- qtlAssociationPostprocess( @@ -90,7 +20,7 @@ test_that("qtlAssociationPostprocess enriches with package-computed columns", { ) expect_s4_class(r, "QtlSumStats") - expect_false(is.null(qcInfo(r)$associationPostprocess)) # recipe stashed + expect_false(is.null(qcOptions(r)$associationPostprocess)) # recipe stashed # Bonferroni original == min over variants of p.adjust(P, "bonferroni", n). expP <- map_dbl( @@ -178,28 +108,6 @@ test_that("significantQtls (bonferroni) matches the derived threshold rule", { expect_equal(length(sig), expN) }) -test_that("sumStats(annotateSignificance=) adds a derived logical mcol", { - x <- .qapDefaultFixture - r <- qtlAssociationPostprocess(x, methods = "permutation") - gr <- sumStats( - r, - studyName = "s", - context = "brain", - trait = "g1", - annotateSignificance = "permutation" - ) - expect_true("significant" %in% names(S4Vectors::mcols(gr))) - expect_type(S4Vectors::mcols(gr)$significant, "logical") - # matches the permutation rule P < p_nominal_threshold[gene 1] - thr1 <- as.numeric(r$p_nominal_threshold)[1] - exp1 <- if (is.na(thr1)) { - rep(FALSE, length(gr)) - } else { - S4Vectors::mcols(gr)$P < thr1 - } - expect_equal(S4Vectors::mcols(gr)$significant, exp1) -}) - test_that("significance accessors require a postprocessed object", { x <- .qapDefaultFixture # not postprocessed expect_error( @@ -214,34 +122,29 @@ test_that("significance accessors require a postprocessed object", { # qvalue-native error on the primary (no-lambda) call and succeed on the retry # (lambda supplied), then assert the retry value flows through unchanged. -test_that(".qapSafeQvalue retries with lambda=0 on qvalue 'missing or infinite'", { +test_that(".qapSafeQvalue retries both qvalue-native degenerate cases", { skip_if_not_installed("qvalue") - testthat::local_mocked_bindings( - qvalue = function(p, lambda, ...) { - if (missing(lambda)) { - stop("missing or infinite values in the smoother") - } - list(qvalues = rep(0.111, length(p))) - }, - .package = "qvalue" - ) - r <- qtlAssociationPostprocess(.qapDefaultFixture, methods = "permutation") - expect_true(all(as.numeric(r$q_beta) == 0.111)) -}) - -test_that(".qapSafeQvalue retries with bootstrap pi0 on qvalue 'pi0 <= 0'", { - skip_if_not_installed("qvalue") - testthat::local_mocked_bindings( - qvalue = function(p, lambda, ...) { - if (missing(lambda)) { - stop("ERROR: The estimated pi0 <= 0.") - } - list(qvalues = rep(0.222, length(p))) - }, - .package = "qvalue" - ) - r <- qtlAssociationPostprocess(.qapDefaultFixture, methods = "permutation") - expect_true(all(as.numeric(r$q_beta) == 0.222)) + # 'missing or infinite' retries with lambda = 0, 'pi0 <= 0' with a + # bootstrap pi0. + for (err in c( + "missing or infinite values in the smoother", + "ERROR: The estimated pi0 <= 0." + )) { + testthat::local_mocked_bindings( + qvalue = function(p, lambda, ...) { + if (missing(lambda)) { + stop(err) + } + list(qvalues = rep(0.111, length(p))) + }, + .package = "qvalue" + ) + r <- qtlAssociationPostprocess( + .qapDefaultFixture, + methods = "permutation" + ) + expect_true(all(as.numeric(r$q_beta) == 0.111), info = err) + } }) test_that(".qapSafeQvalue re-raises a non-native qvalue error (no hand-rolled q)", { @@ -296,8 +199,10 @@ test_that("significantQtls (permutation) uses each gene's nominal threshold", { test_that("significantQtls (permutation) skips genes with an NA threshold", { # Gene 1's NA beta_shape1 makes its qbeta nominal threshold NA, so the mask # loop must `next` past it while still processing the non-NA genes. + x <- .qapDefaultFixture + S4Vectors::mcols(x)$beta_shape1[1L] <- NA_real_ r <- qtlAssociationPostprocess( - .qapFixture(naShapeIdx = 1L), + x, fdrThreshold = 0.1, methods = "permutation" ) @@ -322,31 +227,13 @@ test_that("significantQtls (permutation) skips genes with an NA threshold", { test_that("significantQtls (permutation) errors without a nominal threshold", { # No beta shapes -> postprocess produces no p_nominal_threshold column. r <- qtlAssociationPostprocess( - .qapFixture(drop = c("beta_shape1", "beta_shape2")), + .qapWithout(c("beta_shape1", "beta_shape2")), methods = "permutation" ) expect_null(r$p_nominal_threshold) expect_error(significantQtls(r, "permutation"), "p_nominal_threshold") }) -test_that("significantQtls (bonferroni_filtered) applies the MAF/cis keep filter", { - r <- qtlAssociationPostprocess( - .qapDefaultFixture, - mafCutoff = 0.01, - cisWindow = 1e6 - ) - sig <- significantQtls(r, "bonferroni_filtered", threshold = 0.5) - expect_s4_class(sig, "GRanges") - expect_gt(length(sig), 0) - # Every returned variant must satisfy the filtered keep rule (MAF & cis window). - af <- S4Vectors::mcols(sig)$af - expect_true(all(pmin(af, 1 - af) > 0.01)) - expect_true(all( - S4Vectors::mcols(sig)$tss_distance >= -1e6 & - S4Vectors::mcols(sig)$tes_distance <= 1e6 - )) -}) - test_that("significantQtls (bonferroni) errors when its columns are absent", { r <- qtlAssociationPostprocess(.qapDefaultFixture, methods = "permutation") # no bonferroni expect_error(significantQtls(r, "bonferroni_original"), "columns absent") @@ -355,7 +242,7 @@ test_that("significantQtls (bonferroni) errors when its columns are absent", { test_that("significantQtls (qvalue) selects variants by their qvalue mcol", { skip_if_not_installed("qvalue") r <- qtlAssociationPostprocess( - .qapFixture(withQvalue = TRUE), + .qapDefaultFixture, fdrThreshold = 0.1, methods = "permutation" ) @@ -379,7 +266,7 @@ test_that("significantQtls (qvalue) errors when no event q column exists", { # Drop p_beta so permutation adds no q_beta, and skip bonferroni so there is # no q_bonferroni_min_original either -- yet the object is still postprocessed. r <- qtlAssociationPostprocess( - .qapFixture(drop = "p_beta"), + .qapWithout("p_beta"), methods = "permutation" ) expect_null(r$q_beta) @@ -403,7 +290,7 @@ test_that("significantQtls returns an empty GRanges when nothing is significant" test_that("qtlAssociationPostprocess requires n_variants for Bonferroni", { expect_error( qtlAssociationPostprocess( - .qapFixture(drop = "n_variants"), + .qapWithout("n_variants"), methods = "bonferroni" ), "required for the Bonferroni" @@ -413,7 +300,7 @@ test_that("qtlAssociationPostprocess requires n_variants for Bonferroni", { test_that("qtlAssociationPostprocess requires n_variants_filtered when filtering", { expect_error( qtlAssociationPostprocess( - .qapFixture(drop = "n_variants_filtered"), + .qapWithout("n_variants_filtered"), methods = "bonferroni", mafCutoff = 0.01 ), @@ -475,7 +362,16 @@ test_that("significantQtls(bonferroni_filtered) applies the derived rule on the sum(pmin(1, p * 30) <= varThr) } )) + expect_gt(expN, 0) expect_equal(length(sig), expN) + # Every returned variant satisfies the filtered keep rule (MAF and the + # cis window). + af <- S4Vectors::mcols(sig)$af + expect_true(all(pmin(af, 1 - af) > 0.01)) + expect_true(all( + S4Vectors::mcols(sig)$tss_distance >= -1e6 & + S4Vectors::mcols(sig)$tes_distance <= 1e6 + )) }) test_that(".qapSignificanceMask returns empty masks for an unknown method", { @@ -498,7 +394,7 @@ test_that(".qapSignificanceMask returns empty masks for an unknown method", { genome = "hg19" ) local_mocked_bindings( - qcInfo = function(x) { + qcOptions = function(x) { list( associationPostprocess = list( fdrThreshold = 0.05, diff --git a/tests/testthat/test_qtlEnrichmentPipeline.R b/tests/testthat/test_qtlEnrichmentPipeline.R index 35202b32..28dd8846 100644 --- a/tests/testthat/test_qtlEnrichmentPipeline.R +++ b/tests/testthat/test_qtlEnrichmentPipeline.R @@ -30,7 +30,7 @@ context("qtlEnrichmentPipeline") format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -60,7 +60,7 @@ context("qtlEnrichmentPipeline") stringsAsFactors = FALSE ) fit <- list(alpha = alpha, pip = setNames(pip, variant_ids), V = 0.1) - fineMappingRow(variantIds = variant_ids, susieFit = fit, topLoci = tl) + FineMappingRow(variantIds = variant_ids, susieFit = fit, topLoci = tl) } .qep_makeGwasFmr <- function( @@ -161,7 +161,7 @@ test_that("qtlEnrichmentPipeline: the real estimator fills the value columns", { gfmr <- GwasFineMappingResult( studyName = "G1", method = "susie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( variantIds = ids, susieFit = list( alpha = matrix(1 / 50, nrow = 1L, ncol = 50L), @@ -177,7 +177,7 @@ test_that("qtlEnrichmentPipeline: the real estimator fills the value columns", { context = "c1", trait = "t1", method = "susie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( variantIds = ids, susieFit = list( alpha = alpha, @@ -409,7 +409,7 @@ test_that("qtlEnrichmentPipeline: qtlEnrichment failure produces a warning + ski test_that("qtlEnrichmentPipeline: empty input collections yield the empty schema", { # Build a GwasFineMappingResult whose entries have empty fits so the PIP # vector is empty. - emptyEntry <- fineMappingRow( + emptyEntry <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(), # no pip -> .enrBuildGwasPipVector returns numeric(0) topLoci = data.frame( @@ -440,8 +440,10 @@ test_that("qtlEnrichmentPipeline: empty input collections yield the empty schema "gwasStudy", "gwasContext", "gwasTrait", + "gwasMethod", "qtlStudy", "qtlContext", + "qtlMethod", names(pecotmr:::.enrNaEnrichment()) ) ) @@ -544,9 +546,7 @@ test_that(".enrBuildQtlRegionsList: returns empty list when the (study, context) # qtlEnrichment() — kernel wrapper + real C++ integration # These tests deliberately do NOT mock qtlEnrichmentCpp so the C++ # kernel in src/qtl_enrichment.cpp gets coverage. The wrapper itself -# (R/qtlEnrichmentPipeline.R::qtlEnrichment) is exercised here directly -# rather than via the deprecated `computeQtlEnrichment` shim (which has -# skip_on_covr()). +# (R/qtlEnrichmentPipeline.R::qtlEnrichment) is exercised here directly. # =========================================================================== # Build a small (gwasPip, susieQtlRegions) fixture with a sparse causal @@ -595,7 +595,7 @@ test_that("qtlEnrichment: real C++ kernel returns the expected keys (numGwas + p piQtl = 0.5, lambda = 1, impN = 5, - numThreads = 1, + BPPARAM = BiocParallel::SerialParam(), verbose = FALSE ) expect_type(res, "list") @@ -627,7 +627,7 @@ test_that("qtlEnrichment: a single MI round is estimable, not NaN", { numGwas = 5000, piQtl = 0.5, impN = 1, - numThreads = 1, + BPPARAM = BiocParallel::SerialParam(), verbose = FALSE, seed = 1L ) @@ -648,7 +648,7 @@ test_that("qtlEnrichment: numGwas omitted -> estimates piGwas from data + warns" susieQtlRegions = fx$susieQtlRegions, piQtl = 0.5, impN = 5, - numThreads = 1, + BPPARAM = BiocParallel::SerialParam(), verbose = FALSE ), "numGwas is not provided" @@ -664,7 +664,7 @@ test_that("qtlEnrichment: piQtl omitted -> estimates from susieQtlRegions + warn susieQtlRegions = fx$susieQtlRegions, numGwas = 3000, impN = 5, - numThreads = 1, + BPPARAM = BiocParallel::SerialParam(), verbose = FALSE ), "piQtl is not provided" @@ -681,7 +681,7 @@ test_that("qtlEnrichment: errors when piGwas resolves to zero", { gwasPip = zeroGwas, susieQtlRegions = fx$susieQtlRegions, piQtl = 0.5, - numThreads = 1, + BPPARAM = BiocParallel::SerialParam(), verbose = FALSE ), "No association signal found" @@ -696,7 +696,7 @@ test_that("qtlEnrichment: errors when piQtl resolves to zero", { susieQtlRegions = fx$susieQtlRegions, numGwas = 5000, piQtl = 0, - numThreads = 1, + BPPARAM = BiocParallel::SerialParam(), verbose = FALSE ), "No QTL associated" @@ -712,7 +712,7 @@ test_that("qtlEnrichment: errors when gwasPip has no names", { susieQtlRegions = fx$susieQtlRegions, numGwas = 5000, piQtl = 0.5, - numThreads = 1, + BPPARAM = BiocParallel::SerialParam(), verbose = FALSE ), "Variant names are missing in gwasPip" @@ -728,14 +728,14 @@ test_that("qtlEnrichment: errors when susieQtlRegions$pip lacks names", { susieQtlRegions = fx$susieQtlRegions, numGwas = 5000, piQtl = 0.5, - numThreads = 1, + BPPARAM = BiocParallel::SerialParam(), verbose = FALSE ), "Variant names are missing in susieQtlRegions" ) }) -test_that("qtlEnrichment: tracks unmatched QTL variants in the output", { +test_that("qtlEnrichment: tracks unmatched QTL variants, either alignNames", { fx <- .qep_makeRealKernelInputs(nSnps = 30, causalIdx = c(5, 15)) # Inject a couple of variant IDs into the QTL fit that don't exist # in the GWAS PIP vector. @@ -743,33 +743,45 @@ test_that("qtlEnrichment: tracks unmatched QTL variants in the output", { newNames[1:2] <- c("1:9999:A:G", "1:9998:A:G") names(fx$susieQtlRegions$fit1$pip) <- newNames colnames(fx$susieQtlRegions$fit1$alpha) <- newNames - res <- qtlEnrichment( - gwasPip = fx$gwasPip, - susieQtlRegions = fx$susieQtlRegions, - numGwas = 3000, - piQtl = 0.5, - impN = 5, - numThreads = 1, - verbose = FALSE - ) - expect_true("unused_xqtl_variants" %in% names(res)) + # alignNames = FALSE is the cheap set-membership branch + # qtlEnrichmentPipeline uses once it has aligned the QTL names against + # the union GWAS panel; both branches report the two injected ids. + for (alignNames in c(TRUE, FALSE)) { + res <- qtlEnrichment( + gwasPip = fx$gwasPip, + susieQtlRegions = fx$susieQtlRegions, + numGwas = 3000, + piQtl = 0.5, + impN = 5, + BPPARAM = BiocParallel::SerialParam(), + verbose = FALSE, + alignNames = alignNames + ) + expect_true( + all( + c("1:9999:A:G", "1:9998:A:G") %in% + unlist(res$unused_xqtl_variants) + ), + info = str_c("alignNames = ", alignNames) + ) + } }) # =========================================================================== -# qtlEnrichment(): verbose messages + alignNames = FALSE branch +# qtlEnrichment(): verbose messages # =========================================================================== test_that("qtlEnrichment: verbose=TRUE emits 'Estimated piGwas'/'Estimated piQtl' messages", { # numGwas = NULL and piQtl = NULL both trigger data-estimation paths; - # with verbose = TRUE each emits a message (lines 391 and 407). + # with verbose = TRUE each emits a message. fx <- .qep_makeRealKernelInputs(nSnps = 30, causalIdx = c(5, 15)) msgs <- testthat::capture_messages( suppressWarnings(qtlEnrichment( gwasPip = fx$gwasPip, susieQtlRegions = fx$susieQtlRegions, impN = 5, - numThreads = 1, + BPPARAM = BiocParallel::SerialParam(), verbose = TRUE )) ) @@ -778,34 +790,6 @@ test_that("qtlEnrichment: verbose=TRUE emits 'Estimated piGwas'/'Estimated piQtl expect_match(allMsgs, "Estimated piQtl") }) -test_that("qtlEnrichment: alignNames=FALSE recomputes only the unmatched set", { - # Exercises the cheap set-membership branch (lines 438-444) used by - # qtlEnrichmentPipeline after it has already aligned QTL names against - # the union GWAS panel. Two injected names are absent from gwasPip, so - # the unmatched-variant accumulation (lines 441-442) runs. - fx <- .qep_makeRealKernelInputs(nSnps = 30, causalIdx = c(5, 15)) - newNames <- names(fx$susieQtlRegions$fit1$pip) - newNames[1:2] <- c("1:9999:A:G", "1:9998:A:G") - names(fx$susieQtlRegions$fit1$pip) <- newNames - colnames(fx$susieQtlRegions$fit1$alpha) <- newNames - res <- qtlEnrichment( - gwasPip = fx$gwasPip, - susieQtlRegions = fx$susieQtlRegions, - numGwas = 3000, - piQtl = 0.5, - impN = 5, - numThreads = 1, - verbose = FALSE, - alignNames = FALSE - ) - expect_true("unused_xqtl_variants" %in% names(res)) - expect_true(any( - c("1:9999:A:G", "1:9998:A:G") %in% - unlist(res$unused_xqtl_variants) - )) -}) - - # =========================================================================== # .enrFlattenEnrichment(): shape coercion + NA fallbacks # =========================================================================== @@ -861,7 +845,7 @@ test_that(".enrBuildGwasPipVector: skips a block whose pip length disagrees with # Unnamed pip of length 2 against 3 variant ids -> ids come from # variantIds and length(ids) != length(pip) -> the block is skipped, # leaving no pieces -> numeric(0). - badEntry <- fineMappingRow( + badEntry <- FineMappingRow( variantIds = c("chr1:100:A:G", "chr1:200:A:G", "chr1:300:A:G"), susieFit = list(pip = c(0.1, 0.2)), topLoci = data.frame( @@ -888,7 +872,7 @@ test_that(".enrBuildGwasPipVector: skips a block whose pip length disagrees with # =========================================================================== test_that(".enrBuildQtlRegionsList: skips an entry whose fit lacks alpha/pip", { - badEntry <- fineMappingRow( + badEntry <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(), topLoci = data.frame( @@ -914,44 +898,13 @@ test_that(".enrBuildQtlRegionsList: skips an entry whose fit lacks alpha/pip", { ) }) -test_that(".enrBuildQtlRegionsList: skips a fit with no V and no prior_variance", { - noVfit <- list( - alpha = matrix(c(0.6, 0.4), nrow = 1), - pip = setNames(c(0.6, 0.4), c("chr1:100:A:G", "chr1:200:A:G")) - ) - entry <- fineMappingRow( - variantIds = c("chr1:100:A:G", "chr1:200:A:G"), - susieFit = noVfit, - topLoci = data.frame( - variant_id = c("chr1:100:A:G", "chr1:200:A:G"), - pip = c(0.6, 0.4), - stringsAsFactors = FALSE - ) - ) - qfmr <- QtlFineMappingResult( - studyName = "Q1", - context = "c1", - trait = "t1", - method = "susie", - entry = list(entry), - ldReference = NULL - ) - expect_equal( - length(pecotmr:::.enrBuildQtlRegionsList( - qfmr, - .qep_qtlIdent("Q1", "c1") - )), - 0L - ) -}) - test_that(".enrBuildQtlRegionsList: names an unnamed pip from the entry's variant ids", { unnamedPipFit <- list( alpha = matrix(c(0.6, 0.4), nrow = 1), pip = c(0.6, 0.4), # unnamed -> names assigned from variantIds V = 0.1 ) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = c("chr1:100:A:G", "chr1:200:A:G"), susieFit = unnamedPipFit, topLoci = data.frame( @@ -1002,7 +955,7 @@ test_that("qtlEnrichmentPipeline: empty QTL collection errors with the no-triple test_that("qtlEnrichmentPipeline: alignTuple cache is reused across GWAS studies", { # Two GWAS studies -> each QTL tuple's alignment is computed for the # first study (cache miss) and served from cache for the second - # (alignTuple early-return branch, line 119). + # (alignTuple early-return branch). e1 <- .qep_makeFmEntry( variant_ids = sprintf("chr1:%d:A:G", 100L * (1:3)), pip = c(0.5, 0.2, 0.1) @@ -1032,7 +985,7 @@ test_that("qtlEnrichmentPipeline: alignTuple cache is reused across GWAS studies test_that("qtlEnrichmentPipeline: a tuple with no usable QTL regions warns and is skipped", { gfmr <- .qep_makeGwasFmr() - emptyQtlEntry <- fineMappingRow( + emptyQtlEntry <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(), topLoci = data.frame( @@ -1072,7 +1025,7 @@ test_that(".enrRunEnrichment turns a stored alignment failure into a warning", { k = 1L, alignedByTuple = list(cnd), qtlEnrichmentParam = QtlEnrichmentParam(), - numThreads = 1L, + BPPARAM = BiocParallel::SerialParam(), seed = NULL, verbose = FALSE, gwasFineMappingResult = NULL, @@ -1172,3 +1125,98 @@ test_that("qtlEnrichmentPipeline refuses overlapping rows on two references", { "disagree on the LD" ) }) + +test_that("qtlEnrichmentPipeline keeps each fine-mapping method's fits apart", { + # The same GWAS blocks fine-mapped by two methods are two outcome PIP + # vectors, and the same QTL regions by two methods two annotations. + gwas <- .qep_makeGwasFmr(n_blocks = 2L) + gwas2 <- gwas + S4Vectors::mcols(gwas2)$method <- "ser" + gfmr <- combineFineMappingResults(gwas, gwas2) + qtl <- .qep_makeQtlFmr() + qtl2 <- qtl + S4Vectors::mcols(qtl2)$method <- "ser" + qfmr <- combineFineMappingResults(qtl, qtl2) + seen <- new.env() + seen$regions <- integer(0) + local_mocked_bindings( + qtlEnrichment = function(gwasPip, susieQtlRegions, ...) { + seen$regions <- c(seen$regions, length(susieQtlRegions)) + .qep_mockEnrichment(2.0)(gwasPip, susieQtlRegions, ...) + }, + .package = "pecotmr" + ) + out <- qtlEnrichmentPipeline( + gwasFineMappingResult = gfmr, + qtlFineMappingResult = qfmr, + verbose = FALSE + ) + expect_equal(nrow(out), 4L) + expect_setequal( + str_c(out$gwasMethod, out$qtlMethod, sep = "/"), + c("susie/susie", "susie/ser", "ser/susie", "ser/ser") + ) + # Each annotation is one method's one region, counted once. + expect_true(all(seen$regions == 1L)) + # The GWAS outcome is both blocks of its fit. + ident <- list( + study = "G1", + context = NA_character_, + trait = NA_character_, + method = "ser" + ) + expect_length(pecotmr:::.enrBuildGwasPipVector(gfmr, ident), 6L) +}) + +# =========================================================================== +# A narrowed row's PIPs are named by the variants of its fit +# =========================================================================== + +test_that("enrichment names a narrowed row's PIPs by its fit's variants", { + vids <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A") + pip <- c(0.5, 0.3, 0.2) + fit <- list(pip = pip, alpha = matrix(pip, 1L), V = 1) + tl <- data.frame(variant_id = vids, pip = pip) + row <- FineMappingRow(vids, fit, tl) + gwas <- GwasFineMappingResult( + studyName = "g1", + method = "susie", + entry = list(row) + ) + expect_equal( + pecotmr:::.enrRowPipVector(1L, endoapply(gwas, utils::head, 2L)), + set_names(pip, vids) + ) + qtl <- QtlFineMappingResult( + studyName = "q1", + context = "c1", + trait = "g1", + method = "susie", + entry = list(row) + ) + region <- pecotmr:::.enrRowRegion(1L, endoapply(qtl, utils::head, 2L)) + expect_equal(region$pip, set_names(pip, vids)) + expect_equal(region$prior_variance, 1) +}) + +test_that("qtlEnrichmentPipeline warns about narrowed fits on both sides", { + data(gwasFineMappingExample, qtlFineMappingExample) + cnd <- .fitCoverageCondition(qtlEnrichmentPipeline( + gwasFineMappingResult = endoapply( + gwasFineMappingExample, + utils::head, + 2000L + ), + qtlFineMappingResult = endoapply( + qtlFineMappingExample, + utils::head, + 2000L + ), + verbose = FALSE + )) + expect_s3_class(cnd, "pecotmrFitCoverage") + expect_match( + conditionMessage(cnd), + "qtlEnrichmentPipeline\\(\\): 2 row\\(s\\)" + ) +}) diff --git a/tests/testthat/test_qtlSumStats.R b/tests/testthat/test_qtlSumStats.R index e1e99396..9a000b82 100644 --- a/tests/testthat/test_qtlSumStats.R +++ b/tests/testthat/test_qtlSumStats.R @@ -1,71 +1,5 @@ context("qtlSumStats") -# =========================================================================== -# Test helpers -# =========================================================================== - -.qtlMakeGenotypeHandle <- function() { - new( - "GenotypeHandle", - path = "/tmp/test", - format = "plink2", - snpInfo = data.frame(), - nSamples = 0L, - sampleIds = character(), - pgenPtr = NULL - ) -} - -.qtlMakeEntryGr <- function( - n = 5, - chr = "chr1", - start_at = 100L, - step = 100L, - with_maf = FALSE -) { - gr <- GenomicRanges::GRanges( - seqnames = rep(chr, n), - ranges = IRanges::IRanges( - start = seq(start_at, by = step, length.out = n), - width = 1L - ) - ) - mcols_list <- list( - SNP = paste0("rs", seq_len(n)), - A1 = rep("A", n), - A2 = rep("G", n), - Z = seq(1.0, by = 0.5, length.out = n), - N = rep(1000L, n) - ) - if (with_maf) { - mcols_list$MAF <- seq(0.05, by = 0.01, length.out = n) - } - S4Vectors::mcols(gr) <- S4Vectors::DataFrame(mcols_list) - gr -} - -.qtlMakeOne <- function( - studyName = "study1", - context = "Cortex", - trait = "ENSG001", - n = 5, - varY = NA_real_, - with_maf = FALSE, - qcInfo = list(), - genome = "hg19" -) { - QtlSumStats( - studyName = studyName, - context = context, - trait = trait, - entry = list(.qtlMakeEntryGr(n, with_maf = with_maf)), - genome = genome, - ldReference = .qtlMakeGenotypeHandle(), - varY = varY, - qcInfo = qcInfo - ) -} - # =========================================================================== # Constructor / validity # =========================================================================== @@ -95,12 +29,13 @@ test_that("QtlSumStats: multi-tuple object is keyed by (study, context, trait)", expect_equal(traitNames(obj), "t1") }) -test_that("QtlSumStats: traitPosition returns NA when no trait position supplied", { +test_that("QtlSumStats: traitPosition is empty when no position was supplied", { obj <- .qtlMakeOne(trait = "ENSG001") # traitPos cannot be inferred from summary statistics, so an unsupplied - # position reports NA rather than a fabricated range. - expect_identical(traitPosition(obj), NA) - expect_identical(traitPosition(obj, "ENSG001"), NA) + # position is an empty GRanges rather than a fabricated range. + expect_s4_class(traitPosition(obj), "GRanges") + expect_length(traitPosition(obj), 0L) + expect_length(traitPosition(obj, "ENSG001"), 0L) }) test_that("QtlSumStats: traitPosition returns the supplied trait position", { @@ -119,8 +54,9 @@ test_that("QtlSumStats: traitPosition returns the supplied trait position", { expect_equal(GenomicRanges::start(tp), 1000L) expect_equal(GenomicRanges::end(tp), 1500L) expect_equal(GenomicRanges::start(traitPosition(obj, "ENSGX")), 1000L) - # a trait not in the collection -> NA - expect_identical(traitPosition(obj, "nope"), NA) + # a trait not in the collection -> an empty GRanges + expect_s4_class(traitPosition(obj, "nope"), "GRanges") + expect_length(traitPosition(obj, "nope"), 0L) }) test_that("QtlSumStats: errors when required args are missing", { @@ -210,19 +146,23 @@ test_that("QtlSumStats: scalar varY is recycled across tuples", { expect_equal(obj$varY, c(1.5, 1.5)) }) -test_that("QtlSumStats: errors when varY length is neither 1 nor n", { - expect_error( - QtlSumStats( - studyName = c("s1", "s2"), - context = c("c1", "c1"), - trait = c("t1", "t1"), - entry = list(.qtlMakeEntryGr(2), .qtlMakeEntryGr(2)), - genome = "hg19", - ldReference = .qtlMakeGenotypeHandle(), - varY = c(1, 2, 3) - ), - "length 1 or length\\(study\\)" - ) +test_that("QtlSumStats: errors when varY or nSample length is not 1 or n", { + for (arg in c("varY", "nSample")) { + expect_error( + exec( + QtlSumStats, + studyName = c("s1", "s2"), + context = c("c1", "c1"), + trait = c("t1", "t1"), + entry = list(.qtlMakeEntryGr(2), .qtlMakeEntryGr(2)), + genome = "hg19", + ldReference = .qtlMakeGenotypeHandle(), + !!arg := c(1, 2, 3) + ), + "length 1 or length\\(study\\)", + info = arg + ) + } }) test_that("QtlSumStats: optional nSample column is absent by default, attached and recycled when supplied", { @@ -241,22 +181,7 @@ test_that("QtlSumStats: optional nSample column is absent by default, attached a expect_true(methods::validObject(obj)) }) -test_that("QtlSumStats: errors when nSample length is neither 1 nor n", { - expect_error( - QtlSumStats( - studyName = c("s1", "s2"), - context = c("c1", "c1"), - trait = c("t1", "t1"), - entry = list(.qtlMakeEntryGr(2), .qtlMakeEntryGr(2)), - genome = "hg19", - ldReference = .qtlMakeGenotypeHandle(), - nSample = c(1, 2, 3) - ), - "length 1 or length\\(study\\)" - ) -}) - -test_that("QtlSumStats: subsetChr preserves the nSample column", { +test_that("QtlSumStats: keepSeqlevels preserves the nSample column", { gr <- .qtlMakeEntryGr(4, chr = "chr1") obj <- QtlSumStats( studyName = "s1", @@ -267,7 +192,7 @@ test_that("QtlSumStats: subsetChr preserves the nSample column", { ldReference = .qtlMakeGenotypeHandle(), nSample = 838 ) - sub <- subsetChr(obj, "chr1") + sub <- GenomeInfoDb::keepSeqlevels(obj, "chr1", pruning.mode = "coarse") expect_equal(as.numeric(sub$nSample), 838) }) @@ -301,20 +226,12 @@ test_that("QtlSumStats: accepts and stores extra per-tuple columns via ...", { # Accessors # =========================================================================== -test_that("sumStats / z / nSamples return values from the single-tuple entry", { +test_that("sumStats / z / sampleSize read the single-tuple entry", { obj <- .qtlMakeOne(n = 4) expect_s4_class(sumStats(obj), "GRanges") expect_equal(length(sumStats(obj)), 4L) expect_equal(z(obj), seq(1.0, by = 0.5, length.out = 4)) - expect_equal(nSamples(obj), rep(1000L, 4)) -}) - -test_that("maf returns NULL when MAF column is absent, vector when present", { - obj_no_maf <- .qtlMakeOne(with_maf = FALSE) - expect_null(maf(obj_no_maf)) - - obj_maf <- .qtlMakeOne(n = 4, with_maf = TRUE) - expect_equal(length(maf(obj_maf)), 4L) + expect_equal(sampleSize(obj), rep(1000L, 4)) }) test_that("nSnps reports the number of variants in the selected entry", { @@ -358,7 +275,7 @@ test_that("accessors require (study, context, trait) when collection has >1 entr ) expect_error( sumStats(obj), - "Pass `study`, `context`, and `trait` to select one" + "Pass `studyName`, `context`, and `trait` to select one" ) expect_s4_class( @@ -384,10 +301,10 @@ test_that("accessors require length-1 selection args", { }) # =========================================================================== -# subsetChr +# Narrowing with the standard verbs # =========================================================================== -test_that("subsetChr keeps only variants on the requested chromosome", { +test_that("keepSeqlevels keeps only the requested chromosome's rows", { # Multi-chromosome entry: 3 on chr1, 2 on chr2. Built in one shot so # the resulting GRanges already shares seqlevels across rows. gr <- GenomicRanges::GRanges( @@ -413,21 +330,27 @@ test_that("subsetChr keeps only variants on the requested chromosome", { ldReference = .qtlMakeGenotypeHandle() ) - chr1_only <- subsetChr(obj, "1") - expect_equal(nSnps(chr1_only), 3L) - - # The "chr" prefix is accepted equivalently. - chr2_only <- subsetChr(obj, "chr2") - expect_equal(nSnps(chr2_only), 2L) + chr1Only <- GenomeInfoDb::keepSeqlevels( + obj, + "chr1", + pruning.mode = "coarse" + ) + expect_equal(nSnps(chr1Only), 3L) + chr2Only <- GenomeInfoDb::keepSeqlevels( + obj, + "chr2", + pruning.mode = "coarse" + ) + expect_equal(nSnps(chr2Only), 2L) }) -test_that("subsetChr drops the element when no variants on that chromosome", { - # subsetChr is now the whole-seqname case of subsetRegion, which DROPS - # elements that trim to nothing rather than keeping an empty one. After - # the seqname split an element belongs to exactly one chromosome, so - # "kept but empty" no longer describes anything real. +test_that("a range subset that keeps no row leaves an empty collection", { obj <- .qtlMakeOne(n = 4) - empty <- subsetChr(obj, "22") + # A window on the collection's own chromosome, past its variants. + empty <- IRanges::subsetByOverlaps( + obj, + GenomicRanges::GRanges("chr1:90000000-90000100") + ) expect_equal(nrow(empty), 0L) expect_equal(length(empty), 0L) # The collection-level state survives even when nothing is left; no row @@ -440,14 +363,14 @@ test_that("subsetChr drops the element when no variants on that chromosome", { expect_identical(ldReference(empty), list()) }) -test_that("subsetChr keeps class-level slots (genome, ldReference, qcInfo)", { - obj <- .qtlMakeOne(qcInfo = list(step1 = "ok")) - res <- subsetChr(obj, "1") +test_that("keepSeqlevels keeps the collection-level slots", { + obj <- .qtlMakeOne(qcOptions = list(step1 = "ok")) + res <- GenomeInfoDb::keepSeqlevels(obj, "chr1", pruning.mode = "coarse") expect_equal( unname(GenomeInfoDb::genome(res)), unname(GenomeInfoDb::genome(obj)) ) - expect_equal(qcInfo(res), qcInfo(obj)) + expect_equal(qcOptions(res), qcOptions(obj)) expect_identical(ldReference(res), ldReference(obj)) }) @@ -605,7 +528,13 @@ test_that("combineQtlSumStats() row-binds collections and LD-free rows", { out <- combineQtlSumStats(a, b) expect_s4_class(out, "QtlSumStats") expect_equal(nrow(out), nrow(a) + nrow(b)) - expect_identical(as.list(out), c(as.list(a), as.list(b))) + expect_identical(unname(as.list(out)), unname(c(as.list(a), as.list(b)))) + # The combined rows are named from their own tuples; mcols<- left `b` + # with the names of the study it was copied from. + expect_identical( + names(out), + c("study1|brain|ENSG_example", "study1_b|brain|ENSG_example") + ) expect_equal( unname(GenomeInfoDb::genome(out)), unname(GenomeInfoDb::genome(a)) @@ -677,9 +606,12 @@ test_that("existing mcols survive the trait-distance annotation", { }) test_that("an entry with no variants is returned untouched", { + # A variant set with no ranges has no positions to take a distance from. gr0 <- GenomicRanges::GRanges() tp <- GenomicRanges::GRanges("chr1", IRanges::IRanges(5L, width = 1L)) - expect_equal(length(pecotmr:::.qssAppendTraitDist(1L, list(gr0), tp)), 0L) + out <- pecotmr:::.qssAppendTraitDist(1L, list(gr0), tp) + expect_s4_class(out, "GRanges") + expect_length(out, 0L) }) test_that("validity names the identity columns that are missing", { @@ -701,10 +633,184 @@ test_that(".appendTraitDistances is a no-op without a trait position", { expect_identical(pecotmr:::.appendTraitDistances(entry, NULL), entry) }) -test_that(".qssAppendTraitDist returns an empty entry untouched", { - # A variant set with no ranges has no positions to take a distance from. - empty <- GenomicRanges::GRanges() - out <- pecotmr:::.qssAppendTraitDist(1L, list(empty), NULL) - expect_s4_class(out, "GRanges") - expect_length(out, 0L) +test_that("QtlSumStats records each tuple's window and its origin", { + data(qtlSumStatsExample) + q <- qtlSumStatsExample + g <- q[[1L]] + chrom <- as.character(GenomicRanges::seqnames(g))[[1L]] + lo <- GenomicRanges::start(g)[[10L]] + hi <- GenomicRanges::start(g)[[150L]] + build <- function(...) { + QtlSumStats( + studyName = q$study, + context = q$context, + trait = q$trait, + entry = list(g), + genome = unique(GenomeInfoDb::genome(q)), + ... + ) + } + # Without one, a tuple's window is the span it was built with. + plain <- build() + expect_false(plain$regionGiven) + expect_identical(as.character(plain$region), as.character(range(g))) + # A window drops the variants outside it, with a warning, and is given. + window <- str_c(chrom, ":", lo, "-", hi) + expect_warning( + inside <- build(region = GenomicRanges::GRanges(window)), + "variant(s) lie outside their tuple's `region`", + fixed = TRUE + ) + expect_true(inside$regionGiven) + expect_identical(as.character(inside$region), window) + expect_identical(length(inside[[1L]]), 141L) + # Read from a BED file, its start is 0-based. + bedPath <- withr::local_tempfile(fileext = ".bed") + writeLines(str_c(chrom, "\t", lo - 1L, "\t", hi), bedPath) + bed <- suppressWarnings(build(region = bedPath)) + expect_identical(as.character(bed$region), window) + # One window for every tuple, or one per tuple. + expect_error( + build(region = GenomicRanges::GRanges(c(window, window))), + "one window, or one per tuple" + ) +}) + +test_that("a cisWindow narrows each selected tuple to its trait's window", { + data(qtlSumStatsExample) + q <- qtlSumStatsExample + g <- q[[1L]] + chrom <- as.character(GenomicRanges::seqnames(g))[[1L]] + tp <- GenomicRanges::GRanges( + chrom, + IRanges::IRanges(GenomicRanges::start(g)[[80L]], width = 1L) + ) + build <- function(...) { + QtlSumStats( + studyName = q$study, + context = q$context, + trait = q$trait, + entry = list(g), + genome = unique(GenomeInfoDb::genome(q)), + ... + ) + } + x <- build(traitPos = tp) + expect_identical(pecotmr:::.qssApplyCisWindow(x, NULL, "f", 1L), x) + cis <- pecotmr:::.qssApplyCisWindow(x, 5000, "f", 1L) + expect_true(cis$regionGiven) + expect_identical( + GenomicRanges::start(cis$region), + GenomicRanges::start(tp) - 5000L + ) + expect_true(all( + abs(GenomicRanges::start(cis[[1L]]) - GenomicRanges::start(tp)) <= 5000L + )) + # The cis window keeps inside the window the tuple already had. + edge <- GenomicRanges::GRanges( + chrom, + IRanges::IRanges( + GenomicRanges::start(tp), + GenomicRanges::end(g)[[200L]] + ) + ) + clipped <- pecotmr:::.qssApplyCisWindow( + suppressWarnings(build(traitPos = tp, region = edge)), + 5000, + "f", + 1L + ) + expect_identical( + GenomicRanges::start(clipped$region), + GenomicRanges::start(tp) + ) + # A selected tuple with no trait position has no cis window; one the + # selection leaves out is left alone. + bare <- build() + expect_error( + pecotmr:::.qssApplyCisWindow( + bare, + 5000, + "fineMappingPipeline", + 1L + ), + "fineMappingPipeline: `cisWindow` is laid around each tuple's trait", + fixed = TRUE + ) + expect_identical( + pecotmr:::.qssApplyCisWindow(bare, 5000, "f", integer(0)), + bare + ) +}) + +test_that(".clipWindows keeps nothing of a window that misses its row's", { + windows <- GenomicRanges::GRanges( + c("chr1", "chr1", "chr2"), + IRanges::IRanges(c(100L, 100L, 100L), c(200L, 200L, 200L)) + ) + regions <- GenomicRanges::GRanges( + c("chr1", "chr1", "chr1"), + IRanges::IRanges(c(150L, 300L, 100L), c(400L, 400L, 200L)) + ) + clipped <- pecotmr:::.clipWindows(windows, regions) + expect_identical(as.character(clipped)[[1L]], "chr1:150-200") + expect_identical(GenomicRanges::width(clipped)[2:3], c(0L, 0L)) +}) + +# =========================================================================== +# metadata, qcOptions and a tabular extraCols +# =========================================================================== + +test_that("QtlSumStats() takes extra columns as a DataFrame", { + obj <- QtlSumStats( + studyName = c("s1", "s2"), + context = c("c1", "c1"), + trait = c("t1", "t1"), + entry = list(.qtlMakeEntryGr(2), .qtlMakeEntryGr(2)), + genome = "hg19", + ldReference = .qtlMakeGenotypeHandle(), + extraCols = S4Vectors::DataFrame(cohort = c("UKB", "FinnGen")) + ) + expect_equal(obj$cohort, c("UKB", "FinnGen")) +}) + +test_that("QtlSumStats() keeps the caller's metadata and QC options", { + obj <- .qtlMakeOne(qcOptions = list(step1 = "ok")) + expect_equal(qcOptions(obj), list(step1 = "ok")) + withMeta <- QtlSumStats( + studyName = "s1", + context = "c1", + trait = "t1", + entry = list(.qtlMakeEntryGr(2)), + genome = "hg19", + ldReference = .qtlMakeGenotypeHandle(), + metadata = list(source = "unit test") + ) + expect_equal(S4Vectors::metadata(withMeta), list(source = "unit test")) +}) + +# =========================================================================== +# sumStats(annotateSignificance =) +# =========================================================================== + +test_that("sumStats(annotateSignificance=) adds a derived logical mcol", { + x <- .qapDefaultFixture + r <- qtlAssociationPostprocess(x, methods = "permutation") + gr <- sumStats( + r, + studyName = "s", + context = "brain", + trait = "g1", + annotateSignificance = "permutation" + ) + expect_true("significant" %in% names(S4Vectors::mcols(gr))) + expect_type(S4Vectors::mcols(gr)$significant, "logical") + # matches the permutation rule P < p_nominal_threshold[gene 1] + thr1 <- as.numeric(r$p_nominal_threshold)[1] + exp1 <- if (is.na(thr1)) { + rep(FALSE, length(gr)) + } else { + S4Vectors::mcols(gr)$P < thr1 + } + expect_equal(S4Vectors::mcols(gr)$significant, exp1) }) diff --git a/tests/testthat/test_regularizedRegressionWrappers.R b/tests/testthat/test_regularizedRegressionWrappers.R index 2c48d991..9b4fe7b7 100644 --- a/tests/testthat/test_regularizedRegressionWrappers.R +++ b/tests/testthat/test_regularizedRegressionWrappers.R @@ -1,30 +1,19 @@ -context("SS-TWAS: weights, pipeline, and omnibus combination") - -# Previous TwasWeights-class tests used the legacy constructor -# `TwasWeights(weights = list(...), variantIds = ..., standardized = ...)`. -# The new `TwasWeights` is a DFrame collection class with (study, -# context, trait, method, entry) columns where each entry is a -# `TwasWeightsRow` S4 object carrying weights / fits / cvResult. -# Class-shape tests for the new collection should live alongside the -# pipeline tests and assert via accessors (`weights`, `studyName`, -# `cvResult`, etc.) — not against legacy slot shapes. -# -# `twasAnalysis()` was collapsed into the unified `twasZ()` dispatcher -# (task #37); its tests are removed here. -# `twasWeightsSumstatPipeline()` was removed without replacement in the -# S4 refactor (twasWeightsPipeline now dispatches directly on -# `QtlSumStats` / `QtlDataset` / `MultiStudyQtlDataset`). -# -# What remains: tests of the internal SuSiE-RSS weight extractors that -# are still present in `R/twasWeights.R` (`.susieRssExtractWeights`, -# `susieRssWeights`, `susieInfRssWeights`). +context("regularized_regression - wrappers") + +# Tests of R/regularizedRegressionWrappers.R: the mr.mash helpers, the weight +# wrappers' engine arguments and fit retention, and their real-fit coverage. +# Each method's own tests live in the matching test_rr*.R topic file. # ============================================================================= -# SuSiE-RSS weight extraction +# mrmashWeights fit retention # ============================================================================= -test_that("mrmashWeights fitRetention: slim omits the full fit, full keeps it", { +test_that("mrmashWeights retains nothing, the prior parts, or the full fit", { skip_if_not_installed("mr.mashr") + # The slim payload is exactly what fineMappingPipeline needs to rebuild the + # mvSuSiE reweighted mixture prior (w0 -> rescaleCovW0, original $U) and + # the residual variance (V); the heavy mu1 coefficient matrix is not + # retained. fakeFit <- list(w0 = c(a_1 = 0.5, a_2 = 0.5), V = diag(2)) ddpm <- list(U = list(a = diag(2))) # Mock coef extraction so we exercise only the retain payload logic, not a @@ -41,10 +30,17 @@ test_that("mrmashWeights fitRetention: slim omits the full fit, full keeps it", ), "fit" ) + expect_true(is.list(fitSlim)) expect_setequal(names(fitSlim), c("dataDrivenPriorMatrices", "w0", "V")) expect_null(fitSlim$fit) # slim: no full fit expect_identical(fitSlim$dataDrivenPriorMatrices, ddpm) expect_identical(fitSlim$w0, fakeFit$w0) + expect_identical(fitSlim$V, fakeFit$V) + # The default ("none") leaves the weights free of the fit attribute. + expect_null(attr( + mrmashWeights(mrmashFit = fakeFit, dataDrivenPriorMatrices = ddpm), + "fit" + )) fitFull <- attr( mrmashWeights( @@ -59,13 +55,10 @@ test_that("mrmashWeights fitRetention: slim omits the full fit, full keeps it", expect_identical(fitFull$w0, fakeFit$w0) # slim fields still present }) - # ============================================================================= -# Two-stage SuSiE-RSS fitting +# mr.mash helpers: computeW0 # ============================================================================= -# === Tests migrated from test_mrmashWrapper.R (mr.mash + glasso/glmnet coef helpers) === - test_that("computeW0 returns uniform weights when ncomps == 1", { Bhat <- matrix(c(1, 0, 0, 2, 0, 0), nrow = 3, ncol = 2) result <- pecotmr:::computeW0(Bhat, ncomps = 1) @@ -96,7 +89,7 @@ test_that("computeW0 distributes weight based on nonzero rows when ncomps > 1", }) # ========================================================================= -# mrmashWrapper.R: rescaleCovW0 (lines 300-329) +# rescaleCovW0 # ========================================================================= test_that("rescaleCovW0 removes null component and renormalizes", { @@ -137,7 +130,7 @@ test_that("rescaleCovW0 groups correctly by prior group prefix", { }) # ========================================================================= -# mrmashWrapper.R: computeGrid (mr.mash's own exported grid builder) +# computeGrid (mr.mash's own exported grid builder) # ========================================================================= test_that("computeGrid is mr.mash's grid, not a reimplementation of it", { @@ -148,28 +141,19 @@ test_that("computeGrid is mr.mash's grid, not a reimplementation of it", { set.seed(3) bhat <- matrix(rnorm(20, sd = 2), nrow = 10, ncol = 2) sbhat <- matrix(abs(rnorm(20, mean = 0.5, sd = 0.1)), nrow = 10, ncol = 2) + grid <- pecotmr:::computeGrid(bhat, sbhat) expect_equal( - pecotmr:::computeGrid(bhat, sbhat), + grid, mr.mashr::autoselect.mixsd( list(Bhat = bhat, Shat = sbhat), mult = sqrt(2) )^2 ) + expect_true(all(grid > 0)) # The ported floor would have been 10^2 times this one, since the grid # scales variances. ported <- min(sbhat) - expect_lt(min(pecotmr:::computeGrid(bhat, sbhat)), ported^2) -}) - - -test_that("compute_grid produces a valid grid from summary statistics", { - set.seed(42) - bhat <- matrix(rnorm(20, sd = 2), nrow = 10, ncol = 2) - sbhat <- matrix(abs(rnorm(20, mean = 0.5, sd = 0.1)), nrow = 10, ncol = 2) - result <- pecotmr:::computeGrid(bhat, sbhat) - expect_true(is.numeric(result)) - expect_true(length(result) > 0) - expect_true(all(result > 0)) + expect_lt(min(grid), ported^2) }) @@ -182,7 +166,7 @@ test_that("compute_grid handles NA and zero sbhat values", { }) # ========================================================================= -# mrmashWrapper.R: mrmashWrapper input validation (lines 99-130) +# mrmashWrapper input validation # ========================================================================= # Note: Cannot mock requireNamespace via local_mocked_bindings because it is a @@ -273,7 +257,7 @@ test_that("mrmashWrapper warns when Y has missing and B_init_method is glasso", }) # ========================================================================= -# mrmashWrapper.R: computeCoefficientsGlasso (lines 211-240) +# computeCoefficientsGlasso # ========================================================================= test_that("computeCoefficientsGlasso runs without Xnew", { @@ -289,7 +273,6 @@ test_that("computeCoefficientsGlasso runs without Xnew", { X, Y, standardize = FALSE, - numThreads = 1, Xnew = NULL ) expect_true("Bhat" %in% names(result)) @@ -314,7 +297,6 @@ test_that("computeCoefficientsGlasso runs with Xnew", { X, Y, standardize = FALSE, - numThreads = 1, Xnew = Xnew ) expect_true("Yhat_new" %in% names(result)) @@ -324,9 +306,30 @@ test_that("computeCoefficientsGlasso runs with Xnew", { }) # ========================================================================= -# mrmashWrapper.R: computeCoefficientsUnivGlmnet (lines 243-281) +# computeCoefficientsUnivGlmnet # ========================================================================= +test_that("computeCoefficientsUnivGlmnet gives the same fits on two workers", { + skip_if_not_installed("glmnet") + skip_on_os("windows") + set.seed(5) + X <- matrix(rnorm(60 * 5), 60, 5) + Y <- matrix(rnorm(60 * 2), 60, 2, dimnames = list(NULL, c("a", "b"))) + fit <- function(bp) { + pecotmr:::computeCoefficientsUnivGlmnet( + X, + Y, + alpha = 0.5, + standardize = FALSE, + BPPARAM = bp + ) + } + expect_equal( + fit(BiocParallel::SerialParam(RNGseed = 9L)), + fit(BiocParallel::MulticoreParam(2, RNGseed = 9L)) + ) +}) + test_that("computeCoefficientsUnivGlmnet runs without Xnew", { skip_if_not_installed("glmnet") set.seed(42) @@ -397,22 +400,22 @@ test_that("computeCoefficientsUnivGlmnet handles NA in Y", { }) # ========================================================================= -# mrmashWrapper.R: mrmashWrapper seed warning (line 107-108) +# mrmashWrapper seed message # ========================================================================= # Note: Cannot mock base::exists() via local_mocked_bindings. -# The seed-check message on line 107-108 would require removing .Random.seed -# from the global environment, which is not safe to do in tests. +# The seed-check message would require removing .Random.seed from the global +# environment, which is not safe to do in tests. # ============================================================================= # Real-fit coverage for the solver wrappers in R/regularizedRegressionWrappers.R # ----------------------------------------------------------------------------- -# The fine-mapping / TWAS pipelines MOCK these wrappers, so their bodies are -# otherwise untested. Here we drive each wrapper on a SMALL real fixture and -# assert the return shape (weight length == #variants; matrix for multivariate; -# attr(.,"fit") unless fitRetention is "none"). MCMC iterations kept tiny. -# fsusieWeights and the mock-based mrmash/mvsusie payload tests live in -# test_rrMrmashMvsusie.R and are not duplicated here. +# The fine-mapping / TWAS pipelines MOCK these wrappers. Here we drive the +# wrappers on a SMALL real fixture and assert the return shape (weight length +# == #variants; matrix for multivariate; attr(.,"fit") unless fitRetention is +# "none"). MCMC iterations kept tiny. Each method's shape and signal-recovery +# tests live in its test_rr*.R topic file; fsusieWeights is tested in +# test_fineMappingWrappers.R. # ============================================================================= # (Shared .rrwXy / .rrwStatLd / .rrwMulti fixtures live in helper-rrwFixtures.R @@ -528,8 +531,7 @@ test_that("mr.mash glmnet initialisation routes through fitGlmnetCv", { gl <- .rrw_captureGlmnet(computeCoefficientsGlasso( f$X, Y, - standardize = TRUE, - numThreads = 1L + standardize = TRUE )) expect_equal(gl$family, "mgaussian") expect_equal(gl$alpha, 1) @@ -550,26 +552,6 @@ test_that("mr.mash glmnet initialisation routes through fitGlmnetCv", { expect_false(is_in("parallel", names(uv))) }) -test_that("lassoWeights / enetWeights (glmnet) return length-p weights", { - skip_if_not_installed("glmnet") - f <- .rrwXy() - expect_length(as.numeric(lassoWeights(f$X, f$y)), f$p) - expect_length(as.numeric(enetWeights(f$X, f$y)), f$p) -}) - -test_that("scadWeights / mcpWeights (ncvreg) return length-p weights", { - skip_if_not_installed("ncvreg") - f <- .rrwXy() - expect_length(as.numeric(scadWeights(f$X, f$y)), f$p) - expect_length(as.numeric(mcpWeights(f$X, f$y)), f$p) -}) - -test_that("l0learnWeights returns length-p weights", { - skip_if_not_installed("L0Learn") - f <- .rrwXy() - expect_length(as.numeric(l0learnWeights(f$X, f$y)), f$p) -}) - test_that("mrashWeights returns length-p weights and can retain the fit", { skip_if_not_installed("susieR") skip_if_not_installed("glmnet") @@ -588,7 +570,10 @@ test_that("qgg Bayes-alphabet weights (N/L/A/C/R) return length-p weights", { skip_if_not_installed("qgg") f <- .rrwXy() mc <- list(nit = 200, nburn = 20, nthin = 1) - expect_length(exec(bayesNWeights, !!!c(list(f$X, f$y), mc)), f$p) + wN <- exec(bayesNWeights, !!!c(list(f$X, f$y), mc)) + expect_length(wN, f$p) + expect_true(is.numeric(wN)) + expect_true(all(is.finite(wN))) expect_length(exec(bayesLWeights, !!!c(list(f$X, f$y), mc)), f$p) expect_length(exec(bayesAWeights, !!!c(list(f$X, f$y), mc)), f$p) expect_length(exec(bayesCWeights, !!!c(list(f$X, f$y), mc)), f$p) @@ -650,37 +635,6 @@ test_that("bayesAlphabetWeights forwards every MCMC control to gbayes", { expect_equal(seen$nthin, 7) }) -test_that("bayesAlphabetWeights validates matching row counts before fitting", { - skip_if_not_installed("qgg") - f <- .rrwXy() - expect_error( - bayesAlphabetWeights(f$X, f$y[-1], method = "bayesN"), - "y.*Must have length 50" - ) - expect_error( - bayesAlphabetWeights( - f$X, - f$y, - method = "bayesN", - Z = matrix(1, f$n - 1, 1) - ), - "Z.*Must have exactly 50 rows" - ) -}) - -test_that("bayesBWeights / bLassoWeights (BGLR) return length-p weights", { - skip_if_not_installed("BGLR") - f <- .rrwXy() - expect_length( - bayesBWeights(f$X, f$y, nIter = 200, burnIn = 20, thin = 1), - f$p - ) - expect_length( - bLassoWeights(f$X, f$y, nIter = 200, burnIn = 20, thin = 1), - f$p - ) -}) - test_that("dprVbWeights returns length-p weights and retains the fit", { skip_if_not_installed("RcppDPR") f <- .rrwXy() @@ -692,7 +646,15 @@ test_that("dprVbWeights returns length-p weights and retains the fit", { test_that("dprGibbsWeights returns length-p weights", { skip_if_not_installed("RcppDPR") f <- .rrwXy() - invisible(capture.output(w <- dprGibbsWeights(f$X, f$y, sStep = 200))) + # Capturing the DPR engine's progress bar is what is slow, not sampling. + invisible(capture.output( + w <- dprGibbsWeights( + f$X, + f$y, + sStep = 200, + methodArgs = DprOptions(show_progress = FALSE) + ) + )) expect_length(w, f$p) }) @@ -703,7 +665,7 @@ test_that("dprAdaptiveGibbsWeights returns length-p weights", { w <- dprAdaptiveGibbsWeights( f$X, f$y, - methodArgs = DprOptions(s_step = 100) + methodArgs = DprOptions(s_step = 100, show_progress = FALSE) ) )) expect_length(w, f$p) @@ -724,66 +686,6 @@ test_that("mrmashWeights fits from (X, Y) and returns p x K weights", { }) -# ----------------------------- RSS solvers (C++) ---------------------------- - -test_that("lassosumRss returns a p x nlambda beta matrix", { - f <- .rrwStatLd() - out <- lassosumRss(f$stat$b, f$LD, f$n) - expect_equal(nrow(out$beta), f$p) - expect_equal(ncol(out$beta), length(out$lambda)) - expect_length(out$conv, length(out$lambda)) -}) - -test_that("penalizedRss traces a solution path for MCP / SCAD / L0", { - f <- .rrwStatLd() - for (pen in c("MCP", "SCAD")) { - out <- penalizedRss(f$stat$b, f$LD, f$n, penalty = pen) - expect_equal(nrow(out$beta), f$p) - } - outL0 <- penalizedRss( - f$stat$b, - f$LD, - f$n, - penalty = "L0", - lambda0 = 0.01, - lambda = c(0) - ) - expect_equal(nrow(outL0$beta), f$p) -}) - -test_that("prsCs returns posterior betaEst of length p", { - f <- .rrwStatLd() - out <- prsCs(f$stat$b, f$LD, f$n, nIter = 100, nBurnin = 20, thin = 1) - expect_length(out$betaEst, f$p) - expect_true(all(is.finite(out$betaEst))) -}) - -test_that("sdpr returns betaEst of length p", { - f <- .rrwStatLd() - out <- sdpr( - f$stat$b, - f$LD, - f$n, - iter = 100, - burn = 20, - thin = 1, - verbose = FALSE - ) - expect_length(out$betaEst, f$p) -}) - -test_that("RSS solvers validate their R-matrix / sample-size / length inputs", { - f <- .rrwStatLd() - # A list (the old block-list contract) is now rejected: R must be a matrix. - expect_error(prsCs(f$stat$b, list(blk1 = f$LD), f$n), "as a matrix") - expect_error(lassosumRss(f$stat$b, list(blk1 = f$LD), f$n), "as a matrix") - expect_error(penalizedRss(f$stat$b, list(blk1 = f$LD), f$n), "as a matrix") - expect_error(prsCs(f$stat$b, f$LD, -1), "sample size") - expect_error(prsCs(f$stat$b[-1], f$LD, f$n), "bhat.*Must have length 6") - expect_error(sdpr(f$stat$b[-1], f$LD, f$n), "bhat.*Must have length 6") - expect_error(sdpr(f$stat$b, f$LD, f$n, M = 2), "at least 4") -}) - # --------------------------- RSS weight wrappers ---------------------------- test_that("lassosumRssWeights returns length-p weights and records the selection", { @@ -797,18 +699,19 @@ test_that("lassosumRssWeights returns length-p weights and records the selection ) }) -test_that("scadRssWeights / mcpRssWeights / l0learnRssWeights return length-p weights", { - f <- .rrwStatLd() - expect_length(scadRssWeights(f$stat, f$ldReference), f$p) - expect_length(mcpRssWeights(f$stat, f$ldReference), f$p) - expect_length(l0learnRssWeights(f$stat, f$ldReference), f$p) -}) - test_that("mrashRssWeights attaches the mr.ash.rss fit on request", { f <- .rrwStatLd() - none <- mrashRssWeights(f$stat, f$ldReference) + # At mr.ash.rss's own tol (1e-8) this fit takes some 10,000 iterations; + # what is retained does not depend on how tightly it converged. + opts <- MrashRssOptions(tol = 1e-4) + none <- mrashRssWeights(f$stat, f$ldReference, methodArgs = opts) expect_null(attr(none, "fit")) - slim <- mrashRssWeights(f$stat, f$ldReference, fitRetention = "slim") + slim <- mrashRssWeights( + f$stat, + f$ldReference, + fitRetention = "slim", + methodArgs = opts + ) expect_equal(as.numeric(slim), as.numeric(none)) expect_equal(as.numeric(attr(slim, "fit")$mu1), as.numeric(none)) }) @@ -822,6 +725,8 @@ test_that("the raw RSS solvers are internal behind their weight adapters", { "prsCsWeights", "sdprWeights", "lassosumRssWeights", + "enetRssWeights", + "ridgeRssWeights", "scadRssWeights", "mcpRssWeights", "l0learnRssWeights" @@ -834,6 +739,35 @@ test_that("the raw RSS solvers are internal behind their weight adapters", { expect_error(PenalizedRssOptions(notAnOption = 1), "unknown argument") }) +test_that("PenalizedRssOptions refuses the settings its wrappers own", { + for (nm in c( + "penalty", + "alpha", + "gamma", + "lambda0", + "lambda2", + "maxSwaps" + )) { + expect_error( + exec(PenalizedRssOptions, !!!set_names(list(1), nm)), + str_c(nm, " is supplied by pecotmr"), + label = nm + ) + } + # The rest stay tunable: `lambda` is the only route to the path for the + # wrappers that take none. + expect_no_error( + PenalizedRssOptions(lambda = c(0.1, 0.01), thr = 1e-6, maxiter = 500) + ) +}) + +test_that("GlmnetOptions points alpha at the wrapper that takes it", { + expect_error( + GlmnetOptions(alpha = 0.3), + "alpha is supplied by pecotmr.*enetWeights' own `alpha`" + ) +}) + test_that("prsCsWeights and sdprWeights attach the sampler's estimates", { # What the samplers estimate besides the weights reaches the caller as # the "fit" attribute; asking for it leaves the weights unchanged. @@ -946,46 +880,79 @@ test_that("the RSS solvers run on a factor of the LD as on the LD itself", { beta <- replace(numeric(120), c(5, 40, 90), c(0.3, -0.2, 0.25)) z <- as.vector(R %*% beta) + rnorm(120, sd = 0.05) lambda <- exp(seq(log(0.1), log(0.001), length.out = 8)) + # lassosum is the lasso at alpha = 1; below it, the elastic net and ridge. + # L0L2 adds its fixed ridge weight lambda2, which both routes apply in + # the shared thresholding, swaps and objective. + cases <- data.frame( + penalty = c( + "lasso", + "lasso", + "lasso", + "MCP", + "MCP", + "SCAD", + "L0", + "L0L2", + "L0L2" + ), + alpha = c(1, 0.5, 0, 1, 0.5, 1, 1, 1, 1), + lambda2 = c(0, 0, 0, 0, 0, 0, 0, 0.05, 0.5) + ) for (s in c(0.2, 0.9)) { Rs <- (1 - s) * R + s * diag(120) - dense <- pecotmr:::lassosumRssCpp(z, list(R), s, lambda, 1e-6, 1000L) - expect_equal( - dense, - pecotmr:::lassosumRssCpp(z, list(Rs), 0, lambda, 1e-6, 1000L), - tolerance = 1e-10 - ) - expect_equal( - pecotmr:::lassosumRssFactorCpp(z, F, s, lambda, 1e-6, 1000L), - dense, - tolerance = 1e-8 - ) - for (pen in c("lasso", "MCP", "SCAD", "L0")) { + for (k in seq_len(nrow(cases))) { args <- list( lambdaR = lambda, - penaltyStr = pen, + penaltyStr = cases$penalty[[k]], gamma = 3.7, - alpha = 1, + alpha = cases$alpha[[k]], lambda0 = 0.001, - lambda2 = 0, + lambda2 = cases$lambda2[[k]], thr = 1e-6, maxiter = 1000L, maxSwaps = 10L ) + label <- str_c( + cases$penalty[[k]], + ", alpha = ", + cases$alpha[[k]], + ", lambda2 = ", + cases$lambda2[[k]] + ) dense <- exec(pecotmr:::penalizedRssCpp, z, list(R), s, !!!args) expect_equal( dense, exec(pecotmr:::penalizedRssCpp, z, list(Rs), 0, !!!args), tolerance = 1e-10, - label = pen + label = label ) expect_equal( exec(pecotmr:::penalizedRssFactorCpp, z, F, s, !!!args), dense, tolerance = 1e-8, - label = pen + label = label ) } } + # The two routes agreeing would not show lambda2 is applied at all; the + # fit with it must differ from the one without. + l0Fit <- function(lambda2) { + pecotmr:::penalizedRssFactorCpp( + z, + F, + 0.2, + lambdaR = lambda, + penaltyStr = "L0L2", + gamma = 3.7, + alpha = 1, + lambda0 = 0.001, + lambda2 = lambda2, + thr = 1e-6, + maxiter = 1000L, + maxSwaps = 10L + )$beta + } + expect_false(isTRUE(all.equal(l0Fit(0.5), l0Fit(0)))) }) test_that("SDPR on a factor of the LD draws as it does on the matrix", { @@ -1014,8 +981,10 @@ test_that("SDPR on a factor of the LD draws as it does on the matrix", { M = 50L, a0k = 0.5, b0k = 0.5, - iter = 200L, - burn = 50L, + # Every sampler step runs on each iteration, so a short chain already + # exercises burn-in, thinning and the draws the routes must share. + iter = 100L, + burn = 25L, thin = 5L, numThreads = 1L, optLlk = 1L, @@ -1048,31 +1017,6 @@ test_that("SDPR on a factor of the LD draws as it does on the matrix", { ) }) -test_that("prsCsWeights and sdprWeights take (stat, ldReference)", { - f <- .rrwStatLd() - expect_length( - prsCsWeights( - f$stat, - f$ldReference, - methodArgs = PrsCsOptions(nIter = 100, nBurnin = 20, thin = 1) - ), - f$p - ) - expect_length( - sdprWeights( - f$stat, - f$ldReference, - methodArgs = SdprOptions( - iter = 100, - burn = 20, - thin = 1, - verbose = FALSE - ) - ), - f$p - ) -}) - test_that("prsCsWeights and sdprWeights hand the engine z / sqrt(n)", { # Both upstream tools fit the standardized marginal effects, so a z-only # stat (the QtlSumStats shape) and b with its standard error both reach @@ -1132,19 +1076,24 @@ test_that("RSS weights read a genotype panel's LD as they read the matrix", { label = nm ) } - # mr.ash.rss takes only a matrix, formed from the panel. + # mr.ash.rss takes only a matrix, formed from the panel. A looser tol + # than its own 1e-8 (some 7,000 iterations here) converges in about 100; + # the two routes fit the same matrix whatever the tolerance. + mrashOpts <- MrashRssOptions(tol = 1e-4) expect_equal( - mrashRssWeights(d$stat, d$panel), - mrashRssWeights(d$stat, d$ldMatrix), + mrashRssWeights(d$stat, d$panel, methodArgs = mrashOpts), + mrashRssWeights(d$stat, d$ldMatrix, methodArgs = mrashOpts), tolerance = 1e-8 ) # SDPR runs its own sampler on the low-rank form of its matrices, so a - # seeded chain lands on the matrix route's. + # seeded chain lands on the matrix route's. A 50-component mixture + # rather than the default 1000 keeps the chains quick. for (optLlk in 1:2) { opts <- SdprOptions( iter = 100, burn = 20, thin = 1, + M = 50, optLlk = optLlk, verbose = FALSE, seed = 1L @@ -1194,7 +1143,15 @@ test_that("mrashRssWeights defaults to mr.ash's own prior grid", { fit$data$sa2 ) f <- .rrwStatLd() - expect_length(mrashRssWeights(f$stat, f$ldReference), f$p) + # A looser tol than mr.ash.rss's 1e-8, which takes some 10,000 iterations. + expect_length( + mrashRssWeights( + f$stat, + f$ldReference, + methodArgs = MrashRssOptions(tol = 1e-4) + ), + f$p + ) # With b, seb and varY the unstandardized statistics set the scale. z <- f$stat$z shat <- f$stat$seb @@ -1205,21 +1162,6 @@ test_that("mrashRssWeights defaults to mr.ash's own prior grid", { ) }) -test_that("mrashRssWeights returns posterior-mean weights of length p", { - skip_if_not_installed("susieR") - f <- .rrwStatLd() - w <- mrashRssWeights( - f$stat, - f$ldReference, - varY = 1, - sigma2E = 1, - s0 = c(0, 0.01, 0.1, 0.5, 1), - w0 = rep(1 / 5, 5) - ) - expect_length(w, f$p) - expect_true(all(is.finite(w))) -}) - test_that("mrmashRssWeights fits mr.mash.rss and returns p x K weights", { skip_if_not_installed("mr.mashr") @@ -1356,7 +1298,7 @@ test_that("buildMrmashPriorMatrices errors without canonical or data-driven prio # =========================================================================== -# mr.mash weight tests (relocated from test_rrMrmashMvsusie.R) +# mrmashWeights and the mr.mash engine arguments # =========================================================================== # ---- mrmashWeights ---- @@ -1387,41 +1329,6 @@ test_that("mrmashWeights errors when X and Y are NULL and fit is NULL", { ) }) -test_that("mrmashWeights retaining attaches {dataDrivenPriorMatrices, w0, V}", { - skip_if_not( - requireNamespace("mr.mashr", quietly = TRUE), - "mr.mashr not installed" - ) - # These are exactly the parts fineMappingPipeline needs to rebuild the - # mvSuSiE reweighted mixture prior (w0 -> rescaleCovW0, original $U) and the - # residual variance (V); the heavy mu1 coefficient matrix is not retained. - ddpm <- list(U = list(comp = diag(2))) - fakeFit <- structure( - list(w0 = c(null = 0.4, comp_grid1 = 0.6), V = diag(2) * 2), - class = "mr.mash" - ) - fakeCoef <- matrix(0.1, nrow = 5, ncol = 2) - local_mocked_bindings( - coef.mr.mash = function(object, ...) fakeCoef, - .package = "mr.mashr" - ) - w <- mrmashWeights( - mrmashFit = fakeFit, - dataDrivenPriorMatrices = ddpm, - fitRetention = "slim" - ) - fit <- attr(w, "fit") - expect_true(is.list(fit)) - expect_identical(fit$dataDrivenPriorMatrices, ddpm) - expect_identical(fit$w0, fakeFit$w0) - expect_identical(fit$V, fakeFit$V) - # The default ("none") leaves the weights free of the fit attribute. - expect_null(attr( - mrmashWeights(mrmashFit = fakeFit, dataDrivenPriorMatrices = ddpm), - "fit" - )) -}) - test_that("MCMC / optimiser control arguments are guarded", { expect_error( bayesBWeights(NULL, NULL, nIter = 0), @@ -1452,18 +1359,9 @@ test_that("MCMC / optimiser control arguments are guarded", { "nfolds.*Must be >= 1" ) expect_error( - computeCoefficientsGlasso(NULL, NULL, standardize = NA, numThreads = 1), + computeCoefficientsGlasso(NULL, NULL, standardize = NA), "standardize.*May not be NA" ) - expect_error( - computeCoefficientsGlasso( - NULL, - NULL, - standardize = TRUE, - numThreads = 1.5 - ), - "numThreads.*integerish" - ) }) test_that("RSS solver control arguments are guarded", { @@ -1539,7 +1437,7 @@ test_that("MrmashPriorParam nests each engine function's own arguments", { expect_length(MrmashExpandCovsOptions(), 0L) }) -test_that("mrmashWrapper forwards methodArgs under mr.mash's own names", { +test_that("MrmashOptions takes mr.mash's own argument names", { skip_if_not_installed("mr.mashr") ma <- MrmashOptions(max_iter = 10, tol = 0.5) expect_equal(ma$max_iter, 10) diff --git a/tests/testthat/test_relatednessQc.R b/tests/testthat/test_relatednessQc.R index f78614d0..2b0e83b4 100644 --- a/tests/testthat/test_relatednessQc.R +++ b/tests/testthat/test_relatednessQc.R @@ -101,6 +101,7 @@ test_that("maximizeCases preferentially retains cases", { # Related pairs above threshold: # C1-X1 (case-control), C2-X2 (case-control), C1-C2 (case-case), # X1-X3 (control-control) + # C3-X3 and X2-X3 sit below it, so they exclude nobody. rel <- data.frame( IID1 = c("C1", "C2", "C1", "X1", "C3", "X2"), IID2 = c("X1", "X2", "C2", "X3", "X3", "X3"), @@ -124,15 +125,49 @@ test_that("maximizeCases preferentially retains cases", { ) expect_type(result, "character") - # Controls related to kept cases should be excluded preferentially retained <- setdiff(pheno$IID, result) retained_cases <- intersect(retained, pheno$IID[pheno$pheno == 1]) retained_controls <- intersect(retained, pheno$IID[pheno$pheno == 0]) - # We expect at least 2 of 3 cases kept, and controls sacrificed - expect_true(length(retained_cases) >= 2) + # A case is lost only to another case: C1-C2 costs one (plinkQC drops + # a lone pair's IID1, C1), and C3 is related to no case. + expect_setequal(retained_cases, c("C2", "C3")) + # The controls are sacrificed instead: X2 for its kinship with the + # retained C2, then X1 of the remaining related pair X1 / X3. + expect_setequal(result, c("C1", "X2", "X1")) + expect_equal(retained_controls, "X3") expect_true(noRelatedPairsRemain(rel, result, threshold)) }) +test_that("maximizeCases ignores a case-control pair below the threshold", { + skip_if_not_installed("igraph") + skip_if_not_installed("plinkQC") + # Kinship 0.05 is not related at 0.125: nobody is excluded, as under + # maximizeUnrelated. + rel <- data.frame( + IID1 = "C1", + IID2 = "X1", + PI_HAT = 0.05, + stringsAsFactors = FALSE + ) + pheno <- data.frame( + IID = c("C1", "X1"), + pheno = c(1, 0), + stringsAsFactors = FALSE + ) + for (type in c("maximizeCases", "maximizeUnrelated")) { + expect_length( + filterRelatedness( + relatedness = rel, + relatednessThreshold = 0.125, + analysisType = type, + phenoData = pheno, + phenoCol = "pheno" + ), + 0L + ) + } +}) + test_that("maximizeCases errors without phenoData", { skip_if_not_installed("igraph") skip_if_not_installed("plinkQC") diff --git a/tests/testthat/test_resultReaders.R b/tests/testthat/test_resultReaders.R index d6dca5a6..1177ca4c 100644 --- a/tests/testthat/test_resultReaders.R +++ b/tests/testthat/test_resultReaders.R @@ -75,12 +75,42 @@ path } +# The bundled fine-mapping example, published once as a VCF and read back +# once. Reading a published VCF is the slow step of a round trip, so the tests +# that need only "the example after a VCF round trip" share this copy instead +# of each writing and reading the same file again. +# @noRd +.rdr_fmVcf <- .rdr_tmp("shared_fm.vcf") +if (requireNamespace("VariantAnnotation", quietly = TRUE)) { + data(qtlFineMappingExample, envir = environment()) + writeGwasVcf(qtlFineMappingExample, .rdr_fmVcf, context = "context_1") + .rdr_fmVcfBack <- readFineMappingResult( + .rdr_fmVcf, + weightStandardized = TRUE + ) +} + +# One three-variant fit per context: small enough to publish and read back in +# a fraction of the example's time, for the tests that edit a published VCF's +# header or need only some VCF to read. +# @noRd +.rdr_smallFmr <- function(contexts = "c1") { + n <- length(contexts) + QtlFineMappingResult( + studyName = rep("s1", n), + context = contexts, + trait = rep("t1", n), + method = rep("susie", n), + entry = rep(list(.sc_makeFineMappingRow(3)), n) + ) +} + # ---- round trips ---------------------------------------------------------- test_that("a fine-mapping result round-trips through a published BED", { data(qtlFineMappingExample, envir = environment()) path <- .rdr_tmp("rt_fm.bed") - exportToBed(qtlFineMappingExample, path, columns = "all") + writeBed(qtlFineMappingExample, path, columns = "all") back <- readFineMappingResult(path, weightStandardized = TRUE) expect_s4_class(back, "QtlFineMappingResult") expect_equal(nrow(back), nrow(qtlFineMappingExample)) @@ -109,10 +139,9 @@ test_that("a fine-mapping result round-trips through a published BED", { }) test_that("a fine-mapping result round-trips through a published VCF", { + skip_if_not_installed("VariantAnnotation") data(qtlFineMappingExample, envir = environment()) - path <- .rdr_tmp("rt_fm.vcf") - exportToVcf(qtlFineMappingExample, path, context = "context_1") - back <- readFineMappingResult(path, weightStandardized = TRUE) + back <- .rdr_fmVcfBack expect_s4_class(back, "QtlFineMappingResult") expect_equal( .rdr_diff( @@ -126,16 +155,15 @@ test_that("a fine-mapping result round-trips through a published VCF", { }) test_that("the two formats agree with each other", { + skip_if_not_installed("VariantAnnotation") # The point of one shared vocabulary: whichever format a result was # published in, it reads back the same. A `region_start` that is 0-based # in the table and 1-based in the VCF header was caught by exactly this. data(qtlFineMappingExample, envir = environment()) bed <- .rdr_tmp("agree.bed") - vcf <- .rdr_tmp("agree.vcf") - exportToBed(qtlFineMappingExample, bed, columns = "all") - exportToVcf(qtlFineMappingExample, vcf, context = "context_1") + writeBed(qtlFineMappingExample, bed, columns = "all") fromBed <- readFineMappingResult(bed, weightStandardized = TRUE) - fromVcf <- readFineMappingResult(vcf, weightStandardized = TRUE) + fromVcf <- .rdr_fmVcfBack expect_equal(genomicRegion(fromBed), genomicRegion(fromVcf)) expect_equal( .rdr_diff( @@ -151,10 +179,9 @@ test_that("a published VCF restores the per-effect fit the header carried", { # `V` and `sets$cs_index` are per EFFECT, so no per-variant column can # hold them -- the `##SAMPLE` block is why they survive at all, and # colocalization's credible-set filter reads them off the fit. + skip_if_not_installed("VariantAnnotation") data(qtlFineMappingExample, envir = environment()) - path <- .rdr_tmp("fit.vcf") - exportToVcf(qtlFineMappingExample, path, context = "context_1") - fit <- susieFit(readFineMappingResult(path, weightStandardized = TRUE)) + fit <- susieFit(.rdr_fmVcfBack) original <- susieFit(qtlFineMappingExample) expect_equal(as.numeric(fit$V), as.numeric(original$V), tolerance = 1e-8) expect_equal( @@ -164,7 +191,7 @@ test_that("a published VCF restores the per-effect fit the header carried", { # A BED has no header to carry them, so there the fit is honestly absent # rather than half-invented. bed <- .rdr_tmp("fit.bed") - exportToBed(qtlFineMappingExample, bed) + writeBed(qtlFineMappingExample, bed) expect_null(susieFit(readFineMappingResult(bed, weightStandardized = TRUE))) }) @@ -172,7 +199,7 @@ test_that("TWAS weights round-trip through a published BED", { data(twasWeightsExample, envir = environment()) path <- .rdr_tmp("rt_w.bed") expect_message( - exportToBed(twasWeightsExample, path), + writeBed(twasWeightsExample, path), "fine-mapping-derived" ) back <- readTwasWeights(path) @@ -216,7 +243,7 @@ test_that("a merged table reads back as a multi-row collection", { qtlFineMappingLbfExample ) path <- .rdr_tmp("merged.bed") - exportToBed(combined, path) + writeBed(combined, path) back <- readFineMappingResult(path, weightStandardized = TRUE) expect_equal(nrow(back), nrow(combined)) md <- S4Vectors::mcols(back) @@ -402,7 +429,7 @@ test_that("a table with no way to identify its variants says so", { test_that("a weights file read as a fine-mapping result points back", { data(twasWeightsExample, envir = environment()) wt <- .rdr_tmp("x_wt.bed") - suppressMessages(exportToBed(twasWeightsExample, wt)) + suppressMessages(writeBed(twasWeightsExample, wt)) expect_error( readFineMappingResult(wt, weightStandardized = TRUE), "no `PIP` column.*readTwasWeights" @@ -414,7 +441,7 @@ test_that("a fine-mapping table reads as weights, because WGT is the weight", { # TWAS coefficient, which is why it publishes as WGT in both schemas. data(qtlFineMappingExample, envir = environment()) fm <- .rdr_tmp("x_fm.bed") - exportToBed(qtlFineMappingExample, fm) + writeBed(qtlFineMappingExample, fm) asWeights <- readTwasWeights(fm, weightStandardized = TRUE) expect_s4_class(asWeights, "TwasWeights") expect_equal( @@ -435,7 +462,7 @@ test_that("a fine-mapping table reads as weights, because WGT is the weight", { test_that("a published weight without its scale has to be told", { data(twasWeightsExample, envir = environment()) path <- .rdr_tmp("scale.bed") - suppressMessages(exportToBed(twasWeightsExample, path)) + suppressMessages(writeBed(twasWeightsExample, path)) # This fixture records the flag, so it reads without one. expect_s4_class(readTwasWeights(path), "TwasWeights") df <- utils::read.delim(path, check.names = FALSE) @@ -547,7 +574,7 @@ test_that("EZ round-trips as a SUPPLIED z and is not invented", { test_that("a result with no context or trait is a GWAS result", { data(gwasFineMappingExample, envir = environment()) path <- .rdr_tmp("gwas.bed") - exportToBed(gwasFineMappingExample, path) + writeBed(gwasFineMappingExample, path) back <- readFineMappingResult(path, weightStandardized = TRUE) expect_s4_class(back, "GwasFineMappingResult") expect_equal( @@ -571,7 +598,7 @@ test_that("the format follows the extension unless it is named", { test_that("a tabix-indexed table can be read by region", { data(qtlFineMappingExample, envir = environment()) path <- .rdr_tmp("region.bed.gz") - exportToBed(qtlFineMappingExample, path) + writeBed(qtlFineMappingExample, path) all <- readFineMappingResult(path, weightStandardized = TRUE) full <- topLoci(all, signalCutoff = 0) window <- GenomicRanges::GRanges( @@ -583,7 +610,7 @@ test_that("a tabix-indexed table can be read by region", { ) part <- readFineMappingResult( path, - region = window, + which = window, weightStandardized = TRUE ) expect_lt(length(variantIds(part)), length(variantIds(all))) @@ -605,9 +632,17 @@ test_that("an un-indexed file ignores a region loudly", { ) path <- .rdr_writeTable(df, "noindex.bed") expect_warning( - readFineMappingResult(path, region = "chr1:1-1000"), + readFineMappingResult( + path, + which = GenomicRanges::GRanges("chr1:1-1000") + ), "not bgzipped \\+ tabix-indexed" ) + # A region given in R is a GRanges; a string is refused, not read. + expect_error( + readFineMappingResult(path, which = "chr1:1-1000"), + "`which` must be a GRanges" + ) }) test_that("a missing file names itself", { @@ -637,10 +672,8 @@ test_that("a per-fit field with no ##SAMPLE key stops the writer", { }) test_that("the ##SAMPLE block survives a VariantAnnotation read", { - data(qtlFineMappingExample, envir = environment()) - path <- .rdr_tmp("sample_block.vcf") - exportToVcf(qtlFineMappingExample, path, context = "context_1") - meta <- pecotmr:::.prdVcfSampleMeta(VariantAnnotation::readVcf(path)) + skip_if_not_installed("VariantAnnotation") + meta <- pecotmr:::.prdVcfSampleMeta(VariantAnnotation::readVcf(.rdr_fmVcf)) # Named in the shared vocabulary, not the header's CamelCase: the reader # inverts the key table so everything downstream sees one set of names. expect_true(all(is_in( @@ -670,7 +703,7 @@ test_that("an empty result survives an export and a read", { data(qtlFineMappingExample, envir = environment()) path <- .rdr_tmp("empty_rt.bed") # A signal cutoff above 1 retains nothing, so the table is vacuous. - exportToBed(qtlFineMappingExample, path, signalCutoff = 2) + writeBed(qtlFineMappingExample, path, signalCutoff = 2) expect_equal(nrow(readFineMappingResult(path)), 0L) }) @@ -678,11 +711,9 @@ test_that("an empty result survives an export and a read", { # The VCF reader's edge paths # --------------------------------------------------------------------------- -# A published VCF, bgzipped and tabix-indexed so it can be read by region. +# A published VCF's bgzipped, tabix-indexed copy, so it can be read by region. # @noRd -.rdr_indexedVcf <- function(x, name, ...) { - plain <- .rdr_tmp(name) - exportToVcf(x, plain, ...) +.rdr_indexedVcf <- function(plain) { gz <- Rsamtools::bgzip(plain, dest = str_c(plain, ".gz"), overwrite = TRUE) Rsamtools::indexTabix(gz, format = "vcf") gz @@ -690,13 +721,9 @@ test_that("an empty result survives an export and a read", { test_that("a tabix-indexed VCF can be read by region", { skip_if_not_installed("VariantAnnotation") - data(qtlFineMappingExample, envir = environment()) - gz <- .rdr_indexedVcf( - qtlFineMappingExample, - "region.vcf", - context = "context_1" - ) - all <- readFineMappingResult(gz, weightStandardized = TRUE) + gz <- .rdr_indexedVcf(.rdr_fmVcf) + # Read whole, the indexed copy holds what the shared round trip read. + all <- .rdr_fmVcfBack full <- topLoci(all, signalCutoff = 0) window <- GenomicRanges::GRanges( as.character(GenomicRanges::seqnames(full))[[1L]], @@ -707,7 +734,7 @@ test_that("a tabix-indexed VCF can be read by region", { ) part <- readFineMappingResult( gz, - region = window, + which = window, weightStandardized = TRUE ) expect_lt(length(variantIds(part)), length(variantIds(all))) @@ -719,15 +746,10 @@ test_that("a tabix-indexed VCF can be read by region", { test_that("a region naming no seqname in the VCF reads as empty", { skip_if_not_installed("VariantAnnotation") - data(qtlFineMappingExample, envir = environment()) - gz <- .rdr_indexedVcf( - qtlFineMappingExample, - "noseq.vcf", - context = "context_1" - ) + gz <- .rdr_indexedVcf(.rdr_fmVcf) back <- readFineMappingResult( gz, - region = "chrZZ:1-1000", + which = GenomicRanges::GRanges("chrZZ:1-1000"), weightStandardized = TRUE, studyName = "s", context = "c", @@ -739,13 +761,12 @@ test_that("a region naming no seqname in the VCF reads as empty", { test_that("an un-indexed VCF ignores a region loudly", { skip_if_not_installed("VariantAnnotation") - data(qtlFineMappingExample, envir = environment()) path <- .rdr_tmp("plain.vcf") - exportToVcf(qtlFineMappingExample, path, context = "context_1") + writeGwasVcf(.rdr_smallFmr(), path) expect_warning( readFineMappingResult( path, - region = "chr22:1-1000000", + which = GenomicRanges::GRanges("chr1:1-1000"), weightStandardized = TRUE ), "not bgzipped \\+ tabix-indexed" @@ -762,11 +783,9 @@ test_that("a missing VCF names itself before VariantAnnotation is asked", { test_that("sampleSelect picks fits out of a multi-sample VCF", { skip_if_not_installed("VariantAnnotation") - data(qtlFineMappingLbfExample, envir = environment()) # Two rows -> two samples in one file, which is GWAS-VCF's own shape. - expect_equal(nrow(qtlFineMappingLbfExample), 2L) path <- .rdr_tmp("multi.vcf") - exportToVcf(qtlFineMappingLbfExample, path) + writeGwasVcf(.rdr_smallFmr(c("c1", "c2")), path) both <- readFineMappingResult(path, weightStandardized = TRUE) expect_equal(nrow(both), 2L) samples <- VariantAnnotation::samples( @@ -786,9 +805,8 @@ test_that("sampleSelect picks fits out of a multi-sample VCF", { test_that("a VCF with no ##SAMPLE block falls back to the sample name", { skip_if_not_installed("VariantAnnotation") - data(qtlFineMappingExample, envir = environment()) path <- .rdr_tmp("nosample.vcf") - exportToVcf(qtlFineMappingExample, path, context = "context_1") + writeGwasVcf(.rdr_smallFmr(), path) stripped <- .rdr_tmp("nosample_stripped.vcf") lines <- readLines(path) writeLines(lines[!str_starts(lines, "##SAMPLE=")], stripped) @@ -860,6 +878,17 @@ test_that("a weights file read with no WGT column points at the other reader", { ) }) +test_that("a published window is read on UCSC sequence names", { + df <- data.frame( + region_id = "22_100_200", + region_start = 99L, + region_end = 200L + ) + gr <- .prdRowRegion(df, 1L, "x") + expect_identical(as.character(GenomicRanges::seqnames(gr)), "chr22") + expect_identical(GenomicRanges::start(gr), 100L) +}) + test_that("a region id with no underscores falls back to the variants' chrom", { expect_equal( .prdRegionChrom( @@ -895,9 +924,8 @@ test_that("a packed header value unpacks, and an absent one is NULL", { # there rather than requiring the full set. # @noRd .rdr_reheaderedVcf <- function(name, keys) { - data(qtlFineMappingExample, envir = environment()) path <- .rdr_tmp(str_c(name, "_src.vcf")) - exportToVcf(qtlFineMappingExample, path, context = "context_1") + writeGwasVcf(.rdr_smallFmr(), path) lines <- readLines(path) at <- which(str_starts(lines, "##SAMPLE=")) expect_length(at, 1L) @@ -956,10 +984,7 @@ test_that("a ##SAMPLE block with no RegionStart still reads", { test_that("a VCF with no samples reads as an empty result", { skip_if_not_installed("VariantAnnotation") - data(qtlFineMappingExample, envir = environment()) - path <- .rdr_tmp("sites_src.vcf") - exportToVcf(qtlFineMappingExample, path, context = "context_1") - lines <- readLines(path) + lines <- readLines(.rdr_fmVcf) keep <- !str_starts(lines, "##SAMPLE=") & !str_starts(lines, "##FORMAT=") # A sites-only VCF: the eight fixed columns and no sample at all, which # is a legal VCF and carries no results. @@ -974,3 +999,156 @@ test_that("a VCF with no samples reads as an empty result", { ) expect_error(readTwasWeights(out), "the VCF has no samples") }) + +test_that("each sample of a VCF reads back only its own variants", { + skip_if_not_installed("VariantAnnotation") + # Two fits over different variants: the records are their union, and a + # fit leaves the cells of the other's variants empty. + fmr <- GwasFineMappingResult( + studyName = c("g1", "g2"), + method = c("susie", "susie"), + entry = list( + .sc_makeFineMappingRow(3), + .sc_makeFineMappingRow(2, offset = 1000L) + ) + ) + path <- .rdr_tmp("disjoint.vcf") + writeGwasVcf(fmr, path) + back <- readFineMappingResult(path, weightStandardized = TRUE) + expect_equal(unname(lengths(back)), c(3L, 2L)) + expect_false(anyNA(pip(back[1L]))) + expect_false(anyNA(pip(back[2L]))) +}) + +test_that("a BID naming a block the header does not list is refused", { + row <- data.frame(block_id = "b1|b2") + expect_identical( + pecotmr:::.prdBlockPositions(row, c("b2", NA, "b1")), + c(2L, NA, 1L) + ) + expect_null(pecotmr:::.prdBlockPositions(data.frame(block_id = "b1"), "b1")) + expect_error( + pecotmr:::.prdBlockPositions(row, "b3"), + "names block\\(s\\) b3 that the sample's header does not list" + ) +}) + +test_that("a header field one sample lacks reads back as NA for it", { + skip_if_not_installed("VariantAnnotation") + fmr <- GwasFineMappingResult( + studyName = c("g1", "g2"), + method = c("susie", "susie"), + entry = list( + .sc_makeFineMappingRow(3), + .sc_makeFineMappingRow(2, offset = 1000L) + ), + dataType = c("gwas", NA) + ) + path <- .rdr_tmp("onefield.vcf") + writeGwasVcf(fmr, path) + back <- readFineMappingResult(path, weightStandardized = TRUE) + expect_identical(back$dataType, c("gwas", NA)) +}) + +test_that(".prdBlockPiece reads one block's part of a header cell", { + expect_null(pecotmr:::.prdBlockPiece(NULL, 1L)) + expect_null(pecotmr:::.prdBlockPiece(".", 1L)) + expect_null(pecotmr:::.prdBlockPiece("a|b", NA_integer_)) + expect_identical(pecotmr:::.prdBlockPiece("a|b", 2L), "b") + # A single-block sample's cell is its one value whole. + expect_identical(pecotmr:::.prdBlockPiece("a", 2L), "a") +}) + +# ---- the genome build ------------------------------------------------------- + +test_that("a result read back carries the build its file recorded", { + x <- .rdr_smallFmr() + GenomeInfoDb::genome(x) <- "hg38" + bed <- .rdr_tmp("build_fm.bed") + writeBed(x, bed, columns = "all") + expect_equal( + unique(unname(GenomeInfoDb::genome( + readFineMappingResult(bed, weightStandardized = TRUE) + ))), + "hg38" + ) + skip_if_not_installed("VariantAnnotation") + vcf <- .rdr_tmp("build_fm.vcf") + writeGwasVcf(x, vcf) + expect_equal( + unique(unname(GenomeInfoDb::genome( + readFineMappingResult(vcf, weightStandardized = TRUE) + ))), + "hg38" + ) +}) + +test_that("a file that names no build reads back with none", { + data(qtlFineMappingExample, envir = environment()) + x <- qtlFineMappingExample + GenomeInfoDb::genome(x) <- NA_character_ + bed <- .rdr_tmp("nobuild_fm.bed") + writeBed(x, bed, columns = "all") + expect_true(all(is.na(GenomeInfoDb::genome( + readFineMappingResult(bed, weightStandardized = TRUE) + )))) + expect_true(is.na(pecotmr:::.prdBedBuild(bed))) +}) + +test_that("TWAS weights read back with the build their file recorded", { + data(twasWeightsExample, envir = environment()) + x <- twasWeightsExample + GenomeInfoDb::genome(x) <- "hg19" + bed <- .rdr_tmp("build_tw.bed") + writeBed(x, bed) + expect_equal( + unique(unname(GenomeInfoDb::genome(readTwasWeights(bed)))), + "hg19" + ) +}) + +test_that("a file of no lines, or of meta lines alone, still reads a build", { + # Every line a `##` line is the count's other branch: there is no first + # non-meta line to stop at. + empty <- .rdr_tmp("empty_build.bed") + writeLines(character(0), empty) + expect_true(is.na(pecotmr:::.prdBedBuild(empty))) + metaOnly <- .rdr_tmp("meta_only_build.bed") + writeLines(c("##genome=hg38", "##source=pecotmr"), metaOnly) + expect_equal(pecotmr:::.prdBedBuild(metaOnly), "hg38") + expect_equal(pecotmr:::.prdLeadingCount(c(TRUE, FALSE, TRUE)), 1L) +}) + +# =========================================================================== +# readFineMappingResult: a joined sample splits back into its blocks +# =========================================================================== + +test_that("readFineMappingResult splits a joined sample back into its blocks", { + skip_if_not_installed("VariantAnnotation") + x <- .rw_blockedGwasFmr() + out <- tempfile(fileext = ".vcf") + writeGwasVcf(x, out) + back <- readFineMappingResult(out, weightStandardized = TRUE) + expect_s4_class(back, "GwasFineMappingResult") + expect_identical(back$blockId, x$blockId) + expect_equal(unname(lengths(back)), c(3L, 3L)) + expect_equal(susieFit(back[2L])$V, c(0.3, 0.4)) + expect_identical(susieFit(back[2L])$sets$cs_index, 2L) + expect_equal(pip(back[2L]), pip(x[2L])) + expect_identical( + as.character(genomicRegion(back)), + as.character(genomicRegion(x)) + ) + expect_identical(back$regionGiven, c(TRUE, TRUE)) + # A block whose range is its variants' span reads back as computed. + mixed <- .rw_mixedGwasFmr() + out2 <- tempfile(fileext = ".vcf") + writeGwasVcf(mixed, out2) + expect_match( + .rw_sampleLines(out2), + "RegionGiven=TRUE|FALSE", + fixed = TRUE + ) + back2 <- readFineMappingResult(out2, weightStandardized = TRUE) + expect_identical(back2$regionGiven, c(TRUE, FALSE)) +}) diff --git a/tests/testthat/test_resultWriters.R b/tests/testthat/test_resultWriters.R index 8dde69f0..72d0875e 100644 --- a/tests/testthat/test_resultWriters.R +++ b/tests/testthat/test_resultWriters.R @@ -1,5 +1,5 @@ -# Tests for the published result writers (resultWriters.R): exportToVcf, the -# GWAS-VCF-style writer, and exportToBed, the published long-format tables. +# Tests for the published result writers (resultWriters.R): writeGwasVcf, the +# GWAS-VCF-style writer, and writeBed, the published long-format tables. # ============================================================================= # Test data helpers @@ -64,7 +64,7 @@ makeTestFineMappingResult <- function(n = 5) { method = rep("susie", n), stringsAsFactors = FALSE ) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = tl$variant_id, susieFit = list(), topLoci = tl @@ -76,68 +76,18 @@ makeTestFineMappingResult <- function(n = 5) { ) } -# ============================================================================= -# GwasSumStats to VCF -# ============================================================================= - -test_that("exportToVcf writes GwasSumStats to uncompressed VCF", { - skip_if_not_installed("VariantAnnotation") - skip_if_not_installed("Biostrings") - - ss <- makeTestGwasSumStats(5) - out <- tempfile(fileext = ".vcf") - on.exit(unlink(out), add = TRUE) - - result <- exportToVcf(ss, out) - expect_equal(result, out) - expect_true(file.exists(out)) - expect_gt(file.info(out)$size, 0) -}) - -# ============================================================================= -# GwasSumStats to bgzipped VCF -# ============================================================================= - -test_that("exportToVcf writes GwasSumStats to bgzipped VCF", { - skip_if_not_installed("VariantAnnotation") - skip_if_not_installed("Biostrings") - - ss <- makeTestGwasSumStats(5) - out <- tempfile(fileext = ".vcf.bgz") - on.exit(unlink(c(out, paste0(out, ".tbi")), force = TRUE), add = TRUE) - - result <- exportToVcf(ss, out) - expect_equal(result, out) - expect_true(file.exists(out)) - expect_gt(file.info(out)$size, 0) -}) - # ============================================================================= # Fine-mapping result to VCF # ============================================================================= -test_that("exportToVcf writes a fine-mapping result to uncompressed VCF", { +test_that("writeGwasVcf(FineMapping): emits PIP + CS FORMAT fields", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") fm <- makeTestFineMappingResult(5) out <- tempfile(fileext = ".vcf") on.exit(unlink(out), add = TRUE) - - result <- exportToVcf(fm, out) - expect_equal(result, out) - expect_true(file.exists(out)) - expect_gt(file.info(out)$size, 0) -}) - -test_that("exportToVcf(FineMapping): emits PIP + CS FORMAT fields", { - skip_if_not_installed("VariantAnnotation") - skip_if_not_installed("Biostrings") - - fm <- makeTestFineMappingResult(5) - out <- tempfile(fileext = ".vcf") - on.exit(unlink(out), add = TRUE) - exportToVcf(fm, out) + expect_equal(writeGwasVcf(fm, out), out) ln <- readLines(out) # The posterior fields the legacy create_vcf carried must be present. The CS # field is DYNAMIC (CS) -- the fixture carries cs_95 -> CS95. @@ -156,7 +106,7 @@ test_that("exportToVcf(FineMapping): emits PIP + CS FORMAT fields", { # Fine-mapping result to BCF # ============================================================================= -test_that("exportToVcf writes a fine-mapping result to BCF", { +test_that("writeGwasVcf writes a fine-mapping result to BCF", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") skip_if_not_installed("Rsamtools") @@ -205,7 +155,7 @@ test_that("exportToVcf writes a fine-mapping result to BCF", { out <- tempfile(fileext = ".bcf") on.exit(unlink(out), add = TRUE) - result <- exportToVcf(fm, out) + result <- writeGwasVcf(fm, out) expect_equal(result, out) expect_true(file.exists(out)) expect_gt(file.info(out)$size, 0) @@ -215,7 +165,7 @@ test_that("exportToVcf writes a fine-mapping result to BCF", { # Empty fine-mapping result errors # ============================================================================= -test_that("exportToVcf errors on an empty fine-mapping result", { +test_that("writeGwasVcf errors on an empty fine-mapping result", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") @@ -236,7 +186,7 @@ test_that("exportToVcf errors on an empty fine-mapping result", { posterior_sd = numeric(0), stringsAsFactors = FALSE ) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = character(0), susieFit = list(), topLoci = empty_tl @@ -250,7 +200,7 @@ test_that("exportToVcf errors on an empty fine-mapping result", { out <- tempfile(fileext = ".vcf") on.exit(unlink(out), add = TRUE) - expect_error(exportToVcf(fm_empty, out), "no variants to write") + expect_error(writeGwasVcf(fm_empty, out), "no variants to write") }) # ============================================================================= @@ -280,7 +230,7 @@ test_that("exportToVcf errors on an empty fine-mapping result", { cs_95 = paste0("susie_", c(1L, 1L, 0L)), stringsAsFactors = FALSE ) - fineMappingRow(variantIds = ids, susieFit = list(), topLoci = tl) + FineMappingRow(variantIds = ids, susieFit = list(), topLoci = tl) }) QtlFineMappingResult( studyName = rep("study1", 2), @@ -291,73 +241,47 @@ test_that("exportToVcf errors on an empty fine-mapping result", { ) } -test_that("exportToVcf(FineMapping): splitByContext emits one VCF each", { +test_that("writeGwasVcf(FineMapping): each split flag emits one VCF per tag", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") fmr <- .makeMultiTupleQtlFmr() - baseOut <- tempfile(fileext = ".vcf") - on.exit( - unlink(list.files( - dirname(baseOut), - pattern = basename(tools::file_path_sans_ext(baseOut)), - full.names = TRUE - )), - add = TRUE + # Each path is decorated with the tags its flags select; both flags + # combine them, context first. + cases <- list( + context = list( + flags = list(splitByContext = TRUE), + tags = c("brain", "blood") + ), + trait = list( + flags = list(splitByTrait = TRUE), + tags = c("ENSG_A", "ENSG_B") + ), + both = list( + flags = list(splitByContext = TRUE, splitByTrait = TRUE), + tags = c("brain.ENSG_A", "blood.ENSG_B") + ) ) - paths <- exportToVcf(fmr, baseOut, splitByContext = TRUE) - expect_length(paths, 2L) - # Each path is decorated with the context tag. - expect_true(any(grepl("\\.brain\\.vcf$", paths))) - expect_true(any(grepl("\\.blood\\.vcf$", paths))) - for (p in paths) { - expect_true(file.exists(p)) + d <- withr::local_tempdir() + for (case in names(cases)) { + paths <- exec( + writeGwasVcf, + fmr, + file.path(d, str_c(case, ".vcf")), + !!!cases[[case]]$flags + ) + expect_equal(length(paths), 2L, info = case) + expect_true( + setequal( + basename(paths), + str_c(case, ".", cases[[case]]$tags, ".vcf") + ), + info = case + ) + expect_true(all(file.exists(paths)), info = case) } }) -test_that("exportToVcf(FineMapping): splitByTrait emits one VCF each", { - skip_if_not_installed("VariantAnnotation") - skip_if_not_installed("Biostrings") - fmr <- .makeMultiTupleQtlFmr() - baseOut <- tempfile(fileext = ".vcf") - on.exit( - unlink(list.files( - dirname(baseOut), - pattern = basename(tools::file_path_sans_ext(baseOut)), - full.names = TRUE - )), - add = TRUE - ) - paths <- exportToVcf(fmr, baseOut, splitByTrait = TRUE) - expect_length(paths, 2L) - expect_true(any(grepl("\\.ENSG_A\\.vcf$", paths))) - expect_true(any(grepl("\\.ENSG_B\\.vcf$", paths))) -}) - -test_that("exportToVcf(FineMapping): both split flags combine the tags", { - skip_if_not_installed("VariantAnnotation") - skip_if_not_installed("Biostrings") - fmr <- .makeMultiTupleQtlFmr() - baseOut <- tempfile(fileext = ".vcf") - on.exit( - unlink(list.files( - dirname(baseOut), - pattern = basename(tools::file_path_sans_ext(baseOut)), - full.names = TRUE - )), - add = TRUE - ) - paths <- exportToVcf( - fmr, - baseOut, - splitByContext = TRUE, - splitByTrait = TRUE - ) - expect_length(paths, 2L) - expect_true(any(grepl("\\.brain\\.ENSG_A\\.vcf$", paths))) - expect_true(any(grepl("\\.blood\\.ENSG_B\\.vcf$", paths))) -}) - -test_that("exportToVcf(FineMapping): several fits make one multi-sample VCF", { +test_that("writeGwasVcf(FineMapping): several fits make one multi-sample VCF", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") fmr <- .makeMultiTupleQtlFmr() @@ -365,7 +289,7 @@ test_that("exportToVcf(FineMapping): several fits make one multi-sample VCF", { on.exit(unlink(out), add = TRUE) # No selector and no split flag: every matching fit is a SAMPLE of one # file, which is what GWAS-VCF's per-sample design means. - expect_identical(exportToVcf(fmr, out), out) + expect_identical(writeGwasVcf(fmr, out), out) lines <- readLines(out) header <- str_split(lines[str_starts(lines, "#CHROM")][[1L]], "\t")[[1L]] samples <- header[-seq_len(9L)] @@ -381,7 +305,7 @@ test_that("exportToVcf(FineMapping): several fits make one multi-sample VCF", { expect_length(body, 9L + 2L) }) -test_that("exportToVcf(FineMapping): a fit missing a variant leaves a gap", { +test_that("writeGwasVcf(FineMapping): a fit missing a variant leaves a gap", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") # Two fits over DISJOINT variants: the records are the union, and each @@ -404,7 +328,7 @@ test_that("exportToVcf(FineMapping): a fit missing a variant leaves a gap", { context = ctx, trait = "g1", method = "susie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( variantIds = ids, susieFit = list(), topLoci = tl @@ -414,7 +338,7 @@ test_that("exportToVcf(FineMapping): a fit missing a variant leaves a gap", { fmr <- combineFineMappingResults(mk(c(100, 200), "a"), mk(c(300), "b")) out <- tempfile(fileext = ".vcf") on.exit(unlink(out), add = TRUE) - exportToVcf(fmr, out) + writeGwasVcf(fmr, out) lines <- readLines(out) cells <- str_split(keep(lines, str_starts, "chr1"), "\t") expect_identical(map_chr(cells, 2L), c("100", "200", "300")) @@ -429,8 +353,10 @@ test_that("exportToVcf(FineMapping): a fit missing a variant leaves a gap", { # GwasSumStats: multi-study selection, MAF/AF field, .gz rename # ============================================================================= -.makeTwoStudyGwasSumStats <- function(n = 3, withMaf = FALSE) { - mkGr <- function() { +# Two studies over the same variants, told apart by their sample size: N is +# 1000 in studyA and 2000 in studyB. +.makeTwoStudyGwasSumStats <- function(n = 3) { + mkGr <- function(nSample) { gr <- GenomicRanges::GRanges( "chr1", IRanges::IRanges( @@ -443,41 +369,45 @@ test_that("exportToVcf(FineMapping): a fit missing a variant leaves a gap", { A1 = rep("A", n), A2 = rep("T", n), Z = seq(1.5, by = -0.5, length.out = n), - N = rep(1000L, n) + N = rep(nSample, n) ) - if (withMaf) { - mc$MAF <- rep(0.2, n) - } S4Vectors::mcols(gr) <- mc gr } GwasSumStats( studyName = c("studyA", "studyB"), - entry = list(mkGr(), mkGr()), + entry = list(mkGr(1000L), mkGr(2000L)), genome = "hg38", ldReference = makeTestGenotypeHandle() ) } -test_that("exportToVcf(SumStats): multi-study needs a `study`", { +test_that("writeGwasVcf(SumStats): multi-study needs a `studyName`", { skip_if_not_installed("VariantAnnotation") ss2 <- .makeTwoStudyGwasSumStats() out <- tempfile(fileext = ".vcf") - expect_error(exportToVcf(ss2, out), "2 studies") + expect_error(writeGwasVcf(ss2, out), "2 studies") }) -test_that("exportToVcf(SumStats): `study` picks the chosen study", { +test_that("writeGwasVcf(SumStats): `studyName` picks the chosen study", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") ss2 <- .makeTwoStudyGwasSumStats() out <- tempfile(fileext = ".vcf") on.exit(unlink(out), add = TRUE) - res <- exportToVcf(ss2, out, studyName = "studyB") + res <- writeGwasVcf(ss2, out, studyName = "studyB") expect_equal(res, out) - expect_true(file.exists(out)) + # The file holds studyB alone: one sample, named for it, with its N. A + # Number=A field reads back as a list matrix, one value per cell. + vcf <- VariantAnnotation::readVcf(out) + expect_identical(colnames(vcf), "studyB") + expect_identical( + list_c(VariantAnnotation::geno(vcf)$NS[, 1L]), + rep(2000L, 3L) + ) }) -test_that("exportToVcf(SumStats): emits AF when MAF is present", { +test_that("writeGwasVcf(SumStats): emits AF when MAF is present", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") ss <- GwasSumStats( @@ -502,7 +432,7 @@ test_that("exportToVcf(SumStats): emits AF when MAF is present", { ) out <- tempfile(fileext = ".vcf") on.exit(unlink(out), add = TRUE) - exportToVcf(ss, out) + writeGwasVcf(ss, out) expect_true(file.exists(out)) # The AF FORMAT field is declared in the header when MAF is present. # A source carrying only MAF gets the MAF key, not AF: the spec's AF is @@ -512,15 +442,16 @@ test_that("exportToVcf(SumStats): emits AF when MAF is present", { expect_false(any(grepl("ID=AF,", readLines(out)))) }) -test_that("exportToVcf(SumStats): .vcf.gz is renamed from .bgz", { +test_that("writeGwasVcf(SumStats): .vcf.gz is renamed from .bgz", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") ss <- makeTestGwasSumStats(5) out <- tempfile(fileext = ".vcf.gz") on.exit(unlink(c(out, paste0(out, ".tbi")), force = TRUE), add = TRUE) - res <- exportToVcf(ss, out) + res <- writeGwasVcf(ss, out) expect_equal(res, out) - # writeVcf always emits .bgz; the writer renames it to the requested .gz. + # VariantAnnotation::writeVcf() always emits .bgz; the writer renames it + # to the requested .gz. expect_true(file.exists(out)) expect_false(file.exists(sub("\\.gz$", ".bgz", out))) }) @@ -530,13 +461,13 @@ test_that("exportToVcf(SumStats): .vcf.gz is renamed from .bgz", { # tags # ============================================================================= -test_that("exportToVcf(FineMapping): selectors pick a single row", { +test_that("writeGwasVcf(FineMapping): selectors pick a single row", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") fmr <- .makeMultiTupleQtlFmr() out <- tempfile(fileext = ".vcf") on.exit(unlink(out), add = TRUE) - res <- exportToVcf( + res <- writeGwasVcf( fmr, out, studyName = "study1", @@ -545,21 +476,28 @@ test_that("exportToVcf(FineMapping): selectors pick a single row", { method = "susie" ) expect_equal(res, out) - expect_true(file.exists(out)) + # One sample, the brain / ENSG_A fit, carrying that row's marginal + # effects; the blood row's are 0.01 larger. + vcf <- VariantAnnotation::readVcf(out) + expect_identical(colnames(vcf), "study1|brain|ENSG_A|susie") + expect_equal( + list_c(VariantAnnotation::geno(vcf)$ES[, 1L]), + c(0.31, 0.11, -0.19) + ) }) -test_that("exportToVcf(fine-mapping result): no matching rows errors", { +test_that("writeGwasVcf(fine-mapping result): no matching rows errors", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") fmr <- .makeMultiTupleQtlFmr() out <- tempfile(fileext = ".vcf") expect_error( - exportToVcf(fmr, out, studyName = "does_not_exist"), + writeGwasVcf(fmr, out, studyName = "does_not_exist"), "no rows match" ) }) -test_that("exportToVcf(FineMapping): split decorates a .vcf.bgz path", { +test_that("writeGwasVcf(FineMapping): split decorates a .vcf.bgz path", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") fmr <- .makeMultiTupleQtlFmr() @@ -576,7 +514,7 @@ test_that("exportToVcf(FineMapping): split decorates a .vcf.bgz path", { ), add = TRUE ) - paths <- exportToVcf(fmr, baseOut, splitByContext = TRUE) + paths <- writeGwasVcf(fmr, baseOut, splitByContext = TRUE) expect_length(paths, 2L) # The composite extension survives; the tag is injected before it. expect_true(all(grepl("\\.vcf\\.bgz$", paths))) @@ -584,7 +522,7 @@ test_that("exportToVcf(FineMapping): split decorates a .vcf.bgz path", { expect_true(any(grepl("\\.blood\\.vcf\\.bgz$", paths))) }) -test_that("exportToVcf(FineMapping): a context-less split keeps the path", { +test_that("writeGwasVcf(FineMapping): a context-less split keeps the path", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") # GwasFineMappingResult has no context/trait axes, so the split tag set is @@ -592,13 +530,13 @@ test_that("exportToVcf(FineMapping): a context-less split keeps the path", { fm <- makeTestFineMappingResult(5) out <- tempfile(fileext = ".vcf") on.exit(unlink(out), add = TRUE) - paths <- exportToVcf(fm, out, splitByContext = TRUE) + paths <- writeGwasVcf(fm, out, splitByContext = TRUE) expect_length(paths, 1L) expect_equal(paths[[1L]], out) expect_true(file.exists(out)) }) -test_that("exportToVcf(FineMapping): AF comes from topLoci `af`", { +test_that("writeGwasVcf(FineMapping): AF comes from topLoci `af`", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") # The marginal view projects allele frequency to a column named `af`, so a @@ -622,7 +560,7 @@ test_that("exportToVcf(FineMapping): AF comes from topLoci `af`", { cs_95 = paste0("susie_", c(1L, 0L, 2L)), stringsAsFactors = FALSE ) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = tl$variant_id, susieFit = list(), topLoci = tl @@ -634,12 +572,12 @@ test_that("exportToVcf(FineMapping): AF comes from topLoci `af`", { ) out <- tempfile(fileext = ".vcf") on.exit(unlink(out), add = TRUE) - exportToVcf(fm, out) + writeGwasVcf(fm, out) expect_true(file.exists(out)) expect_true(any(grepl("ID=AF", readLines(out)))) }) -test_that("exportToVcf(FineMapping): LBF / LFSR / PUR / fullFit fields", { +test_that("writeGwasVcf(FineMapping): LBF / LFSR / PUR / fullFit fields", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") # A rich topLoci exercises every posterior FORMAT field: per-variant @@ -670,7 +608,7 @@ test_that("exportToVcf(FineMapping): LBF / LFSR / PUR / fullFit fields", { cs_effect_susie_1 = c(0.4, NA, NA), stringsAsFactors = FALSE ) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = tl$variant_id, susieFit = list(), topLoci = tl @@ -682,7 +620,7 @@ test_that("exportToVcf(FineMapping): LBF / LFSR / PUR / fullFit fields", { ) out <- tempfile(fileext = ".vcf") on.exit(unlink(out), add = TRUE) - exportToVcf(fm, out) + writeGwasVcf(fm, out) ln <- readLines(out) for (id in c( "ID=LBF", @@ -696,7 +634,7 @@ test_that("exportToVcf(FineMapping): LBF / LFSR / PUR / fullFit fields", { } }) -test_that("exportToVcf(FineMapping): falls back to marginal sumstats", { +test_that("writeGwasVcf(FineMapping): falls back to marginal sumstats", { skip_if_not_installed("VariantAnnotation") skip_if_not_installed("Biostrings") fm <- makeTestFineMappingResult(5) @@ -708,7 +646,7 @@ test_that("exportToVcf(FineMapping): falls back to marginal sumstats", { ) out <- tempfile(fileext = ".vcf") on.exit(unlink(out), add = TRUE) - exportToVcf(fm, out) + writeGwasVcf(fm, out) expect_true(file.exists(out)) # marginal beta -> ES expect_true(any(grepl("ID=ES", readLines(out), fixed = TRUE))) @@ -723,11 +661,18 @@ test_that("plain and bgzipped VCF are written, the latter with an index", { skip_if_not_installed("VariantAnnotation") data(gwasSumStatsS4Example) d <- withr::local_tempdir() - exportToVcf(gwasSumStatsS4Example, outputPath = file.path(d, "a.vcf")) + # Each call returns the path it wrote. + expect_equal( + writeGwasVcf(gwasSumStatsS4Example, filename = file.path(d, "a.vcf")), + file.path(d, "a.vcf") + ) expect_true(file.exists(file.path(d, "a.vcf"))) - exportToVcf( - gwasSumStatsS4Example, - outputPath = file.path(d, "b.vcf.bgz") + expect_equal( + writeGwasVcf( + gwasSumStatsS4Example, + filename = file.path(d, "b.vcf.bgz") + ), + file.path(d, "b.vcf.bgz") ) expect_true(file.exists(file.path(d, "b.vcf.bgz"))) # index = TRUE, so the tabix index is written alongside. @@ -751,9 +696,9 @@ test_that("BCF output explains itself when Rsamtools cannot convert", { ) skip_if(canConvert, "Rsamtools::asBcf() works here; nothing to translate") expect_error( - exportToVcf( + writeGwasVcf( gwasSumStatsS4Example, - outputPath = file.path(d, "c.bcf") + filename = file.path(d, "c.bcf") ), "BCF output needs a working Rsamtools::asBcf" ) @@ -787,7 +732,7 @@ test_that(".vcfResolveBody uses posterior rows when no marginals exist", { expect_null(out$m) }) -test_that(".writeVcfImpl adds the chr prefix to bare chromosome names", { +test_that(".writeVcfImpl writes UCSC chromosome names", { skip_if_not_installed("VariantAnnotation") out <- tempfile(fileext = ".vcf") on.exit(unlink(out), add = TRUE) @@ -799,7 +744,7 @@ test_that(".writeVcfImpl adds the chr prefix to bare chromosome names", { row.names = "Z" ) pecotmr:::.writeVcfImpl( - chrom = c("1", "1"), + chrom = c("1", "MT"), pos = c(100L, 200L), ref = c("A", "C"), alt = c("G", "T"), @@ -811,18 +756,18 @@ test_that(".writeVcfImpl adds the chr prefix to bare chromosome names", { ) body <- readLines(out) body <- body[!startsWith(body, "#")] - expect_true(all(startsWith(body, "chr1\t"))) + expect_setequal(stringr::str_extract(body, "^[^\t]+"), c("chr1", "chrM")) }) # ============================================================================= -# exportToBed: the fine-mapping schemas +# writeBed: the fine-mapping schemas # ============================================================================= -test_that("exportToBed writes the published top-loci schema", { +test_that("writeBed writes the published top-loci schema", { data(qtlFineMappingExample) out <- withr::local_tempfile(fileext = ".bed") expect_identical( - exportToBed(qtlFineMappingExample, out, signalCutoff = 0), + writeBed(qtlFineMappingExample, out, signalCutoff = 0), out ) tbl <- utils::read.delim(out, check.names = FALSE) @@ -854,10 +799,10 @@ test_that("exportToBed writes the published top-loci schema", { expect_false(is.unsorted(tbl$start[tbl[[1L]] == first])) }) -test_that("exportToBed bgzips and tabix-indexes a .gz fsusie table", { +test_that("writeBed bgzips and tabix-indexes a .gz fsusie table", { data(fsusieFineMappingExample) out <- withr::local_tempfile(fileext = ".bed.gz") - exportToBed(fsusieFineMappingExample, out, schema = "fsusie") + writeBed(fsusieFineMappingExample, out, schema = "fsusie") expect_true(file.exists(out)) expect_true(file.exists(str_c(out, ".tbi"))) hdr <- readLines(gzfile(out), n = 1L) @@ -888,12 +833,12 @@ test_that("exportToBed bgzips and tabix-indexes a .gz fsusie table", { )) }) -test_that("exportToBed emits the full schema for an empty result", { +test_that("writeBed emits the full schema for an empty result", { data(qtlFineMappingExample) out <- withr::local_tempfile(fileext = ".bed") # A cutoff no variant clears -> 0 data rows, but the schema must not # collapse. read.table() cannot read a header-only file, so read the line. - exportToBed(qtlFineMappingExample, out, signalCutoff = 2) + writeBed(qtlFineMappingExample, out, signalCutoff = 2) lines <- readLines(out) expect_length(lines, 1L) # A header-only file documents the whole vocabulary rather than @@ -903,13 +848,13 @@ test_that("exportToBed emits the full schema for an empty result", { expect_true(all(c("ES", "WGT", "PIP", "region_id") %in% hdr)) }) -test_that("exportToBed combines several results into one table", { +test_that("writeBed combines several results into one table", { data(qtlFineMappingExample) data(mvsusieFineMappingExample) one <- withr::local_tempfile(fileext = ".bed") both <- withr::local_tempfile(fileext = ".bed") - exportToBed(qtlFineMappingExample, one, signalCutoff = 0) - exportToBed( + writeBed(qtlFineMappingExample, one, signalCutoff = 0) + writeBed( list(qtlFineMappingExample, mvsusieFineMappingExample), both, signalCutoff = 0 @@ -928,17 +873,17 @@ test_that("exportToBed combines several results into one table", { ) }) -test_that("exportToBed rejects something that is not a result collection", { +test_that("writeBed rejects something that is not a result collection", { out <- withr::local_tempfile(fileext = ".bed") - expect_error(exportToBed(data.frame(a = 1), out), "FineMappingResult") - expect_error(exportToBed(list(), out), "at least one") + expect_error(writeBed(data.frame(a = 1), out), "FineMappingResult") + expect_error(writeBed(list(), out), "at least one") }) test_that("the fsusie schema is still complete when no fsusie rows exist", { data(qtlFineMappingExample) out <- withr::local_tempfile(fileext = ".bed") # No fsusie rows at all -> a header-only table, not an error. - exportToBed(qtlFineMappingExample, out, schema = "fsusie") + writeBed(qtlFineMappingExample, out, schema = "fsusie") lines <- readLines(out) expect_length(lines, 1L) # a header-only file documents the schema, with no coverage discovered @@ -966,7 +911,7 @@ test_that("a merged multi-region fSuSiE table keeps each region's own window", { withRegion(b, wantB) ) out <- withr::local_tempfile(fileext = ".bed.gz") - exportToBed(both, out, schema = "fsusie") + writeBed(both, out, schema = "fsusie") tbl <- utils::read.delim(gzfile(out), check.names = FALSE) expect_setequal( unique(tbl$region_id), @@ -979,7 +924,7 @@ test_that("a merged multi-region fSuSiE table keeps each region's own window", { test_that("extraColumns appends trailing fields the object cannot know", { data(qtlFineMappingExample) out <- withr::local_tempfile(fileext = ".bed") - exportToBed( + writeBed( qtlFineMappingExample, out, signalCutoff = 0, @@ -991,7 +936,7 @@ test_that("extraColumns appends trailing fields the object cannot know", { # one value per row is equally valid perRow <- withr::local_tempfile(fileext = ".bed") - exportToBed( + writeBed( qtlFineMappingExample, perRow, signalCutoff = 0, @@ -1007,7 +952,7 @@ test_that("extraColumns refuses a clash, a bad length, an unnamed list", { data(qtlFineMappingExample) out <- withr::local_tempfile(fileext = ".bed") expect_error( - exportToBed( + writeBed( qtlFineMappingExample, out, signalCutoff = 0, @@ -1016,7 +961,7 @@ test_that("extraColumns refuses a clash, a bad length, an unnamed list", { "would overwrite" ) expect_error( - exportToBed( + writeBed( qtlFineMappingExample, out, signalCutoff = 0, @@ -1025,7 +970,7 @@ test_that("extraColumns refuses a clash, a bad length, an unnamed list", { "one value per row" ) expect_error( - exportToBed( + writeBed( qtlFineMappingExample, out, signalCutoff = 0, @@ -1038,7 +983,7 @@ test_that("extraColumns refuses a clash, a bad length, an unnamed list", { test_that("extraColumns survive an empty table", { data(qtlFineMappingExample) out <- withr::local_tempfile(fileext = ".bed") - exportToBed( + writeBed( qtlFineMappingExample, out, signalCutoff = 2, @@ -1046,9 +991,12 @@ test_that("extraColumns survive an empty table", { ) lines <- readLines(out) expect_length(lines, 1L) + # The header-only schema, with the extra column after it. + plain <- withr::local_tempfile(fileext = ".bed") + writeBed(qtlFineMappingExample, plain, signalCutoff = 2) expect_identical( str_split(lines[[1L]], "\t")[[1L]], - c(str_split(readLines(out)[[1L]], "\t")[[1L]]) + c(str_split(readLines(plain)[[1L]], "\t")[[1L]], "source_file") ) }) @@ -1097,7 +1045,7 @@ test_that("genomicOrder uses `end` only to break ties, and only if numeric", { }) # ============================================================================= -# exportToBed: the TWAS-weight schemas +# writeBed: the TWAS-weight schemas # ============================================================================= makeTestTwasWeights <- function(weights, method = "lasso", nVariants = 3L) { @@ -1107,7 +1055,7 @@ makeTestTwasWeights <- function(weights, method = "lasso", nVariants = 3L) { context = "brain", trait = "g1", method = method, - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = ids, weights = weights, cvResult = list(metrics = c(rsq = 0.5, pval = 0.01)), @@ -1116,10 +1064,10 @@ makeTestTwasWeights <- function(weights, method = "lasso", nVariants = 3L) { ) } -test_that("exportToBed writes the published TWAS-weight schema", { +test_that("writeBed writes the published TWAS-weight schema", { data(twasWeightsExample) out <- withr::local_tempfile(fileext = ".bed") - expect_identical(exportToBed(twasWeightsExample, out), out) + expect_identical(writeBed(twasWeightsExample, out), out) tbl <- utils::read.delim(out, check.names = FALSE) expect_identical( names(tbl)[1:6], @@ -1147,11 +1095,11 @@ test_that("exportToBed writes the published TWAS-weight schema", { expect_identical(unique(tbl$region_end), 18850784L) }) -test_that("exportToBed writes one TWAS-weight row per matrix column", { +test_that("writeBed writes one TWAS-weight row per matrix column", { w <- matrix(c(0.1, 0.2, 0.3, -0.4, -0.5, -0.6), nrow = 3L) colnames(w) <- c("mark_a", "mark_b") out <- withr::local_tempfile(fileext = ".bed") - exportToBed(makeTestTwasWeights(w), out) + writeBed(makeTestTwasWeights(w), out) tbl <- utils::read.delim(out, check.names = FALSE) expect_identical(nrow(tbl), 6L) expect_setequal(unique(tbl$trait), c("mark_a", "mark_b")) @@ -1161,17 +1109,17 @@ test_that("exportToBed writes one TWAS-weight row per matrix column", { ) # a plain weight vector has no feature axis, so the column is empty plain <- withr::local_tempfile(fileext = ".bed") - exportToBed(makeTestTwasWeights(c(0.1, 0.2, 0.3)), plain) + writeBed(makeTestTwasWeights(c(0.1, 0.2, 0.3)), plain) plainTbl <- utils::read.delim(plain, check.names = FALSE) expect_identical(nrow(plainTbl), 3L) # a plain weight vector has no feature axis, so `trait` stays the row's expect_identical(unique(plainTbl$trait), "g1") }) -test_that("exportToBed bgzips and tabix-indexes a .gz TWAS-weight table", { +test_that("writeBed bgzips and tabix-indexes a .gz TWAS-weight table", { data(twasWeightsExample) out <- withr::local_tempfile(fileext = ".bed.gz") - exportToBed(twasWeightsExample, out) + writeBed(twasWeightsExample, out) expect_true(file.exists(out)) expect_true(file.exists(str_c(out, ".tbi"))) cols <- str_split(readLines(gzfile(out), n = 1L), "\t")[[1L]] @@ -1187,24 +1135,24 @@ test_that("exporting refuses a TwasWeights with no full-data fit", { context = "brain", trait = "g1", method = "susie", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = character(0), weights = NULL, cvResult = list(metrics = c(rsq = 0.5)) )) ) out <- withr::local_tempfile(fileext = ".bed") - expect_error(exportToBed(cvOnly, out), "no full-data fit") - expect_error(exportToBed(cvOnly, out), "fitFullData") + expect_error(writeBed(cvOnly, out), "no full-data fit") + expect_error(writeBed(cvOnly, out), "fitFullData") expect_error( - exportToVcf(cvOnly, withr::local_tempfile(fileext = ".vcf")), + writeGwasVcf(cvOnly, withr::local_tempfile(fileext = ".vcf")), "no full-data fit" ) # the offending row is named, so a genome-wide run says which one - expect_error(exportToBed(cvOnly, out), "s1\\|brain\\|g1\\|susie") + expect_error(writeBed(cvOnly, out), "s1\\|brain\\|g1\\|susie") # and a weightless-but-populated row is refused for the same reason expect_error( - exportToBed(makeTestTwasWeights(NULL), out), + writeBed(makeTestTwasWeights(NULL), out), "no full-data fit" ) }) @@ -1217,45 +1165,45 @@ test_that("exporting refuses a fine-mapping row with no fitted variants", { context = "c1", trait = "g1", method = "susie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( variantIds = character(0), susieFit = list(), topLoci = data.frame() )) ) out <- withr::local_tempfile(fileext = ".bed") - expect_error(exportToBed(fmr, out), "no full-data fit") + expect_error(writeBed(fmr, out), "no full-data fit") }) -test_that("exportToBed combines a list of TwasWeights into one table", { +test_that("writeBed combines a list of TwasWeights into one table", { one <- withr::local_tempfile(fileext = ".bed") both <- withr::local_tempfile(fileext = ".bed") a <- makeTestTwasWeights(c(0.1, 0.2, 0.3), method = "lasso") b <- makeTestTwasWeights(c(0.4, 0.5, 0.6), method = "enet") - exportToBed(a, one) - exportToBed(list(a, b), both) + writeBed(a, one) + writeBed(list(a, b), both) expect_identical(length(readLines(both)), 2L * length(readLines(one)) - 1L) tbl <- utils::read.delim(both, check.names = FALSE) expect_setequal(unique(tbl$method), c("lasso", "enet")) }) -test_that("exportToBed rejects a list that holds neither result type", { +test_that("writeBed rejects a list that holds neither result type", { out <- withr::local_tempfile(fileext = ".bed") - expect_error(exportToBed(list(), out), "at least one") + expect_error(writeBed(list(), out), "at least one") expect_error( - exportToBed(list(1, 2), out), + writeBed(list(1, 2), out), "TwasWeights, QtlFineMappingResult or GwasFineMappingResult" ) }) # ============================================================================= -# exportToVcf: TWAS weights +# writeGwasVcf: TWAS weights # ============================================================================= -test_that("exportToVcf writes TWAS weights with one sample per model", { +test_that("writeGwasVcf writes TWAS weights with one sample per model", { data(twasWeightsExample) out <- withr::local_tempfile(fileext = ".vcf") - exportToVcf(twasWeightsExample, out) + writeGwasVcf(twasWeightsExample, out) lines <- readLines(out) header <- str_split( lines[str_starts(lines, "#CHROM")][[1L]], @@ -1274,23 +1222,27 @@ test_that("exportToVcf writes TWAS weights with one sample per model", { expect_length(body, 9L + 9L) }) -test_that("the TWAS-weight VCF describes each model in a ##SAMPLE line", { +test_that("the TWAS-weight VCF's ##SAMPLE lines describe each model, not CV", { data(twasWeightsExample) out <- withr::local_tempfile(fileext = ".vcf") - exportToVcf(twasWeightsExample, out) + writeGwasVcf(twasWeightsExample, out) sampleLines <- keep(readLines(out), str_starts, "##SAMPLE=") expect_length(sampleLines, 9L) + expect_true(all(str_detect(sampleLines, "TotalVariants="))) susie <- keep(sampleLines, str_detect, fixed("Method=lasso,"))[[1L]] expect_true(str_detect(susie, "Trait=ENSG00000130538")) expect_true(str_detect(susie, "TotalVariants=168")) expect_true(str_detect(susie, "WeightStandardized=FALSE")) expect_true(str_detect(susie, "DataType=bulk_rnaseq")) + # CV describes held-out folds; a published file has no data-secure way to + # say anything fold-level, so the header stops at identity + counts. + expect_false(any(str_detect(sampleLines, "rsq=|corr=|pval=|CvRegions="))) }) -test_that("exportToVcf narrows TWAS models with the identity selectors", { +test_that("writeGwasVcf narrows TWAS models with the identity selectors", { data(twasWeightsExample) out <- withr::local_tempfile(fileext = ".vcf") - exportToVcf(twasWeightsExample, out, method = "lasso") + writeGwasVcf(twasWeightsExample, out, method = "lasso") lines <- readLines(out) header <- str_split( lines[str_starts(lines, "#CHROM")][[1L]], @@ -1298,13 +1250,13 @@ test_that("exportToVcf narrows TWAS models with the identity selectors", { )[[1L]] expect_length(header[-seq_len(9L)], 1L) expect_error( - exportToVcf(twasWeightsExample, out, method = "nope"), + writeGwasVcf(twasWeightsExample, out, method = "nope"), "no rows match" ) # Selecting a fine-mapping method leaves nothing exportable, which is a # different refusal from "no rows match". expect_error( - suppressMessages(exportToVcf( + suppressMessages(writeGwasVcf( twasWeightsExample, out, method = "susie" @@ -1313,10 +1265,10 @@ test_that("exportToVcf narrows TWAS models with the identity selectors", { ) }) -test_that("exportToVcf names TWAS samples, or refuses a mismatched count", { +test_that("writeGwasVcf names TWAS samples, or refuses a mismatched count", { out <- withr::local_tempfile(fileext = ".vcf") tw <- makeTestTwasWeights(c(0.1, 0.2, 0.3)) - exportToVcf(tw, out, sampleName = "my_model") + writeGwasVcf(tw, out, sampleName = "my_model") lines <- readLines(out) header <- str_split( lines[str_starts(lines, "#CHROM")][[1L]], @@ -1324,7 +1276,7 @@ test_that("exportToVcf names TWAS samples, or refuses a mismatched count", { )[[1L]] expect_identical(header[[10L]], "my_model") expect_error( - exportToVcf(tw, out, sampleName = c("a", "b")), + writeGwasVcf(tw, out, sampleName = c("a", "b")), "one name per model" ) }) @@ -1336,13 +1288,13 @@ test_that("a TWAS-weight VCF unions the variants its models disagree on", { context = "brain", trait = "g1", method = "enet", - entry = list(twasWeightsRow( + entry = list(TwasWeightsRow( variantIds = c("chr1:300:A:G", "chr1:400:A:G"), weights = c(0.7, 0.8) )) ) out <- withr::local_tempfile(fileext = ".vcf") - exportToVcf(list(a, b), out) + writeGwasVcf(list(a, b), out) body <- keep(readLines(out), str_starts, "chr1") # union of {100,200,300} and {300,400} expect_length(body, 4L) @@ -1388,14 +1340,14 @@ test_that(".pubJoinMarginals gives an NA row where no marginal exists", { }) # ============================================================================= -# exportToBed: variant-level column completeness +# writeBed: variant-level column completeness # ============================================================================= test_that("the top-loci schema identifies the fit each row came from", { data(qtlFineMappingExample) data(mvsusieFineMappingExample) out <- withr::local_tempfile(fileext = ".bed") - exportToBed( + writeBed( list(qtlFineMappingExample, mvsusieFineMappingExample), out, signalCutoff = 0 @@ -1444,8 +1396,8 @@ test_that("columns = 'all' appends the rest of the source view", { data(qtlFineMappingExample) base <- withr::local_tempfile(fileext = ".bed") full <- withr::local_tempfile(fileext = ".bed") - exportToBed(qtlFineMappingExample, base, signalCutoff = 0) - exportToBed(qtlFineMappingExample, full, signalCutoff = 0, columns = "all") + writeBed(qtlFineMappingExample, base, signalCutoff = 0) + writeBed(qtlFineMappingExample, full, signalCutoff = 0, columns = "all") baseCols <- names(utils::read.delim(base, check.names = FALSE)) fullCols <- names(utils::read.delim(full, check.names = FALSE)) # additive: the published columns keep their place, the rest follow @@ -1464,7 +1416,7 @@ test_that("columns = 'all' appends the rest of the source view", { test_that("columns takes an explicit set, and refuses a bad one", { data(qtlFineMappingExample) out <- withr::local_tempfile(fileext = ".bed") - exportToBed( + writeBed( qtlFineMappingExample, out, signalCutoff = 0, @@ -1473,7 +1425,7 @@ test_that("columns takes an explicit set, and refuses a bad one", { cols <- names(utils::read.delim(out, check.names = FALSE)) expect_identical(cols[[length(cols)]], "grange_start") expect_error( - exportToBed( + writeBed( qtlFineMappingExample, out, signalCutoff = 0, @@ -1482,7 +1434,7 @@ test_that("columns takes an explicit set, and refuses a bad one", { "does not carry" ) expect_error( - exportToBed( + writeBed( qtlFineMappingExample, out, signalCutoff = 0, @@ -1492,11 +1444,13 @@ test_that("columns takes an explicit set, and refuses a bad one", { ) }) -test_that("the fsusie schema carries its study and takes columns = 'all'", { +test_that("the fsusie schema: both resolutions, its study, columns = 'all'", { data(fsusieFineMappingExample) out <- withr::local_tempfile(fileext = ".bed") - exportToBed(fsusieFineMappingExample, out, schema = "fsusie") + writeBed(fsusieFineMappingExample, out, schema = "fsusie") tbl <- utils::read.delim(out, check.names = FALSE) + # MAF is absent from this fixture, so the file carries the schema minus + # the columns that had nothing to say. expect_identical( names(tbl), setdiff( @@ -1507,10 +1461,13 @@ test_that("the fsusie schema carries its study and takes columns = 'all'", { "AF" ) ) + # Both resolutions by default. + expect_true(all(.FMB_FSUSIE_WAVELET_COLUMNS %in% names(tbl))) + expect_true(all(.FMB_FSUSIE_TRAIT_COLUMNS %in% names(tbl))) expect_false(anyNA(tbl$study)) full <- withr::local_tempfile(fileext = ".bed") - exportToBed( + writeBed( fsusieFineMappingExample, full, schema = "fsusie", @@ -1523,7 +1480,7 @@ test_that("the fsusie schema carries its study and takes columns = 'all'", { expect_true(all(names(tbl) %in% fullCols)) # an explicitly named column is written even though it is empty here named <- withr::local_tempfile(fileext = ".bed") - exportToBed( + writeBed( fsusieFineMappingExample, named, schema = "fsusie", @@ -1537,35 +1494,14 @@ test_that("a TwasWeights element has no variant columns left to add", { data(twasWeightsExample) base <- withr::local_tempfile(fileext = ".bed") full <- withr::local_tempfile(fileext = ".bed") - exportToBed(twasWeightsExample, base) - exportToBed(twasWeightsExample, full, columns = "all") + writeBed(twasWeightsExample, base) + writeBed(twasWeightsExample, full, columns = "all") expect_identical( names(utils::read.delim(full, check.names = FALSE)), names(utils::read.delim(base, check.names = FALSE)) ) }) -test_that("the fsusie schema writes both resolutions by default", { - data(fsusieFineMappingExample) - out <- withr::local_tempfile(fileext = ".bed") - exportToBed(fsusieFineMappingExample, out, schema = "fsusie") - cols <- names(utils::read.delim(out, check.names = FALSE)) - # MAF is absent from this fixture, so the file carries the schema minus - # the columns that had nothing to say. - expect_identical( - cols, - setdiff( - .fmbFsusieColumns( - c("wavelet", "trait"), - c("CS95", "PUR95") - ), - "AF" - ) - ) - expect_true(all(.FMB_FSUSIE_WAVELET_COLUMNS %in% cols)) - expect_true(all(.FMB_FSUSIE_TRAIT_COLUMNS %in% cols)) -}) - test_that("fsusie `levels` drops one resolution, leaving a strict subset", { data(fsusieFineMappingExample) read <- function(lv) { @@ -1573,7 +1509,7 @@ test_that("fsusie `levels` drops one resolution, leaving a strict subset", { fileext = ".bed", .local_envir = parent.frame() ) - exportToBed( + writeBed( fsusieFineMappingExample, out, schema = "fsusie", @@ -1609,7 +1545,7 @@ test_that("fsusie `levels` drops one resolution, leaving a strict subset", { expect_identical(wav$grid_effects, both$grid_effects) expect_error( - exportToBed( + writeBed( fsusieFineMappingExample, withr::local_tempfile(), schema = "fsusie", @@ -1619,18 +1555,6 @@ test_that("fsusie `levels` drops one resolution, leaving a strict subset", { ) }) -test_that("the weight VCF header carries no cross-validation metrics", { - # CV describes held-out folds; a published file has no data-secure way to - # say anything fold-level, so the header stops at identity + counts. - data(twasWeightsExample) - out <- withr::local_tempfile(fileext = ".vcf") - exportToVcf(twasWeightsExample, out) - sampleLines <- keep(readLines(out), str_starts, "##SAMPLE=") - expect_length(sampleLines, 9L) - expect_true(all(str_detect(sampleLines, "TotalVariants="))) - expect_false(any(str_detect(sampleLines, "rsq=|corr=|pval=|CvRegions="))) -}) - # --------------------------------------------------------------------------- # EZ on the GwasSumStats path # @@ -1642,42 +1566,17 @@ test_that("the weight VCF header carries no cross-validation metrics", { # about where ES and SE came from. # --------------------------------------------------------------------------- -# @noRd -.ezss <- function(supplied) { - gr <- GenomicRanges::GRanges( - "chr1", - IRanges::IRanges(c(100L, 200L), width = 1L) - ) - cols <- S4Vectors::DataFrame( - SNP = c("chr1:100:A:G", "chr1:200:C:T"), - A1 = c("G", "T"), - A2 = c("A", "C"), - Z = c(2.5, -1.2), - N = c(1000L, 1000L), - BETA = c(0.25, -0.12), - SE = c(0.1, 0.1) - ) - if (!is.null(supplied)) { - cols$z_supplied <- rep(supplied, 2L) - } - GwasSumStats( - studyName = "s", - entry = list(S4Vectors::`mcols<-`(gr, value = cols)), - genome = "hg38" - ) -} - # @noRd .ezFields <- function(x, name) { skip_if_not_installed("VariantAnnotation") out <- withr::local_tempfile(fileext = ".vcf") - exportToVcf(x, out) + writeGwasVcf(x, out) lines <- readLines(out) record <- keep(lines, str_starts, "chr1")[[1L]] str_split(str_split(record, "\t")[[1L]][[9L]], ":")[[1L]] } -test_that("exportToVcf(GwasSumStats) publishes EZ only for a supplied z", { +test_that("writeGwasVcf(GwasSumStats) publishes EZ only for a supplied z", { expect_true(is_in("EZ", .ezFields(.ezss(TRUE)))) expect_false(is_in("EZ", .ezFields(.ezss(FALSE)))) # A collection built by hand that never recorded the provenance is @@ -1689,50 +1588,17 @@ test_that("exportToVcf(GwasSumStats) publishes EZ only for a supplied z", { test_that("a supplied z survives the GwasSumStats VCF round trip", { skip_if_not_installed("VariantAnnotation") out <- withr::local_tempfile(fileext = ".vcf") - exportToVcf(.ezss(TRUE), out) + writeGwasVcf(.ezss(TRUE), out) back <- .readSumStatsVcf(out, NULL, NULL, NULL, "x") expect_equal(back$Z, c(2.5, -1.2)) expect_true(all(back$z_supplied)) # The derived case comes back derived, so a re-export does not promote it. - exportToVcf(.ezss(FALSE), out) + writeGwasVcf(.ezss(FALSE), out) derived <- .readSumStatsVcf(out, NULL, NULL, NULL, "x") expect_false(any(derived$z_supplied)) expect_equal(derived$Z, c(2.5, -1.2)) }) -# Drop the ES and SE subfields from one record (or leave a header line as-is). -# @noRd -.ezDropEsSe <- function(line) { - if (!str_starts(line, "chr1")) { - return(line) - } - fields <- str_split(line, "\t")[[1L]] - keys <- str_split(fields[[9L]], ":")[[1L]] - values <- str_split(fields[[10L]], ":")[[1L]] - keep <- !is_in(keys, c("ES", "SE")) - fields[[9L]] <- str_flatten(keys[keep], ":") - fields[[10L]] <- str_flatten(values[keep], ":") - str_flatten(fields, "\t") -} - -test_that("a z-only GWAS-VCF reads without ES and SE", { - # Reading EZ was missing altogether, so a file whose ES/SE were derived - # upstream from z either lost that fact or, with no ES/SE at all, was - # refused outright. - skip_if_not_installed("VariantAnnotation") - out <- withr::local_tempfile(fileext = ".vcf") - exportToVcf(.ezss(TRUE), out) - lines <- readLines(out) - lines <- lines[!str_detect(lines, "^##FORMAT= helper -> solver. +# through the helper hop. This is the same pattern as the BGLR probIn test in +# test_rrBglr.R, applied to every method. Together with the dispatch +# verification tests in test_rrDispatch.R, this covers the parameter-passing +# chain wrapper -> helper -> solver. # # Two patterns are used: # - For solvers whose results are consumed via direct field access (BGLR, @@ -15,7 +15,7 @@ context("regularized_regression - end-to-end solver verification") # ncvreg, L0Learn), faking the result is awkward, so the mock captures # the parameter and then raises a sentinel error that the test catches. -test_that("glmnetWeights forwards alpha to glmnet::cv.glmnet", { +test_that("lassoWeights / enetWeights forward alpha to glmnet::cv.glmnet", { skip_if_not_installed("glmnet") set.seed(42) X <- matrix(rnorm(50), nrow = 10) @@ -35,7 +35,7 @@ test_that("glmnetWeights forwards alpha to glmnet::cv.glmnet", { expect_equal(captured$alpha, 0.5) }) -test_that("ncvreg_weights forwards penalty to ncvreg::cv.ncvreg", { +test_that("scadWeights / mcpWeights forward penalty and nfolds to cv.ncvreg", { skip_if_not_installed("ncvreg") set.seed(42) X <- matrix(rnorm(50), nrow = 10) diff --git a/tests/testthat/test_rrGlmnet.R b/tests/testthat/test_rrGlmnet.R index 75650e1d..4b90324e 100644 --- a/tests/testthat/test_rrGlmnet.R +++ b/tests/testthat/test_rrGlmnet.R @@ -24,17 +24,6 @@ test_that("enetWeights computes elastic net weights", { expect_equal(nrow(result), p) }) -test_that("lassoWeights computes LASSO weights", { - skip_if_not_installed("glmnet") - set.seed(42) - n <- 50 - p <- 10 - X <- matrix(rnorm(n * p), nrow = n) - y <- X[, 1] * 0.5 + rnorm(n) - result <- lassoWeights(X, y) - expect_equal(nrow(result), p) -}) - test_that("glmnetWeights handles zero-variance columns", { skip_if_not_installed("glmnet") set.seed(42) @@ -47,6 +36,7 @@ test_that("glmnetWeights handles zero-variance columns", { result <- glmnetWeights(X, y, alpha = 1), "glmnetWeights: dropping 1 zero-variance column" ) + expect_equal(nrow(result), p) expect_equal(result[3, 1], 0) }) @@ -83,13 +73,38 @@ test_that("glmnetWeights handles NA-producing columns gracefully", { expect_equal(result[4, 1], 0) }) -test_that("glmnetWeights with alpha = 0 (ridge regression) works", { +test_that("enetWeights takes its mixing, and ridgeWeights fixes it at 0", { skip_if_not_installed("glmnet") set.seed(42) - n <- 50 - p <- 10 + n <- 60 + p <- 8 X <- matrix(rnorm(n * p), nrow = n) y <- X[, 1] * 0.5 + rnorm(n) - result <- glmnetWeights(X, y, alpha = 0) - expect_equal(nrow(result), p) + # cv.glmnet draws its folds, so each pair is fitted from the same seed. + set.seed(11) + mixed <- enetWeights(X, y, alpha = 0.3) + set.seed(11) + expect_equal(mixed, glmnetWeights(X, y, 0.3)) + set.seed(11) + ridge <- ridgeWeights(X, y) + set.seed(11) + expect_equal(ridge, glmnetWeights(X, y, 0)) + expect_equal(nrow(ridge), p) + # A ridge keeps every variant. + expect_true(all(ridge != 0)) + expect_error(enetWeights(X, y, alpha = 2), "alpha.*<= 1") +}) + +test_that("glmnetWeights produces non-zero weights for correlated data", { + skip_if_not_installed("glmnet") + set.seed(42) + n <- 100 + p <- 10 + X <- matrix(rnorm(n * p), n, p) + beta_true <- c(3, -2, rep(0, p - 2)) + y <- X %*% beta_true + rnorm(n) + + w <- glmnetWeights(X, y, alpha = 0.5) + expect_length(w, p) + expect_true(any(w != 0)) }) diff --git a/tests/testthat/test_rrL0learn.R b/tests/testthat/test_rrL0learn.R index a48a83d6..f138b061 100644 --- a/tests/testthat/test_rrL0learn.R +++ b/tests/testthat/test_rrL0learn.R @@ -1,32 +1,6 @@ context("regularized_regression - l0learn") # ---- l0learnWeights ---- -test_that("l0learnWeights computes weights with default L0 penalty", { - skip_if_not_installed("L0Learn") - set.seed(42) - n <- 50 - p <- 10 - X <- matrix(rnorm(n * p), nrow = n) - y <- X[, 1] * 0.5 + rnorm(n) - result <- l0learnWeights(X, y) - expect_equal(nrow(result), p) - expect_equal(ncol(result), 1) - expect_true(all(is.finite(result))) -}) - -test_that("l0learnWeights computes weights with L0L2 penalty", { - skip_if_not_installed("L0Learn") - set.seed(42) - n <- 50 - p <- 10 - X <- matrix(rnorm(n * p), nrow = n) - y <- X[, 1] * 0.5 + rnorm(n) - result <- l0learnWeights(X, y, penalty = "L0L2") - expect_equal(nrow(result), p) - expect_equal(ncol(result), 1) - expect_true(all(is.finite(result))) -}) - test_that("l0learnWeights warns and zero-pads when X has zero-variance columns", { skip_if_not_installed("L0Learn") set.seed(42) @@ -50,7 +24,25 @@ test_that("l0learnWeights passes nGamma through to L0Learn.cvfit", { p <- 10 X <- matrix(rnorm(n * p), nrow = n) y <- X[, 1] * 0.5 + rnorm(n) - # nGamma = 0 is invalid; the underlying function should reject it, - # proving the argument reached L0Learn.cvfit. - expect_error(l0learnWeights(X, y, penalty = "L0L2", nGamma = 0)) + # nGamma is not a formal of l0learnWeights; it reaches the engine through + # methodArgs. + captured <- new.env(parent = emptyenv()) + local_mocked_bindings( + L0Learn.cvfit = function(...) { + captured$args <- list(...) + stop("STOP_AFTER_CAPTURE") + }, + .package = "L0Learn" + ) + expect_error( + l0learnWeights( + X, + y, + penalty = "L0L2", + methodArgs = L0learnOptions(nGamma = 3) + ), + "STOP_AFTER_CAPTURE" + ) + expect_equal(captured$args$nGamma, 3) + expect_equal(captured$args$penalty, "L0L2") }) diff --git a/tests/testthat/test_rrLassosum.R b/tests/testthat/test_rrLassosum.R index 9e2be53b..ce130481 100644 --- a/tests/testthat/test_rrLassosum.R +++ b/tests/testthat/test_rrLassosum.R @@ -39,6 +39,7 @@ test_that("lassosumRss runs successfully with valid input", { expect_true(all(is.finite(result$betaEst))) expect_equal(nrow(result$beta), p) expect_equal(ncol(result$beta), 20) + expect_length(result$conv, length(result$lambda)) }) test_that("lassosumRss with large lambda gives all-zero betas", { @@ -65,7 +66,7 @@ test_that("lassosumRssWeights calls lassosumRss and returns betaEst", { stat <- list(b = bhat, n = rep(n, p), variantNames = .rrwIds(p)) expected <- seq_len(p) * 0.02 local_mocked_bindings( - .lassosumRssPath = function(bhat, ld, n, ...) { + .penalizedRssPath = function(bhat, ld, n, ...) { list( beta = cbind(rep(0, length(bhat)), expected), lambda = c(0.05, 0.01), @@ -97,7 +98,7 @@ test_that("lassosumRssWeights clamps correlation input before scaling", { stat <- list(b = bhat, n = rep(n, p), variantNames = .rrwIds(p)) captured <- NULL local_mocked_bindings( - .lassosumRssPath = function(bhat, ld, n, ...) { + .penalizedRssPath = function(bhat, ld, n, ...) { captured <<- bhat list( beta = matrix(0, nrow = length(bhat), ncol = 2), diff --git a/tests/testthat/test_rrMrash.R b/tests/testthat/test_rrMrash.R index 14a59325..538b4cc8 100644 --- a/tests/testthat/test_rrMrash.R +++ b/tests/testthat/test_rrMrash.R @@ -1,21 +1,6 @@ context("regularized_regression - mrash") # ---- mrashWeights ---- -test_that("mrashWeights calls lassoWeights as default beta.init", { - skip_if_not_installed("glmnet") - set.seed(42) - n <- 50 - p <- 10 - X <- matrix(rnorm(n * p), nrow = n) - y <- X[, 1] * 0.5 + rnorm(n) - local_mocked_bindings( - lassoWeights = function(X, y) rep(0.01, ncol(X)) - ) - result <- mrashWeights(X, y) - expect_true(is.numeric(result)) - expect_equal(length(result), p) -}) - test_that("mrashWeights subsets a user-supplied beta.init of length ncol(X) by keep", { skip_if_not_installed("glmnet") set.seed(42) diff --git a/tests/testthat/test_rrNcvreg.R b/tests/testthat/test_rrNcvreg.R index 292a7743..49131c49 100644 --- a/tests/testthat/test_rrNcvreg.R +++ b/tests/testthat/test_rrNcvreg.R @@ -30,19 +30,6 @@ test_that("ncvregWeights warns and zero-pads when X has zero-variance columns", expect_equal(result[5, 1], 0) }) -test_that("scadWeights computes weights and dispatches to ncvregWeights", { - skip_if_not_installed("ncvreg") - set.seed(42) - n <- 50 - p <- 10 - X <- matrix(rnorm(n * p), nrow = n) - y <- X[, 1] * 0.5 + rnorm(n) - result <- scadWeights(X, y) - expect_equal(nrow(result), p) - expect_equal(ncol(result), 1) - expect_true(all(is.finite(result))) -}) - test_that("mcpWeights computes weights and dispatches to ncvregWeights", { skip_if_not_installed("ncvreg") set.seed(42) @@ -55,22 +42,3 @@ test_that("mcpWeights computes weights and dispatches to ncvregWeights", { expect_equal(ncol(result), 1) expect_true(all(is.finite(result))) }) - -test_that("scadWeights passes nfolds through to cv.ncvreg", { - skip_if_not_installed("ncvreg") - set.seed(42) - n <- 50 - p <- 10 - X <- matrix(rnorm(n * p), nrow = n) - y <- X[, 1] * 0.5 + rnorm(n) - captured <- new.env(parent = emptyenv()) - local_mocked_bindings( - cv.ncvreg = function(X, y, penalty, nfolds = 5, ...) { - captured$nfolds <- nfolds - stop("STOP_AFTER_CAPTURE") - }, - .package = "ncvreg" - ) - expect_error(scadWeights(X, y, nfolds = 7), "STOP_AFTER_CAPTURE") - expect_equal(captured$nfolds, 7) -}) diff --git a/tests/testthat/test_rrPenalizedRss.R b/tests/testthat/test_rrPenalizedRss.R index 65dce373..45c1b343 100644 --- a/tests/testthat/test_rrPenalizedRss.R +++ b/tests/testthat/test_rrPenalizedRss.R @@ -28,34 +28,21 @@ test_that("penalizedRss errors on mismatched bhat and R dimensions", { ) }) -test_that("penalizedRss with large lambda gives all-zero betas (MCP)", { +test_that("penalizedRss with large lambda gives all-zero betas (MCP, SCAD)", { set.seed(42) p <- 10 n <- 100 bhat <- rnorm(p, sd = 0.1) - result <- penalizedRss( - bhat = bhat, - R = diag(p), - n = n, - penalty = "MCP", - lambda = c(100) - ) - expect_true(all(result$betaEst == 0)) -}) - -test_that("penalizedRss with large lambda gives all-zero betas (SCAD)", { - set.seed(42) - p <- 10 - n <- 100 - bhat <- rnorm(p, sd = 0.1) - result <- penalizedRss( - bhat = bhat, - R = diag(p), - n = n, - penalty = "SCAD", - lambda = c(100) - ) - expect_true(all(result$betaEst == 0)) + for (pen in c("MCP", "SCAD")) { + result <- penalizedRss( + bhat = bhat, + R = diag(p), + n = n, + penalty = pen, + lambda = c(100) + ) + expect_true(all(result$betaEst == 0), info = pen) + } }) test_that("penalizedRss with large lambda0 gives all-zero betas (L0)", { @@ -104,6 +91,7 @@ test_that("penalizedRss runs with SCAD and returns correct structure", { expect_type(result, "list") expect_equal(length(result$betaEst), p) expect_true(all(is.finite(result$betaEst))) + expect_equal(nrow(result$beta), p) }) test_that("penalizedRss runs with L0 and returns correct structure", { @@ -123,50 +111,12 @@ test_that("penalizedRss runs with L0 and returns correct structure", { expect_type(result, "list") expect_equal(length(result$betaEst), p) expect_true(all(is.finite(result$betaEst))) -}) - -test_that("penalizedRss LASSO matches lassosumRss on identity LD", { - set.seed(42) - p <- 10 - n <- 200 - bhat <- rnorm(p, sd = 0.2) - R <- diag(p) - lam <- exp(seq(log(0.001), log(0.1), length.out = 5)) - res_lasso <- penalizedRss( - bhat = bhat, - R = R, - n = n, - penalty = "lasso", - lambda = lam - ) - res_lassosum <- lassosumRss(bhat = bhat, R = R, n = n, lambda = lam) - expect_equal(res_lasso$beta, res_lassosum$beta, tolerance = 1e-4) + expect_equal(nrow(result$beta), p) }) # ---- Signal recovery on simulated summary statistics ---- -test_that("penalizedRss MCP recovers signal direction", { - set.seed(2024) - n <- 500 - p <- 20 - X <- matrix(rbinom(n * p, 2, 0.3), nrow = n) - beta_true <- rep(0, p) - beta_true[c(3, 10, 15)] <- c(0.4, -0.3, 0.2) - y <- as.numeric(X %*% beta_true) + rnorm(n) - bhat <- as.vector(cor(y, X)) - R <- cor(X) - stat <- list(b = bhat, n = rep(n, p), variantNames = .rrwIds(p)) - w <- mcpRssWeights( - stat = stat, - ldReference = .rrwLdMatrix(R), - s = c(0.5, 0.9) - ) - expect_equal(length(w), p) - expect_true(all(is.finite(w))) - expect_gt(cor(w, beta_true), 0.4) -}) - -test_that("penalizedRss SCAD recovers signal direction", { +test_that("mcpRssWeights / scadRssWeights recover the signal direction", { set.seed(2024) n <- 500 p <- 20 @@ -177,14 +127,17 @@ test_that("penalizedRss SCAD recovers signal direction", { bhat <- as.vector(cor(y, X)) R <- cor(X) stat <- list(b = bhat, n = rep(n, p), variantNames = .rrwIds(p)) - w <- scadRssWeights( - stat = stat, - ldReference = .rrwLdMatrix(R), - s = c(0.5, 0.9) - ) - expect_equal(length(w), p) - expect_true(all(is.finite(w))) - expect_gt(cor(w, beta_true), 0.4) + fns <- list(MCP = mcpRssWeights, SCAD = scadRssWeights) + for (pen in names(fns)) { + w <- fns[[pen]]( + stat = stat, + ldReference = .rrwLdMatrix(R), + s = c(0.5, 0.9) + ) + expect_equal(length(w), p, info = pen) + expect_true(all(is.finite(w)), info = pen) + expect_gt(cor(w, beta_true), 0.4, label = str_c(pen, " correlation")) + } }) test_that("penalizedRss L0 recovers signal direction", { @@ -212,34 +165,22 @@ test_that("penalizedRss L0 recovers signal direction", { # ---- Weight wrapper structure ---- -test_that("scadRssWeights returns correct-length vector with attributes", { - set.seed(42) - p <- 10 - n <- 100 - bhat <- rnorm(p, sd = 0.1) - R <- diag(p) - stat <- list(b = bhat, n = rep(n, p), variantNames = .rrwIds(p)) - w <- scadRssWeights(stat = stat, ldReference = .rrwLdMatrix(R), s = 0.5) - expect_equal(length(w), p) - expect_true(is.numeric(w)) - sel <- attr(w, "penalized_rss_selection") - expect_true(!is.null(sel)) - expect_equal(unname(sel["penalty"]), "SCAD") -}) - -test_that("mcpRssWeights returns correct-length vector with attributes", { +test_that("scadRssWeights / mcpRssWeights return p weights with attributes", { set.seed(42) p <- 10 n <- 100 bhat <- rnorm(p, sd = 0.1) R <- diag(p) stat <- list(b = bhat, n = rep(n, p), variantNames = .rrwIds(p)) - w <- mcpRssWeights(stat = stat, ldReference = .rrwLdMatrix(R), s = 0.5) - expect_equal(length(w), p) - expect_true(is.numeric(w)) - sel <- attr(w, "penalized_rss_selection") - expect_true(!is.null(sel)) - expect_equal(unname(sel["penalty"]), "MCP") + fns <- list(SCAD = scadRssWeights, MCP = mcpRssWeights) + for (pen in names(fns)) { + w <- fns[[pen]](stat = stat, ldReference = .rrwLdMatrix(R), s = 0.5) + expect_equal(length(w), p, info = pen) + expect_true(is.numeric(w), info = pen) + sel <- attr(w, "penalized_rss_selection") + expect_true(!is.null(sel), info = pen) + expect_equal(unname(sel["penalty"]), pen, info = pen) + } }) test_that("l0learnRssWeights returns correct-length vector with attributes", { @@ -262,3 +203,328 @@ test_that("l0learnRssWeights returns correct-length vector with attributes", { expect_true(!is.null(sel)) expect_equal(unname(sel["penalty"]), "L0") }) + +# ---- Elastic-net mixing (alpha) ---------------------------------------------- + +# `v` centered and scaled to unit variance with the 1/n denominator. +.prs_scaleN <- function(v) { + v <- v - mean(v) + v / sqrt(mean(v^2)) +} + +# Genotypes and a phenotype standardized with the 1/n denominator, so that +# R = X'X / n is their LD and z = X'y / n the marginal effects: the RSS +# objective is then exactly twice glmnet's gaussian one. +.prs_standardized <- function(n = 200L, p = 15L, seed = 7L) { + set.seed(seed) + X <- matrix(rbinom(n * p, 2, 0.3), n, p) + beta <- replace(numeric(p), c(2, 4, 5), c(0.5, -0.4, 0.3)) + y <- as.numeric(X %*% beta) + rnorm(n) + Xs <- apply(X, 2, .prs_scaleN) + ys <- .prs_scaleN(y) + list( + X = Xs, + y = ys, + R = crossprod(Xs) / n, + z = as.numeric(crossprod(Xs, ys)) / n, + n = n + ) +} + +# MCP and SCAD at threshold `l` and concavity `g`, for |beta| = `ab`. +.prs_mcp <- function(ab, l, g) { + inner <- ab <= g * l + inner * (l * ab - ab^2 / (2 * g)) + (!inner) * (g * l^2 / 2) +} + +.prs_scad <- function(ab, l, g) { + lin <- ab <= l + mid <- !lin & ab <= g * l + flat <- !lin & !mid + lin * + l * + ab + + mid * (2 * g * l * ab - ab^2 - l^2) / (2 * (g - 1)) + + flat * l^2 * (g + 1) / 2 +} + +# The penalty penalizedRss() minimizes, written out: +# 2 P(beta; lambda * alpha) + lambda * (1 - alpha) * beta'beta. +.prs_penalty <- function(beta, lambda, alpha, penalty, gamma) { + l1 <- lambda * alpha + ab <- abs(beta) + p1 <- switch( + penalty, + lasso = l1 * ab, + MCP = .prs_mcp(ab, l1, gamma), + SCAD = .prs_scad(ab, l1, gamma) + ) + 2 * sum(p1) + lambda * (1 - alpha) * sum(beta^2) +} + +# The derivative of the L1-type part of the penalty at |beta| = `ab` > 0. +.prs_dpen <- function(ab, l1, penalty, gamma) { + switch( + penalty, + lasso = rep(l1, length(ab)), + MCP = pmax(l1 - ab / gamma, 0), + SCAD = (ab <= l1) * + l1 + + (ab > l1) * pmax(gamma * l1 - ab, 0) / (gamma - 1) + ) +} + +test_that("penalizedRss reproduces glmnet's elastic-net path on exact LD", { + skip_if_not_installed("glmnet") + d <- .prs_standardized() + lam <- c(0.1, 0.05, 0.02, 0.01) + for (a in c(1, 0.5, 0.2)) { + rss <- penalizedRss( + bhat = d$z * sqrt(d$n), + R = d$R, + n = d$n, + penalty = "lasso", + alpha = a, + lambda = lam, + thr = 1e-12, + maxiter = 1e5 + ) + gl <- glmnet::glmnet( + d$X, + d$y, + alpha = a, + lambda = lam, + standardize = FALSE, + intercept = FALSE, + thresh = 1e-14 + ) + expect_equal( + rss$beta, + unname(as.matrix(gl$beta)), + tolerance = 1e-6, + label = str_c("alpha = ", a) + ) + } +}) + +test_that("penalizedRss at alpha = 0 is ridge regression", { + d <- .prs_standardized() + p <- ncol(d$R) + rss <- penalizedRss( + bhat = d$z * sqrt(d$n), + R = d$R, + n = d$n, + penalty = "lasso", + alpha = 0, + lambda = c(1, 0.3), + thr = 1e-13, + maxiter = 1e5 + ) + expect_equal( + rss$beta[, 1], + as.numeric(solve(d$R + diag(p), d$z)), + tolerance = 1e-8 + ) + expect_equal( + rss$beta[, 2], + as.numeric(solve(d$R + 0.3 * diag(p), d$z)), + tolerance = 1e-8 + ) +}) + +test_that("fbeta is the objective the operators minimize, at any alpha", { + d <- .prs_standardized() + lam <- c(0.08, 0.03, 0.01) + for (pen in c("lasso", "MCP", "SCAD")) { + gamma <- if (pen == "SCAD") 3.7 else 3 + res <- penalizedRss( + bhat = d$z * sqrt(d$n), + R = d$R, + n = d$n, + penalty = pen, + alpha = 0.5, + lambda = lam, + gamma = gamma + ) + for (k in seq_along(lam)) { + b <- res$beta[, k] + objective <- sum(b * (d$R %*% b)) - + 2 * sum(b * d$z) + + .prs_penalty(b, lam[[k]], 0.5, pen, gamma) + expect_equal( + res$fbeta[[k]], + objective, + tolerance = 1e-10, + label = str_c(pen, " at lambda ", lam[[k]]) + ) + } + } +}) + +test_that("the updates are exact when the LD diagonal is not 1", { + # The curvature of one coordinate is v + l2. ncvreg writes it v (1 + l2), + # the same only at v = 1, so with a ridge term and a diagonal of 2 its + # fixed point is not the optimum. + d <- .prs_standardized() + R2 <- 2 * d$R + lam <- 0.03 + for (pen in c("lasso", "MCP", "SCAD")) { + gamma <- if (pen == "SCAD") 3.7 else 3 + b <- penalizedRss( + bhat = d$z * sqrt(d$n), + R = R2, + n = d$n, + penalty = pen, + alpha = 0.5, + lambda = lam, + gamma = gamma, + thr = 1e-13, + maxiter = 1e5 + )$beta[, 1] + l1 <- lam * 0.5 + # Half the gradient of the smooth part and the ridge term. + grad <- as.numeric(R2 %*% b) - d$z + lam * 0.5 * b + nz <- b != 0 + expect_gt(sum(nz), 0L) + stationary <- grad[nz] + + sign(b[nz]) * .prs_dpen(abs(b[nz]), l1, pen, gamma) + expect_lt(max(abs(stationary)), 1e-8, label = pen) + expect_true(all(abs(grad[!nz]) <= l1 + 1e-9), label = pen) + } +}) + +test_that("the default lambda path is scaled by the L1 share", { + d <- .prs_standardized(p = 6L) + bhat <- d$z * sqrt(d$n) + base <- exp(seq(log(1e-4), log(0.1), length.out = 20)) + expect_equal(penalizedRss(bhat, d$R, d$n)$lambda, base) + expect_equal(penalizedRss(bhat, d$R, d$n, alpha = 0.5)$lambda, base / 0.5) + expect_equal(penalizedRss(bhat, d$R, d$n, alpha = 0)$lambda, base / 1e-3) + # A path the caller gives is used as given. + expect_equal( + penalizedRss(bhat, d$R, d$n, alpha = 0.5, lambda = c(0.2, 0.1))$lambda, + c(0.2, 0.1) + ) +}) + +test_that("alpha is a share in [0, 1], above 0 for MCP and SCAD", { + d <- .prs_standardized(p = 5L) + bhat <- d$z * sqrt(d$n) + expect_error(penalizedRss(bhat, d$R, d$n, alpha = 1.5), "alpha.*<= 1") + expect_error(penalizedRss(bhat, d$R, d$n, alpha = -0.1), "alpha.*>= 0") + expect_error( + penalizedRss(bhat, d$R, d$n, penalty = "MCP", alpha = 0), + "above 0 for MCP" + ) + expect_error( + penalizedRss(bhat, d$R, d$n, penalty = "SCAD", alpha = 0), + "above 0 for SCAD" + ) + expect_error(penalizedRss(bhat, d$R, d$n, maxSwaps = -1), "maxSwaps") +}) + +test_that("lassosumRss is penalizedRss's lasso at alpha = 1, bit for bit", { + d <- .prs_standardized() + bhat <- d$z * sqrt(d$n) + lassosum <- lassosumRss(bhat, d$R, d$n) + lasso <- penalizedRss(bhat, d$R, d$n, penalty = "lasso") + expect_identical(lassosum$beta, lasso$beta) + expect_identical(lassosum$conv, lasso$conv) + expect_identical(lassosum$fbeta, lasso$fbeta) +}) + +# ---- enetRssWeights / ridgeRssWeights ---------------------------------------- + +# Twelve variants, two of them causal, as summary statistics with their LD. +.prs_weightsInput <- function() { + set.seed(42) + p <- 12 + n <- 300 + X <- matrix(rbinom(n * p, 2, 0.3), n, p) + y <- as.numeric(X[, c(2, 9)] %*% c(0.4, -0.3)) + rnorm(n) + list( + stat = list( + b = as.vector(cor(y, X)), + n = rep(n, p), + variantNames = .rrwIds(p) + ), + ld = .rrwLdMatrix(cor(X)) + ) +} + +test_that("enetRssWeights mixes at alpha and is lassosum at alpha = 1", { + f <- .prs_weightsInput() + w <- enetRssWeights(f$stat, f$ld) + expect_length(w, 12L) + sel <- attr(w, "penalized_rss_selection") + expect_equal(unname(sel[c("penalty", "alpha")]), c("lasso", "0.5")) + other <- enetRssWeights(f$stat, f$ld, alpha = 0.2) + expect_equal( + unname(attr(other, "penalized_rss_selection")["alpha"]), + "0.2" + ) + expect_equal( + as.numeric(enetRssWeights(f$stat, f$ld, alpha = 1)), + as.numeric(lassosumRssWeights(f$stat, f$ld)) + ) + expect_error(enetRssWeights(f$stat, f$ld, alpha = 2), "alpha.*<= 1") + # Its errors name it. + expect_error( + enetRssWeights(list(b = 1:3, n = rep(10, 3)), f$ld), + "enetRssWeights: `stat` must carry `variantNames`" + ) +}) + +test_that("ridgeRssWeights fits the alpha = 0 mixing over the ridge path", { + f <- .prs_weightsInput() + w <- ridgeRssWeights(f$stat, f$ld, fitRetention = "full") + expect_equal(unname(attr(w, "penalized_rss_selection")["alpha"]), "0") + # A ridge keeps every variant, along a path from 0.1 up. + expect_true(all(w != 0)) + fit <- attr(w, "fit") + expect_gte(min(fit$path$lambda), 0.1) + expect_equal(ncol(fit$beta), nrow(fit$path)) + expect_error( + ridgeRssWeights(list(b = 1:3, n = rep(10, 3)), f$ld), + "ridgeRssWeights: `stat` must carry `variantNames`" + ) +}) + +test_that("scadRssWeights and mcpRssWeights refuse alpha = 0 before fitting", { + f <- .prs_weightsInput() + cnd <- tryCatch(scadRssWeights(f$stat, f$ld, alpha = 0), error = identity) + expect_match(conditionMessage(cnd), "above 0 for SCAD") + # Raised up front, not from inside the shrinkage grid. + expect_null(cnd$parent) + expect_error(mcpRssWeights(f$stat, f$ld, alpha = 0), "above 0 for MCP") + expect_error(mcpRssWeights(f$stat, f$ld, alpha = 1.2), "alpha.*<= 1") +}) + +test_that("l0learnRssWeights takes its lambda path only as its own argument", { + f <- .prs_weightsInput() + expect_error( + l0learnRssWeights( + f$stat, + f$ld, + methodArgs = PenalizedRssOptions(lambda = 0.01) + ), + "lambda is supplied by pecotmr.*l0learnRssWeights' own `lambda`" + ) +}) + +test_that(".rssPenalty checks a penalty once and fills MCP / SCAD's gamma", { + pen <- pecotmr:::.rssPenalty + expect_equal(pen("SCAD")$gamma, 3.7) + expect_equal(pen("MCP")$gamma, 3) + expect_equal(pen("lasso")$gamma, 0) + expect_equal(pen("MCP", gamma = 5)$gamma, 5) + expect_equal(pen("lasso", alpha = 0)$alpha, 0) + expect_error(pen("SCAD", gamma = Inf), "gamma") + expect_error(pen("L0", lambda0 = -1), "lambda0") + expect_error(pen("L0L2", lambda2 = -1), "lambda2") + expect_error(pen("L0", maxSwaps = -1), "maxSwaps") + expect_error(pen("MCP", alpha = 0), "above 0 for MCP") + # l0learnRssWeights checks its lambda0 grid before any fit. + f <- .prs_weightsInput() + expect_error(l0learnRssWeights(f$stat, f$ld, lambda0 = -1), "lambda0") +}) diff --git a/tests/testthat/test_rrPrsCs.R b/tests/testthat/test_rrPrsCs.R index 8342a4d7..e6fcb255 100644 --- a/tests/testthat/test_rrPrsCs.R +++ b/tests/testthat/test_rrPrsCs.R @@ -29,7 +29,7 @@ test_that("prsCs errors on mismatched bhat and R dimensions", { ) }) -test_that("prsCs runs successfully with valid input", { +test_that("prsCs runs with valid input and estimates phi when none is given", { set.seed(42) p <- 10 n <- 100 @@ -52,24 +52,6 @@ test_that("prsCs runs successfully with valid input", { expect_true("betaEst" %in% names(result)) expect_equal(length(result$betaEst), p) expect_true(all(is.finite(result$betaEst))) -}) - -test_that("prsCs with phi = NULL estimates phi automatically", { - set.seed(42) - p <- 10 - n <- 100 - bhat <- rnorm(p, sd = 0.1) - R <- diag(p) - result <- prsCs( - bhat = bhat, - R = R, - n = n, - phi = NULL, - maf = rep(0.3, p), - nIter = 50, - nBurnin = 10, - thin = 2 - ) expect_true("phiEst" %in% names(result)) }) @@ -94,67 +76,33 @@ test_that("prsCs with explicit phi value", { expect_true("psiEst" %in% names(result)) }) -test_that("prsCs works without maf (maf = NULL)", { - set.seed(42) - p <- 10 - n <- 100 - bhat <- rnorm(p, sd = 0.1) - R <- diag(p) - result <- prsCs( - bhat = bhat, - R = R, - n = n, - maf = NULL, - nIter = 50, - nBurnin = 10, - thin = 2 - ) - expect_equal(length(result$betaEst), p) -}) - # ---- prsCs verbose output ---- -test_that("prsCs with verbose = TRUE produces output", { +test_that("prsCs verbose = TRUE reports its iterations and estimated phi", { set.seed(42) p <- 10 n <- 100 bhat <- rnorm(p, sd = 0.1) R <- diag(p) - # n_iter >= 100 triggers the verbose print inside the MCMC loop - result <- prsCs( - bhat = bhat, - R = R, - n = n, - maf = rep(0.3, p), - nIter = 110, - nBurnin = 10, - thin = 2, - verbose = TRUE, - seed = 42L + # n_iter >= 100 triggers the verbose print inside the MCMC loop; phi is + # left NULL, so the sampler estimates it and prints the estimate. + out <- capture.output( + result <- prsCs( + bhat = bhat, + R = R, + n = n, + maf = rep(0.3, p), + nIter = 110, + nBurnin = 10, + thin = 2, + verbose = TRUE, + seed = 42L + ) ) + expect_match(out, "Iteration +100 of 110", all = FALSE) + expect_match(out, "Estimated global shrinkage parameter", all = FALSE) expect_type(result, "list") expect_equal(length(result$betaEst), p) expect_true(all(is.finite(result$betaEst))) -}) - -test_that("prsCs verbose with phi = NULL shows estimated phi", { - set.seed(42) - p <- 10 - n <- 100 - bhat <- rnorm(p, sd = 0.1) - R <- diag(p) - result <- prsCs( - bhat = bhat, - R = R, - n = n, - phi = NULL, - maf = rep(0.3, p), - nIter = 110, - nBurnin = 10, - thin = 2, - verbose = TRUE, - seed = 42L - ) - expect_true("phiEst" %in% names(result)) expect_true(result$phiEst > 0) }) diff --git a/tests/testthat/test_rrSdpr.R b/tests/testthat/test_rrSdpr.R index 6b6ac884..3b55ca23 100644 --- a/tests/testthat/test_rrSdpr.R +++ b/tests/testthat/test_rrSdpr.R @@ -68,42 +68,30 @@ test_that("sdpr runs successfully", { expect_true(all(is.finite(result$betaEst))) }) -test_that("sdpr with per_variant_sample_size", { +test_that("sdpr runs with a per-variant sample size or an array vector", { set.seed(42) p <- 10 bhat <- rnorm(p, sd = 0.1) R <- diag(p) - result <- sdpr( - bhat = bhat, - R = R, - n = 100, - perVariantSampleSize = rep(100, p), - iter = 50, - burn = 10, - thin = 2, - verbose = FALSE + extras <- list( + perVariantSampleSize = list(perVariantSampleSize = rep(100, p)), + array = list(array = rep(1, p)) ) - expect_equal(length(result$betaEst), p) - expect_true(all(is.finite(result$betaEst))) -}) - -test_that("sdpr with valid array parameter", { - set.seed(42) - p <- 10 - bhat <- rnorm(p, sd = 0.1) - R <- diag(p) - result <- sdpr( - bhat = bhat, - R = R, - n = 100, - array = rep(1, p), - iter = 50, - burn = 10, - thin = 2, - verbose = FALSE - ) - expect_equal(length(result$betaEst), p) - expect_true(all(is.finite(result$betaEst))) + for (nm in names(extras)) { + result <- exec( + sdpr, + bhat = bhat, + R = R, + n = 100, + !!!extras[[nm]], + iter = 50, + burn = 10, + thin = 2, + verbose = FALSE + ) + expect_equal(length(result$betaEst), p, info = nm) + expect_true(all(is.finite(result$betaEst)), info = nm) + } }) # ---- sdpr signal recovery ---- @@ -122,8 +110,8 @@ test_that("sdpr recovers signal direction on simulated genotype data", { bhat = bhat, R = R, n = n, - iter = 500, - burn = 200, + iter = 200, + burn = 50, thin = 5, verbose = FALSE, seed = 42L @@ -142,48 +130,26 @@ test_that("sdpr with verbose = TRUE produces output", { bhat <- rnorm(p, sd = 0.1) R <- diag(p) # iter >= 100 triggers the verbose print inside the MCMC loop - result <- sdpr( - bhat = bhat, - R = R, - n = 100, - iter = 110, - burn = 10, - thin = 2, - verbose = TRUE, - seed = 42L + out <- capture.output( + result <- sdpr( + bhat = bhat, + R = R, + n = 100, + iter = 110, + burn = 10, + thin = 2, + verbose = TRUE, + seed = 42L + ) ) + expect_match(out, "^100 iter\\. h2:", all = FALSE) expect_type(result, "list") expect_equal(length(result$betaEst), p) expect_true(all(is.finite(result$betaEst))) }) # ---- sdpr optLlk = 2 (multi-array) ---- -test_that("sdpr runs with optLlk = 2 and mixed array values", { - set.seed(42) - p <- 10 - bhat <- rnorm(p, sd = 0.1) - R <- diag(p) - # Mixed array: some variants from array 1, some from array 2 - arr <- c(rep(1, 5), rep(2, 5)) - result <- sdpr( - bhat = bhat, - R = R, - n = 100, - perVariantSampleSize = rep(100, p), - array = arr, - optLlk = 2, - iter = 50, - burn = 10, - thin = 2, - verbose = FALSE, - seed = 42L - ) - expect_type(result, "list") - expect_equal(length(result$betaEst), p) - expect_true(all(is.finite(result$betaEst))) -}) - -test_that("sdpr optLlk = 2 with realistic genotype data", { +test_that("sdpr runs with optLlk = 2 on mixed arrays and genotype LD", { set.seed(2024) n <- 500 p <- 20 @@ -209,6 +175,7 @@ test_that("sdpr optLlk = 2 with realistic genotype data", { verbose = FALSE, seed = 42L ) + expect_type(result, "list") expect_equal(length(result$betaEst), p) expect_true(all(is.finite(result$betaEst))) }) diff --git a/tests/testthat/test_rrSignalRecovery.R b/tests/testthat/test_rrSignalRecovery.R index fca5df91..7271ad5f 100644 --- a/tests/testthat/test_rrSignalRecovery.R +++ b/tests/testthat/test_rrSignalRecovery.R @@ -38,7 +38,7 @@ test_that("scadWeights recovers signal indices on simulated data", { skip_if_not_installed("ncvreg") sim <- .simulateSparseXY() w <- scadWeights(sim$X, sim$y, nfolds = 5) - expect_equal(length(w), ncol(sim$X)) + expect_equal(dim(w), c(ncol(sim$X), 1L)) expect_true(all(is.finite(w))) # SCAD is sparse: top-3 by absolute weight should heavily overlap truth. top3 <- order(abs(w), decreasing = TRUE)[1:3] @@ -49,7 +49,7 @@ test_that("l0learnWeights with default L0 penalty recovers signal indices", { skip_if_not_installed("L0Learn") sim <- .simulateSparseXY() w <- l0learnWeights(sim$X, sim$y, penalty = "L0", nFolds = 5) - expect_equal(length(w), ncol(sim$X)) + expect_equal(dim(w), c(ncol(sim$X), 1L)) expect_true(all(is.finite(w))) top3 <- order(abs(w), decreasing = TRUE)[1:3] expect_gte(length(intersect(top3, sim$signal_idx)), 2L) @@ -59,7 +59,7 @@ test_that("l0learnWeights with L0L2 penalty recovers signal direction", { skip_if_not_installed("L0Learn") sim <- .simulateSparseXY() w <- l0learnWeights(sim$X, sim$y, penalty = "L0L2", nFolds = 5) - expect_equal(length(w), ncol(sim$X)) + expect_equal(dim(w), c(ncol(sim$X), 1L)) expect_true(all(is.finite(w))) # L0L2 selects (gamma, lambda) over a 2D grid; correlation is the safer bet. expect_gt(cor(w, sim$beta_true), 0.4) @@ -69,6 +69,7 @@ test_that("dprWeights with VB fitting recovers signal direction", { skip_if_not_installed("RcppDPR") sim <- .simulateSparseXY() w <- dprWeights(sim$X, sim$y, fittingMethod = "VB") + expect_true(is.numeric(w)) expect_equal(length(w), ncol(sim$X)) expect_true(all(is.finite(w))) expect_gt(cor(w, sim$beta_true), 0.4) diff --git a/tests/testthat/test_rrSusie.R b/tests/testthat/test_rrSusie.R deleted file mode 100644 index 118877d3..00000000 --- a/tests/testthat/test_rrSusie.R +++ /dev/null @@ -1,156 +0,0 @@ -context("regularized_regression - susie") - -# ---- susieWeights ---- -test_that("susieWeights returns zeros when no alpha/mu/X_column_scale_factors", { - mock_fit <- list(pip = c(0.1, 0.2, 0.3)) - result <- susieWeights(susieFit = mock_fit) - expect_equal(result, rep(0, 3)) -}) - -test_that("susieWeights errors on dimension mismatch", { - mock_fit <- list(pip = c(0.1, 0.2)) - X <- matrix(rnorm(30), nrow = 10, ncol = 3) - expect_error(susieWeights(X = X, susieFit = mock_fit), "Dimension mismatch") -}) - -test_that("susieWeights with alpha/mu/X_column_scale_factors calls coef.susie", { - p <- 5 - L <- 2 - mock_fit <- list( - alpha = matrix( - c( - 0.9, - 0.05, - 0.02, - 0.02, - 0.01, - 0.1, - 0.1, - 0.6, - 0.1, - 0.1 - ), - nrow = L, - ncol = p, - byrow = TRUE - ), - mu = matrix( - c( - 2.0, - 0.1, - 0.05, - 0.03, - 0.01, - 0.5, - 0.2, - 1.5, - 0.1, - 0.05 - ), - nrow = L, - ncol = p, - byrow = TRUE - ), - X_column_scale_factors = rep(1.0, p), - pip = runif(p), - intercept = 0 - ) - result <- susieWeights(susieFit = mock_fit) - expect_length(result, p) - expect_true(is.numeric(result)) - expect_true(any(result != 0)) -}) - -test_that("susieWeights calls susie when susie_fit is NULL", { - set.seed(42) - p <- 5 - n <- 50 - X <- matrix(rnorm(n * p), nrow = n) - y <- rnorm(n) - result <- susieWeights(susieFit = list(pip = rep(0.1, p))) - expect_equal(result, rep(0, p)) -}) - -# ---- susieAshWeights ---- -test_that("susieAshWeights returns zeros when no expected fields", { - mock_fit <- list(pip = c(0.1, 0.2, 0.3)) - result <- susieAshWeights(susieAshFit = mock_fit) - expect_equal(result, rep(0, 3)) -}) - -test_that("susieAshWeights errors on dimension mismatch", { - mock_fit <- list(pip = c(0.1, 0.2)) - X <- matrix(rnorm(30), nrow = 10, ncol = 3) - expect_error( - susieAshWeights(X = X, susieAshFit = mock_fit), - "Dimension mismatch" - ) -}) - -test_that("susieAshWeights with proper fields calls coef.susie", { - p <- 4 - L <- 2 - mock_fit <- list( - alpha = matrix(runif(L * p), nrow = L, ncol = p), - mu = matrix(rnorm(L * p), nrow = L, ncol = p), - theta = matrix(rnorm(L * p), nrow = L, ncol = p), - X_column_scale_factors = rep(1.0, p), - pip = runif(p), - intercept = 0 - ) - result <- susieAshWeights(susieAshFit = mock_fit) - expect_true(is.numeric(result)) - expect_true(length(result) >= p) -}) - -test_that("susieAshWeights calls susie when fit is NULL", { - set.seed(42) - p <- 4 - n <- 30 - X <- matrix(rnorm(n * p), nrow = n) - y <- rnorm(n) - result <- susieAshWeights(susieAshFit = list(pip = rep(0.1, p))) - expect_equal(result, rep(0, p)) -}) - -# ---- susieInfWeights ---- -test_that("susieInfWeights returns zeros when no expected fields", { - mock_fit <- list(pip = c(0.4, 0.5)) - result <- susieInfWeights(susieInfFit = mock_fit) - expect_equal(result, rep(0, 2)) -}) - -test_that("susieInfWeights errors on dimension mismatch", { - mock_fit <- list(pip = c(0.1, 0.2)) - X <- matrix(rnorm(30), nrow = 10, ncol = 3) - expect_error( - susieInfWeights(X = X, susieInfFit = mock_fit), - "Dimension mismatch" - ) -}) - -test_that("susieInfWeights with proper fields calls coef.susie", { - p <- 4 - L <- 2 - mock_fit <- list( - alpha = matrix(runif(L * p), nrow = L, ncol = p), - mu = matrix(rnorm(L * p), nrow = L, ncol = p), - theta = matrix(rnorm(L * p), nrow = L, ncol = p), - X_column_scale_factors = rep(1.0, p), - pip = runif(p), - intercept = 0 - ) - result <- susieInfWeights(susieInfFit = mock_fit) - expect_true(is.numeric(result)) - expect_true(length(result) >= p) -}) - -test_that("susieInfWeights calls susie when fit is NULL", { - set.seed(42) - p <- 4 - n <- 30 - X <- matrix(rnorm(n * p), nrow = n) - y <- rnorm(n) - result <- susieInfWeights(susieInfFit = list(pip = rep(0.1, p))) - expect_equal(result, rep(0, p)) -}) diff --git a/tests/testthat/test_sldscPostprocessingPipeline.R b/tests/testthat/test_sldscPostprocessingPipeline.R index d2f4f89a..15b6c150 100644 --- a/tests/testthat/test_sldscPostprocessingPipeline.R +++ b/tests/testthat/test_sldscPostprocessingPipeline.R @@ -2,7 +2,7 @@ # The pipeline is pure computation over an in-memory SldscData: no file I/O, # no mocks. Fixtures come from helper-sldsc.R (.sldscMkData / .sldscMkRun). -test_that("pipeline runs end-to-end on a single + joint SldscData", { +test_that("pipeline runs end-to-end, pooling every trait in the meta tables", { sd <- .sldscMkData() res <- suppressMessages(sldscPostprocessingPipeline(sd, mafCutoff = 0.05)) @@ -32,17 +32,12 @@ test_that("pipeline runs end-to-end on a single + joint SldscData", { expect_equal(res$params$trait_names, c("traitX", "traitY")) # baseline annotation detected from the joint run expect_true("baselineLD_0" %in% res$params$baseline_categories) -}) - -# The shape assertions above pass even when every meta row is NA, which is -# what a degenerate per-block tau (constant annotationJackknifeCoefs -> jackknife SE of 0) -# produces: metafor gets zero-variance inputs and DerSimonian-Laird drops -# every trait, leaving nTraits == 0. Assert on the values, not just the -# columns. -test_that("meta tables pool every trait rather than dropping them", { - sd <- .sldscMkData() - res <- suppressMessages(sldscPostprocessingPipeline(sd, mafCutoff = 0.05)) + # The shape assertions above pass even when every meta row is NA, which + # is what a degenerate per-block tau (constant annotationJackknifeCoefs + # -> jackknife SE of 0) produces: metafor gets zero-variance inputs and + # DerSimonian-Laird drops every trait, leaving nTraits == 0. Assert on + # the values, not just the columns. for (tbl in c("tauStar", "enrichment", "enrichstat")) { meta <- res$meta[[tbl]] expect_equal(meta$nTraits, rep(2L, nrow(meta)), info = tbl) @@ -146,9 +141,9 @@ test_that("pipeline falls back to positional rename when names don't match", { expect_equal(res$params$target_categories, c("L2_1", "L2_2")) }) -test_that("pipeline breaks the single loop when a trait has fewer runs than targets", { - # traitX has only ONE single run but there are TWO target categories: the - # i > length(singleRuns) break is hit on the 2nd target. +test_that("pipeline skips targets beyond a trait's single runs", { + # traitX has only ONE single run but there are TWO target categories, so + # only the first target is standardized in single mode. annot <- data.frame( CHR = c(1, 1, 2, 2), SNP = paste0("rs", 1:4), @@ -173,8 +168,8 @@ test_that("pipeline breaks the single loop when a trait has fewer runs than targ sd, targetCategories = c("annot_A_0", "annot_B_0") )) - # The break stops before annot_B_0's single run; the single-keyed summary - # therefore carries only annot_A_0. + # annot_B_0 has no single run; the single-keyed summary therefore + # carries only annot_A_0. sm <- res$per_trait$traitX$summary expect_equal(sm$target, "annot_A_0") expect_false(is.na(sm$tauStarSingle)) @@ -182,7 +177,7 @@ test_that("pipeline breaks the single loop when a trait has fewer runs than targ test_that("pipeline warns and skips a single run that fails to standardize", { # traitX's 2nd single run lacks the target category annot_B_0, so - # standardizeSldscTrait errors and the pipeline's tryCatch warns + skips it. + # standardizeSldscTrait errors and the pipeline warns and skips it. annot <- data.frame( CHR = c(1, 1, 2, 2), SNP = paste0("rs", 1:4), @@ -257,7 +252,7 @@ test_that("pipeline errors when targetCategories cannot be auto-detected", { test_that("pipeline warns and skips a joint run that fails to standardize", { af <- .sldscBranchAnnotFrq() # The joint run lacks the target category annot_A_0, so its standardization - # errors and the pipeline's joint-side tryCatch warns + skips it. + # errors and the pipeline warns and skips it. traits <- list( traitX = list( single = list(.sldscMkRun(c("annot_A_0", "baselineLD_0"))), @@ -302,7 +297,7 @@ test_that(".sldscCollectSingle returns empty parts for no standardizations", { test_that(".sldscTraitSingle tolerates a trait with no single-mode runs", { local_mocked_bindings( - sldscResults = function(...) NULL, + .sldscRun = function(...) NULL, .package = "pecotmr" ) ctx <- list(sldscData = NULL, targetCategories = c("t1", "t2")) diff --git a/tests/testthat/test_sldscWrapper.R b/tests/testthat/test_sldscWrapper.R index 86fbc9b1..2bc03644 100644 --- a/tests/testthat/test_sldscWrapper.R +++ b/tests/testthat/test_sldscWrapper.R @@ -1,14 +1,122 @@ # Tests for R/sldscWrapper.R # -# File-based fixture builders (.makeAnnotGz / .make_frq / .makePolyfunSingle -# / .makePolyfunJoint / .makeSldscFixtures) and the in-memory SldscData -# builders (.sldscMkRun / .sldscMkData) live in helper-sldsc.R. +# The file-based fixture builders are below; the in-memory SldscData builders +# (.sldscMkRun / .sldscMkData), shared with the other S-LDSC tests, live in +# helper-sldsc.R. # # The reader functions (readSldscTrait/readSldscAnnot/readSldscFrq) do file I/O # and are tested against real fixture files. The compute functions # (computeSldscMRef/computeSldscAnnotSd/isBinarySldscAnnot/standardizeSldscTrait) # operate on an in-memory SldscData and are tested with in-memory fixtures. +# ============================================================================= +# File-based fixtures for the readers +# ============================================================================= +# +# Fixture convention: +# - 2 chromosomes (1, 2), 50 SNPs each -> 100 total +# - 2 target annotations: "annot_A" (binary), "annot_B" (continuous) +# - 10 jackknife blocks +# - Polyfun appends "_0" to target annotation names in .results + +# Create a single .annot.gz file for one chromosome. +# Real polyfun .annot.gz files have CHR, SNP, BP, CM + annotation columns only +# (no MAF/A1/A2 -- those come from the .frq / PLINK files). +.makeAnnotGz <- function(dir, chrom, nSnps = 50) { + df <- data.frame( + CHR = chrom, + SNP = paste0("rs", (chrom - 1L) * 100L + seq_len(nSnps)), + BP = seq_len(nSnps) * 1000L, + CM = seq_len(nSnps) * 0.01, + annot_A = sample(c(0L, 1L), nSnps, replace = TRUE), + annot_B = rnorm(nSnps, 2, 0.5), + stringsAsFactors = FALSE + ) + path <- file.path(dir, sprintf("target.%d.annot.gz", chrom)) + gz <- gzfile(path, "wb") + vroom::vroom_write(df, gz, delim = "\t") + close(gz) + invisible(df) +} + +# Create a PLINK .frq file for one chromosome +.make_frq <- function(dir, chrom, plinkName = "ref_chr", nSnps = 50) { + df <- data.frame( + CHR = chrom, + SNP = paste0("rs", (chrom - 1L) * 100L + seq_len(nSnps)), + A1 = "A", + A2 = "G", + MAF = runif(nSnps, 0.01, 0.49), + NCHROBS = 200L, + stringsAsFactors = FALSE + ) + path <- file.path(dir, sprintf("%s%d.frq", plinkName, chrom)) + vroom::vroom_write(df, path, delim = "\t") + invisible(df) +} + +# Create the three polyfun output files (.results, .log, .part_delete) +# for a single-target run. Real polyfun output includes baseline categories +# even in single-target mode, so we add 2 dummy baseline categories. +.makePolyfunSingle <- function( + dir, + prefix, + target_name, + nBlocks = 10, + h2g = 0.3, + tau = 1e-7, + enrichment = 2.5, + n_baseline = 2 +) { + target_cat <- paste0(target_name, "_0") + baseline_cats <- paste0("baselineLD_", seq_len(n_baseline) - 1L) + all_cats <- c(target_cat, baseline_cats) + n_cats <- length(all_cats) + + taus_all <- c(tau, rep(1e-8, n_baseline)) + enrichments_all <- c(enrichment, rep(1.0, n_baseline)) + + results <- data.frame( + Category = all_cats, + Coefficient = taus_all, + Coefficient_std_error = abs(taus_all) * 0.3, + Enrichment = enrichments_all, + Enrichment_std_error = enrichments_all * 0.2, + Enrichment_p = rep(0.01, n_cats), + `Prop._h2` = c(0.15, rep(0.425, n_baseline)), + `Prop._SNPs` = c(0.06, rep(0.47, n_baseline)), + check.names = FALSE, + stringsAsFactors = FALSE + ) + vroom::vroom_write(results, paste0(prefix, ".results"), delim = "\t") + + writeLines( + c( + "Analysis started at 2024-01-01", + sprintf("Total Observed scale h2: %g (0.05)", h2g), + "Analysis finished" + ), + paste0(prefix, ".log") + ) + + blocks <- matrix( + rnorm( + nBlocks * n_cats, + mean = rep(taus_all, each = nBlocks), + sd = abs(rep(taus_all, each = nBlocks)) * 0.5 + ), + nrow = nBlocks, + ncol = n_cats + ) + colnames(blocks) <- all_cats + vroom::vroom_write( + as.data.frame(blocks), + paste0(prefix, ".part_delete"), + delim = "\t" + ) + invisible(NULL) +} + # ============================================================================= # .sldscDetectAnnotCols # ============================================================================= @@ -262,12 +370,6 @@ test_that("computeSldscAnnotSd errors with zero degrees of freedom", { # computeSldscMRef (operates on SldscData) # ============================================================================= -test_that("computeSldscMRef counts MAF > cutoff SNPs from the frq table", { - M <- computeSldscMRef(.sldscMkData(), mafCutoff = 0.05) - expect_true(is.integer(M)) - expect_equal(M, 6L) # all 6 frq SNPs have MAF 0.2 > 0.05 -}) - test_that("computeSldscMRef counts all SNPs when mafCutoff = 0", { expect_equal(computeSldscMRef(.sldscMkData(), mafCutoff = 0), 6L) }) @@ -286,7 +388,9 @@ test_that("computeSldscMRef applies the MAF cutoff", { stringsAsFactors = FALSE ) sd <- SldscData(annot, frq, list()) - expect_equal(computeSldscMRef(sd, mafCutoff = 0.05), 2L) # rs1, rs3 + M <- computeSldscMRef(sd, mafCutoff = 0.05) + expect_true(is.integer(M)) + expect_equal(M, 2L) # rs1, rs3 }) test_that("computeSldscMRef falls back to annot row count when frq absent and mafCutoff = 0", { @@ -539,7 +643,7 @@ test_that("standardizeSldscTrait errors on non-SldscData input", { # ============================================================================= -# metaSldscRandom (unchanged: operates on standardized per-trait estimates) +# metaSldscRandom (operates on standardized per-trait estimates) # ============================================================================= .makePerTraitMeta <- function( @@ -549,7 +653,9 @@ test_that("standardizeSldscTrait errors on non-SldscData input", { ses = NULL ) { if (is.null(means)) { - means <- rnorm(nTraits, 1e-5, 1e-6) + # Seeded, so the fixture is the same on every run, and scoped, so + # the caller's random stream is left as it was. + means <- withr::with_seed(1L, rnorm(nTraits, 1e-5, 1e-6)) } if (is.null(ses)) { ses <- rep(1e-6, nTraits) @@ -572,30 +678,18 @@ test_that("standardizeSldscTrait errors on non-SldscData input", { per_trait } -test_that("metaSldscRandom works for tauStar", { +test_that("metaSldscRandom meta-analyzes tauStar, enrichment and enrichstat", { pt <- .makePerTraitMeta(nTraits = 4) - result <- metaSldscRandom(pt, "A_0", quantity = "tauStar") - expect_true(is.list(result)) - expect_equal(result$nTraits, 4L) - expect_true(is.numeric(result$mean)) - expect_true(is.numeric(result$se)) - expect_true(is.numeric(result$p)) - expect_true(result$se > 0) - expect_equal(length(result$traitsUsed), 4L) -}) - -test_that("metaSldscRandom works for enrichment", { - pt <- .makePerTraitMeta(nTraits = 3) - result <- metaSldscRandom(pt, "A_0", quantity = "enrichment") - expect_equal(result$nTraits, 3L) - expect_true(is.finite(result$mean)) -}) - -test_that("metaSldscRandom works for enrichstat", { - pt <- .makePerTraitMeta(nTraits = 3) - result <- metaSldscRandom(pt, "A_0", quantity = "enrichstat") - expect_equal(result$nTraits, 3L) - expect_true(is.finite(result$mean)) + for (quantity in c("tauStar", "enrichment", "enrichstat")) { + result <- metaSldscRandom(pt, "A_0", quantity = quantity) + expect_true(is.list(result), info = quantity) + expect_equal(result$nTraits, 4L, info = quantity) + expect_true(is.finite(result$mean), info = quantity) + expect_true(is.numeric(result$se), info = quantity) + expect_true(is.numeric(result$p), info = quantity) + expect_true(result$se > 0, info = quantity) + expect_equal(length(result$traitsUsed), 4L, info = quantity) + } }) # A per-trait $summary carrying the wide (Single/Joint) columns that @@ -682,13 +776,6 @@ test_that("metaSldscRandom skips traits with NA or zero SE", { expect_true(is.na(result$mean)) }) -test_that("metaSldscRandom skips NULL entries", { - pt <- .makePerTraitMeta(nTraits = 3) - pt$trait2 <- NULL - result <- metaSldscRandom(pt, "A_0", "tauStar") - expect_equal(result$nTraits, 2L) -}) - test_that("metaSldscRandom generates names for unnamed list", { pt <- .makePerTraitMeta(nTraits = 2) names(pt) <- NULL @@ -864,6 +951,10 @@ test_that(".sldscViewForMeta returns NULL when no matching columns", { }) +# ============================================================================= +# Annotation variance, positional annotCols, and meta-analysis arguments +# ============================================================================= + test_that("a constant annotation column contributes no variance", { # var() of a constant is 0 and of an all-NA column is NA; both must come # back as 0 so the column simply drops out of the weighted sum rather diff --git a/tests/testthat/test_sumstatsQc.R b/tests/testthat/test_sumstatsQc.R index 93a87f00..73865558 100644 --- a/tests/testthat/test_sumstatsQc.R +++ b/tests/testthat/test_sumstatsQc.R @@ -1,20 +1,41 @@ context("sumstats_qc") -# Previous tests against `rssBasicQc()` and the legacy -# `summaryStatsQc(rssInput, ldData)` signature have been removed because: -# * `rssBasicQc()` was folded into `summaryStatsQc()` -# * `summaryStatsQc()` now dispatches on `GwasSumStats` / `QtlSumStats` -# S4 collections (DFrame subclasses), not on a (rssInput list, ldData) -# pair -# * `QcResult` and the accessors `getRssInput()`, `getLdData()`, -# `getOutlierNumber()` have been removed; QC audit lives on -# `qcInfo()` -# Integration coverage of `summaryStatsQc()` lives in the -# pipeline test files (test_colocboostPipeline.R, etc.). -# -# What remains here: tests of internal QC helpers -# (`ldMismatchQc`, `krigingOutlierQc`) whose -# signatures and contracts are unchanged. +.gsd_makeHandle <- function(snp_n = 2L) { + new( + "GenotypeHandle", + path = "/tmp/sketch", + format = "plink2", + snpInfo = data.frame( + SNP = paste0("rs", seq_len(snp_n)), + CHR = rep("chr1", snp_n), + BP = seq(100L, by = 100L, length.out = snp_n), + A1 = rep("A", snp_n), + A2 = rep("G", snp_n), + stringsAsFactors = FALSE + ), + nSamples = 10L, + sampleIds = paste0("s", seq_len(10L)), + pgenPtr = NULL + ) +} + +.gsd_makeGwasSumStats <- function(mcolsDf, snp_n = nrow(mcolsDf)) { + gr <- GenomicRanges::GRanges( + seqnames = rep("chr1", snp_n), + ranges = IRanges::IRanges( + start = seq(100L, by = 100L, length.out = snp_n), + width = 1L + ) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame(mcolsDf) + GwasSumStats( + studyName = "G1", + entry = list(gr), + genome = "hg19", + ldReference = .gsd_makeHandle(snp_n), + qcOptions = list(prebuilt = "synthetic") + ) +} # =========================================================================== # ldMismatchQc @@ -78,6 +99,52 @@ test_that(".entryToSumstatDf: a declared MAF is not overwritten by af", { expect_equal(df$af, 0.8) }) +test_that(".sumStatsDf flattens the tuple sumStats() selects", { + data(qtlSumStatsExample, package = "pecotmr", envir = environment()) + qss <- qtlSumStatsExample + st <- as.character(qss$study[[1L]]) + ctx <- as.character(qss$context[[1L]]) + tr <- as.character(qss$trait[[1L]]) + expect_identical( + .sumStatsDf(qss, studyName = st, context = ctx, trait = tr), + .entryToSumstatDf( + sumStats(qss, studyName = st, context = ctx, trait = tr) + ) + ) + expect_error( + .sumStatsDf( + qss, + studyName = st, + context = ctx, + trait = tr, + require = "NOPE" + ), + str_c("QtlSumStats[", st, "/", ctx, "/", tr, "]: entry has no NOPE"), + fixed = TRUE + ) +}) + +test_that(".sumStatsDf names a GWAS by study, an unset selector ", { + data( + gwasSumStatsS4Example, + qtlSumStatsExample, + package = "pecotmr", + envir = environment() + ) + gss <- gwasSumStatsS4Example + st <- as.character(gss$study[[1L]]) + expect_error( + .sumStatsDf(gss, studyName = st, require = "NOPE"), + str_c("GwasSumStats[", st, "]: entry has no NOPE"), + fixed = TRUE + ) + expect_error( + .sumStatsDf(qtlSumStatsExample, require = "NOPE"), + "QtlSumStats[//]: entry has no NOPE", + fixed = TRUE + ) +}) + test_that("ldMismatchQc dentist returns a data frame with an outlier column", { set.seed(42) p <- 20 @@ -104,15 +171,15 @@ test_that("ldMismatchQc slalom returns a data frame with an outlier column", { test_that("ldMismatchQc method argument is validated", { z <- rnorm(5) R <- diag(5) - expect_error(ldMismatchQc(z, R = R, method = "invalid")) + expect_error( + ldMismatchQc(z, R = R, method = "invalid"), + "`method`: unknown engine 'invalid'. Known: slalom, dentist.", + fixed = TRUE + ) }) # =========================================================================== -# ldMismatchQcMethod resolver -# =========================================================================== - -# =========================================================================== -# krigingOutlierQc +# raiss and its helpers # =========================================================================== context("raiss") @@ -181,16 +248,22 @@ test_that("Input validation for raiss works correctly", { input_data_zscores_unordered <- generateDummyData( known_zscores_ordered = FALSE ) - expect_error(raiss( - input_data_ref_panel_unordered$ref_panel, - input_data$known_zscores, - input_data$ldMatrix - )) - expect_error(raiss( - input_data$ref_panel, - input_data_zscores_unordered$known_zscores, - input_data$ldMatrix - )) + expect_error( + raiss( + input_data_ref_panel_unordered$ref_panel, + input_data$known_zscores, + input_data$ldMatrix + ), + "refPanel and knownZscores must be in increasing order of pos" + ) + expect_error( + raiss( + input_data$ref_panel, + input_data_zscores_unordered$known_zscores, + input_data$ldMatrix + ), + "refPanel and knownZscores must be in increasing order of pos" + ) }) test_that("raiss refuses a plain list of block matrices", { @@ -247,12 +320,17 @@ test_that("raiss takes an LdMatrix and uses its variants", { A2 = "A" ) ) - # No refPanel: the LdMatrix's own variants supply it, so the z-scores - # label chromosomes canonically, as it does. - chr <- transform(known, chrom = "chr1") + # No refPanel: the LdMatrix's own variants supply it. The z-scores' + # chromosomes are read in UCSC style, so "1" and "chr1" both meet them; + # z-scores on a chromosome the reference lacks have nothing to impute + # from. expect_error( - raiss(knownZscores = chr, ldMatrix = ld, verbose = FALSE), - "chromosome labels" + raiss( + knownZscores = transform(known, chrom = "2"), + ldMatrix = ld, + verbose = FALSE + ), + "shares no chromosome with the LD reference" ) fromLd <- raiss( knownZscores = known, @@ -265,12 +343,74 @@ test_that("raiss takes an LdMatrix and uses its variants", { arrange(fromLd$resultNofilter, variant_id)$z, arrange(full$resultNofilter, variant_id)$z ) + fromChr <- raiss( + knownZscores = transform(known, chrom = "chr1"), + ldMatrix = ld, + r2Threshold = 0.3, + minimumLd = 1, + verbose = FALSE + ) + expect_equal(fromChr, fromLd) expect_error( raiss(knownZscores = known, genotypes = ld), "must be a genotype panel or a GenotypeMixture" ) }) +test_that("raiss takes a summary-statistics GRanges as knownZscores", { + set.seed(3) + p <- 30L + R <- 0.6^abs(outer(seq_len(p), seq_len(p), "-")) + pos <- seq(100L, by = 100L, length.out = p) + ref_panel <- data.frame( + chrom = "1", + pos = pos, + variant_id = sprintf("chr1:%d:A:G", pos), + A1 = "G", + A2 = "A" + ) + known <- ref_panel[seq_len(p) %% 3L != 0L, ] + known$z <- rnorm(nrow(known)) + # One entry as sumStats() returns it: the variants as ranges, the + # statistics as SNP / A1 / A2 / Z columns. + gr <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(known$pos, width = 1L), + SNP = known$variant_id, + A1 = known$A1, + A2 = known$A2, + Z = known$z + ) + fromTable <- raiss( + ref_panel, + known, + ldMatrix = R, + r2Threshold = 0.3, + minimumLd = 1, + verbose = FALSE + ) + fromRanges <- raiss( + ref_panel, + gr, + ldMatrix = R, + r2Threshold = 0.3, + minimumLd = 1, + verbose = FALSE + ) + expect_equal( + arrange(fromRanges$resultNofilter, variant_id)$z, + arrange(fromTable$resultNofilter, variant_id)$z + ) + expect_equal( + arrange(fromRanges$resultFilter, variant_id)$variant_id, + arrange(fromTable$resultFilter, variant_id)$variant_id + ) + expect_error( + raiss(ref_panel, gr[, "Z"], ldMatrix = R), + "lacks column\\(s\\) SNP, A1, A2" + ) +}) + test_that("Default parameters for raiss work correctly", { input_data <- generateDummyData() result <- raiss( @@ -328,21 +468,6 @@ test_that("Test Default Parameters for raissModel", { expect_true(all(result$raissLdScore >= 0)) }) -test_that("Test with Different lamb Values for raissModel", { - zt <- c(1.2, 0.5) - sig_t <- matrix(c(1, 0.5, 0.5, 1), nrow = 2) - sig_i_t <- matrix(c(0.5, 0.2, 0.2, 0.5), nrow = 2) - - lamb_values <- c(0.01, 0.05, 0.1) - for (lamb in lamb_values) { - result <- raissModel(zt, sig_t, sig_i_t, lamb) - expect_true(is.list(result)) - expect_true(all(c("var", "mu", "raissLdScore") %in% names(result))) - expect_true(is.numeric(result$mu)) - expect_true(all(is.finite(result$mu))) - } -}) - test_that("Report Condition Number in raissModel", { zt <- c(1.2, 0.5) sig_t <- matrix(c(1, 0.5, 0.5, 1), nrow = 2) @@ -377,9 +502,18 @@ test_that("Input Validation of raissModel", { sig_t_invalid <- "not a matrix" sig_i_t_invalid <- "not a matrix" - expect_error(raissModel(zt_invalid, sig_t, sig_i_t)) - expect_error(raissModel(zt, sig_t_invalid, sig_i_t)) - expect_error(raissModel(zt, sig_t, sig_i_t_invalid)) + expect_error( + raissModel(zt_invalid, sig_t, sig_i_t), + "Assertion on 'zt' failed: Must be of type 'numeric'" + ) + expect_error( + raissModel(zt, sig_t_invalid, sig_i_t), + "Assertion on 'sigT' failed: Must be of type 'numeric'" + ) + expect_error( + raissModel(zt, sig_t, sig_i_t_invalid), + "Assertion on 'sigIT' failed: Must be of type 'numeric'" + ) }) test_that("Boundary Conditions of raissModel", { @@ -391,33 +525,18 @@ test_that("Boundary Conditions of raissModel", { sig_t_empty <- matrix(numeric(0), nrow = 0) sig_i_t_empty <- matrix(numeric(0), nrow = 0) - expect_error(raissModel(zt_empty, sig_t, sig_i_t)) - expect_error(raissModel(zt, sig_t_empty, sig_i_t)) - expect_error(raissModel(zt, sig_t, sig_i_t_empty)) -}) - -test_that("Test with Different rcond Values for raissModel", { - zt <- c(1.2, 0.5) - sig_t <- matrix(c(1, 0.5, 0.5, 1), nrow = 2) - sig_i_t <- matrix(c(0.5, 0.2, 0.2, 0.5), nrow = 2) - - rcond_values <- c(0.01, 0.05, 0.1) - for (rcond in rcond_values) { - result <- raissModel(zt, sig_t, sig_i_t, lamb = 0.01, rcond = rcond) - expect_true(is.list(result)) - expect_true(all( - c( - "var", - "mu", - "raissLdScore", - "conditionNumber", - "correctInversion" - ) %in% - names(result) - )) - expect_true(is.numeric(result$mu)) - expect_true(all(is.finite(result$mu))) - } + expect_error( + raissModel(zt_empty, sig_t, sig_i_t), + "Assertion on 'zt' failed: Must have length >= 1" + ) + expect_error( + raissModel(zt, sig_t_empty, sig_i_t), + "Assertion on 'sigT' failed: Must have exactly 2 rows" + ) + expect_error( + raissModel(zt, sig_t, sig_i_t_empty), + "Assertion on 'sigIT' failed: Must have at least 1 rows" + ) }) test_that("formatRaissDf returns correctly formatted data frame", { @@ -543,16 +662,6 @@ test_that("raissR2 is calculated correctly in filterRaissOutput", { expect_equal(output$raissR2, expected_R2[which(expected_R2 > 0.6)]) }) -test_that("Filtering is applied correctly in filterRaissOutput", { - test_data <- generateFroTestData() - R2_threshold <- 0.6 - minimum_ld <- 5 - output <- filterRaissOutput(test_data, R2_threshold, minimum_ld)$zscores - - expect_true(all(output$raissR2 > R2_threshold)) - expect_true(all(output$raissLdScore >= minimum_ld)) -}) - test_that("Function returns the correct subset in filterRaissOutput", { test_data <- generateFroTestData() test_data$raissR2 <- 1 - test_data$Var @@ -586,34 +695,25 @@ generateMockDataForComputeVar <- function(seed = 1) { ) } -test_that("computeVar returns correct output for batch = TRUE", { +test_that("computeVar returns var and raissLdScore with and without batch", { input_data <- generateMockDataForComputeVar() - result <- computeVar( - input_data$sig_i_t_1, - input_data$sig_t_inv_1, - input_data$lamb_1, - batch = TRUE - ) - expect_true(is.list(result)) - expect_length(result, 2) - expect_true(all(c("var", "raissLdScore") %in% names(result))) - expect_true(is.numeric(result$var)) - expect_true(is.numeric(result$raissLdScore)) -}) - -test_that("computeVar returns correct output for batch = FALSE", { - input_data <- generateMockDataForComputeVar() - result <- computeVar( - input_data$sig_i_t_1, - input_data$sig_t_inv_1, - input_data$lamb_1, - batch = FALSE - ) - expect_true(is.list(result)) - expect_length(result, 2) - expect_true(all(c("var", "raissLdScore") %in% names(result))) - expect_true(is.numeric(result$var)) - expect_true(is.numeric(result$raissLdScore)) + for (batch in c(TRUE, FALSE)) { + result <- computeVar( + input_data$sig_i_t_1, + input_data$sig_t_inv_1, + input_data$lamb_1, + batch = batch + ) + lbl <- str_c("batch = ", batch) + expect_true(is.list(result), info = lbl) + expect_length(result, 2) + expect_true( + all(c("var", "raissLdScore") %in% names(result)), + info = lbl + ) + expect_true(is.numeric(result$var), info = lbl) + expect_true(is.numeric(result$raissLdScore), info = lbl) + } }) test_that("checkInversion correctly identifies inverse matrices in", { @@ -635,50 +735,110 @@ test_that("varInBoundaries sets boundaries correctly", { result <- varInBoundaries(var, lamb_test) - expect_equal(result[1], 0) # Value less than 0 should be set to 0 - expect_equal(result[2], 0) # Value within lower boundary should remain unchanged - expect_equal(result[3], 0.5) # Value within boundaries should remain unchanged - expect_equal(result[4], 1.04) # Value greater than 0.99999 + lamb should be set to 1 - expect_equal(result[5], 1) # Value greater than 0.99999 + lamb should be set to 1 + # Below 0 is floored to 0; above 0.99999 + lamb is capped to 1; anything + # in between, the bounds included, is unchanged. + expect_equal(result[1], 0) + expect_equal(result[2], 0) + expect_equal(result[3], 0.5) + expect_equal(result[4], 1.04) + expect_equal(result[5], 1) }) test_that("invertMat computes correct pseudo-inverse", { + # The diagonal is replaced by 1 + lamb, not added to: what is inverted + # is the ridged matrix. mat <- matrix(c(1, 2, 3, 4), nrow = 2) - lamb <- 0.5 - rcond <- 1e-7 - result <- invertMat(mat, lamb, rcond) - expect_true(is.matrix(result)) + result <- invertMat(mat, lamb = 0.5, rcond = 1e-7) + ridged <- matrix(c(1.5, 2, 3, 1.5), nrow = 2) + expect_equal(ridged %*% result, diag(2)) + expect_equal(result %*% ridged, diag(2)) + # A singular ridged matrix has no inverse; the result is its + # Moore-Penrose pseudo-inverse. + ones <- matrix(1, nrow = 2, ncol = 2) + pinv <- invertMat(ones, lamb = 0, rcond = 1e-7) + expect_equal(pinv, matrix(0.25, nrow = 2, ncol = 2)) + expect_equal(ones %*% pinv %*% ones, ones) + expect_equal(pinv %*% ones %*% pinv, pinv) }) test_that("invertMat handles errors and retries", { - mat <- matrix(c(0, 0, 0, 0), nrow = 2) - lamb <- 0.1 - rcond <- 1e-7 - result <- invertMat(mat, lamb, rcond) - expect_true(is.matrix(result)) + # ginv() can fail, as when LAPACK's SVD does not converge. invertMat() + # then tries once more with the ridge and the cutoff each raised 10%. + ridges <- numeric(0) + tols <- numeric(0) + local_mocked_bindings( + ginv = function(X, tol = sqrt(.Machine$double.eps)) { + ridges <<- c(ridges, X[1, 1]) + tols <<- c(tols, tol) + if (length(tols) == 1L) { + stop("SVD did not converge") + } + MASS::ginv(X, tol = tol) + }, + .package = "pecotmr" + ) + mat <- matrix(c(1, 0.5, 0.5, 1), nrow = 2) + result <- invertMat(mat, lamb = 0.1, rcond = 1e-7) + expect_equal(ridges, c(1.1, 1.11)) + expect_equal(tols, c(1e-7, 1.1e-7)) + # What comes back is the retry's inverse, of the matrix ridged to 1.11. + retried <- matrix(c(1.11, 0.5, 0.5, 1.11), nrow = 2) + expect_equal(retried %*% result, diag(2)) }) test_that("invertMatRecursive correctly inverts a valid square matrix", { mat <- matrix(c(2, -1, -1, 2), nrow = 2) - lamb <- 0.5 - rcond <- 0.01 - result <- invertMatRecursive(mat, lamb, rcond) - expect_true(is.matrix(result)) - expect_equal(dim(result), dim(mat)) + result <- invertMatRecursive(mat, lamb = 0.5, rcond = 0.01) + # What is inverted is mat with its diagonal set to 1 + lamb. + ridged <- matrix(c(1.5, -1, -1, 1.5), nrow = 2) + expect_equal(ridged %*% result, diag(2)) + expect_equal(result %*% ridged, diag(2)) }) -test_that("invertMatRecursive handles non-square matrices appropriately", { +test_that("invertMatRecursive gives a non-square matrix its pseudo-inverse", { mat <- matrix(1:6, nrow = 2) - lamb <- 0.5 - rcond <- 0.01 - expect_silent(invertMatRecursive(mat, lamb, rcond)) -}) - -test_that("invertMatRecursive handles errors and recurses correctly", { - mat <- "not a matrix" - lamb <- 0.5 - rcond <- 0.01 - expect_error(invertMatRecursive(mat, lamb, rcond)) + result <- invertMatRecursive(mat, lamb = 0.5, rcond = 0.01) + # The ridge sets the leading diagonal, [1, 1] and [2, 2]. The ridged + # 2 x 3 matrix A has full row rank, so its Moore-Penrose inverse is the + # right inverse t(A) (A t(A))^-1. + ridged <- matrix(c(1.5, 2, 3, 1.5, 5, 6), nrow = 2) + expect_equal(dim(result), c(3L, 2L)) + expect_equal(ridged %*% result, diag(2)) + expect_equal(result, t(ridged) %*% solve(ridged %*% t(ridged))) +}) + +test_that("invertMatRecursive retries via invertMat, three attempts in all", { + # A failed inversion falls back to invertMat() with lamb and rcond + # raised 10%, which retries once more itself: three attempts, each 10% + # above the last, before the error reaches the caller. + failures <- 2L + ridges <- numeric(0) + tols <- numeric(0) + local_mocked_bindings( + ginv = function(X, tol = sqrt(.Machine$double.eps)) { + ridges <<- c(ridges, X[1, 1]) + tols <<- c(tols, tol) + if (length(tols) <= failures) { + stop("SVD did not converge") + } + MASS::ginv(X, tol = tol) + }, + .package = "pecotmr" + ) + mat <- matrix(c(1, 0.5, 0.5, 1), nrow = 2) + result <- invertMatRecursive(mat, lamb = 0.1, rcond = 0.01) + expect_equal(ridges, 1 + 0.1 * c(1, 1.1, 1.21)) + expect_equal(tols, 0.01 * c(1, 1.1, 1.21)) + lastTry <- matrix(c(1.121, 0.5, 0.5, 1.121), nrow = 2) + expect_equal(lastTry %*% result, diag(2)) + # A third failure is not retried: it reaches the caller. + failures <- 3L + tols <- numeric(0) + expect_error( + invertMatRecursive(mat, lamb = 0.1, rcond = 0.01), + "SVD did not converge" + ) + expect_length(tols, 3L) }) # =========================================================================== @@ -820,10 +980,6 @@ test_that("raissSingleMatrixFromX returns known z when nothing to impute", { expect_null(result$ldMat) }) -# =========================================================================== -# raiss() dispatch paths: single-matrix list and genotype_matrix list -# =========================================================================== - # ============================================================================ # Tests for SVD-based genotype matrix path (raissSingleMatrixFromX) # ============================================================================ @@ -910,7 +1066,7 @@ generateXTestData <- function(n = 200, p = 100, n_known = 50, seed = 42) { ) } -test_that("safeSvd basic functionality", { +test_that(".safeSvd basic functionality", { set.seed(1) mat <- matrix(rnorm(20), nrow = 5, ncol = 4) s <- pecotmr:::.safeSvd(mat) @@ -921,7 +1077,7 @@ test_that("safeSvd basic functionality", { expect_equal(mat, reconstructed, tolerance = 1e-10) }) -test_that("safeSvd filters small singular values", { +test_that(".safeSvd filters small singular values", { set.seed(2) # Create rank-2 matrix u <- matrix(rnorm(10), nrow = 5, ncol = 2) @@ -931,7 +1087,7 @@ test_that("safeSvd filters small singular values", { expect_equal(length(s$d), 2) }) -test_that("safeSvd max_rank works", { +test_that(".safeSvd maxRank works", { set.seed(3) mat <- matrix(rnorm(50), nrow = 10, ncol = 5) s <- pecotmr:::.safeSvd(mat, maxRank = 2) @@ -940,7 +1096,7 @@ test_that("safeSvd max_rank works", { expect_equal(ncol(s$v), 2) }) -test_that("safeSvd rejects all-zero matrix", { +test_that(".safeSvd rejects all-zero matrix", { mat <- matrix(0, nrow = 5, ncol = 3) expect_error(pecotmr:::.safeSvd(mat), "all-zero") }) @@ -1094,36 +1250,6 @@ test_that("the genotype and LD routes drop the same weak directions", { )$resultNofilter expect_false(isTRUE(all.equal(uncut$z, viaLd$z, tolerance = 1e-6))) }) -test_that("X path matches R path: n >> p regime", { - data <- generateXTestData(n = 500, p = 50, n_known = 25, seed = 99) - - result_R <- raiss( - data$ref_panel, - data$known_zscores, - ldMatrix = data$R, - lamb = 0.01, - rcond = 0.01, - r2Threshold = 0, - minimumLd = 0, - verbose = FALSE - ) - result_X <- .raissX( - data$ref_panel, - data$known_zscores, - data$X, - lamb = 0.01, - svdTol = 1e-12, - r2Threshold = 0, - minimumLd = 0, - verbose = FALSE - ) - - r_sorted <- result_R$resultNofilter %>% arrange(variant_id) - x_sorted <- result_X$resultNofilter %>% arrange(variant_id) - - expect_equal(r_sorted$z, x_sorted$z, tolerance = 1e-4) - expect_equal(r_sorted$Var, x_sorted$Var, tolerance = 1e-4) -}) test_that("X path matches R path: varying lambda", { data <- generateXTestData(n = 150, p = 80, n_known = 40, seed = 7) @@ -1168,27 +1294,6 @@ test_that("X path matches R path: varying lambda", { } }) -test_that("X path handles all-known edge case", { - data <- generateXTestData(n = 100, p = 50, n_known = 50, seed = 10) - # Make all variants known - all_known <- data.frame( - chrom = data$ref_panel$chrom, - pos = data$ref_panel$pos, - variant_id = data$ref_panel$variant_id, - A1 = data$ref_panel$A1, - A2 = data$ref_panel$A2, - z = rnorm(nrow(data$ref_panel)), - stringsAsFactors = FALSE - ) - result <- .raissX( - data$ref_panel, - all_known, - data$X, - verbose = FALSE - ) - expect_equal(nrow(result$resultNofilter), nrow(data$ref_panel)) -}) - test_that("X path handles single unknown variant", { data <- generateXTestData(n = 100, p = 50, n_known = 49, seed = 15) @@ -1426,121 +1531,34 @@ test_that("the SVD route reports its progress when verbose", { expect_equal(nrow(res$resultNofilter), nrow(data$ref_panel)) }) -test_that("X path with collinear variants matches R path", { - set.seed(55) - n <- 150 - p <- 60 - # Create X with some near-duplicate columns - X_raw <- matrix( - sample(0:2, n * p, replace = TRUE, prob = c(0.25, 0.5, 0.25)), - nrow = n, - ncol = p - ) - # Make columns 5 and 6 nearly identical - X_raw[, 6] <- X_raw[, 5] + sample(c(0, 0, 0, 0, 1), n, replace = TRUE) - X_raw[X_raw > 2] <- 2 - - X <- scale(X_raw) - X[is.na(X)] <- 0 +context("slalom") - ref_panel <- data.frame( - chrom = rep(1, p), - pos = seq(1, p * 10, 10), - variant_id = paste0("rs", seq_len(p)), - A1 = rep("A", p), - A2 = rep("G", p), - stringsAsFactors = FALSE +# ============================================================================ +# Helper: build a valid positive-definite LD matrix from a genotype matrix +# ============================================================================ +makeSyntheticLd <- function(n_samples, n_snps, seed = 1) { + set.seed(seed) + # Simulate genotypes with some LD structure by using a factor model + # X = Z %*% L + noise, where Z is latent and L is a loading matrix + n_factors <- min(3, n_snps) + Z <- matrix(rnorm(n_samples * n_factors), nrow = n_samples) + L <- matrix(runif(n_factors * n_snps, -1, 1), nrow = n_factors) + X_raw <- Z %*% + L + + matrix(rnorm(n_samples * n_snps, sd = 0.5), nrow = n_samples) + # Discretise to genotype-like values (0, 1, 2) + X <- matrix( + as.integer(cut(X_raw, breaks = c(-Inf, -0.5, 0.5, Inf))) - 1L, + nrow = n_samples, + ncol = n_snps ) - colnames(X) <- ref_panel$variant_id - - n_known <- 30 - known_idx <- sort(sample(seq_len(p), n_known)) - known_zscores <- data.frame( - chrom = rep(1, n_known), - pos = ref_panel$pos[known_idx], - variant_id = ref_panel$variant_id[known_idx], - A1 = ref_panel$A1[known_idx], - A2 = ref_panel$A2[known_idx], - z = rnorm(n_known), - stringsAsFactors = FALSE - ) - - R <- cor(X_raw) - R[is.na(R)] <- 0 - colnames(R) <- rownames(R) <- ref_panel$variant_id - - result_R <- raiss( - ref_panel, - known_zscores, - ldMatrix = R, - lamb = 0.01, - rcond = 0.01, - r2Threshold = 0, - minimumLd = 0, - verbose = FALSE - ) - result_X <- .raissX( - ref_panel, - known_zscores, - X, - lamb = 0.01, - svdTol = 1e-12, - r2Threshold = 0, - minimumLd = 0, - verbose = FALSE - ) - - r_sorted <- result_R$resultNofilter %>% arrange(variant_id) - x_sorted <- result_X$resultNofilter %>% arrange(variant_id) - - expect_equal( - r_sorted$z, - x_sorted$z, - tolerance = 1e-3, - info = "Collinear case: z-scores should be close" - ) -}) - -context("RAISS missing-variant imputation in TWAS pipelines") - -# Previous tests covered `twasWeightsSumstatPipeline(imputeMissing = ...)`, -# which has been removed in favor of the S4 `twasWeightsPipeline` family -# dispatching on `QtlSumStats` / `QtlDataset`. The missing-variant -# imputation knob now lives inside `summaryStatsQc(impute = TRUE)`, and -# tests for that path live in test_sumstatsQc.R (internal helpers) and -# in the SumStats pipeline tests. -# -# RAISS itself (`raiss()`) still exists with the same signature; its -# direct tests live in test_raiss.R. - -context("slalom") - -# ============================================================================ -# Helper: build a valid positive-definite LD matrix from a genotype matrix -# ============================================================================ -makeSyntheticLd <- function(n_samples, n_snps, seed = 1) { - set.seed(seed) - # Simulate genotypes with some LD structure by using a factor model - # X = Z %*% L + noise, where Z is latent and L is a loading matrix - n_factors <- min(3, n_snps) - Z <- matrix(rnorm(n_samples * n_factors), nrow = n_samples) - L <- matrix(runif(n_factors * n_snps, -1, 1), nrow = n_factors) - X_raw <- Z %*% - L + - matrix(rnorm(n_samples * n_snps, sd = 0.5), nrow = n_samples) - # Discretise to genotype-like values (0, 1, 2) - X <- matrix( - as.integer(cut(X_raw, breaks = c(-Inf, -0.5, 0.5, Inf))) - 1L, - nrow = n_samples, - ncol = n_snps - ) - colnames(X) <- paste0("snp", seq_len(n_snps)) - R <- cor(X) - # Ensure perfect diagonal and clean NaN from any zero-variance columns - R[is.na(R) | is.nan(R)] <- 0 - diag(R) <- 1.0 - list(X = X, R = R) -} + colnames(X) <- paste0("snp", seq_len(n_snps)) + R <- cor(X) + # Ensure perfect diagonal and clean NaN from any zero-variance columns + R[is.na(R) | is.nan(R)] <- 0 + diag(R) <- 1.0 + list(X = X, R = R) +} # ============================================================================ # Basic output structure @@ -1622,7 +1640,10 @@ test_that("slalom still refuses both or neither of R and X", { R <- diag(4) X <- matrix(rnorm(40), nrow = 10, ncol = 4) expect_error(slalom(zScore = z), "Either R .* or X .* must be provided") - expect_error(slalom(zScore = z, R = R, X = X), "not both") + expect_error( + slalom(zScore = z, R = R, X = X), + "Provide either R or X, not both" + ) }) test_that("slalom accepts X matrix instead of R", { @@ -1707,22 +1728,6 @@ test_that("ABF: lbf formula matches manual calculation", { expect_equal(actual_ratio, expected_ratio, tolerance = 1e-10) }) -test_that("ABF: PIPs always sum to exactly 1", { - for (s in 1:5) { - set.seed(200 + s) - n <- sample(5:30, 1) - z <- rnorm(n, sd = 2) - R <- diag(n) - result <- slalom(zScore = z, R = R) - expect_equal( - sum(result$data$prob), - 1, - tolerance = 1e-12, - label = paste("seed", 200 + s) - ) - } -}) - test_that("ABF: symmetric z-scores give symmetric PIPs", { z <- c(-3, 3) R <- diag(2) @@ -1746,6 +1751,8 @@ test_that("CS95 contains the causal variant in a simple synthetic signal", { expect_true(causal %in% result$summary$cs95) expect_true(causal %in% result$summary$cs99) + # ... and, as the top-PIP variant, it heads the CS. + expect_equal(result$summary$cs95[1], causal) }) test_that("CS99 is a superset of CS95", { @@ -1776,20 +1783,6 @@ test_that("CS95 covers at least 95% of posterior mass", { expect_gt(cs99_mass, 0.99) }) -test_that("CS with very strong signal contains only the causal variant", { - set.seed(303) - n <- 15 - z <- rnorm(n, sd = 0.1) - z[8] <- 15 # extremely strong - R <- diag(n) - - result <- slalom(zScore = z, R = R) - - expect_equal(result$summary$cs95[1], 8) - expect_true(8 %in% result$summary$cs95) - expect_true(8 %in% result$summary$cs99) -}) - test_that("CS with diffuse signal contains many variants", { set.seed(304) n <- 10 @@ -1806,25 +1799,8 @@ test_that("CS with diffuse signal contains many variants", { # Lead variant by pvalue vs abf # ============================================================================ -test_that("lead variant by pvalue selects most negative z-score", { - z <- c(0, -4, 3, -1, 2) - R <- diag(5) - - result <- slalom(zScore = z, R = R, leadVariantChoice = "pvalue") - - expect_equal(result$summary$leadPipVariant, 2) -}) - -test_that("lead variant by abf selects highest PIP", { - z <- c(0, -4, 3, -1, 2) - R <- diag(5) - - result <- slalom(zScore = z, R = R, leadVariantChoice = "abf") - - expect_equal(result$summary$leadPipVariant, which.max(result$data$prob)) -}) - -test_that("pvalue and abf lead can differ when z has asymmetric magnitudes", { +test_that("pvalue lead is the most negative z, abf lead the highest PIP", { + # Asymmetric magnitudes, so the two choices disagree. z <- c(-3.0, 5.0, 0.1, -0.2, 0.3) R <- diag(5) @@ -1833,6 +1809,10 @@ test_that("pvalue and abf lead can differ when z has asymmetric magnitudes", { expect_equal(result_pv$summary$leadPipVariant, 1) expect_equal(result_abf$summary$leadPipVariant, 2) + expect_equal( + result_abf$summary$leadPipVariant, + which.max(result_abf$data$prob) + ) expect_false( result_pv$summary$leadPipVariant == result_abf$summary$leadPipVariant ) @@ -1978,28 +1958,6 @@ test_that("edge case: all zero z-scores", { expect_equal(result$summary$maxPip, 1 / n, tolerance = 1e-14) }) -test_that("edge case: very large z-scores do not produce NaN in PIPs", { - z <- c(50, -50, 30, -30, 0) - R <- diag(5) - - result <- slalom(zScore = z, R = R) - - expect_false(any(is.nan(result$data$prob))) - expect_false(any(is.na(result$data$prob))) - expect_equal(sum(result$data$prob), 1, tolerance = 1e-10) - expect_equal(result$data$prob[1], result$data$prob[2], tolerance = 1e-14) -}) - -test_that("edge case: identical z-scores yield uniform PIPs", { - n <- 8 - z <- rep(2.5, n) - R <- diag(n) - - result <- slalom(zScore = z, R = R) - - expect_equal(result$data$prob, rep(1 / n, n), tolerance = 1e-14) -}) - test_that("edge case: two variants only", { z <- c(-3, 2) R <- matrix(c(1, 0.5, 0.5, 1), nrow = 2) @@ -2012,68 +1970,6 @@ test_that("edge case: two variants only", { expect_gt(result$data$prob[1], result$data$prob[2]) }) -test_that("edge case: mismatched dimensions error", { - z <- rnorm(10) - R <- diag(5) - expect_error( - slalom(zScore = z, R = R), - "R.*Must have exactly 10 rows" - ) -}) - -test_that("edge case: no R and no X provided errors", { - z <- rnorm(5) - expect_error(slalom(zScore = z), "Either R.*or X.*must be provided") -}) - -test_that("edge case: both R and X provided errors", { - set.seed(500) - n <- 5 - z <- rnorm(n) - R <- diag(n) - X <- matrix(sample(0:2, 50 * n, replace = TRUE), nrow = 50, ncol = n) - expect_error( - slalom(zScore = z, R = R, X = X), - "Provide either R or X, not both" - ) -}) - -# ============================================================================ -# X input mode -# ============================================================================ - -test_that("X input yields same result as R = cor(X)", { - set.seed(600) - n_samples <- 200 - n_snps <- 10 - X <- matrix( - sample(0:2, n_samples * n_snps, replace = TRUE), - nrow = n_samples, - ncol = n_snps - ) - colnames(X) <- paste0("snp", seq_len(n_snps)) - z <- rnorm(n_snps, sd = 2) - - R_manual <- cor(X) - diag(R_manual) <- 1.0 - - result_X <- slalom(zScore = z, X = X) - result_R <- slalom(zScore = z, R = R_manual) - - expect_equal(result_X$data$prob, result_R$data$prob, tolerance = 1e-10) - expect_equal( - result_X$data$original_z, - result_R$data$original_z, - tolerance = 1e-14 - ) - expect_equal( - result_X$summary$leadPipVariant, - result_R$summary$leadPipVariant - ) - expect_equal(result_X$summary$cs95, result_R$summary$cs95) - expect_equal(result_X$summary$cs99, result_R$summary$cs99) -}) - # ============================================================================ # Parameter variation # ============================================================================ @@ -2127,30 +2023,6 @@ test_that("r2_threshold variation affects n_r2 count", { expect_gte(result_low$summary$nR2, result_high$summary$nR2) }) -test_that("nlog10p_dentist_s_threshold variation affects outlier count", { - set.seed(702) - n <- 10 - syn <- makeSyntheticLd(200, n, seed = 702) - z <- rnorm(n, sd = 2) - z[1] <- -6 - - result_low_thresh <- slalom( - zScore = z, - R = syn$R, - nlog10pDentistSThreshold = 1.0 - ) - result_high_thresh <- slalom( - zScore = z, - R = syn$R, - nlog10pDentistSThreshold = 10.0 - ) - - expect_gte( - result_low_thresh$summary$nDentistSOutlier, - result_high_thresh$summary$nDentistSOutlier - ) -}) - # ============================================================================ # Output structure validation # ============================================================================ @@ -2227,21 +2099,6 @@ test_that("fraction = 0 with no outliers (identity LD, consistent z)", { expect_equal(result$summary$fraction, 0) }) -test_that("fraction is between 0 and 1", { - set.seed(900) - for (s in 1:5) { - set.seed(900 + s) - n <- sample(10:30, 1) - syn <- makeSyntheticLd(200, n, seed = 900 + s) - z <- rnorm(n, sd = 2) - z[1] <- -6 - - result <- slalom(zScore = z, R = syn$R, r2Threshold = 0.3) - expect_gte(result$summary$fraction, 0) - expect_lte(result$summary$fraction, 1) - } -}) - test_that("maxPip equals the maximum of prob vector", { set.seed(901) n <- 20 @@ -2273,38 +2130,34 @@ test_that("realistic LD: correlated variants share PIP mass", { }) test_that("realistic LD: DENTIST-S detects outlier in correlated block", { - set.seed(1001) - syn <- makeSyntheticLd(500, 15, seed = 1001) - R <- syn$R - - lead_idx <- 1 - z <- R[, lead_idx] * (-5) - z[1] <- -5 - - r2_to_lead <- R[, 1]^2 - candidates <- which(r2_to_lead > 0.3 & seq_along(z) != 1) - if (length(candidates) > 0) { - corrupt_idx <- candidates[1] - z[corrupt_idx] <- z[corrupt_idx] + 10 + # LD decaying with distance from the lead, r = 0.9^d, so its neighbour + # is in LD with it by construction (r2 = 0.81, above the 0.2 cutoff). + p <- 15L + R <- 0.9^abs(outer(seq_len(p), seq_len(p), "-")) + # Every z-score as the lead's LD predicts it, then the neighbour's + # corrupted by +10. + z <- R[, 1] * (-5) + z[2] <- z[2] + 10 - result <- slalom( - zScore = z, - R = R, - r2Threshold = 0.2, - nlog10pDentistSThreshold = 3.0 - ) + result <- slalom( + zScore = z, + R = R, + r2Threshold = 0.2, + nlog10pDentistSThreshold = 3.0 + ) - expect_true(result$data$outliers[corrupt_idx]) - } + expect_equal(result$summary$leadPipVariant, 1L) + # The corrupted variant, and only it, is flagged. + expect_equal(which(result$data$outliers), 2L) }) test_that("realistic LD: no outliers when z perfectly matches LD structure", { - set.seed(1002) - syn <- makeSyntheticLd(500, 10, seed = 1002) - R <- syn$R - - lead_idx <- 1 - z <- R[, lead_idx] * (-4) + # LD decaying with distance from the lead, r = 0.9^d: the lead and + # variants 2-6 clear the 0.3 r2 cutoff, so only their DENTIST-S + # statistic keeps them from being flagged. + p <- 10L + R <- 0.9^abs(outer(seq_len(p), seq_len(p), "-")) + z <- R[, 1] * (-4) result <- slalom( zScore = z, @@ -2313,57 +2166,13 @@ test_that("realistic LD: no outliers when z perfectly matches LD structure", { nlog10pDentistSThreshold = 4.0 ) - non_lead <- setdiff(seq_along(z), result$summary$leadPipVariant) - lead <- result$summary$leadPipVariant - for (i in non_lead) { - r2_val <- R[i, lead]^2 - if (r2_val > 0.3 && r2_val < 1.0) { - expect_false(result$data$outliers[i]) - } else if (r2_val >= 1.0) { - expect_true( - is.na(result$data$outliers[i]) || !result$data$outliers[i] - ) - } - } -}) - -# ============================================================================ -# Internal function access (resolveLdInput, pecotmr internal) -# ============================================================================ - -test_that("resolveLdInput returns R when R is provided", { - R <- diag(5) - res <- pecotmr:::resolveLdInput(R = R, needNSample = FALSE) - expect_equal(res$R, R) -}) - -test_that("resolveLdInput computes R from X", { - set.seed(1100) - X <- matrix(sample(0:2, 200 * 5, replace = TRUE), nrow = 200, ncol = 5) - colnames(X) <- paste0("s", 1:5) - res <- pecotmr:::resolveLdInput(X = X, needNSample = FALSE) - expect_true(is.matrix(res$R)) - expect_equal(nrow(res$R), 5) - expect_equal(ncol(res$R), 5) - for (j in seq_len(5)) { - expect_equal(res$R[j, j], 1.0, tolerance = 1e-6) - } -}) - -test_that("resolveLdInput errors when neither R nor X given", { - expect_error( - pecotmr:::resolveLdInput(R = NULL, X = NULL), - "Either R.*or X.*must be provided" - ) -}) - -test_that("resolveLdInput errors when both R and X given", { - R <- diag(3) - X <- matrix(1, nrow = 10, ncol = 3) - expect_error( - pecotmr:::resolveLdInput(R = R, X = X), - "Provide either R or X, not both" - ) + expect_equal(result$summary$leadPipVariant, 1L) + expect_equal(result$summary$nR2, 6L) + # Each z is exactly what the lead's LD predicts, so every statistic is 0 + # and nothing is flagged. + expect_equal(result$data$nlog10p_dentist_s[-1], rep(0, p - 1L)) + expect_false(any(result$data$outliers[-1])) + expect_equal(result$summary$nDentistSOutlier, 0L) }) # ============================================================================ @@ -2376,7 +2185,7 @@ test_that("log-sum-exp trick prevents overflow with extreme z-scores", { result <- slalom(zScore = z, R = R) - expect_false(any(is.nan(result$data$prob))) + expect_false(any(is.na(result$data$prob))) expect_false(any(is.infinite(result$data$prob))) expect_equal(sum(result$data$prob), 1, tolerance = 1e-10) expect_equal(result$data$prob[1], result$data$prob[3], tolerance = 1e-14) @@ -2449,25 +2258,6 @@ context("summaryStatsQc") # Fixture builders # =========================================================================== -.ssQ_makeHandle <- function(snp_n = 8L, n_samples = 60L) { - new( - "GenotypeHandle", - path = "/tmp/sketch", - format = "plink2", - snpInfo = data.frame( - SNP = paste0("rs", seq_len(snp_n)), - CHR = rep("1", snp_n), - BP = seq(100L, by = 100L, length.out = snp_n), - A1 = rep("A", snp_n), - A2 = rep("G", snp_n), - stringsAsFactors = FALSE - ), - nSamples = n_samples, - sampleIds = paste0("s", seq_len(n_samples)), - pgenPtr = NULL - ) -} - .ssQ_makeEntryGr <- function( snp_ids = paste0("rs", 1:4), positions = c(100L, 200L, 300L, 400L) @@ -2638,14 +2428,6 @@ test_that("summaryStatsQc: PIP screen off leaves the harmonized set intact", { expect_setequal(snps, c("chr1:100:G:A", "chr1:200:G:A", "chr1:300:G:A")) }) -# A panel whose SNP ids follow the formatVariantId convention (chr:pos:A2:A1), -# as real genotype LD sketches do, so a re-keyed entry SNP resolves against it. -.ssQ_makeHandleVid <- function(snp_n = 8L, n_samples = 60L) { - h <- .ssQ_makeHandle(snp_n, n_samples) - h@snpInfo$SNP <- paste0("chr1:", snpInfo(h)$BP, ":G:A") - h -} - # Entry with one allele-swapped variant (pos 200: A1/A2 reversed vs the panel), # carrying its input-orientation SNP. Others are exact matches. .ssQ_makeFlipEntryGr <- function() { @@ -2691,18 +2473,6 @@ test_that("summaryStatsQc: harmonization re-keys SNP and sign-flips Z", { # never drop the variant # --------------------------------------------------------------------------- -test_that(".ldRefMatchIds repairs tag ids and leaves clean labels alone", { - h <- .ssQ_makeHandleVid() # ids chr1:100:G:A .. chr1:800:G:A, A1=A A2=G - h@snpInfo$SNP[h@snpInfo$BP == 200L] <- "chr1:200:INS:A" - ids <- pecotmr:::.ldRefMatchIds(h) - # the tag id is re-rendered from the panel's own A2/A1 columns ... - expect_equal(ids[2L], "chr1:200:G:A") - # ... and every other label is untouched. - expect_equal(ids[-2L], pecotmr:::.ldRefVariantIds(h)[-2L]) - # the raw accessor still answers the panel FILE's label (.afreq keys on it) - expect_equal(pecotmr:::.ldRefVariantIds(h)[2L], "chr1:200:INS:A") -}) - test_that(".raissUnsafeToImpute does not refuse a tag-allele id", { # A tag id is repaired at the panel boundary, so RAISS sees a normal indel # id; only the flip-pair / flip-of-known ambiguities are unsafe. @@ -2932,32 +2702,41 @@ test_that(".deriveBetaSeFromZ: skipped when N missing", { # summaryStatsQc: end-to-end on the synthetic fixture # =========================================================================== -test_that("summaryStatsQc: vanilla run fills qcInfo, returns GwasSumStats", { +test_that("summaryStatsQc: vanilla run records its options and audits", { ss <- .ssQ_makeGwasSumStats() res <- summaryStatsQc(ss) expect_s4_class(res, "GwasSumStats") - qc <- qcInfo(res) - expect_true(length(qc) > 0L) - expect_true("options" %in% names(qc)) - expect_true("entryAudit" %in% names(qc)) - expect_equal(length(qc$entryAudit), nrow(ss)) - ea <- qc$entryAudit[[1L]] + expect_true("options" %in% names(qcOptions(res))) + expect_false("entryAudit" %in% names(qcOptions(res))) + expect_equal(length(res$qcAudit), nrow(ss)) + ea <- res$qcAudit[[1L]] expect_equal(ea$variantsIn, 4L) expect_equal(ea$variantsOut, 4L) + expect_equal(ea$matchedAgainstLdReference, 4L) + # The per-row table: identity columns, then the audit's scalar counts. + tbl <- qcInfo(res) + expect_s4_class(tbl, "DataFrame") + expect_equal(nrow(tbl), nrow(ss)) + expect_equal(tbl$study, as.character(res$study)) + expect_equal(tbl$variantsIn, 4L) + expect_equal(tbl$variantsOut, 4L) }) test_that("summaryStatsQc: keepVariants subsets entries, records the drop", { ss <- .ssQ_makeGwasSumStats() res <- summaryStatsQc(ss, keepVariants = c("rs1", "rs3")) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_equal(ea$keepVariantsDropped, 2L) expect_equal(ea$variantsOut, 2L) }) test_that("summaryStatsQc: skipRegion drops overlapping variants", { ss <- .ssQ_makeGwasSumStats() - res <- summaryStatsQc(ss, skipRegion = "chr1:50-150") - ea <- qcInfo(res)$entryAudit[[1L]] + res <- summaryStatsQc( + ss, + skipRegion = GenomicRanges::GRanges("chr1:50-150") + ) + ea <- res$qcAudit[[1L]] expect_equal(ea$skipRegionDropped, 1L) # rs1 at pos 100 is dropped }) @@ -2973,19 +2752,12 @@ test_that("summaryStatsQc: PIP screen triggers when no variant has signal", { ldReference = .ssQ_makeHandle() ) res <- summaryStatsQc(ss, signalScreenParam = SignalScreenParam(pip = 0.99)) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_true(isTRUE(ea$pipScreenSkipped)) expect_match(ea$pipScreenReason, "no signals above PIP threshold") expect_equal(length(res[[1L]]), 0L) }) -test_that("summaryStatsQc: harmonized variants count is recorded", { - ss <- .ssQ_makeGwasSumStats() - res <- summaryStatsQc(ss) - ea <- qcInfo(res)$entryAudit[[1L]] - expect_equal(ea$matchedAgainstLdReference, 4L) -}) - test_that("summaryStatsQc: options block records the curated knobs", { ss <- .ssQ_makeGwasSumStats() res <- summaryStatsQc( @@ -2996,7 +2768,7 @@ test_that("summaryStatsQc: options block records the curated knobs", { nCutoff = 10 ) ) - opts <- qcInfo(res)$options + opts <- qcOptions(res)$options expect_true(opts$removeIndels) expect_false(opts$removeStrandAmbiguous) expect_equal(opts$nCutoff, 10) @@ -3014,7 +2786,7 @@ test_that("summaryStatsQc: round-trips QtlSumStats inputs", { ) res <- summaryStatsQc(ss) expect_s4_class(res, "QtlSumStats") - expect_equal(length(qcInfo(res)$entryAudit), 1L) + expect_equal(length(res$qcAudit), 1L) }) # =========================================================================== @@ -3089,7 +2861,7 @@ test_that("summaryStatsQc(effectiveN=TRUE): counts, no N -> N == N_eff", { res <- summaryStatsQc(ss) # 4*case*control/(case+control) per variant. expect_equal(.ssQ_entryNByPos(res[[1L]]), c(360, 640, 510, 750)) - expect_identical(qcInfo(res)$entryAudit[[1L]]$nSource, "effective") + expect_identical(res$qcAudit[[1L]]$nSource, "effective") }) test_that("summaryStatsQc(effectiveN=TRUE): counts + N -> counts win", { @@ -3104,18 +2876,17 @@ test_that("summaryStatsQc(effectiveN=TRUE): counts + N -> counts win", { genome = "hg19", ldReference = .ssQ_makeHandle() ) - expect_message(summaryStatsQc(ss), "overridden by effective N") - res <- summaryStatsQc(ss) + expect_message(res <- summaryStatsQc(ss), "overridden by effective N") # N (was 1000) is replaced by the per-variant N_eff. expect_equal(.ssQ_entryNByPos(res[[1L]]), c(360, 640, 510, 750)) - expect_identical(qcInfo(res)$entryAudit[[1L]]$nSource, "effective") + expect_identical(res$qcAudit[[1L]]$nSource, "effective") }) test_that("summaryStatsQc(effectiveN=TRUE): N only, no counts -> used as-is", { ss <- .ssQ_makeGwasSumStats() # entry carries N = 1000, no counts res <- summaryStatsQc(ss) expect_true(all(.ssQ_entryNByPos(res[[1L]]) == 1000)) - expect_identical(qcInfo(res)$entryAudit[[1L]]$nSource, "column") + expect_identical(res$qcAudit[[1L]]$nSource, "column") }) test_that("summaryStatsQc(effectiveN=FALSE): counts + N -> raw N", { @@ -3132,7 +2903,7 @@ test_that("summaryStatsQc(effectiveN=FALSE): counts + N -> raw N", { ) res <- summaryStatsQc(ss, effectiveN = FALSE) expect_true(all(.ssQ_entryNByPos(res[[1L]]) == 1000)) - expect_identical(qcInfo(res)$entryAudit[[1L]]$nSource, "column") + expect_identical(res$qcAudit[[1L]]$nSource, "column") }) test_that("summaryStatsQc(effectiveN=FALSE): counts -> raw total", { @@ -3149,7 +2920,7 @@ test_that("summaryStatsQc(effectiveN=FALSE): counts -> raw total", { res <- summaryStatsQc(ss, effectiveN = FALSE) # Raw total n_case + n_control per variant. expect_equal(.ssQ_entryNByPos(res[[1L]]), c(1000, 1000, 1000, 1000)) - expect_identical(qcInfo(res)$entryAudit[[1L]]$nSource, "total") + expect_identical(res$qcAudit[[1L]]$nSource, "total") }) test_that("summaryStatsQc(effectiveN=TRUE): study scalars fill all variants", { @@ -3163,11 +2934,10 @@ test_that("summaryStatsQc(effectiveN=TRUE): study scalars fill all variants", { nCase = 100, nControl = 900 ) - expect_message(summaryStatsQc(ss), "from study") - res <- summaryStatsQc(ss) + expect_message(res <- summaryStatsQc(ss), "from study") # 4*100*900/1000 = 360 for every variant. expect_true(all(.ssQ_entryNByPos(res[[1L]]) == 360)) - expect_identical(qcInfo(res)$entryAudit[[1L]]$nSource, "effective") + expect_identical(res$qcAudit[[1L]]$nSource, "effective") }) test_that("summaryStatsQc: study nSample is the level-4 fallback", { @@ -3185,7 +2955,7 @@ test_that("summaryStatsQc: study nSample is the level-4 fallback", { ) res <- summaryStatsQc(ss) expect_true(all(.ssQ_entryNByPos(res[[1L]]) == 4321)) - expect_identical(qcInfo(res)$entryAudit[[1L]]$nSource, "study-n") + expect_identical(res$qcAudit[[1L]]$nSource, "study-n") }) test_that("summaryStatsQc: QtlSumStats tuple nSample falls back too", { @@ -3208,7 +2978,7 @@ test_that("summaryStatsQc: QtlSumStats tuple nSample falls back too", { res <- summaryStatsQc(ss) expect_s4_class(res, "QtlSumStats") expect_true(all(.ssQ_entryNByPos(res[[1L]]) == 838)) - expect_identical(qcInfo(res)$entryAudit[[1L]]$nSource, "study-n") + expect_identical(res$qcAudit[[1L]]$nSource, "study-n") expect_equal(as.numeric(res$nSample), 838) # slot preserved through QC }) @@ -3227,7 +2997,7 @@ test_that("summaryStatsQc: counts beat nSample, and an N column beats it", { ) res1 <- summaryStatsQc(ss1) expect_equal(.ssQ_entryNByPos(res1[[1L]]), c(360, 640, 510, 750)) - expect_identical(qcInfo(res1)$entryAudit[[1L]]$nSource, "effective") + expect_identical(res1$qcAudit[[1L]]$nSource, "effective") # per-variant N column present alongside nSample (no counts) -> N wins (column). ss2 <- GwasSumStats( studyName = "g1", @@ -3238,14 +3008,14 @@ test_that("summaryStatsQc: counts beat nSample, and an N column beats it", { ) res2 <- summaryStatsQc(ss2) # .ssQ_makeEntryGr carries N = 1000 expect_true(all(.ssQ_entryNByPos(res2[[1L]]) == 1000)) - expect_identical(qcInfo(res2)$entryAudit[[1L]]$nSource, "column") + expect_identical(res2$qcAudit[[1L]]$nSource, "column") }) -test_that("summaryStatsQc: effectiveN recorded in qcInfo options", { +test_that("summaryStatsQc: effectiveN recorded in qcOptions", { ss <- .ssQ_makeGwasSumStats() - expect_true(qcInfo(summaryStatsQc(ss))$options$effectiveN) + expect_true(qcOptions(summaryStatsQc(ss))$options$effectiveN) expect_false( - qcInfo(summaryStatsQc(ss, effectiveN = FALSE))$options$effectiveN + qcOptions(summaryStatsQc(ss, effectiveN = FALSE))$options$effectiveN ) }) @@ -3263,7 +3033,7 @@ test_that("summaryStatsQc: quantitative QtlSumStats: no effective N", { ) res <- summaryStatsQc(ss) expect_true(all(.ssQ_entryNByPos(res[[1L]]) == 1000)) - expect_identical(qcInfo(res)$entryAudit[[1L]]$nSource, "column") + expect_identical(res$qcAudit[[1L]]$nSource, "column") }) # =========================================================================== @@ -3287,7 +3057,7 @@ test_that("summaryStatsQc: ldMismatchQcMethod 'dentist' walks the LD branch", { .package = "pecotmr" ) res <- suppressWarnings(summaryStatsQc(ss, ldMismatchQcMethod = "dentist")) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_equal(ea$ldMismatchMethod, "dentist") expect_true("ldMismatchOutliersDropped" %in% names(ea)) }) @@ -3339,7 +3109,7 @@ test_that("summaryStatsQc: impute = TRUE invokes RAISS, records counts", { impute = TRUE, raissParam = RaissParam(flank = 500) ) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_equal(ea$raissTotalVariants, 6L) expect_equal(ea$raissImputedVariants, 2L) }) @@ -3405,7 +3175,7 @@ test_that("summaryStatsQc: impute with a NULL raiss records 0 imputed", { .package = "pecotmr" ) res <- summaryStatsQc(ss, impute = TRUE) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_equal(ea$raissImputedVariants, 0L) }) @@ -3413,42 +3183,6 @@ test_that("summaryStatsQc: impute with a NULL raiss records 0 imputed", { # summaryStatsQc: per-step QC counter logging (concept salvaged from PR #520) # =========================================================================== -test_that("harmonizeAlleles surfaces sign/strand/dropped in qcCounts", { - # 4 shared positions: 100 exact, 200 sign-flip, 300 strand-flip (A/G - # unambiguous), 400 allele mismatch (dropped). - target <- data.frame( - chrom = c(1, 1, 1, 1), - pos = c(100, 200, 300, 400), - A2 = c("A", "A", "A", "A"), - A1 = c("G", "G", "G", "G"), - z = c(1, 2, 3, 4), - stringsAsFactors = FALSE - ) - ref <- data.frame( - chrom = c(1, 1, 1, 1), - pos = c(100, 200, 300, 400), - A2 = c("A", "G", "T", "C"), - A1 = c("G", "A", "C", "A"), - stringsAsFactors = FALSE - ) - res <- pecotmr:::harmonizeAlleles( - target, - ref, - colToFlip = "z", - matchMinProp = 0 - ) - # Default return shape unchanged. - expect_named(res, c("harmonizedData", "qcSummary")) - expect_equal(nrow(res$harmonizedData), 3L) - cnt <- attr(res, "qcCounts") - expect_false(is.null(cnt)) - expect_equal(cnt$considered, 4L) - expect_equal(cnt$signFlip, 1L) - expect_equal(cnt$strandFlip, 1L) - expect_equal(cnt$kept, 3L) - expect_equal(cnt$dropped, 1L) -}) - test_that("summaryStatsQc: QC track emits per-step messages and a rollup", { ss <- .ssQ_makeGwasSumStats() local_mocked_bindings( @@ -3524,7 +3258,7 @@ context("sumstatsQc internal helpers") format = "plink2", snpInfo = data.frame( SNP = paste0("rs", seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -3607,7 +3341,7 @@ test_that(".entryGrangesToDf: extracts chrom/pos and all mcols", { gr <- .ssh_makeEntryGr(3, with_extras = TRUE) df <- pecotmr:::.entryGrangesToDf(gr) expect_s3_class(df, "data.frame") - expect_equal(df$chrom, rep("1", 3)) # "chr" stripped + expect_equal(df$chrom, rep("chr1", 3)) expect_equal(df$pos, c(100L, 200L, 300L)) expect_setequal( intersect( @@ -3671,7 +3405,7 @@ test_that("entry GRanges round-trips through df conversion", { test_that(".refVariantsFromLdRef: extracts chr/pos/alleles from snpInfo", { h <- .ssh_makeHandle() rv <- pecotmr:::.refVariantsFromLdRef(h) - expect_equal(rv$chrom, rep("1", 6)) # "chr" stripped + expect_equal(rv$chrom, rep("chr1", 6)) expect_equal(rv$pos, c(100L, 200L, 300L, 400L, 500L, 600L)) expect_equal(rv$variant_id, paste0("rs", 1:6)) expect_equal(rv$A1, rep("A", 6)) @@ -3679,19 +3413,9 @@ test_that(".refVariantsFromLdRef: extracts chr/pos/alleles from snpInfo", { }) # =========================================================================== -# .applySkipRegion +# .applySanityChecks # =========================================================================== -.ssh_smallDf <- function() { - data.frame( - chrom = c("1", "1", "2"), - pos = c(100L, 200L, 100L), - SNP = c("rs1", "rs2", "rs3"), - Z = c(1, 2, 3), - stringsAsFactors = FALSE - ) -} - test_that(".applySanityChecks: empty input is a no-op", { out <- pecotmr:::.applySanityChecks(data.frame(chrom = character())) expect_equal(nrow(out$df), 0L) @@ -3724,7 +3448,7 @@ test_that(".applySanityChecks: normalizeChr maps 23/24/M, drops others", { stringsAsFactors = FALSE ) out <- pecotmr:::.applySanityChecks(df) - expect_equal(out$df$chrom, c("1", "X", "Y", "MT")) + expect_equal(out$df$chrom, c("chr1", "chrX", "chrY", "chrM")) expect_equal(out$audit$nonstandardChrDropped, 1L) }) @@ -3843,55 +3567,67 @@ test_that("summaryStatsQc: surfaces the sanity audit, honours the knobs", { ldReference = .ssQ_makeHandle() ) res <- summaryStatsQc(ss) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_equal(ea$sanityChecks$zeroEffectDropped, 2L) # Disable the knob: zero-effect rows should remain. res2 <- summaryStatsQc( ss, sumstatsCleaningParam = SumstatsCleaningParam(dropZeroEffect = FALSE) ) - ea2 <- qcInfo(res2)$entryAudit[[1L]] + ea2 <- res2$qcAudit[[1L]] expect_null(ea2$sanityChecks$zeroEffectDropped) }) +# =========================================================================== +# .applySkipRegion +# =========================================================================== + +.ssh_smallDf <- function() { + data.frame( + chrom = c("chr1", "chr1", "chr2"), + pos = c(100L, 200L, 100L), + SNP = c("rs1", "rs2", "rs3"), + Z = c(1, 2, 3), + stringsAsFactors = FALSE + ) +} + test_that(".applySkipRegion: NULL / empty skipRegion is a no-op", { df <- .ssh_smallDf() expect_identical(pecotmr:::.applySkipRegion(df, NULL), df) - expect_identical(pecotmr:::.applySkipRegion(df, character()), df) -}) - -test_that(".applySkipRegion: drops variants in a single character region", { - df <- .ssh_smallDf() - out <- pecotmr:::.applySkipRegion(df, "1:50-150") - expect_equal(out$SNP, c("rs2", "rs3")) + expect_identical( + pecotmr:::.applySkipRegion(df, GenomicRanges::GRanges()), + df + ) }) -test_that(".applySkipRegion: handles multiple regions and chr-prefixed input", { +test_that(".applySkipRegion: handles multiple regions", { df <- .ssh_smallDf() - out <- pecotmr:::.applySkipRegion(df, c("chr1:50-250", "chr2:50-150")) + out <- pecotmr:::.applySkipRegion( + df, + GenomicRanges::GRanges(c("chr1:50-250", "chr2:50-150")) + ) expect_equal(nrow(out), 0L) }) test_that(".applySkipRegion: accepts a GRanges of skip regions", { df <- .ssh_smallDf() + # A window spelled "1" is read as chr1, as every range argument is. gr <- GenomicRanges::GRanges("1", IRanges::IRanges(start = 50, end = 150)) out <- pecotmr:::.applySkipRegion(df, gr) expect_equal(out$SNP, c("rs2", "rs3")) }) -test_that(".applySkipRegion: rejects malformed character entries", { +test_that(".applySkipRegion: refuses anything but a GRanges", { df <- .ssh_smallDf() + # A window given in R is a GRanges; a string is refused, not read. expect_error( - pecotmr:::.applySkipRegion(df, "garbage"), - "must be 'chr:start-end'" + pecotmr:::.applySkipRegion(df, "1:50-150"), + "`skipRegion` must be a GRanges \\(got character\\)" ) -}) - -test_that(".applySkipRegion: rejects non-character non-GRanges input", { - df <- .ssh_smallDf() expect_error( pecotmr:::.applySkipRegion(df, 42L), - "must be a character vector" + "`skipRegion` must be a GRanges" ) }) @@ -4116,7 +3852,7 @@ test_that("fine-mapping keeps onMissing='error' for an absent variant", { "chr1:200:G:A", "chr1:300:C:T" ), - CHR = rep("1", 4L), + CHR = rep("chr1", 4L), BP = c(100L, 200L, 200L, 300L), A1 = c("G", "G", "A", "T"), A2 = c("A", "A", "G", "C"), @@ -4329,30 +4065,28 @@ test_that(".applyEntryScreen: bf / logBf screens use the SER lbf_variable", { }) test_that("summaryStatsQc: absZ / bf / logBf screens skip a no-signal entry", { - mk <- function() { - gr <- .ssQ_makeEntryGr() - S4Vectors::mcols(gr)$Z <- rep(0.1, length(gr)) - GwasSumStats( - studyName = "g1", - entry = list(gr), - genome = "hg19", - ldReference = .ssQ_makeHandle() - ) - } - for (arg in list( - list(signalScreenParam = SignalScreenParam(absZ = 5)), - list(signalScreenParam = SignalScreenParam(bf = 100)), - list(signalScreenParam = SignalScreenParam(logBf = 5)) - )) { - res <- exec( - summaryStatsQc, - mk(), - !!!arg, + gr <- .ssQ_makeEntryGr() + S4Vectors::mcols(gr)$Z <- rep(0.1, length(gr)) + ss <- GwasSumStats( + studyName = "g1", + entry = list(gr), + genome = "hg19", + ldReference = .ssQ_makeHandle() + ) + screens <- list( + absZ = SignalScreenParam(absZ = 5), + bf = SignalScreenParam(bf = 100), + logBf = SignalScreenParam(logBf = 5) + ) + for (metric in names(screens)) { + res <- summaryStatsQc( + ss, + signalScreenParam = screens[[metric]], sumstatsFilterParam = SumstatsFilterParam(nCutoff = 0) ) - ea <- qcInfo(res)$entryAudit[[1L]] - expect_true(isTRUE(ea$pipScreenSkipped)) - expect_equal(length(res[[1L]]), 0L) + ea <- res$qcAudit[[1L]] + expect_true(isTRUE(ea$pipScreenSkipped), info = metric) + expect_equal(length(res[[1L]]), 0L, info = metric) } }) @@ -4372,7 +4106,7 @@ test_that("summaryStatsQc: absZ screen keeps a strong marginal Z", { signalScreenParam = SignalScreenParam(absZ = 5), sumstatsFilterParam = SumstatsFilterParam(nCutoff = 0) ) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_false(isTRUE(ea$pipScreenSkipped)) expect_gt(length(res[[1L]]), 0L) }) @@ -4446,53 +4180,42 @@ generateDentistSingleWindowData <- function( # dentist: basic tests # =========================================================================== -test_that("dentist output has exactly N rows for N input variants", { +test_that("dentist returns one row per variant under each DentistParam", { data <- generateDentistData(nSnps = 100) - expect_warning( - res <- dentist(data$sumstat, R = data$ldMat, nSample = data$nSample) - ) - expect_equal(nrow(res), 100) -}) - -test_that("dentist output has exactly N rows with correctChenEtAlBug = FALSE", { - data <- generateDentistData(nSnps = 100) - expect_warning( - res <- dentist( - data$sumstat, - R = data$ldMat, - nSample = data$nSample, - dentistParam = DentistParam(correctChenEtAlBug = FALSE) + params <- list( + default = DentistParam(), + correctChenEtAlBug = DentistParam(correctChenEtAlBug = FALSE), + gcControl = DentistParam(gcControl = TRUE) + ) + for (nm in names(params)) { + expect_warning( + res <- dentist( + data$sumstat, + R = data$ldMat, + nSample = data$nSample, + dentistParam = params[[nm]] + ), + info = nm ) - ) - expect_equal(nrow(res), 100) -}) - -test_that("dentist stops when missing position", { - data <- generateDentistData() - colnames(data$sumstat) <- c("something", "z") - expect_error( - dentist( - data$sumstat, - R = data$ldMat, - nSample = data$nSample, - dentistParam = DentistParam(correctChenEtAlBug = FALSE) - ), - regexp = "missing either.*pos.*or.*z" - ) + expect_equal(nrow(res), 100, info = nm) + } }) -test_that("dentist stops when missing zscore", { +test_that("dentist stops when the position or z column is missing", { data <- generateDentistData() - colnames(data$sumstat) <- c("position", "something") - expect_error( - dentist( - data$sumstat, - R = data$ldMat, - nSample = data$nSample, - dentistParam = DentistParam(correctChenEtAlBug = FALSE) - ), - regexp = "missing either.*pos.*or.*z" - ) + for (cols in list(c("something", "z"), c("position", "something"))) { + sumstat <- `colnames<-`(data$sumstat, cols) + expect_error( + dentist( + sumstat, + R = data$ldMat, + nSample = data$nSample, + dentistParam = DentistParam(correctChenEtAlBug = FALSE) + ), + regexp = "missing either.*pos.*or.*z", + info = str_flatten(cols, " / ") + ) + } }) test_that("dentist accepts 'position' and 'zscore' column names", { @@ -4556,6 +4279,7 @@ test_that("dentistSingleWindow from genotypes matches DENTIST on their LD", { d <- .dentistFactorData() viaX <- suppressWarnings(dentistSingleWindow(d$z, X = d$X)) viaR <- suppressWarnings(dentistSingleWindow(d$z, R = d$R, nSample = d$n)) + expect_equal(nrow(viaX), length(d$z)) expect_equal(viaX, viaR, tolerance = 1e-8) }) @@ -4595,49 +4319,17 @@ test_that("the duplicate scan reads a factor as it reads the LD", { # dentistSingleWindow # =========================================================================== -test_that("dentistSingleWindow returns exactly N rows for N input z-scores", { +test_that("dentistSingleWindow returns one row per z-score under each option", { + # Every option set keeps the input z, reports the documented columns and + # an outlier_stat of (z - imputed)^2 / (1 - rsq); fewer than 2000 + # variants also draw DENTIST's size warning. data <- generateDentistSingleWindowData() - expect_warning( - res <- dentistSingleWindow( - data$z_scores, - R = data$ldMat, - nSample = data$nSample - ) + options <- list( + default = list(), + correctChenEtAlBug = list(correctChenEtAlBug = FALSE), + gcControl = list(gcControl = TRUE) ) - expect_equal(nrow(res), 100) -}) - -test_that("dentistSingleWindow warns when < 2000 variants", { - data <- generateDentistSingleWindowData() - expect_warning(dentistSingleWindow( - data$z_scores, - R = data$ldMat, - nSample = data$nSample - )) -}) - -test_that("dentistSingleWindow stops on a zscore/LD dimension mismatch", { - data <- generateDentistSingleWindowData() - expect_warning(expect_error( - dentistSingleWindow( - generateDentistSingleWindowData()$z_scores, - R = generateDentistSingleWindowData(nSnps = 80)$ldMat, - nSample = data$nSample - ), - regexp = "ldMat must be a square matrix" - )) -}) - -test_that("dentistSingleWindow output columns are correct", { - data <- generateDentistSingleWindowData() - expect_warning( - res <- dentistSingleWindow( - data$z_scores, - R = data$ldMat, - nSample = data$nSample - ) - ) - expected_cols <- c( + expectedCols <- c( "original_z", "imputed_z", "iter_to_correct", @@ -4646,108 +4338,48 @@ test_that("dentistSingleWindow output columns are correct", { "outlier_stat", "outlier" ) - expect_true(all(expected_cols %in% colnames(res))) -}) - -test_that("dentistSingleWindow original_z matches input z-scores", { - data <- generateDentistSingleWindowData() - expect_warning( - res <- dentistSingleWindow( - data$z_scores, - R = data$ldMat, - nSample = data$nSample + for (nm in names(options)) { + expect_warning( + res <- exec( + dentistSingleWindow, + data$z_scores, + R = data$ldMat, + nSample = data$nSample, + !!!options[[nm]] + ), + "below 2000", + info = nm ) - ) - expect_equal(res$original_z, data$z_scores) -}) - -test_that("dentistSingleWindow with X matrix input returns exactly N rows", { - set.seed(42) - nSnps <- 80 - n_samples <- 100 - X <- matrix( - rbinom(nSnps * n_samples, 2, 0.3), - nrow = n_samples, - ncol = nSnps - ) - z_scores <- rnorm(nSnps) - expect_warning(res <- dentistSingleWindow(z_scores, X = X)) - expect_equal(nrow(res), nSnps) -}) - -test_that("dentistSingleWindow correctChenEtAlBug = FALSE returns N rows", { - data <- generateDentistSingleWindowData() - expect_warning( - res <- dentistSingleWindow( - data$z_scores, - R = data$ldMat, - nSample = data$nSample, - correctChenEtAlBug = FALSE + expect_equal(nrow(res), 100, info = nm) + expect_true(all(expectedCols %in% colnames(res)), info = nm) + expect_type(res$outlier, "logical") + expect_equal(res$original_z, data$z_scores, info = nm) + expect_equal( + res$outlier_stat, + (res$original_z - res$imputed_z)^2 / pmax(1 - res$rsq, 1e-8), + tolerance = 1e-10, + info = nm ) - ) - expect_equal(nrow(res), 100) - expect_true(all(c("original_z", "imputed_z", "outlier") %in% colnames(res))) + } }) -test_that("dentistSingleWindow with gcControl = TRUE returns N rows", { +test_that("dentistSingleWindow stops on a zscore/LD dimension mismatch", { data <- generateDentistSingleWindowData() - expect_warning( - res <- dentistSingleWindow( - data$z_scores, - R = data$ldMat, - nSample = data$nSample, - gcControl = TRUE - ) - ) - expect_equal(nrow(res), 100) - expect_true(all(c("original_z", "imputed_z", "outlier") %in% colnames(res))) -}) - -test_that("dentist with gcControl = TRUE returns N rows", { - data <- generateDentistData(nSnps = 100) - expect_warning( - res <- dentist( - data$sumstat, - R = data$ldMat, - nSample = data$nSample, - dentistParam = DentistParam(gcControl = TRUE) - ) - ) - expect_equal(nrow(res), 100) -}) - -test_that("dentistSingleWindow dedup path with message for duplicates", { - set.seed(42) - nSnps <- 80 - n_samples <- 100 - cor_matrix <- matrix(0, nrow = nSnps, ncol = nSnps) - for (i in seq_len(nSnps - 1)) { - for (j in (i + 1):nSnps) { - cor_matrix[i, j] <- runif(1, 0.2, 0.8) - cor_matrix[j, i] <- cor_matrix[i, j] - } - } - diag(cor_matrix) <- 1 - ld_matrix <- cov2cor(make.positive.definite(cor_matrix)) - z_scores <- mvrnorm(n = 1, mu = rep(0, nSnps), Sigma = ld_matrix) - # Use a very low threshold to trigger dedup logic - expect_warning( - res <- dentistSingleWindow( - z_scores, - R = ld_matrix, - nSample = n_samples, - duprThreshold = 0.5 - ) - ) - expect_equal(nrow(res), nSnps) - expect_true("is_duplicate" %in% colnames(res)) + expect_warning(expect_error( + dentistSingleWindow( + generateDentistSingleWindowData()$z_scores, + R = generateDentistSingleWindowData(nSnps = 80)$ldMat, + nSample = data$nSample + ), + regexp = "ldMat must be a square matrix" + )) }) # =========================================================================== -# add_dups_back_dentist +# addDupsBackDentist # =========================================================================== -test_that("add_dups_back_dentist works", { +test_that("addDupsBackDentist works", { zScore <- c(1.2, 2.3, 2.4, 1.4, 5.6) dentist_output <- data.frame( original_z = c(1.2, 2.3, 5.6), @@ -4777,40 +4409,11 @@ test_that("add_dups_back_dentist works", { expect_equal(res$is_duplicate, c(FALSE, FALSE, TRUE, TRUE, FALSE)) }) -test_that("add_dups_back_dentist stops when nrow mismatch", { - z_scores <- rep(0, 5) - dentist_output <- list( - original_z = c(1, 2, 3, 4, 5), - imputed_z = c(1, 2, 3, 4, 5), - iter_to_correct = c(1, 2, 3, 4, 5), - rsq = c(1, 2, 3, 4, 5), - z_diff = c(1, 2, 3, 4, 5) - ) - find_dup_output <- list( - dupBearer = c(-1, -1, -1, -1, -1, -1), - sign = c(1, 2, 3, 4, 5, 6) - ) - expect_error(pecotmr:::addDupsBackDentist( - z_scores, - dentist_output, - find_dup_output - )) -}) - # =========================================================================== -# segment_by_dist +# segmentByDist # =========================================================================== -test_that("segment_by_dist works", { - res <- pecotmr:::segmentByDist( - seq(2000000, 5000000, 100000), - maxDist = 2000000, - minDim = 10 - ) - expect_true(nrow(res) >= 1) -}) - -test_that("segment_by_dist fill regions cover all input positions", { +test_that("segmentByDist fill regions cover all input positions", { # Verify that fill regions cover every SNP index exactly once pos <- seq(1000000, 5000000, length.out = 200) res <- pecotmr:::segmentByDist(pos, maxDist = 2000000, minDim = 10) @@ -4823,11 +4426,11 @@ test_that("segment_by_dist fill regions cover all input positions", { expect_equal(sort(unique(covered)), seq_along(pos)) }) -test_that("segment_by_dist errors on empty positions", { +test_that("segmentByDist errors on empty positions", { expect_error(pecotmr:::segmentByDist(integer(0)), "No positions") }) -test_that("segment_by_dist verbose mode prints intervals", { +test_that("segmentByDist verbose mode prints intervals", { pos <- seq(1000000, 5000000, length.out = 300) expect_message( pecotmr:::segmentByDist( @@ -4841,34 +4444,24 @@ test_that("segment_by_dist verbose mode prints intervals", { }) # =========================================================================== -# detect_gaps +# detectGaps # =========================================================================== -test_that("detect_gaps finds no internal gaps for contiguous positions", { +test_that("detectGaps finds no internal gaps for contiguous positions", { pos <- seq(1000, by = 100, length.out = 50) gaps <- pecotmr:::detectGaps(pos, gapThreshold = 500) # Only start and end sentinel expect_equal(gaps, c(1L, 51L)) }) -test_that("detect_gaps finds a centromeric gap", { - pos <- c( - seq(1000, by = 100, length.out = 50), - seq(2000000, by = 100, length.out = 50) - ) - gaps <- pecotmr:::detectGaps(pos, gapThreshold = 1e6) - expect_equal(length(gaps), 3) # start, gap, end - expect_equal(gaps, c(1L, 51L, 101L)) -}) - -test_that("detect_gaps finds multiple gaps", { +test_that("detectGaps finds multiple gaps", { pos <- c(1000, 2000, 5000000, 6000000, 12000000) gaps <- pecotmr:::detectGaps(pos, gapThreshold = 1e6) # Gaps at positions 3 and 5 (diffs > 1e6 at indices 2 and 4) expect_equal(gaps, c(1L, 3L, 5L, 6L)) }) -test_that("detect_gaps verbose branch prints messages", { +test_that("detectGaps verbose branch prints messages", { pos <- c(1000, 2000, 5000000, 6000000) expect_message( pecotmr:::detectGaps(pos, gapThreshold = 1e6, verbose = TRUE), @@ -4877,27 +4470,22 @@ test_that("detect_gaps verbose branch prints messages", { }) # =========================================================================== -# segment_by_count +# segmentByCount # =========================================================================== -test_that("segment_by_count produces valid windows", { - pos <- seq(1000000, by = 1000, length.out = 500) +test_that("segmentByCount tiles one block with valid, covering windows", { + # 200 variants with maxCount = 100 make a few overlapping windows. + pos <- seq(1000000, by = 1000, length.out = 200) res <- pecotmr:::segmentByCount(pos, maxCount = 100) - expect_true(nrow(res) >= 1) - # All window starts should be >= 1 + expect_true(nrow(res) >= 2) + expect_true(nrow(res) <= 5) + # Window indices stay in range (end indices are 1-based exclusive) and + # each fill region sits inside its window. expect_true(all(res$windowStartIdx >= 1)) - # All window ends should be <= length(pos) + 1 expect_true(all(res$windowEndIdx <= length(pos) + 1)) - # Fill regions should be within windows - for (k in seq_len(nrow(res))) { - expect_true(res$fillStartIdx[k] >= res$windowStartIdx[k]) - expect_true(res$fillEndIdx[k] <= res$windowEndIdx[k]) - } -}) - -test_that("segment_by_count fill regions cover all positions", { - pos <- seq(1000000, by = 1000, length.out = 500) - res <- pecotmr:::segmentByCount(pos, maxCount = 100) + expect_true(all(res$fillStartIdx >= res$windowStartIdx)) + expect_true(all(res$fillEndIdx <= res$windowEndIdx)) + # The fill regions tile every position. covered <- integer(0) for (k in seq_len(nrow(res))) { covered <- c(covered, res$fillStartIdx[k]:(res$fillEndIdx[k] - 1L)) @@ -4905,7 +4493,7 @@ test_that("segment_by_count fill regions cover all positions", { expect_equal(sort(unique(covered)), seq_along(pos)) }) -test_that("segment_by_count handles centromeric gap", { +test_that("segmentByCount handles centromeric gap", { # Create two blocks separated by a large gap pos <- c( seq(1000000, by = 1000, length.out = 200), @@ -4922,8 +4510,8 @@ test_that("segment_by_count handles centromeric gap", { expect_equal(sort(unique(covered)), seq_along(pos)) }) -test_that("segment_by_count skips blocks smaller than half max_count", { - # Block of 20 variants with max_count=100 (half=50): too small, should be skipped +test_that("segmentByCount skips blocks smaller than half maxCount", { + # 20 variants with maxCount = 100 (half = 50): too small, so skipped. pos <- seq(1000000, by = 1000, length.out = 20) expect_error( pecotmr:::segmentByCount(pos, maxCount = 100), @@ -4931,8 +4519,8 @@ test_that("segment_by_count skips blocks smaller than half max_count", { ) }) -test_that("segment_by_count creates single window for small blocks", { - # Block of 60 variants with max_count=100: creates one window (60 >= half=50) +test_that("segmentByCount creates single window for small blocks", { + # 60 variants with maxCount = 100 make one window (60 >= half = 50). pos <- seq(1000000, by = 1000, length.out = 60) res <- pecotmr:::segmentByCount(pos, maxCount = 100) expect_equal(nrow(res), 1) @@ -4940,22 +4528,14 @@ test_that("segment_by_count creates single window for small blocks", { expect_equal(res$windowEndIdx[1], 61) }) -test_that("segment_by_count single block creates correct number of windows", { - # 200 variants with maxCount = 100 should create ~3 windows - pos <- seq(1000000, by = 1000, length.out = 200) - res <- pecotmr:::segmentByCount(pos, maxCount = 100) - expect_true(nrow(res) >= 2) - expect_true(nrow(res) <= 5) -}) - -test_that("segment_by_count errors on empty positions", { +test_that("segmentByCount errors on empty positions", { expect_error( pecotmr:::segmentByCount(integer(0), maxCount = 100), "No positions" ) }) -test_that("segment_by_count verbose mode prints intervals", { +test_that("segmentByCount verbose mode prints intervals", { pos <- seq(1000000, by = 1000, length.out = 300) expect_message( pecotmr:::segmentByCount(pos, maxCount = 100, verbose = TRUE), @@ -4964,12 +4544,15 @@ test_that("segment_by_count verbose mode prints intervals", { }) # =========================================================================== -# merge_windows +# mergeWindows # =========================================================================== -test_that("merge_windows returns exactly N rows", { +test_that("mergeWindows returns exactly N rows", { + # 300 variants over 2 kb with maxDist = 1000 make four overlapping + # windows; the LD build is cubic in the variant count, so no more. + nSnps <- 300L data <- generateDentistData( - nSnps = 1000, + nSnps = nSnps, sample_size = 1000, start_pos = 0, end_pos = 2000 @@ -4997,23 +4580,26 @@ test_that("merge_windows returns exactly N rows", { nIter = 10, gPvalueThreshold = 0.05, duprThreshold = 0.99, - numThreads = 1, + BPPARAM = BiocParallel::SerialParam(), correctChenEtAlBug = TRUE ) } }) res <- pecotmr:::mergeWindows(dentist_result_by_window, window_divided_res) - expect_equal(nrow(res), 1000) + expect_equal(nrow(res), nSnps) }) -test_that("merge_windows stops with window and imputed mismatch", { - expect_error(pecotmr:::mergeWindows( - rep(0, 5), - data.frame(windowStartIdx = rep(0, 2), windowEndIdx = rep(0, 2)) - )) +test_that("mergeWindows stops with window and imputed mismatch", { + expect_error( + pecotmr:::mergeWindows( + rep(0, 5), + data.frame(windowStartIdx = rep(0, 2), windowEndIdx = rep(0, 2)) + ), + "Different number of windows and imputed results" + ) }) -test_that("merge_windows correctly indexes and merges windows", { +test_that("mergeWindows correctly indexes and merges windows", { # Create two fake windows window1 <- data.frame( original_z = c(1.0, 2.0, 3.0), @@ -5051,12 +4637,15 @@ test_that("merge_windows correctly indexes and merges windows", { # =========================================================================== test_that("dentist windowed output has exactly N rows for large input", { - # Generate data large enough to trigger windowed mode (> min_dim) + # 300 variants over 5 Mb with windowSize = 2e6 make five overlapping + # windows of more than minDim variants each; the LD build is cubic in + # the variant count, so no more. + nSnps <- 300L data <- generateDentistData( seed = 123, - nSnps = 1000, + nSnps = nSnps, sample_size = 1000, - n_outliers = 50, + n_outliers = 15, start_pos = 0, end_pos = 5000000 ) @@ -5069,21 +4658,7 @@ test_that("dentist windowed output has exactly N rows for large input", { windowSize = 2000000 ) }) - expect_equal(nrow(res), 1000) -}) - -test_that("dentist outlier_stat formula is correct: (z-imputed)^2/(1-rsq)", { - data <- generateDentistSingleWindowData(seed = 55, nSnps = 100) - expect_warning( - res <- dentistSingleWindow( - data$z_scores, - R = data$ldMat, - nSample = data$nSample - ) - ) - expected_stat <- (res$original_z - res$imputed_z)^2 / - pmax(1 - res$rsq, 1e-8) - expect_equal(res$outlier_stat, expected_stat, tolerance = 1e-10) + expect_equal(nrow(res), nSnps) }) # =========================================================================== @@ -5112,113 +4687,24 @@ test_that("dentist with window_mode='count' returns exactly N rows", { }) # =========================================================================== -# Equivalence tests: both windowing methods +# resolveLdInput (internal) # =========================================================================== -test_that("segment_by_dist and segment_by_count agree on even spacing", { - n <- 200 - spacing <- 10000 # 10kb between each variant - pos <- seq(1000000, by = spacing, length.out = n) - window_count <- 50 # variants per window in count mode - window_dist <- window_count * spacing # equivalent distance - - res_dist <- pecotmr:::segmentByDist(pos, maxDist = window_dist, minDim = 10) - res_count <- pecotmr:::segmentByCount( - pos, - maxCount = window_count, - gapDist = 1e6 - ) - - # Both should cover all positions - covered_dist <- integer(0) - for (k in seq_len(nrow(res_dist))) { - covered_dist <- c( - covered_dist, - res_dist$fillStartIdx[k]:(res_dist$fillEndIdx[k] - 1L) - ) - } - covered_count <- integer(0) - for (k in seq_len(nrow(res_count))) { - covered_count <- c( - covered_count, - res_count$fillStartIdx[k]:(res_count$fillEndIdx[k] - 1L) - ) - } - expect_equal(sort(unique(covered_dist)), seq_len(n)) - expect_equal(sort(unique(covered_count)), seq_len(n)) -}) - -test_that("both windowing modes produce same dentist results on uniform data", { - data <- generateDentistData( - seed = 555, - nSnps = 500, - sample_size = 500, - n_outliers = 25, - start_pos = 0, - end_pos = 5000000 - ) - suppressWarnings({ - res_dist <- dentist( - data$sumstat, - R = data$ldMat, - nSample = data$nSample, - windowMode = "distance", - minDim = 100, - windowSize = 2000000 - ) - res_count <- dentist( - data$sumstat, - R = data$ldMat, - nSample = data$nSample, - windowMode = "count", - minDim = 100 - ) - }) - # Both should return exactly N rows - expect_equal(nrow(res_dist), 500) - expect_equal(nrow(res_count), 500) -}) - -# =========================================================================== -# resolve_LD_input (internal) -# =========================================================================== - -test_that("resolve_LD_input errors when neither R nor X provided", { - expect_error( - pecotmr:::resolveLdInput(R = NULL, X = NULL), - "Either R.*or X.*must be provided" - ) -}) - -test_that("resolve_LD_input errors when both R and X provided", { - R <- diag(3) - X <- matrix(1:9, nrow = 3) - expect_error( - pecotmr:::resolveLdInput(R = R, X = X), - "Provide either R or X, not both" - ) -}) - -test_that("resolve_LD_input errors on R without nSample when required", { - R <- diag(3) - expect_error( - pecotmr:::resolveLdInput(R = R, nSample = NULL, needNSample = TRUE), - "nSample is required" - ) -}) - -test_that("resolve_LD_input returns nSample = NULL when not needed", { +test_that("resolveLdInput passes R through, with or without its nSample", { R <- diag(3) + result <- pecotmr:::resolveLdInput(R = R, needNSample = FALSE) + expect_equal(result$R, R) + expect_null(result$nSample) result <- pecotmr:::resolveLdInput( R = R, - nSample = NULL, - needNSample = FALSE + nSample = 100L, + needNSample = TRUE ) - expect_null(result$nSample) expect_equal(result$R, R) + expect_equal(result$nSample, 100L) }) -test_that("resolve_LD_input infers nSample from X", { +test_that("resolveLdInput computes the LD and nSample from genotypes", { set.seed(42) n <- 50 p <- 5 @@ -5226,10 +4712,12 @@ test_that("resolve_LD_input infers nSample from X", { result <- pecotmr:::resolveLdInput(X = X, needNSample = TRUE) expect_equal(result$nSample, n) expect_true(is.matrix(result$R)) - expect_equal(nrow(result$R), p) + expect_equal(dim(result$R), c(p, p)) + expect_true(isSymmetric(result$R)) + expect_equal(diag(result$R), rep(1, p), tolerance = 1e-6) }) -test_that("resolve_LD_input converts non-matrix X to matrix", { +test_that("resolveLdInput converts a non-matrix X to a matrix", { set.seed(42) X_df <- data.frame(a = rbinom(30, 2, 0.3), b = rbinom(30, 2, 0.3)) result <- pecotmr:::resolveLdInput(X = X_df, needNSample = FALSE) @@ -5237,18 +4725,36 @@ test_that("resolve_LD_input converts non-matrix X to matrix", { expect_equal(result$nSample, 30) }) -test_that("resolve_LD_input uses explicit nSample when X provided", { +test_that("resolveLdInput keeps an explicit nSample given with X", { set.seed(42) X <- matrix(rbinom(100, 2, 0.3), nrow = 20, ncol = 5) result <- pecotmr:::resolveLdInput(X = X, nSample = 999, needNSample = TRUE) expect_equal(result$nSample, 999) }) +test_that("resolveLdInput needs exactly one of R and X", { + expect_error( + pecotmr:::resolveLdInput(), + "Either R.*or X.*must be provided" + ) + expect_error( + pecotmr:::resolveLdInput(R = diag(3), X = matrix(1:9, nrow = 3)), + "Provide either R or X, not both" + ) +}) + +test_that("resolveLdInput needs nSample with R when one is required", { + expect_error( + pecotmr:::resolveLdInput(R = diag(3), needNSample = TRUE), + "nSample is required" + ) +}) + # =========================================================================== -# build_segment_result (internal) +# buildSegmentResult (internal) # =========================================================================== -test_that("build_segment_result caps end indices and verbose prints", { +test_that("buildSegmentResult caps end indices and verbose prints", { expect_message( result <- pecotmr:::buildSegmentResult( startList = c(1L), @@ -5264,7 +4770,7 @@ test_that("build_segment_result caps end indices and verbose prints", { expect_equal(result$fillEndIdx[1], 101) }) -test_that("build_segment_result errors on empty startList", { +test_that("buildSegmentResult errors on empty startList", { expect_error( pecotmr:::buildSegmentResult( startList = integer(0), @@ -5278,10 +4784,10 @@ test_that("build_segment_result errors on empty startList", { }) # =========================================================================== -# sliding_window_loop (iteration limit) +# slidingWindowLoop (iteration limit) # =========================================================================== -test_that("sliding_window_loop errors on infinite loop", { +test_that("slidingWindowLoop errors on infinite loop", { allGaps <- c(1L, 1001L) expect_error( pecotmr:::slidingWindowLoop( @@ -5360,6 +4866,10 @@ test_that("autoDecision assigns SER for single CS", { expect_equal(result$method, "SER") }) +# =========================================================================== +# summaryStatsQc: study-level case/control counts +# =========================================================================== + test_that("summaryStatsQc: preserves nCase/nControl columns through QC", { gr <- .ssQ_makeEntryGr(paste0("rs", 1:4), c(100L, 200L, 300L, 400L)) ss <- GwasSumStats( @@ -5440,254 +4950,54 @@ test_that("mergeVariantInfo (data.frame): all = FALSE returns variants2", { test_that("mergeVariantInfo (GRanges): converts inputs and detects flips", { ssqcMakeGr <- function(chrom, pos, alt, ref) { gr <- GenomicRanges::GRanges( - seqnames = paste0("chr", chrom), - ranges = IRanges::IRanges(start = pos, width = 1L) - ) - S4Vectors::mcols(gr) <- S4Vectors::DataFrame(alt = alt, ref = ref) - gr - } - g1 <- ssqcMakeGr( - c(1, 1, 2), - c(100, 200, 300), - c("A", "C", "G"), - c("G", "T", "A") - ) - g2 <- ssqcMakeGr( - c(1, 1, 3), - c(100, 200, 400), - c("A", "T", "C"), - c("G", "C", "A") - ) - out <- mergeVariantInfo(g1, g2, all = TRUE) - expect_s3_class(out, "data.frame") - expect_equal(nrow(out), 4L) - flipped <- out[out$chrom == "chr1" & out$pos == 200, ] - expect_equal(flipped$alt, "C") - expect_equal(flipped$ref, "T") -}) - -test_that("mergeVariantInfo does not warn on length-mismatch recycling", { - # Regression guard: the flip vector must be full-length so `hasMatch & ...` - # never recycles a subset-length comparison. - v1 <- data.frame( - chrom = c("1", "1", "2"), - pos = c(100, 200, 300), - alt = c("A", "C", "G"), - ref = c("G", "T", "A"), - stringsAsFactors = FALSE - ) - v2 <- data.frame( - chrom = c("1", "1", "3"), - pos = c(100, 200, 400), - alt = c("A", "T", "C"), - ref = c("G", "C", "A"), - stringsAsFactors = FALSE - ) - expect_no_warning(out <- mergeVariantInfo(v1, v2, all = TRUE)) - # Behaviour is unchanged: the flipped row collapses onto v1's orientation. - flipped <- out[out$chrom == "1" & out$pos == 200, ] - expect_equal(flipped$alt, "C") - expect_equal(flipped$ref, "T") -}) - -# =========================================================================== -# harmonizeAlleles uncovered branches -# =========================================================================== - -test_that("harmonizeAlleles: accepts a bare variant-id vector as target", { - res <- pecotmr:::harmonizeAlleles( - c("chr1:100:A:G", "chr1:200:C:T"), - c("chr1:100:A:G", "chr1:200:C:T"), - matchMinProp = 0 - ) - expect_equal(nrow(res$harmonizedData), 2L) -}) - -test_that("harmonizeAlleles: strips a conflicting variant_id from target", { - target <- data.frame( - chrom = c(1, 1), - pos = c(100, 200), - A2 = c("A", "C"), - A1 = c("G", "T"), - variant_id = c("old1", "old2"), - z = c(1, 2), - stringsAsFactors = FALSE - ) - ref <- data.frame( - chrom = c(1, 1), - pos = c(100, 200), - A2 = c("A", "C"), - A1 = c("G", "T"), - stringsAsFactors = FALSE - ) - res <- pecotmr:::harmonizeAlleles( - target, - ref, - colToFlip = "z", - matchMinProp = 0 - ) - expect_equal(nrow(res$harmonizedData), 2L) - # The input variant_id was stripped; the returned id is rebuilt from QC'd alleles. - expect_false(any(c("old1", "old2") %in% res$harmonizedData$variant_id)) -}) - -test_that("harmonizeAlleles: errors when colToFlip column is absent", { - target <- data.frame( - chrom = 1, - pos = 100, - A2 = "A", - A1 = "G", - z = 1, - stringsAsFactors = FALSE - ) - ref <- data.frame( - chrom = 1, - pos = 100, - A2 = "A", - A1 = "G", - stringsAsFactors = FALSE - ) - expect_error( - pecotmr:::harmonizeAlleles( - target, - ref, - colToFlip = "missingCol", - matchMinProp = 0 - ), - "not found in targetData" - ) -}) - -test_that("harmonizeAlleles: errors when colToComplement column is absent", { - target <- data.frame( - chrom = 1, - pos = 100, - A2 = "A", - A1 = "G", - z = 1, - stringsAsFactors = FALSE - ) - ref <- data.frame( - chrom = 1, - pos = 100, - A2 = "A", - A1 = "G", - stringsAsFactors = FALSE - ) - expect_error( - pecotmr:::harmonizeAlleles( - target, - ref, - colToComplement = "missingAf", - matchMinProp = 0 - ), - "not found in targetData" - ) -}) - -test_that("harmonizeAlleles: complements colToComplement on a swap", { - # pos 100 exact; pos 200 allele-swapped -> sign_flip => z negated, af -> 1-af. - target <- data.frame( - chrom = c(1, 1), - pos = c(100, 200), - A2 = c("A", "A"), - A1 = c("G", "G"), - z = c(1, 2), - af = c(0.3, 0.4), - stringsAsFactors = FALSE - ) - ref <- data.frame( - chrom = c(1, 1), - pos = c(100, 200), - A2 = c("A", "G"), - A1 = c("G", "A"), - stringsAsFactors = FALSE - ) - res <- pecotmr:::harmonizeAlleles( - target, - ref, - colToFlip = "z", - colToComplement = "af", - matchMinProp = 0 - ) - hd <- res$harmonizedData - row200 <- hd[hd$pos == 200, ] - expect_equal(row200$af, 0.6) # 1 - 0.4 - expect_equal(row200$z, -2) # sign-flipped -}) - -test_that("harmonizeAlleles: removeDups = TRUE warns and drops dups", { - target <- data.frame( - chrom = c(1, 1), - pos = c(100, 100), - A2 = c("A", "A"), - A1 = c("G", "G"), - stringsAsFactors = FALSE - ) - ref <- data.frame( - chrom = 1, - pos = 100, - A2 = "A", - A1 = "G", - stringsAsFactors = FALSE - ) - expect_warning( - res <- pecotmr:::harmonizeAlleles( - target, - ref, - removeDups = TRUE, - matchMinProp = 0 - ), - "Removed 1 duplicate" - ) - expect_equal(nrow(res$harmonizedData), 1L) -}) - -test_that("harmonizeAlleles: errors when duplicate IDs remain", { - target <- data.frame( - chrom = c(1, 1), - pos = c(100, 100), - A2 = c("A", "A"), - A1 = c("G", "G"), - stringsAsFactors = FALSE - ) - ref <- data.frame( - chrom = 1, - pos = 100, - A2 = "A", - A1 = "G", - stringsAsFactors = FALSE + seqnames = paste0("chr", chrom), + ranges = IRanges::IRanges(start = pos, width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame(alt = alt, ref = ref) + gr + } + g1 <- ssqcMakeGr( + c(1, 1, 2), + c(100, 200, 300), + c("A", "C", "G"), + c("G", "T", "A") ) - expect_error( - pecotmr:::harmonizeAlleles( - target, - ref, - removeDups = FALSE, - matchMinProp = 0 - ), - "Duplicated variant IDs remain" + g2 <- ssqcMakeGr( + c(1, 1, 3), + c(100, 200, 400), + c("A", "T", "C"), + c("G", "C", "A") ) + out <- mergeVariantInfo(g1, g2, all = TRUE) + expect_s3_class(out, "data.frame") + expect_equal(nrow(out), 4L) + flipped <- out[out$chrom == "chr1" & out$pos == 200, ] + expect_equal(flipped$alt, "C") + expect_equal(flipped$ref, "T") }) -test_that("harmonizeAlleles: errors when too few match (matchMinProp)", { - target <- data.frame( - chrom = 1, - pos = 100, - A2 = "A", - A1 = "G", +test_that("mergeVariantInfo does not warn on length-mismatch recycling", { + # Regression guard: the flip vector must be full-length so `hasMatch & ...` + # never recycles a subset-length comparison. + v1 <- data.frame( + chrom = c("1", "1", "2"), + pos = c(100, 200, 300), + alt = c("A", "C", "G"), + ref = c("G", "T", "A"), stringsAsFactors = FALSE ) - ref <- data.frame( - chrom = rep(1, 10), - pos = seq(100, 1000, 100), - A2 = rep("A", 10), - A1 = rep("G", 10), + v2 <- data.frame( + chrom = c("1", "1", "3"), + pos = c(100, 200, 400), + alt = c("A", "T", "C"), + ref = c("G", "C", "A"), stringsAsFactors = FALSE ) - expect_error( - pecotmr:::harmonizeAlleles(target, ref, matchMinProp = 0.9), - "Not enough variants" - ) + expect_no_warning(out <- mergeVariantInfo(v1, v2, all = TRUE)) + # Behaviour is unchanged: the flipped row collapses onto v1's orientation. + flipped <- out[out$chrom == "1" & out$pos == 200, ] + expect_equal(flipped$alt, "C") + expect_equal(flipped$ref, "T") }) # =========================================================================== @@ -5745,23 +5055,53 @@ test_that("slalom coerces a non-matrix X (data.frame) to a matrix", { }) # =========================================================================== -# autoDecision: high-correlation tagging branch is reached +# autoDecision: high-correlation tagging branch # =========================================================================== test_that("autoDecision evaluates the high-corr tag for a non-top CS", { - # A non-top CS with a small p-value forces evaluation of the highCorrCols - # branch (the `..col` accessor errors without data.table; we only need the - # line to be exercised). + # A non-top CS with a small p-value can only be tagged through + # highCorrCols: a 1 in its correlation column tags it, leaving SER. + # cs_corr_1 is each CS's correlation with L1, as extractCsInfo() lays + # it out, so L1's own entry is 1; being the top CS, L1 is never tagged. df <- data.frame( cs_name = c("L1", "L2"), top_z = c(5.0, 3.0), p_value = c(1e-10, 1e-10), + cs_corr_1 = c(1, 1), stringsAsFactors = FALSE ) - expect_error(suppressWarnings(autoDecision( - df, - highCorrCols = c("cs_corr_1") - ))) + tagged <- autoDecision(df, highCorrCols = "cs_corr_1") + expect_equal(tagged$tagged_cs, c(FALSE, TRUE)) + expect_equal(tagged$method, c("SER", "SER")) + # Correlated with L1 short of 1, L2 stays untagged. + df$cs_corr_1 <- c(1, 0.5) + untagged <- autoDecision(df, highCorrCols = "cs_corr_1") + expect_equal(untagged$tagged_cs, c(FALSE, FALSE)) + expect_equal(untagged$method, c("BVSR", "BVSR")) +}) + +test_that("autoDecision never tags a CS by its own correlation column", { + # Every cs_corr_* column passed: L2's diagonal entry (its self- + # correlation, always 1) must not tag it; only its correlation with + # L1 can. + df <- data.frame( + cs_name = c("L1", "L2"), + top_z = c(5.0, 3.0), + p_value = c(1e-10, 1e-10), + cs_corr_1 = c(1, 0.2), + cs_corr_2 = c(0.2, 1), + stringsAsFactors = FALSE + ) + cols <- c("cs_corr_1", "cs_corr_2") + untagged <- autoDecision(df, highCorrCols = cols) + expect_equal(untagged$tagged_cs, c(FALSE, FALSE)) + expect_equal(untagged$method, c("BVSR", "BVSR")) + df$cs_corr_1[2] <- 1 + df$cs_corr_2[1] <- 1 + expect_equal( + autoDecision(df, highCorrCols = cols)$tagged_cs, + c(FALSE, TRUE) + ) }) # =========================================================================== @@ -5948,8 +5288,6 @@ test_that("raissSingleMatrixFromX emits no-known / no-unknown messages", { expect_equal(res_no_unknown$resultNofilter, all_known) }) -# =========================================================================== - # =========================================================================== # .qcRaissMerge: observed-variant AF is preserved through the RAISS merge # =========================================================================== @@ -6006,82 +5344,6 @@ test_that(".qcRaissMerge adds no AF column when the study declared none", { expect_false("AF" %in% colnames(out)) }) -# =========================================================================== -# raiss: multi-LD-block verbose / merge / error branches -# =========================================================================== - -# Build a 2-block LD list whose shared boundary variant is IMPUTED (not known) -# in both blocks, so its raissR2 is a finite value on both sides and the -# boundary-merge R2 comparison branches are exercised. -ssqcOverlapImputedBlocks <- function(seed = 5) { - set.seed(seed) - vid <- sprintf("chr1:%d:A:G", 100L * (1:8)) - pos <- seq(10, 80, by = 10) - ref_panel <- data.frame( - chrom = rep(1, 8), - pos = pos, - variant_id = vid, - A1 = rep("A", 8), - A2 = rep("G", 8), - stringsAsFactors = FALSE - ) - # v4 (the boundary) is left out of the known set so it is imputed in both blocks. - known_idx <- c(1, 2, 3, 5, 6, 7, 8) - known_zscores <- data.frame( - chrom = rep(1, length(known_idx)), - pos = pos[known_idx], - variant_id = vid[known_idx], - A1 = rep("A", length(known_idx)), - A2 = rep("G", length(known_idx)), - z = rnorm(length(known_idx)), - stringsAsFactors = FALSE - ) - mkBlock <- function(ids) { - nb <- length(ids) - m <- matrix(0, nb, nb) - for (a in seq_len(nb)) { - for (b in seq_len(nb)) { - m[a, b] <- if (a == b) 1 else 0.9^abs(a - b) - } - } - rownames(m) <- colnames(m) <- ids - m - } - block1_ids <- vid[1:4] - block2_ids <- vid[4:8] - variantIndices <- rbind( - data.frame( - variant_id = block1_ids, - blockId = 1L, - stringsAsFactors = FALSE - ), - data.frame( - variant_id = block2_ids, - blockId = 2L, - stringsAsFactors = FALSE - ) - ) - blockMetadata <- data.frame( - blockId = c(1L, 2L), - chrom = c(1, 1), - size = c(4L, 5L), - startIdx = c(1L, 4L), - endIdx = c(4L, 8L), - stringsAsFactors = FALSE - ) - ldBlocks <- list( - ldMatrices = list(mkBlock(block1_ids), mkBlock(block2_ids)), - variantIndices = variantIndices, - blockMetadata = blockMetadata, - ldVariants = vid - ) - list( - ref_panel = ref_panel, - known_zscores = known_zscores, - LD_matrix_blocks = ldBlocks - ) -} - # =========================================================================== # raissModel: batch = FALSE with condition-number reporting # =========================================================================== @@ -6115,10 +5377,6 @@ test_that("raissModel flags an inversion the rcond cutoff truncated", { expect_identical(ok$correctInversion, c(TRUE, TRUE)) }) -# =========================================================================== -# krigingOutlierQc: non-square LD stop + variantIds defaulting to rownames -# =========================================================================== - # =========================================================================== # .safeSvd: all singular values below tolerance # =========================================================================== @@ -6251,7 +5509,7 @@ test_that("summaryStatsQc: the N filter emits its message and rollup", { joined <- paste(msgs, collapse = "") expect_match(joined, "MAF/INFO/N filters kept") expect_match(joined, "nCutoff 1") - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_equal(ea$contentFilters$nDropped, 1L) }) @@ -6278,7 +5536,7 @@ test_that("summaryStatsQc: derives BETA/SE from Z+MAF+N, records it", { ss, sumstatsFilterParam = SumstatsFilterParam(nCutoff = 0) ) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_equal(ea$betaSeFromZ$nDerived, 4L) }) @@ -6295,7 +5553,7 @@ test_that("summaryStatsQc: clamps tiny Z-derived P and audits it", { ss, sumstatsFilterParam = SumstatsFilterParam(nCutoff = 0) ) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_true(!is.null(ea$sanityChecks$smallPClamped)) expect_gte(ea$sanityChecks$smallPClamped, 1L) }) @@ -6312,7 +5570,7 @@ test_that("summaryStatsQc: early-exits below two pre-harmonization variants", { ss, sumstatsFilterParam = SumstatsFilterParam(nCutoff = 0) ) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_match(ea$earlyExit, "fewer than two variants") expect_equal(length(res[[1L]]), 1L) }) @@ -6346,7 +5604,7 @@ test_that("summaryStatsQc: kriging QC records its audit and rollup", { joined <- paste(msgs, collapse = "") expect_match(joined, "kriging sign-flipped") expect_match(joined, "kriging-flip ") - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_true("krigingFlipped" %in% names(ea)) expect_true("krigingDiagnostics" %in% names(ea)) kd <- ea$krigingDiagnostics @@ -6405,7 +5663,7 @@ test_that("summaryStatsQc: impute assembles BETA/SE/N, median-fills N", { impute = TRUE, raissParam = RaissParam(flank = 500) ) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_equal(ea$raissTotalVariants, 6L) expect_equal(ea$raissImputedVariants, 2L) mc <- S4Vectors::mcols(res[[1L]]) @@ -6552,7 +5810,7 @@ test_that("summaryStatsQc: the rollup enumerates every removed step", { # The chr99 variant lands in its own ELEMENT (entries are split by seqname # at construction), so the audit is now per (study, chromosome) and the # drop counts are summed across entries rather than read off entry 1. - audits <- qcInfo(res)$entryAudit + audits <- res$qcAudit tally <- function(section, field) { sum(unlist(map(map(audits, section), field))) } @@ -6580,61 +5838,11 @@ test_that("summaryStatsQc: the rollup enumerates every removed step", { } }) -test_that("dentistSingleWindow: rsq warning on a near-singular LD block", { - # Highly collinear LD with a moderately strong signal can push the C++ - # adjusted rsq_eigen above 1, exercising the withCallingHandlers capture / - # summary-warning path. The call is wrapped to stay robust either way. - set.seed(123) - m <- 60 - R <- matrix(0.999, m, m) - diag(R) <- 1 - z <- as.numeric(R %*% rnorm(m, sd = 3)) - res <- suppressWarnings( - dentistSingleWindow( - z, - R = R, - nSample = 50, - propSVD = 0.95, - duprThreshold = 1.0 - ) - ) - expect_equal(nrow(res), m) -}) - # =========================================================================== # Final-coverage closeouts: a handful of branch/error-handler lines that the # existing suite leaves untouched. # =========================================================================== -test_that("harmonizeAlleles renames an empty target column to unnamed_N", { - # 5 columns whose first four are positional (NOT literally named - # chrom/pos/A2/A1), so harmonizeAlleles routes through parseVariantId -- which - # preserves the extra column -- rather than the select()-based path. The 5th - # column has an empty name, so the joined matchResult carries an empty-named - # column and sanitizeNames() rewrites it to "unnamed_1" (sumstatsQc.R:83). - target <- data.frame( - CHR = c(1, 1, 1), - POS = c(100, 200, 300), - ref = c("A", "C", "G"), - alt = c("G", "T", "A"), - extra = c(0.1, 0.2, 0.3), - stringsAsFactors = FALSE - ) - names(target)[5] <- "" - ref <- data.frame( - chrom = c(1, 1, 1), - pos = c(100, 200, 300), - A2 = c("A", "C", "G"), - A1 = c("G", "T", "A"), - stringsAsFactors = FALSE - ) - res <- pecotmr:::harmonizeAlleles(target, ref, matchMinProp = 0) - expect_equal(nrow(res$harmonizedData), 3L) - nm <- colnames(res$harmonizedData) - expect_false(any(nm == "" | is.na(nm))) # the empty name was repaired - expect_true(any(grepl("^unnamed_", nm))) # ... to an "unnamed_*" label -}) - test_that("dentistSingleWindow summarizes the cpp11 rsqExceed field", { # The cpp11 imputer returns any rsq values it capped at 1.0 in `rsqExceed`; # .dentistRunImpute reads that field and summarizes it into a single @@ -6681,9 +5889,9 @@ test_that("dentistSingleWindow summarizes the cpp11 rsqExceed field", { }) test_that("segmentByDist keeps a last window that clears the cutoff", { - # A single dense block spanning 1.25x the distance cutoff produces two windows - # whose final window is wide enough that adjustLastFn does NOT shrink it: the - # else branch returns the current startIdx unchanged (sumstatsQc.R:1095). + # A single dense block spanning 1.25x the distance cutoff produces two + # windows whose final window is wide enough that adjustLastFn does NOT + # shrink it: it keeps the current startIdx unchanged. pos <- as.integer(round(seq(1, 1250000, length.out = 600))) win <- pecotmr:::segmentByDist(pos, maxDist = 1000000, minDim = 500) expect_true(is.data.frame(win)) @@ -6776,7 +5984,7 @@ test_that("summaryStatsQc kriging QC sign-flips and keeps a bad variant", { sumstatsFilterParam = SumstatsFilterParam(nCutoff = 0) ) ) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_gte(ea$krigingFlipped, 1L) # at least one flipped expect_equal(length(res[[1L]]), 8L) # retained, not dropped # rs4's -15 flips to +15; its neighbours were +4, so every retained Z is now @@ -6799,7 +6007,7 @@ test_that(".subsetLdRefToRange keeps panel variants in the entry span", { chIdx <- which(si$CHR == ch) slice <- si[chIdx[seq_len(min(30L, length(chIdx)))], , drop = FALSE] gr <- GenomicRanges::GRanges( - paste0("chr", slice$CHR), + slice$CHR, IRanges::IRanges(as.integer(slice$BP), width = 1L) ) S4Vectors::mcols(gr)$SNP <- slice$SNP @@ -6807,7 +6015,7 @@ test_that(".subsetLdRefToRange keeps panel variants in the entry span", { lo <- min(slice$BP) hi <- max(slice$BP) expected <- si$SNP[ - pecotmr:::canonChrom(si$CHR) == pecotmr:::canonChrom(ch) & + si$CHR == ch & as.integer(si$BP) >= lo & as.integer(si$BP) <= hi ] @@ -6823,7 +6031,7 @@ test_that(".subsetLdRefToIds keeps exactly the entries' variants", { si <- snpInfo(h) sel <- c(3L, 10L, 40L, 200L) gr <- GenomicRanges::GRanges( - paste0("chr", si$CHR[sel]), + si$CHR[sel], IRanges::IRanges(as.integer(si$BP[sel]), width = 1L) ) S4Vectors::mcols(gr)$SNP <- si$SNP[sel] @@ -6867,7 +6075,7 @@ test_that(".subsetLdRefToRange / .subsetLdRefToIds are NULL-safe", { .ssqcPanelSumStats <- function(handle) { si <- snpInfo(handle) gr <- GenomicRanges::GRanges( - seqnames = paste0("chr", si$CHR), + seqnames = si$CHR, ranges = IRanges::IRanges(start = as.integer(si$BP), width = 1L) ) set.seed(11) @@ -7263,18 +6471,10 @@ test_that("a dropped ambiguous variant is not re-imputed, nor is its flip", { expect_false(is_in(normalizeVariantId("chr1:100:AT:A"), got)) }) -test_that("a flip pair is excluded even when nothing is known there", { +test_that("with nothing known, only the flip pair escapes imputation", { # The ambiguity is a property of the panel, not of what the sumstats - # happen to carry. - got <- .raiss_targets(character(0)) - expect_false(any(is_in( - normalizeVariantId(c("chr1:100:A:AT", "chr1:100:AT:A")), - got - ))) -}) - -test_that("unambiguous variants are still imputed", { - # The guard must not cost coverage where there is no ambiguity. + # happen to carry -- and the guard must not cost coverage where there is + # no ambiguity: exactly the unambiguous variants are imputed. expect_setequal( .raiss_targets(character(0)), normalizeVariantId(c("chr1:400:A:G", "chr1:500:C:T")) @@ -7297,17 +6497,12 @@ test_that(".raissFlipPairMask needs both orientations, not just an indel", { expect_equal(.raissFlipPairMask(ids), c(TRUE, TRUE, FALSE, FALSE)) }) -test_that(".raissFlipPairMask sees a strand-recorded second orientation", { - # A:G and C:T are one variant written on opposite strands AND swapped, so - # matchVariants() refuses the position. A literal A1/A2 reversal key read - # this as two unrelated variants and let RAISS impute the pair back. - ids <- normalizeVariantId(c("chr1:100:A:G", "chr1:100:C:T")) - expect_equal(.raissFlipPairMask(ids), c(TRUE, TRUE)) -}) - test_that(".raissFlipPairMask agrees with matchVariants on what is ambiguous", { # The mask exists to stop imputation putting back what matchVariants drops, - # so the two have to answer the same question the same way. + # so the two have to answer the same question the same way. chr1:100's + # A:G and C:T are one variant written on opposite strands AND swapped, so + # matchVariants() refuses the position; a literal A1/A2 reversal key read + # this as two unrelated variants and let RAISS impute the pair back. ids <- normalizeVariantId(c( "chr1:100:A:G", "chr1:100:C:T", @@ -7385,21 +6580,12 @@ test_that(".raissFlipOfKnownMask flags a flip regardless of position", { ) }) -test_that("a second allele at a typed position is not imputed", { +test_that("a typed position imputes no second allele, untyped ones all forms", { # Imputation fills UN-observed variants; another form of a site the GWAS - # measured is a redundant record, not new information. - d <- .raiss_pr573() - idx <- .raissUnknownIdx( - d$refPanel, - d$knownZ, - intersect(d$knownZ$variant_id, d$refPanel$variant_id) - ) - expect_false(is_in("1:100:A:T", d$refPanel$variant_id[idx])) -}) - -test_that("un-observed positions still impute every panel form they have", { - # The guard is about MEASURED positions, not about multi-allelic sites: - # 1:300 is multi-allelic but untyped, so both its forms are targets. + # measured is a redundant record, not new information, so 1:100:A:T is + # no target. The guard is about MEASURED positions, not about + # multi-allelic sites: 1:300 is multi-allelic but untyped, so both its + # forms are targets. d <- .raiss_pr573() idx <- .raissUnknownIdx( d$refPanel, @@ -7412,13 +6598,20 @@ test_that("un-observed positions still impute every panel form they have", { ) }) -test_that("the position guard is chr-prefix tolerant", { - # "chr1" in the panel and "1" in the sumstats is one site, not two. +test_that("raiss() reads either chromosome spelling as one site", { + # "chr1" in the panel and "1" in the sumstats is one site, not two: + # raiss() spells both tables' chromosomes in UCSC style as they come in. d <- .raiss_pr573() d$refPanel$chrom <- str_c("chr", d$refPanel$chrom) - d$refPanel$variant_id <- str_c("chr", d$refPanel$variant_id) - idx <- .raissUnknownIdx(d$refPanel, d$knownZ, character(0)) - expect_false(is_in("chr1:100:A:T", d$refPanel$variant_id[idx])) + ld <- diag(5) + ld[1, 2] <- ld[2, 1] <- 0.7 + ld[1, 3] <- ld[3, 1] <- 0.6 + ld[1, 4] <- ld[4, 1] <- 0.5 + ld[1, 5] <- ld[5, 1] <- 0.45 + r <- raiss(d$refPanel, d$knownZ, ldMatrix = ld, verbose = FALSE) + imp <- setdiff(r$resultNofilter$variant_id, d$knownZ$variant_id) + expect_false(is_in("1:100:A:T", imp)) + expect_true(all(r$resultNofilter$chrom == "chr1")) }) test_that("raissSingleMatrix does not impute at a typed position", { @@ -7447,13 +6640,6 @@ test_that("raissSingleMatrix does not impute at a typed position", { # that is ~135 MB of dead weight serialized per such entry. # =========================================================================== -.sk_panel <- function() { - readGenotypes( - test_path("test_data", "test_variants"), - format = "plink1" - ) -} - test_that("both trimmers empty the sketch for zero-variant entries", { h <- .sk_panel() expect_gt(nrow(h), 0L) @@ -7477,26 +6663,6 @@ test_that("emptying drops both axes but keeps the panel's identity", { expect_equal(.ldRefSource(e)$path, .ldRefSource(h)$path) }) -test_that(".emptyLdRef drops the seed, not just the rows", { - # A panel carries its handle twice: as rowRanges and inside the dosage - # assay's DelayedArray seed. Dropping rows alone leaves the seed holding - # the whole panel, which is the weight this exists to shed. - h <- .sk_panel() - e <- .emptyLdRef(h) - expect_equal(nrow(e), 0L) - expect_null(.panelSeed(e)) - expect_lt( - length(serialize(e, NULL)), - length(serialize(h, NULL)) / 2 - ) -}) - -test_that(".emptyLdRef is NULL-safe and idempotent", { - expect_null(.emptyLdRef(NULL)) - e <- .emptyLdRef(.sk_panel()) - expect_equal(nrow(.emptyLdRef(e)), 0L) -}) - test_that(".subsetLdRefToIds keeps the panel when ids are unextractable", { # Ranges present but no SNP mcol is a different situation from zero # variants: the panel cannot be keyed, so blanking it would discard LD the @@ -7518,90 +6684,6 @@ test_that(".subsetLdRefToIds keeps the panel when ids are unextractable", { # NA instead of a silently mislabelled minor-allele frequency. # =========================================================================== -.afm_df <- function(freqcol, val) { - d <- data.frame( - chrom = "chr1", - pos = 100L, - variant_id = "chr1:100:A:G", - A1 = "A", - A2 = "G", - z = 2.5, - n_sample = 1000, - stringsAsFactors = FALSE - ) - d[[freqcol]] <- val - d -} - -.afm_cm <- function(...) { - c( - chrom = "chrom", - pos = "pos", - variant_id = "variant_id", - A1 = "A1", - A2 = "A2", - z = "z", - n_sample = "n_sample", - ... - ) -} - -test_that("an af: key is directional AF; a maf: key is directionless", { - # Same source column, different declaration -> different meaning. - a <- suppressWarnings(.resolveSumstatCols( - .afm_df("effect_allele_frequency", 0.8), - .afm_cm(af = "effect_allele_frequency"), - "af" - )) - expect_equal(a$AF, 0.8) - expect_false("MAF" %in% names(a)) - b <- suppressWarnings(.resolveSumstatCols( - .afm_df("effect_allele_frequency", 0.8), - .afm_cm(maf = "effect_allele_frequency"), - "maf" - )) - expect_false("AF" %in% names(b)) - expect_equal(b$MAF, 0.8) -}) - -test_that("an undeclared af warns distinctly and yields no AF column", { - expect_warning( - out <- .resolveSumstatCols( - .afm_df("maf", 0.2), - .afm_cm(maf = "maf"), - "undeclared" - ), - "no effect-allele frequency declared" - ) - expect_false("AF" %in% names(out)) -}) - -test_that("a declared-but-unusable af warns with a different message", { - # Distinct from "undeclared": this is a data problem, not a mapping one. - expect_warning( - .resolveSumstatCols( - .afm_df("eaf", NA_real_), - .afm_cm(af = "eaf"), - "missing" - ), - "declared but its values are all missing" - ) -}) - -test_that(".fmAfByVar reads AF, and is NULL when af was never declared", { - mk <- function(cm) { - .dfToEntryGranges(suppressWarnings(.resolveSumstatCols( - .afm_df("effect_allele_frequency", 0.8), - cm, - "lbl" - ))) - } - gA <- mk(.afm_cm(af = "effect_allele_frequency")) - expect_equal(unname(.fmAfByVar(gA, "chr1:100:A:G")), 0.8) - gM <- mk(.afm_cm(maf = "effect_allele_frequency")) - expect_null(.fmAfByVar(gM, "chr1:100:A:G")) -}) - test_that(".cfMaf prefers af, falls back to maf, and skips when neither", { expect_equal(nrow(.cfMaf(data.frame(AF = c(0.8, 0.01)), 0.05)$df), 1L) expect_equal(nrow(.cfMaf(data.frame(MAF = c(0.2, 0.01)), 0.05)$df), 1L) @@ -7769,15 +6851,6 @@ test_that("RaissParam carries rcond for an LdMatrix reference", { expect_equal(RaissParam()$rcond, formals(raiss)$rcond) }) -test_that("RaissParam fields split into raiss formals and pecotmr's own", { - forwarded <- c("lamb", "rcond", "svdTol", "r2Threshold", "minimumLd") - expect_true(all(forwarded %in% names(formals(raiss)))) - # The rest scope what RAISS is asked to impute; they are not raiss formals - # and are consumed before the call. - ours <- c("mafCutoff", "macCutoff", "imissCutoff", "flank") - expect_false(any(ours %in% names(formals(raiss)))) -}) - test_that("summaryStatsQc refuses a bare list for raissParam", { data(gwasSumStatsS4Example) expect_error( @@ -7796,8 +6869,13 @@ test_that("an empty raissParam resolves to the full default bundle", { test_that("the forwarded half of RaissParam is exactly raiss's own formals", { fwd <- pecotmr:::.raissForwardedNames() + expect_setequal( + fwd, + c("lamb", "rcond", "svdTol", "r2Threshold", "minimumLd") + ) expect_true(all(fwd %in% names(formals(raiss)))) - # The other half never reaches raiss; splicing it in would be an error. + # The other half scopes what RAISS is asked to impute and is consumed + # before the call; splicing it into raiss would be an error. rest <- setdiff(names(RaissParam()), fwd) expect_false(any(rest %in% names(formals(raiss)))) expect_setequal( @@ -7862,7 +6940,7 @@ test_that("summaryStatsQc gives one result from an LdMatrix and its panel", { entry = list(.collectionEntry(gss, 1L)), genome = "hg19", ldReference = ld, - qcInfo = qcInfo(gss) + qcOptions = qcOptions(gss) ) viaPanel <- suppressMessages( summaryStatsQc(gss, ldMismatchQcMethod = "slalom") @@ -7911,7 +6989,7 @@ test_that("RAISS imputation in QC runs on an LdMatrix reference", { ldReference = ld ) res <- suppressMessages(summaryStatsQc(thin, impute = TRUE)) - ea <- qcInfo(res)$entryAudit[[1L]] + ea <- res$qcAudit[[1L]] expect_gt(ea$raissImputedVariants, 0L) # Target filters read the LdMatrix's AF, which this one does not record. expect_error( @@ -7945,3 +7023,308 @@ test_that("summaryStatsQc QCs each row against its own LD reference", { expect_s4_class(pecotmr:::.rowLdRef(out, 2L), "LdMatrix") expect_equal(length(pecotmr:::.rowLdRef(out, 2L)), length(out[[2L]])) }) + +# =========================================================================== +# RAISS's flank stops at a row's own LD block +# =========================================================================== + +# Every fourth variant of the bundled example, so RAISS has targets, split +# into two LD blocks of one study. `blockId` names the blocks, or leaves +# their coordinates as their keys. +.qcb_thinBlocked <- function(blockId = NULL) { + data(gwasSumStatsS4Example) + gss <- gwasSumStatsS4Example + variants <- unlist(gss) + blocks <- GenomicRanges::GRanges( + "chr22", + IRanges::IRanges(c(1L, 15200001L), c(15200000L, 51304566L)) + ) + if (!is.null(blockId)) { + S4Vectors::mcols(blocks)$blockId <- blockId + } + GwasSumStats( + studyName = studyName(gss), + entry = list(variants[seq(1L, length(variants), by = 4L)]), + genome = unique(unname(GenomeInfoDb::genome(gss))), + ldReference = ldReference(gss), + qcOptions = list(step1 = "ok"), + region = blocks + ) +} + +test_that(".ssqcRaissBounds keeps each row of a split study to its block", { + x <- .qcb_thinBlocked() + on <- list(impute = TRUE, raissParam = list(flank = 1e5)) + bounds <- pecotmr:::.ssqcRaissBounds(x, on) + # The blocks' ranges were given, so the blocks are their own bounds, + # whether the manifest keys them by their coordinates or by name. + expect_identical( + map_chr(bounds, as.character), + c("chr22:1-15200000", "chr22:15200001-51304566") + ) + named <- pecotmr:::.ssqcRaissBounds(.qcb_thinBlocked(c("a", "b")), on) + expect_identical( + map_chr(named, as.character), + c("chr22:1-15200000", "chr22:15200001-51304566") + ) + # Rows whose ranges are only their spans fall back to halfway between. + computed <- x + computed$regionGiven <- c(FALSE, FALSE) + labelled <- pecotmr:::.ssqcRaissBounds(computed, on) + spans <- range(x) + gap <- (GenomicRanges::end(spans[[1L]]) + + GenomicRanges::start(spans[[2L]])) %/% + 2L + expect_identical(GenomicRanges::end(labelled[[1L]]), gap) + expect_identical(GenomicRanges::start(labelled[[2L]]), gap + 1L) + # No flank, or no imputation, needs no bound; nor does a lone row. + expect_true(all(map_lgl( + pecotmr:::.ssqcRaissBounds( + x, + list(impute = TRUE, raissParam = list(flank = 0)) + ), + is.null + ))) + expect_true(all(map_lgl( + pecotmr:::.ssqcRaissBounds(x, list(impute = FALSE)), + is.null + ))) + data(gwasSumStatsS4Example) + expect_null( + pecotmr:::.ssqcRaissBounds(gwasSumStatsS4Example, on)[[1L]] + ) + # A lone row given its block keeps to it all the same: what lies past + # its range is another block, loaded or not. + lone <- x[1L] + expect_identical( + as.character(pecotmr:::.ssqcRaissBounds(lone, on)[[1L]]), + "chr22:1-15200000" + ) +}) + +test_that(".ssqcMidpointBounds splits gaps; an overlap keeps its own span", { + own <- GenomicRanges::GRanges("chr1", IRanges::IRanges(100L, 200L)) + sib <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(10L, 300L), c(50L, 400L)) + ) + mid <- pecotmr:::.ssqcMidpointBounds(own, sib) + expect_identical(GenomicRanges::start(mid), 76L) + expect_identical(GenomicRanges::end(mid), 250L) + # Neighbours on one side only leave the other side open. + below <- pecotmr:::.ssqcMidpointBounds(own, sib[1L]) + expect_identical(GenomicRanges::end(below), .Machine$integer.max) + above <- pecotmr:::.ssqcMidpointBounds(own, sib[2L]) + expect_identical(GenomicRanges::start(above), 1L) + over <- GenomicRanges::GRanges("chr1", IRanges::IRanges(150L, 400L)) + expect_identical(pecotmr:::.ssqcMidpointBounds(own, over), own) +}) + +test_that(".qcRaissClampBounds narrows only the clamp's chromosome", { + bounds <- tibble::tibble( + chrom = c("chr1", "chr2"), + lo = c(50L, 50L), + hi = c(500L, 500L) + ) + clamp <- GenomicRanges::GRanges("chr1", IRanges::IRanges(100L, 300L)) + out <- pecotmr:::.qcRaissClampBounds(bounds, clamp) + expect_identical(out$lo, c(100L, 50L)) + expect_identical(out$hi, c(300L, 500L)) + expect_identical(pecotmr:::.qcRaissClampBounds(bounds, NULL), bounds) +}) + +test_that("RAISS with a flank imputes each variant of a split study once", { + x <- .qcb_thinBlocked() + out <- suppressWarnings(suppressMessages(summaryStatsQc( + x, + impute = TRUE, + raissParam = RaissParam(flank = 2e5, r2Threshold = 0, minimumLd = 0) + ))) + expect_gt(sum(lengths(out)), sum(lengths(x))) + ids <- map(as.list(out), function(el) S4Vectors::mcols(el)$SNP) + expect_length(intersect(ids[[1L]], ids[[2L]]), 0L) + # Each row stays inside its own block. + expect_lte(max(GenomicRanges::end(out[[1L]])), 15200000L) + expect_gte(min(GenomicRanges::start(out[[2L]])), 15200001L) +}) + +test_that("a signal screen may empty every block of a study", { + x <- .qcb_thinBlocked() + out <- suppressMessages(summaryStatsQc( + x, + signalScreenParam = SignalScreenParam(absZ = 1e6) + )) + expect_equal(unname(lengths(out)), c(0L, 0L)) + expect_identical(out$blockId, x$blockId) + # The blocks were given their ranges, which they keep with no variant + # left in them. + expect_identical(out$regionGiven, c(TRUE, TRUE)) + expect_identical(out$region, x$region) +}) + +test_that("a QC pass carries each row's window unchanged", { + x <- .qcb_thinBlocked(c("a", "b")) + out <- suppressMessages(summaryStatsQc(x)) + expect_identical(out$blockId, c("a", "b")) + expect_identical(out$regionGiven, c(TRUE, TRUE)) + expect_identical(out$region, x$region) + # A computed window is the span the row was first built with: QC dropping + # an edge variant does not move it, and range(x) gives what is left. + data(gwasSumStatsS4Example) + v <- sumStats(gwasSumStatsS4Example) + S4Vectors::mcols(v)$Z[[1L]] <- NA + built <- GwasSumStats( + studyName = "s", + entry = list(v), + genome = "hg19", + ldReference = ldReference(gwasSumStatsS4Example)[[1L]], + qcOptions = list(step1 = "ok") + ) + qc <- suppressWarnings(suppressMessages(summaryStatsQc(built))) + expect_false(qc$regionGiven) + expect_identical(qc$region, built$region) + expect_gt( + GenomicRanges::start(range(qc[[1L]])), + GenomicRanges::start(qc$region) + ) +}) + +test_that("a QC pass keeps a QtlSumStats's trait position and columns", { + data(qtlSumStatsExample) + q <- qtlSumStatsExample + g <- q[[1L]] + tp <- GenomicRanges::GRanges( + as.character(GenomicRanges::seqnames(g))[[1L]], + IRanges::IRanges(GenomicRanges::start(g)[[50L]], width = 1L) + ) + y <- QtlSumStats( + studyName = q$study, + context = q$context, + trait = q$trait, + entry = list(g), + genome = unique(GenomeInfoDb::genome(q)), + ldReference = ldReference(q)[[1L]], + traitPos = tp, + extraCols = list(tag = "kept") + ) + out <- suppressMessages(summaryStatsQc(y)) + expect_identical(as.character(out$traitPos), as.character(tp)) + expect_identical(out$tag, "kept") + expect_identical(out$region, y$region) +}) + +test_that(".ssqcRaissBounds leaves an emptied row unbounded", { + x <- .qcb_thinBlocked() + emptied <- GwasSumStats( + studyName = "trait1", + entry = list(sumStats(x)[0L]), + genome = "hg19", + ldReference = ldReference(x)[[1L]], + qcOptions = list(step1 = "ok"), + blockId = "screened" + ) + both <- combineGwasSumStats(x, emptied) + expect_equal(unname(lengths(both)), c(unname(lengths(x)), 0L)) + bounds <- pecotmr:::.ssqcRaissBounds( + both, + list(impute = TRUE, raissParam = list(flank = 1e5)) + ) + # An empty row has no chromosome to share, so it is never bounded; the + # two blocks still bound each other. + expect_null(bounds[[3L]]) + expect_false(is.null(bounds[[1L]])) + expect_false(is.null(bounds[[2L]])) +}) + +# =========================================================================== +# On a real genotype panel: dentistSingleWindow +# =========================================================================== + +test_that("dentistSingleWindow detects injected outliers", { + skip_if_not_installed("pgenlibr") + # 100 samples x 349 variants on chr21 + X <- loadGenotypeRegion(test_path("test_data", "test_variants")) + R <- computeLd(X, method = "sample") + set.seed(42) + z <- rnorm(ncol(X)) + # Inject extreme outliers + z[1] <- 50 + z[2] <- -50 + result <- suppressWarnings(dentistSingleWindow(z, R = R, nSample = nrow(X))) + # At least one of the injected values should be flagged + expect_true(any(result$outlier)) +}) + +# =========================================================================== +# .entryToSumstatDf +# =========================================================================== + +test_that(".entryToSumstatDf: returns the canonical column layout", { + ss <- .gsd_makeGwasSumStats(data.frame( + SNP = c("rs1", "rs2"), + A1 = c("A", "A"), + A2 = c("G", "G"), + Z = c(1.0, -2.5), + N = c(1000L, 1500L), + MAF = c(0.1, 0.3) + )) + df <- pecotmr:::.entryToSumstatDf(sumStats(ss)) + expect_s3_class(df, "data.frame") + expect_equal(df$variant_id, c("rs1", "rs2")) + expect_equal(df$chrom, c("chr1", "chr1")) + expect_equal(df$pos, c(100L, 200L)) + expect_equal(df$z, c(1.0, -2.5)) + expect_equal(df$N, c(1000, 1500)) + expect_equal(df$maf, c(0.1, 0.3)) +}) + +test_that(".entryToSumstatDf: derives z from beta/se on request", { + ss <- .gsd_makeGwasSumStats( + data.frame( + SNP = "rs1", + A1 = "A", + A2 = "G", + BETA = 0.5, + SE = 0.1, + N = 1000L + ), + snp_n = 1L + ) + df <- pecotmr:::.entryToSumstatDf(sumStats(ss), derive = "zFromBetaSe") + expect_equal(df$beta, 0.5) + expect_equal(df$se, 0.1) + expect_equal(df$z, 0.5 / 0.1) +}) + +test_that(".entryToSumstatDf: omits optional columns when absent", { + ss <- .gsd_makeGwasSumStats( + data.frame( + SNP = "rs1", + A1 = "A", + A2 = "G" + ), + snp_n = 1L + ) + df <- pecotmr:::.entryToSumstatDf(sumStats(ss)) + expect_false("z" %in% names(df)) + expect_false("beta" %in% names(df)) + expect_false("se" %in% names(df)) + expect_false("N" %in% names(df)) + expect_false("maf" %in% names(df)) +}) + +test_that(".entryToSumstatDf: require = c('Z', 'N') errors when missing", { + ss <- .gsd_makeGwasSumStats( + data.frame( + SNP = "rs1", + A1 = "A", + A2 = "G", + Z = 1.5 + ), + snp_n = 1L + ) + expect_error( + pecotmr:::.entryToSumstatDf(sumStats(ss), require = c("Z", "N")), + "no N mcol" + ) +}) diff --git a/tests/testthat/test_tupleSelectors.R b/tests/testthat/test_tupleSelectors.R index 076ae464..861a268f 100644 --- a/tests/testthat/test_tupleSelectors.R +++ b/tests/testthat/test_tupleSelectors.R @@ -198,11 +198,11 @@ test_that(".tupleSelectRowGwasFmr: missing selectors on multi-row errors", { ) expect_error( pecotmr:::.tupleSelectRowGwasFmr(multi), - "Pass `study` and `method`" + "Pass `studyName` and `method`" ) }) -test_that(".tupleSelectRowGwasFmr: non-scalar region errors", { +test_that(".tupleSelectRowGwasFmr: non-scalar blockId errors", { multi <- .ts_coll( study = c("g1", "g1"), method = c("susie", "susie"), @@ -214,14 +214,14 @@ test_that(".tupleSelectRowGwasFmr: non-scalar region errors", { multi, studyName = "g1", method = "susie", - region = c("r1", "r2") + blockId = c("r1", "r2") ), - "region.*Must have length 1" + "blockId.*Must have length 1" ) }) -test_that(".tupleSelectRowGwasFmr: region disambiguates per-block rows", { - # Same (study, method) across two regions; region picks the right row. +test_that(".tupleSelectRowGwasFmr: blockId disambiguates per-block rows", { + # Same (study, method) across two blocks; blockId picks the right row. multi <- .ts_coll( study = c("g1", "g1"), method = c("susie", "susie"), @@ -233,13 +233,13 @@ test_that(".tupleSelectRowGwasFmr: region disambiguates per-block rows", { multi, studyName = "g1", method = "susie", - region = "chr22_500_600" + blockId = "chr22_500_600" ), 2L ) }) -test_that(".tupleSelectRowGwasFmr: missing tuple errors and includes region in message", { +test_that(".tupleSelectRowGwasFmr: a missing tuple's error names its blockId", { one <- .ts_coll( study = "g1", method = "susie", @@ -251,13 +251,13 @@ test_that(".tupleSelectRowGwasFmr: missing tuple errors and includes region in m one, studyName = "g1", method = "susie", - region = "ghost" + blockId = "ghost" ), - "region='ghost'" + "blockId='ghost'" ) }) -test_that(".tupleSelectRowGwasFmr: ambiguous multi-match (no region) lists candidates", { +test_that(".tupleSelectRowGwasFmr: ambiguous multi-match lists the blocks", { # Two rows share (study, method); .tupleSelectRowGwasFmr should error # listing the available blockIds since the caller didn't disambiguate. multi <- .ts_coll( @@ -272,7 +272,7 @@ test_that(".tupleSelectRowGwasFmr: ambiguous multi-match (no region) lists candi studyName = "g1", method = "susie" ), - "pass `region` to disambiguate" + "pass `blockId` to disambiguate" ) }) @@ -315,14 +315,14 @@ test_that(".fmrRowsMatching: selectors on absent columns are ignored", { expect_equal(pecotmr:::.fmrRowsMatching(gwas, context = "c1"), c(1L, 2L)) }) -test_that(".fmrRowsMatching: `region` matches the blockId column", { +test_that(".fmrRowsMatching: `blockId` matches the blockId column", { gwas <- .ts_coll( study = c("g1", "g1"), method = c("susie", "susie"), blockId = c("r1", "r2"), stringsAsFactors = FALSE ) - expect_equal(pecotmr:::.fmrRowsMatching(gwas, region = "r2"), 2L) + expect_equal(pecotmr:::.fmrRowsMatching(gwas, blockId = "r2"), 2L) }) test_that(".fmrRowsMatching: a vector selector matches any listed value", { @@ -340,7 +340,7 @@ test_that(".fmrRowsMatching: a vector selector matches any listed value", { }) # =========================================================================== -# .fmrRowMetadata (stable 5-column identity frame) +# .fmrRowMetadata (stable 8-column identity frame) # =========================================================================== test_that(".fmrRowMetadata: emits all eight identity columns, NA-filling absent ones", { @@ -382,7 +382,7 @@ test_that(".fmrRowMetadata: GWAS frame NA-fills context/trait, keeps blockId", { expect_true(all(is.na(m$trait))) }) -test_that(".fmrRowMetadata: zero-row input yields a zero-row 5-column frame", { +test_that(".fmrRowMetadata: zero-row input yields a zero-row 8-column frame", { empty <- .ts_coll( study = character(0), method = character(0), @@ -452,11 +452,8 @@ test_that(".getRegionColumn: a zero-row collection yields an empty GRanges", { }) test_that(".appendBlockIdCol: blockId must match the row count", { - # Replaces the old .appendRegionCol / .validateRegionColumn pair. The - # stored `region` GRanges column retired because it had no correct update - # rule under subsetRegion() -- it would simply go stale. blockId is a - # label keying the external block manifest, so subsetting cannot - # invalidate it. + # blockId is a label keying the external block manifest, so subsetting + # cannot invalidate it. expect_equal(pecotmr:::.appendBlockIdCol(list(), NULL, 2L), list()) expect_equal( pecotmr:::.appendBlockIdCol(list(), c("b1", "b2"), 2L)$blockId, @@ -468,15 +465,6 @@ test_that(".appendBlockIdCol: blockId must match the row count", { ) }) -test_that(".getRegionColumn derives the span rather than reading a column", { - # The one range concept is the intrinsic element range; there is no stored - # window to fall back to any more. - data(gwasFineMappingExample, envir = environment()) - gr <- pecotmr:::.getRegionColumn(gwasFineMappingExample) - expect_s4_class(gr, "GRanges") - expect_length(gr, nrow(gwasFineMappingExample)) -}) - test_that(".appendTraitPosCol: traitPos must be a GRanges of matching length", { expect_error( pecotmr:::.appendTraitPosCol(list(), "notgranges", 1L), @@ -533,10 +521,10 @@ test_that("an exemplar column absent from every part is NULL", { # Combining collections: QC records and chromosome-path unions # =========================================================================== -test_that("combining inputs that carry no QC record yields an empty audit", { +test_that("combining inputs that carry no QC record yields no QC options", { # Empty, not a fabricated record: claiming QC that never ran would be # worse than reporting none. - expect_equal(pecotmr:::.ssCombineQcInfo(list(), "combineX"), list()) + expect_equal(pecotmr:::.ssCombineQcOptions(list(), "combineX"), list()) }) test_that("chromosome paths union when they agree and abort when they clash", { @@ -549,7 +537,7 @@ test_that("chromosome paths union when they agree and abort when they clash", { format = "plink2", snpInfo = data.frame( SNP = "a", - CHR = "1", + CHR = "chr1", BP = 1L, A1 = "A", A2 = "G", @@ -675,7 +663,7 @@ test_that("a collection-level slot with no merge rule is refused", { }) test_that(".twrRowResolveWeights drops rows whose weights are all NA", { - allNa <- twasWeightsRow( + allNa <- TwasWeightsRow( variantIds = c("chr1:1:A:G", "chr1:2:C:T"), weights = c(NA_real_, NA_real_) ) @@ -684,7 +672,7 @@ test_that(".twrRowResolveWeights drops rows whose weights are all NA", { expect_length(out$variantIds, 0L) expect_length(out$weights, 0L) # Control: a single usable weight is kept, and only that one. - partial <- twasWeightsRow( + partial <- TwasWeightsRow( variantIds = c("chr1:1:A:G", "chr1:2:C:T"), weights = c(NA_real_, 0.5) ) @@ -769,13 +757,13 @@ test_that("a region column must be a GRanges with one range per row", { ) }) -test_that(".asAnalysisWindow normalizes strings, GRanges and multi-range input", { +test_that(".asAnalysisWindow keeps a window and spans a multi-range one", { expect_null(.asAnalysisWindow(NULL)) expect_null(.asAnalysisWindow(GenomicRanges::GRanges())) - expect_identical( - as.character(.asAnalysisWindow("chr1:100-200")), - as.character(GenomicRanges::GRanges("chr1:100-200")) - ) + one <- GenomicRanges::GRanges("chr1:100-200") + expect_identical(.asAnalysisWindow(one), one) + # A window is a GRanges; a string is refused rather than read. + expect_error(.asAnalysisWindow("chr1:100-200"), "must be a GRanges") # A multi-range window collapses to the span it covered. span <- .asAnalysisWindow(GenomicRanges::GRanges(c( "chr1:100-200", @@ -870,3 +858,582 @@ test_that("binding stores a mixture another part's covers as that one", { ) expect_length(apart$refs, 2L) }) + +# =========================================================================== +# GWAS block ranges and the QTL variants past them +# =========================================================================== + +# Ten GWAS variants at chr1:100-1000, 100 apart. +.ts_gwasVariants <- function(pos = 100L * (1:10)) { + gr <- GenomicRanges::GRanges("chr1", IRanges::IRanges(pos, width = 1L)) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = sprintf("chr1:%d:A:G", pos), + A1 = "A", + A2 = "G", + Z = 0, + N = 100L + ) + gr +} + +.ts_positions <- function(pos) { + GenomicRanges::GRanges("chr1", IRanges::IRanges(pos, width = 1L)) +} + +test_that(".rowSpanRanges spans each element, an empty one a placeholder", { + v <- .ts_gwasVariants() + spans <- pecotmr:::.rowSpanRanges( + GenomicRanges::GRangesList(v[1:3], v[0], v[5:10]) + ) + expect_identical( + as.character(spans), + c("chr1:100-300", "chrUn:1-0", "chr1:500-1000") + ) + expect_identical(GenomicRanges::width(spans)[[2L]], 0L) +}) + +test_that(".asRegionRanges takes a GRanges, or reads a BED file as BED", { + gr <- GenomicRanges::GRanges("chr1", IRanges::IRanges(10L, 20L)) + expect_identical(pecotmr:::.asRegionRanges(gr), gr) + # A BED file's start is 0-based, and its fourth column names a window. + path <- withr::local_tempfile(fileext = ".bed") + writeLines("chr1\t9\t20\tw1", path) + w <- pecotmr:::.asRegionRanges(path) + expect_identical(as.character(w), "chr1:10-20") + expect_identical(S4Vectors::mcols(w)$blockId, "w1") + # Given in R, a window is a GRanges: a table or a range string is + # refused rather than read, and a lone string is taken for a path. + table <- data.frame(chrom = "chr1", start = 9L, end = 20L) + expect_error( + pecotmr:::.asRegionRanges(table), + "must be a GRanges or the path of a BED file" + ) + expect_error( + pecotmr:::.asRegionRanges(c("chr1:10-20", "chr2:5-8")), + "must be a GRanges or the path of a BED file" + ) + expect_error( + pecotmr:::.asRegionRanges("chr1:10-20"), + "no file exists at 'chr1:10-20'" + ) + expect_error(pecotmr:::.asRegionRanges(42), "must be a GRanges") +}) + +test_that(".assertRegionGRanges takes a GRanges and nothing else", { + gr <- GenomicRanges::GRanges("chr1", IRanges::IRanges(10L, 20L)) + expect_identical(pecotmr:::.assertRegionGRanges(gr), gr) + expect_error( + pecotmr:::.assertRegionGRanges("chr1:10-20"), + "`region` must be a GRanges" + ) +}) + +test_that(".rowRegionAt reads one row's window, or its span", { + v <- .ts_gwasVariants() + x <- GwasSumStats( + studyName = c("s", "s"), + entry = list(v[1:5], v[0L]), + genome = "hg19", + blockId = c("a", "b") + ) + expect_identical( + as.character(pecotmr:::.rowRegionAt(x, 1L)), + "chr1:100-500" + ) + # An empty row built empty has only a placeholder, so no window. + expect_null(pecotmr:::.rowRegionAt(x, 2L)) + old <- x + old$region <- NULL + expect_identical( + as.character(pecotmr:::.rowRegionAt(old, 1L)), + "chr1:100-500" + ) +}) + +test_that(".regionColumns keeps a given range and spans the rest", { + given <- GenomicRanges::GRanges( + c("chr1", "chrUn"), + IRanges::IRanges(1L, c(5000L, 0L)) + ) + spans <- GenomicRanges::GRanges("chr1", IRanges::IRanges(100L, 300L)) + cols <- pecotmr:::.regionColumns(given, c(TRUE, FALSE), rep(spans, 2L)) + expect_identical(cols$regionGiven, c(TRUE, FALSE)) + expect_identical( + as.character(cols$region), + c("chr1:1-5000", "chr1:100-300") + ) + # A row with no variants keeps the range it was given. + empty <- pecotmr:::.regionColumns( + given[1L], + TRUE, + pecotmr:::.placeholderRanges(1L) + ) + expect_true(empty$regionGiven) + expect_identical(as.character(empty$region), "chr1:1-5000") +}) + +test_that(".refuseUncontainedRegions wants a given range to hold its row", { + pieces <- GenomicRanges::GRangesList( + GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(100L, 300L), width = 1L) + ), + GenomicRanges::GRanges(), + GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(100L, 300L), width = 1L) + ) + ) + given <- function(chrom, start, end) { + GenomicRanges::GRanges(chrom, IRanges::IRanges(start, end)) + } + refuse <- function(g, has = c(TRUE, TRUE, FALSE)) { + pecotmr:::.refuseUncontainedRegions(g, has, pieces, "f") + } + # Held; an empty row holds nothing, and a row given no range is not + # checked. + expect_null(refuse(given(c("chr1", "chr9", "chr9"), 50L, 400L))) + expect_error( + refuse(given(c("chr1", "chr1", "chr1"), 150L, 400L)), + "row 1: range chr1:150-400, variants at chr1:100-300", + fixed = TRUE + ) + # Another chromosome holds none of them. + expect_error( + refuse(given(c("chr2", "chr1", "chr1"), 1L, 5000L)), + "variants at chr1:100-300" + ) + # A variant sits at its start, so an indel's width cannot carry it past + # the end of the block it starts in. + indel <- GenomicRanges::GRangesList( + GenomicRanges::GRanges("chr1", IRanges::IRanges(300L, 310L)) + ) + expect_null(pecotmr:::.refuseUncontainedRegions( + given("chr1", 1L, 305L), + TRUE, + indel, + "f" + )) +}) + +test_that(".rowRegions falls back to the span where no range is stored", { + x <- GwasSumStats( + studyName = "s", + entry = list(.ts_gwasVariants()), + genome = "hg19", + region = GenomicRanges::GRanges("chr1:1-5000") + ) + r <- pecotmr:::.rowRegions(x) + expect_identical(as.character(r$region), "chr1:1-5000") + expect_true(r$regionGiven) + # Saved before the columns existed: the span, computed. + old <- x + old$region <- NULL + old$regionGiven <- NULL + r <- pecotmr:::.rowRegions(old) + expect_identical(as.character(r$region), "chr1:100-1000") + expect_false(r$regionGiven) + # A range without its origin is not taken as given. + noOrigin <- x + noOrigin$regionGiven <- NULL + expect_false(pecotmr:::.rowRegions(noOrigin)$regionGiven) + # A placeholder a combine padded in falls back to the span as well. + padded <- x + padded$region <- pecotmr:::.placeholderRanges(1L) + padded$regionGiven <- NA + r <- pecotmr:::.rowRegions(padded) + expect_identical(as.character(r$region), "chr1:100-1000") + expect_false(r$regionGiven) +}) + +test_that(".checkGwasBlockReach words what it finds", { + v <- .ts_gwasVariants() + computed <- GwasSumStats( + studyName = c("s", "s"), + entry = list(v[1:5], v[6:10]), + genome = "hg19", + blockId = c("bA", "bB") + ) + # Two variants before the first block's span count against it. + expect_warning( + pecotmr:::.checkGwasBlockReach( + list(u = .ts_positions(c(10L, 20L, 100L))), + computed, + "f", + "units" + ), + "u: 2 variant(s) past the start of block bA (chr1:100-500) of GWAS", + fixed = TRUE + ) + # Past five lines the rest are counted. + many <- set_names( + rep(list(.ts_positions(c(1000L, 1100L, 1200L))), 7L), + str_c("u", 1:7) + ) + msg <- tryCatch( + pecotmr:::.checkGwasBlockReach(many, computed, "f", "units"), + warning = conditionMessage + ) + expect_match(msg, "u5: 2 variant(s)", fixed = TRUE) + expect_match(msg, "... and 2 more.", fixed = TRUE) + expect_no_match(msg, "u6: ", fixed = TRUE) + # A fine-mapping result's fit is a study and a method, and its given + # window is checked strictly. + fmr <- GwasFineMappingResult( + studyName = "s", + method = "susie", + entry = list(.sc_makeFineMappingRow(3)), + region = GenomicRanges::GRanges("chr1", IRanges::IRanges(1L, 350L)) + ) + expect_error( + pecotmr:::.checkGwasBlockReach( + list(u = .ts_positions(c(200L, 400L))), + fmr, + "f", + "units" + ), + "u: 1 variant(s) past the end of block chr1_100_300 (chr1:1-350) of", + fixed = TRUE + ) + # Nothing to check against, or with. + expect_null( + pecotmr:::.checkGwasBlockReach(list(), computed, "f", "units") + ) + expect_null( + pecotmr:::.checkGwasBlockReach( + list(u = .ts_positions(100L)), + computed[0L], + "f", + "units" + ) + ) +}) + +# =========================================================================== +# Fit coverage: what a narrowed row's stored fit still describes +# =========================================================================== + +.ts_fitted <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A") + +# A fine-mapping row whose fit was made on `.ts_fitted`, holding `keep` of +# them. +.ts_fitRow <- function(keep = seq_along(.ts_fitted)) { + pip <- c(0.5, 0.3, 0.2) + full <- FineMappingRow( + .ts_fitted, + list(pip = pip), + data.frame(variant_id = .ts_fitted, pip = pip) + ) + methods::new( + "FineMappingRow", + variants = variants(full)[keep], + susieFit = susieFit(full), + fitVariants = .ts_fitted + ) +} + +# A collection of `n` rows, each fitted on `.ts_fitted` and narrowed to its +# first two. +.ts_narrowedCollection <- function(n) { + pip <- c(0.5, 0.3, 0.2) + row <- FineMappingRow( + .ts_fitted, + list(pip = pip), + data.frame(variant_id = .ts_fitted, pip = pip) + ) + x <- QtlFineMappingResult( + studyName = sprintf("s%d", seq_len(n)), + context = rep("c1", n), + trait = rep("g1", n), + method = rep("susie", n), + entry = rep(list(row), n) + ) + endoapply(x, utils::head, 2L) +} + +test_that(".lostFitVariantCount counts the fit's variants a row lost", { + f <- pecotmr:::.lostFitVariantCount + expect_equal(f(.ts_fitted, .ts_fitted), 0L) + expect_equal(f(.ts_fitted, .ts_fitted[1:2]), 1L) + expect_equal(f(character(0), .ts_fitted), 0L) + # A variant held under its swapped alleles is still held. + expect_equal(f(.ts_fitted, c("chr1:100:G:A", .ts_fitted[2:3])), 0L) +}) + +test_that(".fitColumnOf finds each held variant's column in the fit", { + f <- pecotmr:::.fitColumnOf + expect_equal(f(.ts_fitted[c(3L, 1L)], .ts_fitted), c(3L, 1L)) + # Allele-aware for a swapped id; NA for a variant the fit never had. + expect_equal(f(c("chr1:200:T:C", "chr1:900:A:G"), .ts_fitted), c(2L, NA)) +}) + +test_that(".mdFitVariants reads a group's first row, nothing for old rows", { + md <- S4Vectors::DataFrame( + fitVariants = IRanges::CharacterList(list(c("a", "b"), c("a", "b"))) + ) + # Rows split from one entry repeat its fit and its variants alike. + expect_equal(pecotmr:::.mdFitVariants(md, c(1L, 2L)), c("a", "b")) + expect_equal( + pecotmr:::.mdFitVariants(S4Vectors::DataFrame(x = 1:2), 1L), + character(0) + ) +}) + +test_that(".partsFitIds: the recorded ids, else the fit's, else the row's", { + expect_equal(pecotmr:::.partsFitIds(.ts_fitRow(1:2)), .ts_fitted) + unrecorded <- methods::new( + "FineMappingRow", + variants = variants(.ts_fitRow()), + susieFit = NULL + ) + named <- matrix(0, 1L, 3L, dimnames = list(NULL, rev(.ts_fitted))) + expect_equal(pecotmr:::.partsFitIds(unrecorded, named), rev(.ts_fitted)) + expect_equal(pecotmr:::.partsFitIds(unrecorded), .ts_fitted) +}) + +test_that("a row records fit variants only when it carries a fit", { + w <- c(0.1, 0.2, 0.3) + withCv <- TwasWeightsRow(.ts_fitted, w, cvResult = list(r2 = 0.5)) + expect_equal(pecotmr:::.rowFitVariants(withCv), .ts_fitted) + # Weights alone are no fit payload, and topLoci alone no fit. + expect_equal( + pecotmr:::.rowFitVariants(TwasWeightsRow(.ts_fitted, w)), + character(0) + ) + fitless <- FineMappingRow( + .ts_fitted, + NULL, + data.frame(variant_id = .ts_fitted, pip = c(0.5, 0.3, 0.2)) + ) + expect_equal(pecotmr:::.rowFitVariants(fitless), character(0)) +}) + +test_that(".fitCoverageChecked warns about a narrowed row and returns it", { + narrowed <- .ts_fitRow(1:2) + expect_warning( + out <- pecotmr:::.fitCoverageChecked(narrowed, "f()"), + "f\\(\\): the stored fit was made with 3 variants, 1 of which" + ) + expect_identical(out, narrowed) + cnd <- tryCatch( + pecotmr:::.fitCoverageChecked(narrowed, "f()"), + warning = identity + ) + expect_s3_class(cnd, "pecotmrFitCoverage") + expect_no_warning(pecotmr:::.fitCoverageChecked(.ts_fitRow(), "f()")) +}) + +test_that(".fitCoverageCheckedRows names at most five narrowed rows", { + x <- .ts_narrowedCollection(6L) + cnd <- tryCatch( + pecotmr:::.fitCoverageCheckedRows(x, "f()"), + warning = identity + ) + expect_s3_class(cnd, "pecotmrFitCoverage") + msg <- conditionMessage(cnd) + expect_match(msg, "f\\(\\): 6 row\\(s\\) hold fewer variants") + expect_equal(stringr::str_count(msg, "\\|c1\\|g1\\|susie"), 5L) + expect_invisible(suppressWarnings( + pecotmr:::.fitCoverageCheckedRows(x, "f()") + )) +}) + +test_that(".fitCoverageCheckedRows is silent without a record or rows", { + x <- .ts_narrowedCollection(1L) + expect_no_warning(pecotmr:::.fitCoverageCheckedRows(x[0], "f()")) + unrecorded <- x + unrecorded$fitVariants <- NULL + expect_no_warning(pecotmr:::.fitCoverageCheckedRows(unrecorded, "f()")) + # An optional input left out is nothing to check. + expect_no_warning(pecotmr:::.fitCoverageCheckedRows(NULL, "f()")) +}) + +# TWAS weights fitted on `.ts_fitted`, holding `keep` of them. +.ts_weights <- function(keep = seq_along(.ts_fitted)) { + tw <- TwasWeights( + studyName = "w1", + context = "c1", + trait = "g1", + method = "lasso", + entry = list( + TwasWeightsRow(.ts_fitted, c(0.1, 0.2, 0.3), cvResult = list()) + ) + ) + endoapply(tw, `[`, keep) +} + +test_that(".narrowedRowLabels labels the narrowed rows and no others", { + labels <- pecotmr:::.narrowedRowLabels(.ts_narrowedCollection(2L)) + expect_length(labels, 2L) + expect_match(labels, "^s[12]\\|c1\\|g1\\|susie") + expect_identical(pecotmr:::.narrowedRowLabels(.ts_weights()), character(0)) + expect_identical( + pecotmr:::.narrowedRowLabels(.ts_weights(1:2)), + pecotmr:::.pubRowLabels(.ts_weights(1:2), 1L) + ) +}) + +test_that(".fitCoverageCheckedAll names every input's narrowed rows at once", { + fm <- .ts_narrowedCollection(2L) + cnd <- tryCatch( + pecotmr:::.fitCoverageCheckedAll( + list(NULL, fm, .ts_weights(1:2)), + "f()" + ), + warning = identity + ) + expect_s3_class(cnd, "pecotmrFitCoverage") + expect_match(conditionMessage(cnd), "f\\(\\): 3 row\\(s\\) hold fewer") + expect_match(conditionMessage(cnd), "w1\\|c1\\|g1\\|lasso") + expect_null(suppressWarnings( + pecotmr:::.fitCoverageCheckedAll(list(fm), "f()") + )) + expect_no_warning( + pecotmr:::.fitCoverageCheckedAll(list(NULL, .ts_weights()), "f()") + ) + # Anything but a collection is left to its caller's own validation. + expect_identical( + pecotmr:::.narrowedRowLabels(data.frame(a = 1)), + character(0) + ) +}) + +test_that("the joint warning's hint is that of the first narrowed input", { + fm <- .ts_narrowedCollection(1L) + weightsFirst <- tryCatch( + pecotmr:::.fitCoverageCheckedAll(list(.ts_weights(1:2), fm), "f()"), + warning = identity + ) + expect_match(conditionMessage(weightsFirst), "Refit on the variants kept") + expect_false(str_detect( + conditionMessage(weightsFirst), + "intersectVariants" + )) + # An input with nothing narrowed does not choose the hint. + fmFirst <- tryCatch( + pecotmr:::.fitCoverageCheckedAll(list(.ts_weights(), fm), "f()"), + warning = identity + ) + expect_match(conditionMessage(fmFirst), "intersectVariants") +}) + +test_that(".muffleFitCoverage muffles fit-coverage warnings and no others", { + expect_no_warning( + out <- pecotmr:::.muffleFitCoverage({ + warn("narrowed", class = "pecotmrFitCoverage") + "value" + }) + ) + expect_equal(out, "value") + expect_warning(pecotmr:::.muffleFitCoverage(warn("other")), "other") +}) + +test_that("the coverage hint names intersectVariants() only where it applies", { + expect_match( + pecotmr:::.fitCoverageHint(.ts_fitRow()), + "intersectVariants\\(\\) restricts a fit" + ) + expect_match( + pecotmr:::.fitCoverageHint(.ts_narrowedCollection(1L)), + "intersectVariants" + ) + weightsHint <- pecotmr:::.fitCoverageHint( + TwasWeightsRow(.ts_fitted, c(0.1, 0.2, 0.3)) + ) + expect_false(str_detect(weightsHint, "intersectVariants")) + expect_match(weightsHint, "Refit on the variants kept") +}) + +test_that(".naLikeColumn pads a list column with empty entries of its kind", { + cl <- pecotmr:::.naLikeColumn(IRanges::CharacterList("a"), 2L) + expect_s4_class(cl, "CharacterList") + expect_equal(unname(lengths(cl)), c(0L, 0L)) + sl <- pecotmr:::.naLikeColumn(S4Vectors::SimpleList(list(1)), 2L) + expect_s4_class(sl, "SimpleList") + expect_length(sl, 2L) + expect_null(sl[[1L]]) +}) + +test_that("binding a collection saved before fitVariants pads the column", { + x <- .ts_narrowedCollection(2L) + old <- x[1L] + old$fitVariants <- NULL + out <- pecotmr:::.rbindCollections(list(old, x[2L])) + expect_s4_class(out$fitVariants, "CharacterList") + expect_equal(unname(lengths(out$fitVariants)), c(0L, 3L)) +}) + +# =========================================================================== +# .fmrRowTopLoci +# =========================================================================== + +test_that(".fmrRowTopLoci() tables convert to ranges", { + tl <- data.frame( + variant_id = c("1:100:A:G", "1:200:C:T"), + pip = c(0.9, 0.1), + betahat = c(0.5, -0.2), + sebetahat = c(0.1, 0.2), + cs = c(1L, 0L), + method = "susie", + stringsAsFactors = FALSE + ) + ent <- FineMappingRow( + variantIds = tl$variant_id, + susieFit = list(), + topLoci = tl + ) + # .fmrRowTopLoci() is the per-row table; topLoci() converts once, after + # the aggregate view has stacked the rows, so the conversion is tested + # through the converter it now lives in. + out <- .fmrRowTopLoci(ent) + expect_s3_class(out, "data.frame") + gr <- pecotmr:::.variantTableGRanges(out) + expect_s4_class(gr, "GRanges") + expect_equal(length(gr), 2) + expect_equal(S4Vectors::mcols(gr)$pip, c(0.9, 0.1)) +}) + +test_that(".fmrRowTopLoci() empty input converts to empty ranges", { + ent <- FineMappingRow( + variantIds = character(0), + susieFit = list(), + topLoci = data.frame() + ) + gr <- pecotmr:::.variantTableGRanges(.fmrRowTopLoci(ent)) + expect_s4_class(gr, "GRanges") + expect_equal(length(gr), 0) +}) + +test_that(".fmrRowTopLoci(raw = TRUE) returns the stored table verbatim", { + vids <- paste0("chr1:", 1:4, ":A:G") + entry <- .makeAdjustEntry(vids) + raw <- .fmrRowTopLoci(entry, raw = TRUE) + expect_equal(nrow(raw), length(vids)) + expect_true(all(c("betahat", "sebetahat") %in% names(raw))) + # The default view filters by pip and projects; raw does neither. + expect_false(identical(names(raw), names(.fmrRowTopLoci(entry)))) +}) + +test_that("topLoci surfaces the mvsusie lfsr through the projector", { + tl <- data.frame( + variant_id = c("chr1:100:A:G", "chr1:200:C:T"), + chrom = "1", + pos = c(100L, 200L), + A1 = c("A", "C"), + A2 = c("G", "T"), + pip = c(0.6, 0.4), + posterior_mean = c(0.1, 0.2), + posterior_sd = c(0.05, 0.05), + cs_95 = c("mvsusie_1", "mvsusie_1"), + lfsr = c(0.001, 0.02), + stringsAsFactors = FALSE + ) + e <- FineMappingRow( + variantIds = tl$variant_id, + susieFit = list(pip = tl$pip), + topLoci = tl + ) + out <- .fmrRowTopLoci(e, signalCutoff = 0) + expect_true(is_in("lfsr", names(out))) + expect_equal(out$lfsr, c(0.001, 0.02)) +}) diff --git a/tests/testthat/test_twasWeights.R b/tests/testthat/test_twasWeights.R index 3a5fcb0d..b81882a3 100644 --- a/tests/testthat/test_twasWeights.R +++ b/tests/testthat/test_twasWeights.R @@ -1,5 +1,18 @@ context("twasWeights") +.sc_makeTwasWeightsRow <- function( + p = 5L, + weightStandardized = FALSE, + weightsDataType = "expression" +) { + TwasWeightsRow( + variantIds = sprintf("chr1:%d:A:G", 100L * seq_len(p)), + weights = rnorm(p), + weightStandardized = weightStandardized, + weightsDataType = weightsDataType + ) +} + # --------------------------------------------------------------------------- # Shared synthetic data generator # --------------------------------------------------------------------------- @@ -87,7 +100,7 @@ mockSusie <- function(...) { # =========================================================================== # -# .twas_method_lookup +# .twasMethodLookup # # =========================================================================== @@ -127,26 +140,8 @@ generateXY <- function( return(list(X = X, Y = y)) } -test_that(".twas_method_lookup: 'default' preset returns 10 methods", { - result <- pecotmr:::.twasMethodLookup("default") - expected_names <- c( - "susie_weights", - "susie_inf_weights", - "mrash_weights", - "enet_weights", - "lasso_weights", - "mcp_weights", - "scad_weights", - "l0learn_weights", - "bayes_r_weights", - "bayes_c_weights" - ) - expect_equal(sort(names(result)), sort(expected_names)) -}) - -test_that(".twas_method_lookup: 'fast_default' preset returns 8 methods", { - result <- pecotmr:::.twasMethodLookup("fastDefault") - expected_names <- c( +test_that(".twasMethodLookup: 'default' (10) and 'fastDefault' (8) presets", { + fastDefault <- c( "susie_weights", "susie_inf_weights", "mrash_weights", @@ -156,10 +151,20 @@ test_that(".twas_method_lookup: 'fast_default' preset returns 8 methods", { "scad_weights", "l0learn_weights" ) - expect_equal(sort(names(result)), sort(expected_names)) + presets <- list( + default = c(fastDefault, "bayes_r_weights", "bayes_c_weights"), + fastDefault = fastDefault + ) + for (preset in names(presets)) { + expect_equal( + sort(names(pecotmr:::.twasMethodLookup(preset))), + sort(presets[[preset]]), + info = preset + ) + } }) -test_that(".twas_method_lookup: custom vector of short names", { +test_that(".twasMethodLookup: custom vector of short names", { result <- pecotmr:::.twasMethodLookup(c("susie", "enet", "dprVb")) expect_equal( sort(names(result)), @@ -167,30 +172,31 @@ test_that(".twas_method_lookup: custom vector of short names", { ) }) -test_that(".twas_method_lookup: unknown method produces error", { +test_that(".twasMethodLookup: unknown method produces error", { expect_error( pecotmr:::.twasMethodLookup(c("susie", "nonexistent_method")), "unknown method token" ) }) -test_that(".twas_method_lookup: default args are set for mrash, not susie", { +test_that(".twasMethodLookup: default args are set for mrash, not susie", { result <- pecotmr:::.twasMethodLookup("fastDefault") # susie carries NO fitting defaults: susieWeights extracts from a supplied - # fit and never runs susie, so `refine` / `L` would have nothing to configure. + # fit and never runs susie, so `refine` / `L` would have nothing to + # configure. expect_length(result$susie_weights, 0L) # mrash keeps mr.ash's own prior grid, so only the iteration cap is set. expect_named(result$mrash_weights, "max.iter") expect_equal(result$mrash_weights$max.iter, 100) }) -test_that(".twas_method_lookup: methods with no special args get empty list", { +test_that(".twasMethodLookup: methods with no special args get empty list", { result <- pecotmr:::.twasMethodLookup(c("enet", "lasso")) expect_equal(length(result$enet_weights), 0L) expect_equal(length(result$lasso_weights), 0L) }) -test_that(".twas_method_lookup: all DPR variants can coexist", { +test_that(".twasMethodLookup: all DPR variants can coexist", { result <- pecotmr:::.twasMethodLookup(c( "dprVb", "dprGibbs", @@ -212,18 +218,6 @@ test_that(".twas_method_lookup: all DPR variants can coexist", { # # =========================================================================== -test_that("twasPredict: basic matrix multiplication is correct", { - d <- makeData(n = 20, p = 5) - set.seed(99) - w <- matrix(runif(5), ncol = 1) - rownames(w) <- colnames(d$X) - wl <- list(test_weights = w) - res <- twasPredict(d$X, wl) - - expected <- d$X %*% w - expect_equal(res[["test_predicted"]], expected) -}) - test_that("twasPredict: multiple weight methods in list", { d <- makeData(n = 20, p = 5) w1 <- matrix(c(1, 0, 0, 0, 0), ncol = 1) @@ -237,22 +231,6 @@ test_that("twasPredict: multiple weight methods in list", { expect_equal(res[["method_b_predicted"]], d$X %*% w2) }) -test_that("twasPredict: name transformation weights -> predicted", { - set.seed(42) - wl <- list( - lassoWeights = matrix(1, nrow = 3, ncol = 1), - enetWeights = matrix(1, nrow = 3, ncol = 1), - susieWeights = matrix(1, nrow = 3, ncol = 1) - ) - X <- matrix(rnorm(9), nrow = 3, ncol = 3) - res <- twasPredict(X, wl) - - expect_equal( - names(res), - c("lassoPredicted", "enetPredicted", "susiePredicted") - ) -}) - test_that("twasPredict: names without _weights suffix are kept unchanged", { wl <- list(custom_method = matrix(1, nrow = 2, ncol = 1)) X <- matrix(1:4, nrow = 2, ncol = 2) @@ -262,17 +240,6 @@ test_that("twasPredict: names without _weights suffix are kept unchanged", { expect_equal(names(res), "custom_method") }) -test_that("twasPredict: single column Y dimension preserved", { - d <- makeData(n = 10, p = 4) - w <- matrix(rep(0.25, 4), ncol = 1) - wl <- list(avg_weights = w) - res <- twasPredict(d$X, wl) - - expect_true(is.matrix(res[["avg_predicted"]])) - expect_equal(nrow(res[["avg_predicted"]]), 10) - expect_equal(ncol(res[["avg_predicted"]]), 1) -}) - test_that("twasPredict: multi-column weights produce multi-column predictions", { set.seed(42) n <- 15 @@ -286,20 +253,13 @@ test_that("twasPredict: multi-column weights produce multi-column predictions", expect_equal(res[["multi_predicted"]], X %*% W) }) -test_that("twasPredict: zero weights give zero predictions", { - X <- matrix(1:6, nrow = 2, ncol = 3) - wl <- list(null_weights = matrix(0, nrow = 3, ncol = 1)) - res <- twasPredict(X, wl) - expect_true(all(res[["null_predicted"]] == 0)) -}) - # =========================================================================== # -# twasWeights (input validation and basic behavior) +# learnTwasWeights (input validation and basic behavior) # # =========================================================================== -test_that("twasWeights: X must be a matrix", { +test_that("learnTwasWeights: X must be a matrix", { d <- makeData() expect_error( learnTwasWeights(as.data.frame(d$X), d$Y, weightMethods = list()), @@ -307,7 +267,7 @@ test_that("twasWeights: X must be a matrix", { ) }) -test_that("twasWeights: Y must be a matrix or vector", { +test_that("learnTwasWeights: Y must be a matrix or vector", { d <- makeData() # In R, is.vector(list(...)) returns TRUE, so a list passes the initial # type check and gets converted via matrix(). The resulting matrix has @@ -318,7 +278,7 @@ test_that("twasWeights: Y must be a matrix or vector", { ) }) -test_that("twasWeights: Y as vector gets converted to matrix internally", { +test_that("learnTwasWeights: Y as vector gets converted to matrix internally", { d <- makeData() y_vec <- as.numeric(d$Y) @@ -341,7 +301,7 @@ test_that("twasWeights: Y as vector gets converted to matrix internally", { expect_true(all(is.finite(w))) }) -test_that("twasWeights: mismatched row counts error", { +test_that("learnTwasWeights: mismatched row counts error", { d <- makeData(n = 50, p = 10) Y_short <- d$Y[1:30, , drop = FALSE] expect_error( @@ -350,18 +310,18 @@ test_that("twasWeights: mismatched row counts error", { ) }) -test_that("twasWeights: character weight_methods input is accepted", { +test_that("learnTwasWeights: character weightMethods input is accepted", { d <- makeData() local_mocked_bindings( lassoWeights = function(X, y, ...) rep(0, ncol(X)) ) - # Short name should be resolved via .twas_method_lookup + # Short name should be resolved via .twasMethodLookup result <- learnTwasWeights(d$X, d$Y, weightMethods = c("lasso")) expect_true(is(result, "TwasWeights")) expect_equal(methodNames(result), "lasso") }) -test_that("twasWeights: zero variance columns are filtered and padded back with zeros", { +test_that("learnTwasWeights: zero-variance columns are filtered, weighted 0", { d <- makeData(n = 50, p = 10, add_zero_var_col = TRUE) p_with_extra <- ncol(d$X) # 11 columns, last is zero-var @@ -378,7 +338,8 @@ test_that("twasWeights: zero variance columns are filtered and padded back with weightMethods = list(lasso_weights = list()) ) - # The returned weight matrix should have rows equal to total columns (including zero-var) + # The returned weight matrix should have rows equal to total columns + # (including zero-var) expect_equal(nrow(.weightsByMethod(result, "lassoWeights")), p_with_extra) # The zero-var column weight should be 0 (padded back) expect_equal( @@ -387,7 +348,7 @@ test_that("twasWeights: zero variance columns are filtered and padded back with ) }) -test_that("twasWeights: rownames of result match colnames of X", { +test_that("learnTwasWeights: weights are ncol(X) x ncol(Y), rows named by X", { d <- makeData() local_mocked_bindings( enetWeights = function(X, y, ...) rep(0.1, ncol(X)) @@ -397,29 +358,17 @@ test_that("twasWeights: rownames of result match colnames of X", { d$Y, weightMethods = list(enetWeights = list()) ) - expect_equal( - rownames(.weightsByMethod(result, "enetWeights")), - colnames(d$X) - ) -}) - -test_that("twasWeights: result dimensions match ncol(X) x ncol(Y)", { - d <- makeData() - local_mocked_bindings( - enetWeights = function(X, y, ...) rep(0, ncol(X)) - ) - result <- learnTwasWeights( - d$X, - d$Y, - weightMethods = list(enetWeights = list()) - ) expect_equal( dim(.weightsByMethod(result, "enetWeights")), c(ncol(d$X), ncol(d$Y)) ) + expect_equal( + rownames(.weightsByMethod(result, "enetWeights")), + colnames(d$X) + ) }) -test_that("twasWeights: multiple methods return named list with one entry per method", { +test_that("learnTwasWeights: multiple methods return one entry per method", { d <- makeData() local_mocked_bindings( lassoWeights = function(X, y, ...) rep(0.1, ncol(X)), @@ -437,39 +386,28 @@ test_that("twasWeights: multiple methods return named list with one entry per me # =========================================================================== # -# twasWeights with actual glmnet (lasso/enet) -- skip if not available +# learnTwasWeights with real glmnet (lasso/enet) # # =========================================================================== -test_that("twasWeights: lassoWeights produces correct structure with real glmnet", { +test_that("learnTwasWeights: lasso and enet fit p x 1 weights with glmnet", { skip_if_not_installed("glmnet") d <- makeData(n = 50, p = 10) - result <- learnTwasWeights( - d$X, - d$Y, - weightMethods = list(lasso_weights = list()) - ) - - expect_true(is(result, "TwasWeights")) - expect_equal(methodNames(result), "lasso") - expect_equal(nrow(.weightsByMethod(result, "lassoWeights")), ncol(d$X)) - expect_equal(ncol(.weightsByMethod(result, "lassoWeights")), 1) - # At least some weights should be non-zero for this strong signal - expect_true(any(.weightsByMethod(result, "lassoWeights") != 0)) -}) - -test_that("twasWeights: enetWeights produces correct structure with real glmnet", { - skip_if_not_installed("glmnet") - d <- makeData(n = 50, p = 10) - result <- learnTwasWeights( - d$X, - d$Y, - weightMethods = list(enetWeights = list()) - ) - - expect_true(is(result, "TwasWeights")) - expect_equal(methodNames(result), "enet") - expect_equal(nrow(.weightsByMethod(result, "enetWeights")), ncol(d$X)) + # One snake_case and one camelCase key: both spellings resolve. + keys <- c(lasso = "lasso_weights", enet = "enetWeights") + for (method in names(keys)) { + result <- learnTwasWeights( + d$X, + d$Y, + weightMethods = set_names(list(list()), keys[[method]]) + ) + w <- .weightsByMethod(result, method) + expect_true(is(result, "TwasWeights"), info = method) + expect_equal(methodNames(result), method, info = method) + expect_equal(dim(w), c(ncol(d$X), 1L), info = method) + # At least some weights should be non-zero for this strong signal + expect_true(any(w != 0), info = method) + } }) # =========================================================================== @@ -478,18 +416,13 @@ test_that("twasWeights: enetWeights produces correct structure with real glmnet" # # =========================================================================== -test_that("twasWeightsCv: NULL weight_methods returns only samplePartition", { - d <- makeData() - result <- twasWeightsCv(d$X, d$Y, fold = 3, weightMethods = NULL) - expect_equal(names(result), "samplePartition") - expect_true(is.data.frame(result$samplePartition)) -}) - -test_that("twasWeightsCv: samplePartition structure is correct", { +test_that("twasWeightsCv: NULL methods return only a well-formed partition", { d <- makeData() result <- twasWeightsCv(d$X, d$Y, fold = 5, weightMethods = NULL) + expect_equal(names(result), "samplePartition") sp <- result$samplePartition + expect_true(is.data.frame(sp)) expect_true("Sample" %in% colnames(sp)) expect_true("Fold" %in% colnames(sp)) expect_equal(nrow(sp), nrow(d$X)) @@ -498,7 +431,7 @@ test_that("twasWeightsCv: samplePartition structure is correct", { expect_true(all(rownames(d$X) %in% sp$Sample)) }) -test_that("twasWeightsCv: character weight_methods are accepted", { +test_that("twasWeightsCv: character weightMethods are accepted", { d <- makeData() local_mocked_bindings( lassoWeights = function(X, y, ...) rep(0, ncol(X)) @@ -619,29 +552,10 @@ test_that("twasWeightsCv: multivariate Y with multiple columns", { # =========================================================================== # -# twasWeightsPipeline (structure and input validation) +# learnTwasWeights with supplied SuSiE fits; twasWeightsCv plumbing # # =========================================================================== -test_that("learnTwasWeights refuses the susie + susieInf pair without fits", { - # The chained susieInf -> susie fit lives in fineMappingPipeline() now; - # learnTwasWeights never fine-maps, so the pair is an error here. - # fitSusieInfThenSusie() itself is covered in test_fineMappingWrappers.R. - d <- makeData(n = 50, p = 10) - expect_error( - learnTwasWeights( - d$X, - as.numeric(d$Y), - weightMethods = list( - susie_weights = list(), - susie_inf_weights = list() - ) - ), - "susie, susieInf" - ) -}) - - test_that("learnTwasWeights resolves fits under camelCase method names", { # `susieWeights` and `susie_weights` name the same method; a fit supplied # for one spelling must land on the other's arguments too. @@ -768,14 +682,10 @@ test_that("twasWeightsCv: dataDrivenPriorMatricesCv is plumbed through", { }) # =========================================================================== -# twasWeightsPipeline: removed_methods warning + max_cv_variants subsampling +# learnTwasWeights: a fit with extra rows is cut back to the fitted variants # =========================================================================== -# =========================================================================== -# twasWeights: dim-fix branch when nrow(weights_matrix) != length(valid_columns) -# =========================================================================== - -test_that("twasWeights: multivariate weights_matrix is reduced to valid_columns when row counts mismatch", { +test_that("learnTwasWeights: mr.mash rows beyond X's variants are dropped", { set.seed(42) n <- 20 p <- 5 @@ -787,8 +697,8 @@ test_that("twasWeights: multivariate weights_matrix is reduced to valid_columns local_mocked_bindings( mrmashWeights = function(X, Y, ...) { - # Return more rows than valid_columns (length p) so the dim-fix branch - # subsets the matrix back to names(valid_columns). + # Return more rows than the p fitted variants, so the result is + # subset back to those variants' names. extra_rows <- p + 2 m <- matrix( seq_len(extra_rows * ncol(Y)), @@ -809,7 +719,7 @@ test_that("twasWeights: multivariate weights_matrix is reduced to valid_columns Y, weightMethods = list(mrmashWeights = list()) ) - # After the dim-fix, the weights matrix is restricted to v1..v5 -> shape p x ncol(Y) + # Restricted to the p fitted variants -> shape p x ncol(Y) expect_equal(nrow(.weightsByMethod(result, "mrmashWeights")), p) expect_equal(ncol(.weightsByMethod(result, "mrmashWeights")), 2) expect_equal( @@ -855,11 +765,7 @@ test_that("twasWeightsCv handles errors appropriately", { sim <- generateXY(seed = 1) X <- sim$X y <- sim$Y - local_mocked_bindings( - susieWeights = function(X, y, ...) rnorm(ncol(X)), - glmnetWeights = function(X, y, ...) runif(ncol(X)) - ) - weight_methods_test <- list(susie = list(), glmnetWeights = list()) + # fold defaults to NULL, so this is also the call that omits it. expect_error(twasWeightsCv(X, y, fold = NULL), "fold.*samplePartitions") expect_error( twasWeightsCv(X, y, fold = "invalid"), @@ -868,39 +774,19 @@ test_that("twasWeightsCv handles errors appropriately", { expect_error(twasWeightsCv(X, y, fold = -1), "Must be >= 1") expect_error(twasWeightsCv(2, y, fold = 2), "Must be of type 'matrix'") expect_error(twasWeightsCv(X, 2, fold = 2), "Y.*Must have exactly 10 rows") - expect_error( - twasWeightsCv( - matrix(rnorm(4, nrow = 2)), - matrix(rnorm(2, nrow = 1)), - fold = 2 - ), - "unused argument" - ) - expect_error(twasWeightsCv(X, y), "fold.*samplePartitions") }) test_that("learnTwasWeights handles errors appropriately", { sim <- generateXY(seed = 1) - X <- sim$X - y <- sim$Y - local_mocked_bindings( - susieWeights = function(X, y, ...) rnorm(ncol(X)), - glmnetWeights = function(X, y, ...) runif(ncol(X)) - ) - weight_methods_test <- list(susie = list(), glmnetWeights = list()) expect_error( - learnTwasWeights( - matrix(rnorm(4, nrow = 2)), - matrix(rnorm(2, nrow = 1)) - ), + learnTwasWeights(sim$X, sim$Y), "weightMethods.*is missing" ) - expect_error(learnTwasWeights(X, y), "weightMethods") }) # =========================================================================== -# twasZ: mathematical correctness (single-method / vector path) +# twasPredict: vector weights # =========================================================================== test_that("twasPredict multiplies X by weights", { @@ -933,14 +819,6 @@ test_that("twasPredict handles multiple weight methods", { }) -test_that("twasPredict with zero weights gives zero predictions", { - X <- matrix(1:6, nrow = 2, ncol = 3) - weights_list <- list(null_weights = c(0, 0, 0)) - result <- twasPredict(X, weights_list) - expect_true(all(result$null_predicted == 0)) -}) - - test_that("twasPredict with single variant", { X <- matrix(c(1, 2, 3), nrow = 3, ncol = 1) weights_list <- list(single_weights = 2.0) @@ -976,6 +854,7 @@ test_that("TwasWeights: studyName / contexts / traitNames / methodNames", { method = c("lasso", "lasso"), entry = list(e, e) ) + expect_setequal(studyName(tw), c("s1", "s2")) expect_setequal(contexts(tw), c("c1", "c2")) expect_equal(traitNames(tw), "t1") expect_equal(methodNames(tw), "lasso") @@ -1050,9 +929,46 @@ test_that("TwasWeights: twasWeights extracts the entry for a tuple", { expect_equal(unname(weights(picked)), unname(weights(e2))) }) -# =========================================================================== -# LdData -# =========================================================================== +test_that("TwasWeights: rows are picked by window through subsetting", { + near <- TwasWeightsRow( + variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), + weights = c(0.1, 0.2, 0.3, 0.4) + ) + far <- TwasWeightsRow( + variantIds = sprintf("chr2:%d:A:G", 100L * (1:4)), + weights = c(0.5, 0.6, 0.7, 0.8) + ) + tw <- TwasWeights( + studyName = c("s1", "s1"), + context = c("c1", "c1"), + trait = c("t1", "t2"), + method = c("lasso", "lasso"), + entry = list(near, far) + ) + # A window selects rows by subsetting the collection on its rows' + # analysis windows; the one row left needs no other selector. + inChr2 <- tw[IRanges::overlapsAny( + genomicRegion(tw), + GenomicRanges::GRanges("chr2:150-250") + )] + expect_identical(as.character(twasWeights(inChr2)$trait), "t2") + expect_equal(resolveWeights(inChr2)$weights, c(0.5, 0.6, 0.7, 0.8)) + inChr1 <- tw[IRanges::overlapsAny( + genomicRegion(tw), + GenomicRanges::GRanges("chr1:1-1000") + )] + expect_equal(unname(weights(inChr1)), c(0.1, 0.2, 0.3, 0.4)) + expect_identical( + variantIds(inChr1), + sprintf("chr1:%d:A:G", 100L * (1:4)) + ) + # A window over both rows still needs the tuple to choose between them. + both <- tw[IRanges::overlapsAny( + genomicRegion(tw), + GenomicRanges::GRanges(c("chr1:1-1000", "chr2:1-1000")) + )] + expect_error(twasWeights(both), "has 2 entries") +}) # === Tests migrated from test_showMethods.R (TwasWeights) === @@ -1256,13 +1172,13 @@ test_that("TwasWeights: joint* column length must match study", { }) test_that("TwasWeights: weightStandardized/weightsDataType/variantIds delegate to the entry", { - e1 <- twasWeightsRow( + e1 <- TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), weights = rnorm(4), weightStandardized = TRUE, weightsDataType = "expression" ) - e2 <- twasWeightsRow( + e2 <- TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), weights = rnorm(4), weightStandardized = FALSE, @@ -1312,27 +1228,15 @@ test_that("TwasWeights: weightStandardized/weightsDataType/variantIds delegate t ) }) -test_that("TwasWeights: studyName returns unique study labels", { - e <- .sc_makeTwasWeightsRow() - tw <- TwasWeights( - studyName = c("s1", "s2"), - context = c("c1", "c2"), - trait = c("t1", "t1"), - method = c("lasso", "lasso"), - entry = list(e, e) - ) - expect_setequal(studyName(tw), c("s1", "s2")) -}) - test_that("TwasWeights: per-tuple weights/cvResult/methodFits/ldReference", { w1 <- rnorm(4) - e1 <- twasWeightsRow( + e1 <- TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), weights = w1, methodFits = list(tag = "fitA"), cvResult = list(rsq = 0.42) ) - e2 <- twasWeightsRow( + e2 <- TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), weights = rnorm(4) ) @@ -1379,6 +1283,35 @@ test_that("TwasWeights: per-tuple weights/cvResult/methodFits/ldReference", { expect_s4_class(ldReference(tw)[[1L]], "RangedSummarizedExperiment") }) +test_that("TwasWeights: rejects non-TwasWeightsRow rows", { + expect_error( + TwasWeights( + studyName = "s1", + context = "c1", + trait = "t1", + method = "lasso", + entry = list("not_an_entry") + ), + "must be a TWAS-weight row" + ) +}) + +test_that("TwasWeights: validity does not recurse on key subset (#546)", { + # Building the tuple-uniqueness key via `object[, keyCols]` preserves the + # TwasWeights class while dropping the required `entry` column; older + # S4Vectors revalidates that intermediate and fails with "missing columns". + e <- .sc_makeTwasWeightsRow(p = 5L) + res <- TwasWeights( + studyName = "s1", + context = "c1", + trait = "t1", + method = "lasso", + entry = list(e) + ) + expect_s4_class(res, "TwasWeights") + expect_true(validObject(res)) +}) + # =========================================================================== # # .resolveMethodFunction: unresolvable-key fallback @@ -1427,7 +1360,7 @@ test_that(".prepareSusieWeightMethods writes supplied fits onto the method args" test_that("twasWeightsCv: warns when no random seed has been set", { d <- makeData(n = 20, p = 5) # makeData() set a seed; drop it just before the call so the unset-seed - # branch (verbose>=1) is exercised. The fold-sampling at line ~713 restores + # branch (verbose>=1) is exercised. The fold sampling creates a fresh # .Random.seed afterwards, so later tests are unaffected. if (exists(".Random.seed", envir = .GlobalEnv)) { rm(".Random.seed", envir = .GlobalEnv) @@ -1623,7 +1556,8 @@ test_that("learnTwasWeights: univariate fitter runs under verbose=2", { expect_equal(nrow(.weightsByMethod(result, "lassoWeights")), ncol(d$X)) }) -test_that("learnTwasWeights: parallel weights path (numThreads = 2)", { +test_that("learnTwasWeights: parallel weights path (two workers)", { + skip_on_os("windows") d <- makeData(n = 30, p = 6) local_mocked_bindings( lassoWeights = function(X, y, ...) rep(0.1, ncol(X)), @@ -1633,7 +1567,7 @@ test_that("learnTwasWeights: parallel weights path (numThreads = 2)", { d$X, d$Y, weightMethods = list(lasso_weights = list(), enetWeights = list()), - numThreads = 2 + BPPARAM = BiocParallel::MulticoreParam(2) )) expect_true(is(result, "TwasWeights")) expect_setequal(methodNames(result), c("lasso", "enet")) @@ -1650,11 +1584,11 @@ test_that("twasPredict: accepts a TwasWeights S4 collection", { p <- 5 w1 <- rnorm(p) w2 <- rnorm(p) - e1 <- twasWeightsRow( + e1 <- TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * seq_len(p)), weights = w1 ) - e2 <- twasWeightsRow( + e2 <- TwasWeightsRow( variantIds = sprintf("chr1:%d:A:G", 100L * seq_len(p)), weights = w2 ) @@ -1790,8 +1724,8 @@ test_that("twasWeightsCv: argument guards fire", { "maxNumVariants.*is not >= 1" ) expect_error( - exec(twasWeightsCv, !!!list_modify(base, !!!list(numThreads = 1.5))), - "numThreads.*Must be of type 'single integerish value'" + exec(twasWeightsCv, !!!list_modify(base, !!!list(BPPARAM = 2))), + "must be a BiocParallelParam" ) expect_error( exec( @@ -1860,55 +1794,8 @@ test_that("twasPredict: weightsList must be a list or TwasWeights", { # fineMappingPipeline's own CV retained each fold's fit. # --------------------------------------------------------------------------- -.twcv_foldFits <- function(seed = 11, fold = 3) { - set.seed(seed) - data(eqtlRegionExample) - X <- eqtlRegionExample$X[, 1:40] - y <- eqtlRegionExample$yRes - Y <- matrix(y, ncol = 1, dimnames = list(rownames(X), "t1")) - cv <- pecotmr:::.fmWeightsCv( - X, - Y, - tokens = "susie", - methodArgs = list(), - fold = fold, - verbose = 0, - seed = 1 - ) - list(X = X, Y = Y, cv = cv, slice = pecotmr:::.fmSliceCv(cv, "susie")) -} - -test_that("fineMappingPipeline CV retains a lean per-fold fit", { - skip_if_not_installed("susieR") - f <- suppressMessages(.twcv_foldFits()) - expect_false(is.null(f$cv$foldFits)) - expect_equal(names(f$cv$foldFits), c("fold_1", "fold_2", "fold_3")) - # lean: only the fields the weight extractors read - fit1 <- f$cv$foldFits[["fold_1"]][["susie"]] - expect_true(all(c("pip", "alpha", "mu") %in% names(fit1))) - expect_false("lbf_variable" %in% names(fit1)) - # and it slices per method onto the row payload - expect_equal(names(f$slice$foldFits), c("fold_1", "fold_2", "fold_3")) -}) - -test_that("twasWeightsCv cannot cross-validate susie without the fold fits", { - skip_if_not_installed("susieR") - f <- suppressMessages(.twcv_foldFits()) - expect_error( - suppressMessages(twasWeightsCv( - f$X, - f$Y, - samplePartitions = f$slice$samplePartition, - weightMethods = list(susie_weights = list()), - verbose = 0 - )), - "never run fine-mapping themselves" - ) -}) - test_that("twasWeightsCv cross-validates susie from the retained fold fits", { - skip_if_not_installed("susieR") - f <- suppressMessages(.twcv_foldFits()) + f <- .twcvFixture out <- suppressMessages(twasWeightsCv( f$X, f$Y, @@ -1921,20 +1808,22 @@ test_that("twasWeightsCv cross-validates susie from the retained fold fits", { expect_false(is.null(out$prediction)) }) -test_that(".twasFoldFit injects the fold's fit under the adapter's fit arg", { +test_that(".twasFoldFit injects the fold's fit, else leaves the args alone", { + f <- pecotmr:::.twasFoldFit ff <- list(susie = list(fold_1 = "FIT1", fold_2 = "FIT2")) - a <- pecotmr:::.twasFoldFit(list(), "susie_weights", 2L, ff) + a <- f(list(), "susie_weights", 2L, ff) expect_identical(a$susieFit, "FIT2") - # a method with no fine-mapping adapter is untouched - b <- pecotmr:::.twasFoldFit(list(), "lasso_weights", 1L, ff) - expect_length(b, 0L) - # and so is the NULL case - expect_length(pecotmr:::.twasFoldFit(list(), "susie_weights", 1L, NULL), 0L) + args <- list(X = 1) + # No CV payload at all. + expect_identical(f(args, "susie_weights", 1L, NULL), args) + # A method with no fine-mapping adapter is untouched. + expect_identical(f(args, "lasso_weights", 1L, ff), args) + # The token is present but carries no folds, so there is nothing to add. + expect_identical(f(args, "susie", 1L, list(susie = list())), args) }) test_that("twasWeightsCv refuses fold fits from a different partition", { - skip_if_not_installed("susieR") - f <- suppressMessages(.twcv_foldFits()) + f <- .twcvFixture wm <- list(susie = list()) # (a) no partition at all: a freshly drawn one would score each fold with @@ -1951,8 +1840,8 @@ test_that("twasWeightsCv refuses fold fits from a different partition", { ) # (b) fits with no fingerprint cannot be shown to match. - unstamped <- f$slice$foldFits - attr(unstamped, "partitionKey") <- NULL + unkeyed <- f$slice$foldFits + attr(unkeyed, "partitionKey") <- NULL expect_error( suppressMessages(twasWeightsCv( f$X, @@ -1960,21 +1849,15 @@ test_that("twasWeightsCv refuses fold fits from a different partition", { weightMethods = wm, verbose = 0, samplePartitions = f$slice$samplePartition, - fittedModelsCv = list(susie = unstamped) + fittedModelsCv = list(susie = unkeyed) )), "no partition fingerprint" ) - # (c) a genuinely different split is caught by the fingerprint. - other <- suppressMessages(pecotmr:::.fmWeightsCv( - f$X, - f$Y, - tokens = "susie", - methodArgs = list(), - fold = 3, - verbose = 0, - seed = 77 - )) + # (c) a genuinely different split is caught by the fingerprint. Drawing + # one needs no fits: with no methods, twasWeightsCv returns just the + # partition. + other <- suppressMessages(twasWeightsCv(f$X, f$Y, fold = 3, seed = 77)) expect_error( suppressMessages(twasWeightsCv( f$X, @@ -1988,21 +1871,6 @@ test_that("twasWeightsCv refuses fold fits from a different partition", { ) }) -test_that(".cvPartitionKey ignores row order but not fold assignment", { - sp <- data.frame(Sample = c("s1", "s2", "s3"), Fold = c(1L, 2L, 1L)) - shuffled <- sp[c(3, 1, 2), ] - expect_identical( - pecotmr:::.cvPartitionKey(sp), - pecotmr:::.cvPartitionKey(shuffled) - ) - moved <- sp - moved$Fold <- c(1L, 1L, 2L) - expect_false(identical( - pecotmr:::.cvPartitionKey(sp), - pecotmr:::.cvPartitionKey(moved) - )) -}) - # --------------------------------------------------------------------------- # Up-front gate: a SuSiE-family method without its fit is refused before any # fitting work, rather than surfacing from inside the per-fold map. @@ -2027,6 +1895,21 @@ test_that("learnTwasWeights refuses a susie token with no fit", { )), "never run fine-mapping themselves" ) + # The susie + susieInf pair is refused too, naming both: the chained + # susieInf -> susie fit lives in fineMappingPipeline(), and + # fitSusieInfThenSusie() itself is covered in test_fineMappingWrappers.R. + expect_error( + learnTwasWeights( + X, + Y, + weightMethods = list( + susie_weights = list(), + susie_inf_weights = list() + ), + verbose = 0 + ), + "susie, susieInf" + ) # supplying it through fittedModels satisfies the gate fit <- suppressMessages(susieR::susie(X, Y[, 1], L = 5)) expect_no_error(suppressMessages(learnTwasWeights( @@ -2046,8 +1929,7 @@ test_that("learnTwasWeights refuses a susie token with no fit", { }) test_that("twasWeightsCv refuses a susie token with no per-fold fits", { - skip_if_not_installed("susieR") - f <- suppressMessages(.twcv_foldFits()) + f <- .twcvFixture expect_error( suppressMessages(twasWeightsCv( f$X, @@ -2056,7 +1938,7 @@ test_that("twasWeightsCv refuses a susie token with no per-fold fits", { weightMethods = list(susie_weights = list()), verbose = 0 )), - "needs that fold's own fit" + "never run fine-mapping themselves.*needs that fold's own fit" ) }) @@ -2075,11 +1957,6 @@ test_that(".twasSusieTokensRequested matches both method spellings", { ) }) -test_that("the twas lookup helpers answer NULL when the token is absent", { - expect_null(pecotmr:::.twasMethodArgsFor(list(), "susie")) - expect_null(pecotmr:::.twasFoldFitsFor(NULL, "susie")) -}) - # --- per-token argument chains ---------------------------------------------- # # The recorded chains in .twasMethodChains() are the basis for checking a @@ -2105,7 +1982,6 @@ test_that("the twas lookup helpers answer NULL when the token is absent", { "penalizedRss", ".penalizedRssPath", "lassosumRss", - ".lassosumRssPath", "sdpr", ".sdprRun", "prsCs", @@ -2197,7 +2073,13 @@ test_that("the recorded RSS chains match what a fit enters", { expect_true(is_in(".rssShrinkGridWeights", seen)) seen <- .tw_traceChain(lassosumRssWeights(fx$stat, fx$ldReference)) expect_true(all(is_in(seen, recordedFor("lasso")))) - expect_true(is_in(".lassosumRssPath", seen)) + expect_true(is_in(".penalizedRssPath", seen)) + seen <- .tw_traceChain(enetRssWeights(fx$stat, fx$ldReference)) + expect_true(all(is_in(seen, recordedFor("enet")))) + expect_true(is_in(".penalizedRssPath", seen)) + seen <- .tw_traceChain(ridgeRssWeights(fx$stat, fx$ldReference)) + expect_true(all(is_in(seen, recordedFor("ridge")))) + expect_true(is_in(".penalizedRssPath", seen)) prsCsOpts <- PrsCsOptions(nIter = 20, nBurnin = 5, thin = 1) seen <- .tw_traceChain( prsCsWeights(fx$stat, fx$ldReference, methodArgs = prsCsOpts) @@ -2212,11 +2094,44 @@ test_that("the recorded RSS chains match what a fit enters", { expect_true(is_in(".sdprRun", recordedFor("dprGibbs"))) }) +test_that("an RSS method accepts its own penalty settings and no other's", { + # The penalty reaches .penalizedRssPath() as the wrapper's record, so + # every chain shares that hop without taking each other's settings. + accepted <- function(tk) pecotmr:::.twasChainAccepted(tk, "QtlSumStats") + path <- c("lambda", "thr", "maxiter") + l0Only <- c("lambda0", "lambda2", "maxSwaps") + expect_true(all(is_in(path, accepted("lasso")))) + expect_false(any(is_in( + c("alpha", "gamma", "penalty", l0Only, "spec", "label", "method"), + accepted("lasso") + ))) + expect_true(all(is_in(c("alpha", path), accepted("enet")))) + expect_false(any(is_in(c("gamma", l0Only), accepted("enet")))) + expect_false(any(is_in(c("alpha", "gamma", l0Only), accepted("ridge")))) + expect_true(all(is_in(c("alpha", "gamma"), accepted("scad")))) + expect_false(any(is_in(l0Only, accepted("scad")))) + expect_true(all(is_in( + c("penalty", "lambda", l0Only), + accepted("l0learn") + ))) + expect_false(any(is_in(c("alpha", "gamma"), accepted("l0learn")))) +}) + test_that("every RSS chain yields a checkable argument set", { # The point of the chains: each summary-statistics path ends in one of # pecotmr's own solvers, which enumerate their formals, so the RSS side # is checkable even where the individual side is not. - for (tk in c("scad", "mcp", "l0learn", "lasso", "prsCs", "dprGibbs")) { + tokens <- c( + "scad", + "mcp", + "l0learn", + "lasso", + "enet", + "ridge", + "prsCs", + "dprGibbs" + ) + for (tk in tokens) { expect_false( is.null(pecotmr:::.twasChainAccepted(tk, "QtlSumStats")), label = paste("accepted set for", tk) @@ -2256,6 +2171,24 @@ test_that("per-class checking rejects a name only the other path accepts", { ) }) +# The exported *Options constructor that method `token` resolves to on input +# path `path`, by name: NA when the method does not run on that path, "?" +# when what it resolves to is not an exported *Options constructor. +optionsCtorName <- function(token, path) { + ctor <- pecotmr:::.twasMethodCtorFor(token, path) + if (is.null(ctor)) { + return(NA_character_) + } + exports <- getNamespaceExports("pecotmr") + candidates <- exports[str_ends(exports, "Options")] + isCtor <- map_lgl( + mget(candidates, envir = asNamespace("pecotmr")), + identical, + ctor + ) + if (any(isCtor)) candidates[isCtor][[1L]] else "?" +} + test_that("the TWAS Options registry is derived from each implementation", { # It used to be 18 hand-written token -> constructor pairs, which had to # restate a pairing the implementation already declares through its own @@ -2265,69 +2198,40 @@ test_that("the TWAS Options registry is derived from each implementation", { pecotmr:::.twasConfigurableMethods(), names(pecotmr:::.twasMethodCapabilities) ) - # Every configurable method has a constructor on each path it runs on. + # Every configurable method resolves, on each path it runs on, to an + # exported *Options constructor a caller can build its options with. The + # pairs themselves are pinned in the next test. for (path in c("QtlDataset", "QtlSumStats")) { toks <- intersect( pecotmr:::.twasConfigurableMethods(), pecotmr:::.twasMethodsFor(path) ) - ctors <- map(toks, pecotmr:::.twasMethodCtorFor, inputKind = path) - expect_true(all(map_lgl(ctors, is.function)), info = path) - } - - nameOf <- function(f) { - if (is.null(f)) { - return(NA_character_) - } - hit <- keep( - grep("Options$", getNamespaceExports("pecotmr"), value = TRUE), - function(n) identical(get(n, envir = asNamespace("pecotmr")), f) + ctorNames <- map_chr(toks, optionsCtorName, path = path) + expect_equal( + toks[is.na(ctorNames) | ctorNames == "?"], + character(0), + info = path ) - if (length(hit) > 0L) hit[[1L]] else "?" - } - # Spot-check the pairs the derivation must reproduce. - ctorName <- function(tk, path) { - nameOf(pecotmr:::.twasMethodCtorFor(tk, path)) } - expect_equal(ctorName("lasso", "QtlDataset"), "GlmnetOptions") - expect_equal(ctorName("mcp", "QtlDataset"), "NcvregOptions") - expect_equal(ctorName("bayesB", "QtlDataset"), "BglrOptions") - # prsCs has no individual implementation; its one constructor is the - # summary-statistics one. - expect_equal(ctorName("prsCs", "QtlSumStats"), "PrsCsOptions") }) test_that("each method's Options constructor is resolved per input path", { - nameOf <- function(f) { - if (is.null(f)) { - return(NA_character_) - } - hit <- keep( - grep("Options$", getNamespaceExports("pecotmr"), value = TRUE), - function(n) identical(get(n, envir = asNamespace("pecotmr")), f) - ) - if (length(hit) > 0L) hit[[1L]] else "?" - } # The two paths of one method can reach different PACKAGES, which is why # one constructor per method was never enough. - expect_equal( - nameOf(pecotmr:::.twasMethodCtorFor("lasso", "QtlDataset")), - "GlmnetOptions" - ) - expect_equal( - nameOf(pecotmr:::.twasMethodCtorFor("lasso", "QtlSumStats")), - "LassosumOptions" - ) - expect_equal( - nameOf(pecotmr:::.twasMethodCtorFor("dprGibbs", "QtlSumStats")), - "SdprOptions" - ) - expect_equal( - nameOf(pecotmr:::.twasMethodCtorFor("mrmash", "QtlSumStats")), - "MrmashRssOptions" - ) + expect_equal(optionsCtorName("lasso", "QtlDataset"), "GlmnetOptions") + expect_equal(optionsCtorName("lasso", "QtlSumStats"), "LassosumOptions") + expect_equal(optionsCtorName("mcp", "QtlDataset"), "NcvregOptions") + expect_equal(optionsCtorName("bayesB", "QtlDataset"), "BglrOptions") + expect_equal(optionsCtorName("dprGibbs", "QtlSumStats"), "SdprOptions") + expect_equal(optionsCtorName("mrmash", "QtlSumStats"), "MrmashRssOptions") + # enet and ridge run on summary statistics through the penalized solver. + expect_equal(optionsCtorName("enet", "QtlSumStats"), "PenalizedRssOptions") + expect_equal(optionsCtorName("ridge", "QtlDataset"), "GlmnetOptions") + # prsCs has no individual implementation; its one constructor is the + # summary-statistics one. + expect_equal(optionsCtorName("prsCs", "QtlSumStats"), "PrsCsOptions") # A method that does not run on a path has no constructor there. - expect_null(pecotmr:::.twasMethodCtorFor("enet", "QtlSumStats")) + expect_null(pecotmr:::.twasMethodCtorFor("dprVb", "QtlSumStats")) expect_null(pecotmr:::.twasMethodCtorFor("prsCs", "QtlDataset")) expect_null(pecotmr:::.twasMethodCtorFor("nosuch", "QtlDataset")) }) @@ -2352,6 +2256,8 @@ test_that("name lookups answer NA / NULL when the name resolves to nothing", { ) expect_null(pecotmr:::.twasImplCtorName("noSuchImplAnywhere")) expect_null(pecotmr:::.twasImplCtorName(NULL)) + # A token no weightMethods name spells has no arguments to look up. + expect_null(pecotmr:::.twasMethodArgsFor(list(), "susie")) }) test_that(".twasCanonicalShortName maps a function name back, else passes on", { @@ -2369,13 +2275,176 @@ test_that(".twasFoldFitsFor answers NULL when no spelling is present", { expect_null(f(list(somethingElse = list()), "susie")) }) -test_that(".twasFoldFit leaves args alone when there is no fold fit", { - f <- pecotmr:::.twasFoldFit - args <- list(X = 1) - # No CV payload at all. - expect_identical(f(args, "susie", 1L, NULL), args) - # A method with no fine-mapping token to look up. - expect_identical(f(args, "lasso", 1L, list(susie = list())), args) - # The token is present but carries no folds, so there is nothing to add. - expect_identical(f(args, "susie", 1L, list(susie = list())), args) +# =========================================================================== +# metadata, and the variants each row's fits were made on +# =========================================================================== + +.tw_ids <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A") + +# A TwasWeights of one row per payload in `rows`, named r1, r2, ... +.tw_collection <- function(rows, metadata = list()) { + n <- length(rows) + TwasWeights( + studyName = rep("s1", n), + context = rep("c1", n), + trait = sprintf("g%d", seq_len(n)), + method = rep("lasso", n), + entry = rows, + metadata = metadata + ) +} + +test_that("TwasWeights() keeps the caller's metadata", { + tw <- .tw_collection( + list(TwasWeightsRow(.tw_ids, c(0.1, 0.2, 0.3))), + metadata = list(run = "r1") + ) + expect_equal(S4Vectors::metadata(tw), list(run = "r1")) +}) + +test_that("a weights row records its fit variants only with a fit payload", { + tw <- .tw_collection(list( + TwasWeightsRow(.tw_ids, c(0.1, 0.2, 0.3), cvResult = list(r2 = 0.4)), + TwasWeightsRow(.tw_ids, c(0.1, 0.2, 0.3)) + )) + expect_s4_class(tw$fitVariants, "CharacterList") + expect_equal(as.character(tw$fitVariants[[1L]]), .tw_ids) + expect_equal(as.character(tw$fitVariants[[2L]]), character(0)) +}) + +test_that("cvResult() and methodFits() of a narrowed row warn", { + fits <- list(lasso = list(lambda = 0.1)) + cv <- list(r2 = 0.4) + tw <- .tw_collection(list( + TwasWeightsRow(.tw_ids, c(0.1, 0.2, 0.3), fits, cv) + )) + narrowed <- endoapply(tw, utils::head, 2L) + expect_warning( + out <- cvResult(narrowed), + "cvResult\\(\\): the stored fit was made with 3 variants, 1 of" + ) + expect_identical(out, cv) + expect_warning( + outFits <- methodFits(narrowed), + "methodFits\\(\\): .* Refit on the variants kept" + ) + expect_identical(outFits, fits) + expect_no_warning(cvResult(tw)) + expect_no_warning(methodFits(tw)) +}) + +test_that("updateObject() backfills a fitted row's held variants", { + tw <- .tw_collection(list( + TwasWeightsRow(.tw_ids, c(0.1, 0.2, 0.3), cvResult = list(r2 = 0.4)), + TwasWeightsRow(.tw_ids, c(0.1, 0.2, 0.3)) + )) + saved <- tw + saved$fitVariants <- NULL + up <- updateObject(saved) + expect_equal(as.character(up$fitVariants[[1L]]), .tw_ids) + expect_equal(as.character(up$fitVariants[[2L]]), character(0)) + # A current collection is left as it is. + expect_identical(updateObject(tw)$fitVariants, tw$fitVariants) + expect_message(updateObject(tw, verbose = TRUE), "TwasWeights") +}) + +# =========================================================================== +# estimateSparsity +# =========================================================================== + +test_that("estimateSparsity: legacy list input reads attr(.,'fit')$pi", { + # Build a weight result that mimics learnTwasWeights keeping its fits: + # element name carries the `_weights` suffix; attr 'fit' carries an mr.ash + # object whose pi[1] is the spike weight. + fake_w <- structure(c(0.1, 0, 0.3), fit = list(pi = c(0.6, 0.2, 0.2))) + weightResults <- list(mrash_weights = fake_w) + expect_equal(estimateSparsity(weightResults), 1 - 0.6, tolerance = 1e-12) +}) + +test_that("estimateSparsity: TwasWeights collection input reads from the mrash entry", { + entry <- TwasWeightsRow( + variantIds = c("chr1:100:A:G", "chr1:200:A:G", "chr1:300:A:G"), + weights = c(0.1, 0, 0.3), + methodFits = list(pi = c(0.7, 0.2, 0.1)), + weightStandardized = FALSE + ) + tw <- TwasWeights( + studyName = "s1", + context = "c1", + trait = "t1", + method = "mrash", + entry = list(entry) + ) + expect_equal(estimateSparsity(tw), 1 - 0.7, tolerance = 1e-12) +}) + +test_that("estimateSparsity: TwasWeights without mrash entry errors", { + entry <- TwasWeightsRow(variantIds = c("chr1:100:A:G"), weights = c(0.1)) + tw <- TwasWeights( + studyName = "s1", + context = "c1", + trait = "t1", + method = "lasso", + entry = list(entry) + ) + expect_error( + estimateSparsity(tw), + "mr.ash entry not found in TwasWeights" + ) +}) + +test_that("estimateSparsity: TwasWeights with mrash entry but no fit$pi errors", { + entry <- TwasWeightsRow( + variantIds = c("chr1:100:A:G"), + weights = c(0.1), + methodFits = list(other = 1) + ) + tw <- TwasWeights( + studyName = "s1", + context = "c1", + trait = "t1", + method = "mrash", + entry = list(entry) + ) + expect_error( + estimateSparsity(tw), + "mr.ash fit object not found" + ) +}) + +test_that("estimateSparsity: legacy list input without mrash_weights errors", { + expect_error( + estimateSparsity(list(lasso = c(0.1, 0.2))), + "'mrash_weights'.*not found" + ) +}) + +test_that("estimateSparsity: legacy list input without fit attr errors", { + expect_error( + estimateSparsity(list(mrash_weights = c(0.1, 0.2))), + "mr.ash fit object not found" + ) +}) + +# =========================================================================== +# .twasMethodMap +# =========================================================================== + +test_that("ser is reachable as a TWAS method", { + # It is fit-derived like susie/mvsusie, so it carries no learner + # arguments and its entry is an empty stub. + expect_true(is_in("ser", names(pecotmr:::.twasMethodMap))) + expect_equal(pecotmr:::.twasMethodMap$ser$impl, "serWeights") + expect_length(pecotmr:::.twasMethodMap$ser$args, 0L) + expect_setequal( + pecotmr:::.twasNormalizeMethods(c("ser", "lasso"))$tokens, + c("ser", "lasso") + ) + # Nothing to configure, same as the other fit-derived methods. + expect_error( + TwasWeightsMethodsParam( + qtlSumStatsMethods = list(ser = list(nope = 1)) + ), + "nothing to configure here" + ) }) diff --git a/tests/testthat/test_twasWeightsPipeline.R b/tests/testthat/test_twasWeightsPipeline.R index 25139967..169873e1 100644 --- a/tests/testthat/test_twasWeightsPipeline.R +++ b/tests/testthat/test_twasWeightsPipeline.R @@ -26,7 +26,7 @@ context("twasWeightsPipeline (S4 dispatch) with mocked weight methods") format = "plink2", snpInfo = data.frame( SNP = sprintf("chr1:%d:A:G", 100L * seq_len(snp_n)), - CHR = rep("1", snp_n), + CHR = rep("chr1", snp_n), BP = seq(100L, by = 100L, length.out = snp_n), A1 = rep("A", snp_n), A2 = rep("G", snp_n), @@ -159,7 +159,7 @@ context("twasWeightsPipeline (S4 dispatch) with mocked weight methods") pip = c(0.9, 0.5, 0.1), stringsAsFactors = FALSE ) - fineMappingRow( + FineMappingRow( variantIds = tl$variant_id, susieFit = fitPayload, topLoci = tl @@ -236,8 +236,7 @@ test_that("twasWeightsPipeline(QtlDataset): runs end-to-end with mocked solvers" expect_setequal(traitNames(res), c("ENSG_A", "ENSG_B")) # Provenance, aligned per row (.tp_makeSe: ENSG_A -> chr1:1000-1499, # ENSG_B -> chr1:2000-2499). traitPos = the bare trait position (no - # cis-window); region = that position expanded by cisWindow (1000), start - # clamped at 1. + # cis-window). reg <- genomicRegion(res) tp <- traitPosition(res) expect_s4_class(reg, "GRanges") @@ -249,7 +248,7 @@ test_that("twasWeightsPipeline(QtlDataset): runs end-to-end with mocked solvers" expect_true(all(GenomicRanges::end(tp)[res$trait == "ENSG_A"] == 1499L)) expect_true(all(GenomicRanges::start(tp)[res$trait == "ENSG_B"] == 2000L)) # region: the REALIZED variant span now, not traitPos +/- cisWindow. The - # nominal window is gone (no correct update rule under subsetRegion); the + # nominal window is gone (no correct update rule under subsetting); the # span is in sync with the variants and still sits inside that window. expect_true(all(GenomicRanges::start(reg)[res$trait == "ENSG_A"] >= 1L)) expect_true(all(GenomicRanges::end(reg)[res$trait == "ENSG_A"] <= 2499L)) @@ -307,7 +306,7 @@ test_that("twasWeightsPipeline(QtlDataset): mafCutoff/xvarCutoff overrides tight ) }) -test_that("twasWeightsPipeline(QtlDataset): contexts filter restricts the per-context loop", { +test_that("twasWeightsPipeline(QtlDataset): context narrows the context loop", { qd <- .tp_makeQtlDataset(contexts = c("brain", "liver"), traits = "ENSG_A") mocks <- c( list(extractBlockGenotypes = .tp_mockExtractor()), @@ -343,7 +342,7 @@ test_that("twasWeightsPipeline(QtlDataset): contexts filter restricts the per-co ) } -test_that("twasWeightsPipeline(QtlDataset): traitId chosen per context", { +test_that("twasWeightsPipeline(QtlDataset): trait chosen per context", { mocks <- c( list(extractBlockGenotypes = .tp_mockExtractor()), .tp_mockIndividualWeights() @@ -458,7 +457,7 @@ test_that("twasWeightsPipeline(QtlDataset): RSS-only method rejected", { gr } -.tp_makeQtlSumStats <- function(n_entries = 1L, qc = TRUE) { +.tp_makeQtlSumStats <- function(n_entries = 1L, qc = TRUE, traitPos = NULL) { studies <- rep("s1", n_entries) contexts <- if (n_entries == 1L) "c1" else paste0("c", seq_len(n_entries)) traits <- rep("t1", n_entries) @@ -470,7 +469,8 @@ test_that("twasWeightsPipeline(QtlDataset): RSS-only method rejected", { entry = entries, genome = "hg19", ldReference = .tp_makeHandle(snp_n = 20L), - qcInfo = if (qc) list(step1 = "ok") else list() + qcOptions = if (qc) list(step1 = "ok") else list(), + traitPos = traitPos ) } @@ -525,7 +525,7 @@ test_that("twasWeightsPipeline(QtlSumStats): un-QCd input is rejected", { test_that("twasWeightsPipeline(QtlSumStats): individual-only method rejected", { ss <- .tp_makeQtlSumStats() expect_error( - twasWeightsPipeline(ss, methods = "enet"), + twasWeightsPipeline(ss, methods = "dprVb"), "not available for input class 'QtlSumStats'" ) }) @@ -564,10 +564,7 @@ test_that("twasWeightsPipeline(QtlSumStats): per-method failure surfaces as warn ) }) -test_that("twasWeightsPipeline( - QtlSumStats): multivariate requires >=2 contexts per (study, - trait -)", { +test_that("twasWeightsPipeline(QtlSumStats): mvsusie needs >= 2 contexts", { ss <- .tp_makeQtlSumStats(n_entries = 1L) # 1 context per (study, trait) # Provide a stub fine-mapping result so the gate passes; the multivariate # guard is what we want to exercise here. @@ -579,7 +576,8 @@ test_that("twasWeightsPipeline( ) expect_error( twasWeightsPipeline(ss, methods = "mvsusie", fineMappingResult = fmr), - "multivariate method.*require at least two contexts" + "multivariate method(s) mvsusie require at least two contexts", + fixed = TRUE ) }) @@ -591,45 +589,36 @@ test_that("twasWeightsPipeline( # rule set stays in sync with fineMappingPipeline. # =========================================================================== -test_that("gate: QtlDataset + susie without fineMappingResult errors", { +test_that("gate: each fine-mapping method without fineMappingResult errors", { qd <- .tp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") - expect_error( - twasWeightsPipeline(qd, methods = "susie"), - "are fine-mapping methods and may not be re-fit" - ) -}) - -test_that("gate: QtlSumStats + susieInf without fineMappingResult errors", { - ss <- .tp_makeQtlSumStats() - expect_error( - twasWeightsPipeline(ss, methods = "susieInf"), - "are fine-mapping methods and may not be re-fit" - ) -}) - -test_that("gate: QtlDataset + susieAsh without fineMappingResult errors", { - qd <- .tp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") - expect_error( - twasWeightsPipeline(qd, methods = "susieAsh"), - "are fine-mapping methods and may not be re-fit" - ) -}) - -test_that("gate: composite (susie + susieInf) without fineMappingResult errors", { - qd <- .tp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") - # Mixed: lasso is allowed, but susie/susieInf must still be gated. - expect_error( - twasWeightsPipeline(qd, methods = c("susie", "susieInf", "lasso")), - "are fine-mapping methods and may not be re-fit" - ) -}) - -test_that("gate: mvsusie without fineMappingResult errors (QtlDataset)", { - qd <- .tp_makeQtlDataset(contexts = c("brain", "liver"), traits = "ENSG_A") - expect_error( - twasWeightsPipeline(qd, methods = "mvsusie"), - "are fine-mapping methods and may not be re-fit" + # Each case: the input it runs on and the methods it asks for. + cases <- list( + "QtlDataset + susie" = list(qd, "susie"), + "QtlSumStats + susieInf" = list(.tp_makeQtlSumStats(), "susieInf"), + "QtlDataset + susieAsh" = list(qd, "susieAsh"), + # Mixed: lasso is allowed, but susie/susieInf must still be gated. + "QtlDataset + susie, susieInf, lasso" = list( + qd, + c("susie", "susieInf", "lasso") + ), + "QtlDataset (two contexts) + mvsusie" = list( + .tp_makeQtlDataset( + contexts = c("brain", "liver"), + traits = "ENSG_A" + ), + "mvsusie" + ) ) + for (label in names(cases)) { + expect_error( + twasWeightsPipeline( + cases[[label]][[1L]], + methods = cases[[label]][[2L]] + ), + "are fine-mapping methods and may not be re-fit", + info = label + ) + } }) test_that("gate: fsusie now has a TWAS-weight extractor (accepted with FMR)", { @@ -837,10 +826,7 @@ test_that("gate: missing matching tuple in fineMappingResult warns and skips", { # matrix; we mock that solver to return a zero matrix of the expected shape. # =========================================================================== -test_that("twasWeightsPipeline( - QtlDataset): mvsusie multivariate path returns one row per (context, - trait -)", { +test_that("twasWeightsPipeline(QtlDataset): mvsusie gives a row per context", { qd <- .tp_makeQtlDataset(contexts = c("brain", "liver"), traits = "ENSG_A") fmr <- .tp_makeStubFineMappingResult( studyName = "study1", @@ -877,12 +863,14 @@ test_that("twasWeightsPipeline( ) )) expect_s4_class(res, "TwasWeights") - # Joint fit on 2 contexts x 1 trait -> 2 rows back, one per (context, trait). + # Joint fit on 2 contexts x 1 trait -> 2 rows back, one per (context, + # trait). expect_equal(nrow(res), 2L) expect_setequal(contexts(res), c("brain", "liver")) expect_setequal(traitNames(res), "ENSG_A") expect_setequal(methodNames(res), "mvsusie") - expect_gte(mvCalls, 1L) + # One joint fit serves both contexts. + expect_equal(mvCalls, 1L) }) test_that("twasWeightsPipeline(QtlDataset): mr.mash multivariate path with 2 traits x 2 contexts", { @@ -1012,7 +1000,7 @@ test_that("twasWeightsPipeline(QtlDataset): mr.mash retains its fit parts in the entry = entries, genome = "hg19", ldReference = .tp_makeHandle(snp_n = 20L), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) } @@ -1097,7 +1085,7 @@ test_that("twasWeightsPipeline(QtlSumStats): mr.mash multivariate solver failure variant_ids = sprintf("chr1:%d:A:G", 100L * (1:8)), weights = rep(0.5, 8) ) { - twasWeightsRow( + TwasWeightsRow( variantIds = variant_ids, weights = weights, weightStandardized = FALSE @@ -1233,7 +1221,7 @@ test_that(".twasCacheLookup: non-TwasWeights input returns NULL", { }) test_that(".twasCacheLookup: returns matching entry by 4-tuple", { - e <- twasWeightsRow(variantIds = "chr1:100:A:G", weights = 0.5) + e <- TwasWeightsRow(variantIds = "chr1:100:A:G", weights = 0.5) tw <- TwasWeights( studyName = "s1", context = "c1", @@ -1260,24 +1248,20 @@ test_that("twasWeightsPipeline(ANY): unsupported input class errors", { }) # =========================================================================== -# twasMultivariateWeightsPipeline +# Both multivariate methods in one run # =========================================================================== -# twasMultivariateWeightsPipeline() was a deprecation stub and was removed in -# 2be68392; its documented replacement is twasWeightsPipeline() with both -# multivariate tokens passed together. That migration path is what is tested -# here -- the two solvers must fit side by side and partition their output by -# (study, context, trait, method) rather than collide. +# twasWeightsPipeline() with both multivariate tokens passed together: the two +# solvers must fit side by side and partition their output by (study, context, +# trait, method) rather than collide. test_that("twasWeightsPipeline: mr.mash and mvSuSiE fit side by side", { - qd <- .tp_makeQtlDataset( - contexts = c("brain", "liver"), - traits = c("ENSG_A", "ENSG_B") - ) + # One trait over two contexts is a multivariate group for both methods. + qd <- .tp_makeQtlDataset(contexts = c("brain", "liver"), traits = "ENSG_A") fmr <- .tp_makeStubFineMappingResult( studyName = "study1", contexts = c("brain", "liver"), - traits = c("ENSG_A", "ENSG_B"), + traits = "ENSG_A", method = "mvsusie" ) mvCalls <- 0L @@ -1320,16 +1304,10 @@ test_that("twasWeightsPipeline: mr.mash and mvSuSiE fit side by side", { expect_gte(mrCalls, 1L) expect_setequal(methodNames(res), c("mrmash", "mvsusie")) expect_setequal(contexts(res), c("brain", "liver")) - expect_setequal(traitNames(res), c("ENSG_A", "ENSG_B")) - # 2 contexts x 2 traits x 2 methods, with no method overwriting the other. - expect_equal(nrow(res), 8L) + expect_setequal(traitNames(res), "ENSG_A") + # 2 contexts x 1 trait x 2 methods, with no method overwriting the other. + expect_equal(nrow(res), 4L) }) -# imputeMissingGwasForSketch was removed: it duplicated the inline RAISS -# imputation step at the bottom of .runEntrySummaryStatsQc (sumstatsQc.R), -# had no production callers, and was orphaned post-S4-refactor. The RAISS- -# against-sketch path that does run in production is exercised via the -# summaryStatsQc test file (with raiss() left to run for real on the small -# fixture). context("ensembleWeights") @@ -1463,29 +1441,12 @@ test_that("ensembleWeights: multi-dataset with different methods errors", { # =========================================================================== # Core algorithm correctness +# +# Coefficient validity, the best method's share and the weight combination +# are asserted per solver, the default (quadprog) included, under "Solver +# alternatives" below. # =========================================================================== -test_that("ensembleWeights: coefficients are non-negative and sum to 1", { - cv <- makeCvResult(n = 100, K = 4, seed = 42) - res <- ensembleWeights(cv, Y = cv$.y) - - expect_true(all(res$methodCoef >= 0)) - expect_equal(sum(res$methodCoef), 1, tolerance = 1e-6) -}) - -test_that("ensembleWeights: best method receives the largest coefficient", { - # Method 1 is best (lowest noise), method K is worst - cv <- makeCvResult( - n = 200, - K = 4, - seed = 7, - method_quality = c(0.1, 0.5, 0.8, 1.2) - ) - res <- ensembleWeights(cv, Y = cv$.y) - - expect_equal(names(which.max(res$methodCoef)), "method1") -}) - test_that("ensembleWeights: does not return ensemble_performance (in-sample R^2 omitted)", { cv <- makeCvResult(n = 300, K = 5, seed = 13) res <- ensembleWeights(cv, Y = cv$.y) @@ -1518,41 +1479,31 @@ test_that("ensembleWeights: method names are stripped of _predicted suffix", { # Sample name alignment # =========================================================================== -test_that("ensembleWeights: aligns Y and predictions by sample name", { +test_that("ensembleWeights: aligns a Y vector or matrix by sample name", { cv <- makeCvResult(n = 50, K = 3, seed = 10) - - # Shuffle Y order relative to predictions - shuffled_order <- sample(50) - y_shuffled <- cv$.y[shuffled_order] - names(y_shuffled) <- paste0("sample_", shuffled_order) - - res_aligned <- ensembleWeights(cv, Y = y_shuffled) res_original <- ensembleWeights(cv, Y = cv$.y) - # Results should be identical regardless of Y order - expect_equal( - res_aligned$methodCoef, - res_original$methodCoef, - tolerance = 1e-10 - ) -}) - -test_that("ensembleWeights: aligns Y matrix and predictions by sample name", { - cv <- makeCvResult(n = 50, K = 3, seed = 10) - - # Create Y as a matrix with shuffled row order + # Shuffle Y order relative to predictions shuffled_order <- sample(50) - Y_mat <- matrix(cv$.y[shuffled_order], ncol = 1) - rownames(Y_mat) <- paste0("sample_", shuffled_order) - - res_aligned <- ensembleWeights(cv, Y = Y_mat) - res_original <- ensembleWeights(cv, Y = cv$.y) - - expect_equal( - res_aligned$methodCoef, - res_original$methodCoef, - tolerance = 1e-10 + sampleIds <- paste0("sample_", shuffled_order) + shapes <- list( + vector = setNames(cv$.y[shuffled_order], sampleIds), + matrix = matrix( + cv$.y[shuffled_order], + ncol = 1, + dimnames = list(sampleIds, NULL) + ) ) + for (shape in names(shapes)) { + res_aligned <- ensembleWeights(cv, Y = shapes[[shape]]) + # Results should be identical regardless of Y order + expect_equal( + res_aligned$methodCoef, + res_original$methodCoef, + tolerance = 1e-10, + info = shape + ) + } }) test_that("ensembleWeights: errors when no common sample names", { @@ -1594,30 +1545,9 @@ test_that("ensembleWeights: all zero-variance methods errors", { }) # =========================================================================== -# Weight combination +# Weight combination (sum of zeta_k * w_k: see "Solver alternatives") # =========================================================================== -test_that("ensembleWeights: ensembleTwasWeights is sum of zeta_k * w_k", { - cv <- makeCvResult(n = 100, K = 3, seed = 42) - wt <- makeWeightList(p = 10, method_names = cv$.method_names) - - res <- ensembleWeights(cv, Y = cv$.y, twasWeightList = wt) - - expect_false(is.null(res$ensembleTwasWeights)) - - # Verify the combination is correct - expected <- matrix(0, nrow = 10, ncol = 1) - for (k in seq_along(cv$.method_names)) { - m <- cv$.method_names[k] - expected <- expected + res$methodCoef[m] * wt[[paste0(m, "_weights")]] - } - expect_equal( - as.numeric(res$ensembleTwasWeights), - as.numeric(expected), - tolerance = 1e-10 - ) -}) - test_that("ensembleWeights: NULL twas_weight_list returns NULL ensembleTwasWeights", { cv <- makeCvResult(n = 50, K = 3, seed = 1) res <- ensembleWeights(cv, Y = cv$.y, twasWeightList = NULL) @@ -1697,10 +1627,6 @@ test_that("ensembleWeights: end-to-end with twasWeightsCv output", { expect_null(res$ensemble_performance) }) -# =========================================================================== -# twasWeightsPipeline ensemble integration -# =========================================================================== - # =========================================================================== # Solver alternatives # =========================================================================== @@ -1834,15 +1760,6 @@ test_that("ensembleWeights: solver='glmnet' respects alpha parameter", { }) -context("multivariate_pipeline") - -# multivariateAnalysisPipeline and the legacy regionDataToMvsusieRssInput / -# regionDataToSusieRssInput entry points have been removed in the S4 -# refactor. Joint multi-trait/multi-context analyses now run through -# fineMappingPipeline(qtlDataset, methods = "mvsusie") (individual-level) -# or fineMappingPipeline(..., methods = "mvsusieRSS") (RSS-based). -# Coverage for those pipelines lives alongside their implementations. - context("twasWeights internal helpers") # =========================================================================== @@ -1855,18 +1772,27 @@ test_that(".twasNormalizeMethods: NULL falls through to the 'default' preset", { expect_equal(sort(names(res$methodList)), sort(default_names)) }) -test_that(".twasNormalizeMethods: character preset string forwards to .twasMethodLookup", { - res <- pecotmr:::.twasNormalizeMethods("fastDefault") - fast_names <- names(pecotmr:::.twasMethodLookup("fastDefault")) - expect_equal(sort(names(res$methodList)), sort(fast_names)) -}) - -test_that(".twasNormalizeMethods: character vector of short names forwards to .twasMethodLookup", { - res <- pecotmr:::.twasNormalizeMethods(c("lasso", "enet")) - expect_equal( - sort(names(res$methodList)), - sort(c("lasso_weights", "enet_weights")) +test_that(".twasNormalizeMethods: character methods go to .twasMethodLookup", { + # Each case: a character `methods` (a preset or short names) and the + # method list it expands to. + cases <- list( + preset = list( + "fastDefault", + names(pecotmr:::.twasMethodLookup("fastDefault")) + ), + shortNames = list( + c("lasso", "enet"), + c("lasso_weights", "enet_weights") + ) ) + for (label in names(cases)) { + res <- pecotmr:::.twasNormalizeMethods(cases[[label]][[1L]]) + expect_equal( + sort(names(res$methodList)), + sort(cases[[label]][[2L]]), + info = label + ) + } }) test_that(".twasNormalizeMethods: a methods record passes its kwargs through", { @@ -1937,9 +1863,9 @@ test_that(".twasCheckMethodCapabilities: sumstat-only token + QtlDataset errors" }) test_that(".twasCheckMethodCapabilities: individual-only token + QtlSumStats errors", { - # enet has individualImpl only -- not legal for QtlSumStats. + # dprVb has individualImpl only -- not legal for QtlSumStats. expect_error( - pecotmr:::.twasCheckMethodCapabilities("enet", "QtlSumStats"), + pecotmr:::.twasCheckMethodCapabilities("dprVb", "QtlSumStats"), "is individual-only" ) }) @@ -1994,7 +1920,7 @@ test_that(".twasCheckMultivariateY: mvsusie/mrmash error with single trait, sing # .twasAssertQcd # =========================================================================== -.tw_makeSumStatsBare <- function() { +.tw_makeSumStatsBare <- function(qcOptions = list()) { gr <- GenomicRanges::GRanges( "chr1", IRanges::IRanges(start = c(100L, 200L), width = 1L) @@ -2019,11 +1945,12 @@ test_that(".twasCheckMultivariateY: mvsusie/mrmash error with single trait, sing studyName = "g1", entry = list(gr), genome = "hg19", - ldReference = gh + ldReference = gh, + qcOptions = qcOptions ) } -test_that(".twasAssertQcd: errors when qcInfo is empty", { +test_that(".twasAssertQcd: errors when qcOptions is empty", { ss <- .tw_makeSumStatsBare() expect_error( pecotmr:::.twasAssertQcd(ss), @@ -2031,225 +1958,15 @@ test_that(".twasAssertQcd: errors when qcInfo is empty", { ) }) -test_that(".twasAssertQcd: passes when qcInfo is populated", { - gr <- GenomicRanges::GRanges( - "chr1", - IRanges::IRanges(start = c(100L, 200L), width = 1L) - ) - S4Vectors::mcols(gr) <- S4Vectors::DataFrame( - SNP = c("rs1", "rs2"), - A1 = c("A", "A"), - A2 = c("G", "G"), - Z = c(1, 2), - N = c(100L, 100L) - ) - gh <- new( - "GenotypeHandle", - path = "/tmp/x", - format = "plink2", - snpInfo = data.frame(), - nSamples = 0L, - sampleIds = character(), - pgenPtr = NULL - ) - ss <- GwasSumStats( - studyName = "g1", - entry = list(gr), - genome = "hg19", - ldReference = gh, - qcInfo = list(step1 = "ok") - ) +test_that(".twasAssertQcd: passes when qcOptions is populated", { + ss <- .tw_makeSumStatsBare(qcOptions = list(step1 = "ok")) expect_silent(pecotmr:::.twasAssertQcd(ss)) }) -# =========================================================================== -# as.data.frame (public method on GwasSumStats / QtlSumStats; replaces -# the now-deleted `.twasSumstatsEntryToDf` shim) -# =========================================================================== - -.gsd_makeHandle <- function(snp_n = 2L) { - new( - "GenotypeHandle", - path = "/tmp/sketch", - format = "plink2", - snpInfo = data.frame( - SNP = paste0("rs", seq_len(snp_n)), - CHR = rep("1", snp_n), - BP = seq(100L, by = 100L, length.out = snp_n), - A1 = rep("A", snp_n), - A2 = rep("G", snp_n), - stringsAsFactors = FALSE - ), - nSamples = 10L, - sampleIds = paste0("s", seq_len(10L)), - pgenPtr = NULL - ) -} - -.gsd_makeGwasSumStats <- function(mcolsDf, snp_n = nrow(mcolsDf)) { - gr <- GenomicRanges::GRanges( - seqnames = rep("chr1", snp_n), - ranges = IRanges::IRanges( - start = seq(100L, by = 100L, length.out = snp_n), - width = 1L - ) - ) - S4Vectors::mcols(gr) <- S4Vectors::DataFrame(mcolsDf) - GwasSumStats( - studyName = "G1", - entry = list(gr), - genome = "hg19", - ldReference = .gsd_makeHandle(snp_n), - qcInfo = list(prebuilt = "synthetic") - ) -} - -test_that("as.data.frame: returns the canonical column layout", { - ss <- .gsd_makeGwasSumStats(data.frame( - SNP = c("rs1", "rs2"), - A1 = c("A", "A"), - A2 = c("G", "G"), - Z = c(1.0, -2.5), - N = c(1000L, 1500L), - MAF = c(0.1, 0.3) - )) - df <- as.data.frame(ss) - expect_s3_class(df, "data.frame") - expect_equal(df$variant_id, c("rs1", "rs2")) - expect_equal(df$chrom, c("chr1", "chr1")) - expect_equal(df$pos, c(100L, 200L)) - expect_equal(df$z, c(1.0, -2.5)) - expect_equal(df$N, c(1000, 1500)) - expect_equal(df$maf, c(0.1, 0.3)) -}) - -test_that("as.data.frame: derives z from beta/se when derive='zFromBetaSe'", { - ss <- .gsd_makeGwasSumStats( - data.frame( - SNP = "rs1", - A1 = "A", - A2 = "G", - BETA = 0.5, - SE = 0.1, - N = 1000L - ), - snp_n = 1L - ) - df <- as.data.frame(ss, derive = "zFromBetaSe") - expect_equal(df$beta, 0.5) - expect_equal(df$se, 0.1) - expect_equal(df$z, 0.5 / 0.1) -}) - -test_that("as.data.frame: omits optional columns when absent", { - ss <- .gsd_makeGwasSumStats( - data.frame( - SNP = "rs1", - A1 = "A", - A2 = "G" - ), - snp_n = 1L - ) - df <- as.data.frame(ss) - expect_false("z" %in% names(df)) - expect_false("beta" %in% names(df)) - expect_false("se" %in% names(df)) - expect_false("N" %in% names(df)) - expect_false("maf" %in% names(df)) -}) - -test_that("as.data.frame: require=c('Z','N') errors when columns missing", { - ss <- .gsd_makeGwasSumStats( - data.frame( - SNP = "rs1", - A1 = "A", - A2 = "G", - Z = 1.5 - ), - snp_n = 1L - ) - expect_error(as.data.frame(ss, require = c("Z", "N")), "no N mcol") -}) - # =========================================================================== # estimateSparsity # =========================================================================== -test_that("estimateSparsity: legacy list input reads attr(.,'fit')$pi", { - # Build a weight result that mimics learnTwasWeights keeping its fits: - # element name carries the `_weights` suffix; attr 'fit' carries an mr.ash - # object whose pi[1] is the spike weight. - fake_w <- structure(c(0.1, 0, 0.3), fit = list(pi = c(0.6, 0.2, 0.2))) - weightResults <- list(mrash_weights = fake_w) - expect_equal(estimateSparsity(weightResults), 1 - 0.6, tolerance = 1e-12) -}) - -test_that("estimateSparsity: TwasWeights collection input reads from the mrash entry", { - entry <- twasWeightsRow( - variantIds = c("chr1:100:A:G", "chr1:200:A:G", "chr1:300:A:G"), - weights = c(0.1, 0, 0.3), - methodFits = list(pi = c(0.7, 0.2, 0.1)), - weightStandardized = FALSE - ) - tw <- TwasWeights( - studyName = "s1", - context = "c1", - trait = "t1", - method = "mrash", - entry = list(entry) - ) - expect_equal(estimateSparsity(tw), 1 - 0.7, tolerance = 1e-12) -}) - -test_that("estimateSparsity: TwasWeights without mrash entry errors", { - entry <- twasWeightsRow(variantIds = c("chr1:100:A:G"), weights = c(0.1)) - tw <- TwasWeights( - studyName = "s1", - context = "c1", - trait = "t1", - method = "lasso", - entry = list(entry) - ) - expect_error( - estimateSparsity(tw), - "mr.ash entry not found in TwasWeights" - ) -}) - -test_that("estimateSparsity: TwasWeights with mrash entry but no fit$pi errors", { - entry <- twasWeightsRow( - variantIds = c("chr1:100:A:G"), - weights = c(0.1), - methodFits = list(other = 1) - ) - tw <- TwasWeights( - studyName = "s1", - context = "c1", - trait = "t1", - method = "mrash", - entry = list(entry) - ) - expect_error( - estimateSparsity(tw), - "mr.ash fit object not found" - ) -}) - -test_that("estimateSparsity: legacy list input without mrash_weights errors", { - expect_error( - estimateSparsity(list(lasso = c(0.1, 0.2))), - "'mrash_weights'.*not found" - ) -}) - -test_that("estimateSparsity: legacy list input without fit attr errors", { - expect_error( - estimateSparsity(list(mrash_weights = c(0.1, 0.2))), - "mr.ash fit object not found" - ) -}) - - context("twasWeights internal helpers (extra)") # =========================================================================== @@ -2257,7 +1974,7 @@ context("twasWeights internal helpers (extra)") # =========================================================================== .tw_makeFmEntry <- function(method_tag = "susie", n = 3) { - fineMappingRow( + FineMappingRow( variantIds = sprintf("chr1:%d:A:G", 100L * seq_len(n)), susieFit = list(payload = method_tag), topLoci = data.frame( @@ -2350,14 +2067,6 @@ test_that(".twasFineMappingFits: ignores non-susie methods (e.g. lasso)", { expect_equal(names(out), "susie") }) -# =========================================================================== -# .twasWeightsPipelineMatrix: susieFit pre-fit pass-through -# =========================================================================== - -# =========================================================================== -# .twasWeightsPipelineMatrix: empirical pi path via mr.ash (mocked) -# =========================================================================== - # =========================================================================== # Multi-region / jointRegions (P3) # =========================================================================== @@ -2383,7 +2092,7 @@ test_that(".twasRegionLabel / .twasFitsForRegion select per-region fits", { test_that(".twasMergeRegionEntries stacks weights and builds a flat per-region CV df", { mk <- function(vids, w, rsq) { - twasWeightsRow( + TwasWeightsRow( variantIds = vids, weights = w, cvResult = list( @@ -2414,7 +2123,7 @@ test_that(".twasMergeRegionEntries stacks weights and builds a flat per-region C }) test_that(".twasMergeRegionEntries returns a single entry unchanged", { - e <- twasWeightsRow(variantIds = "chr1:100:A:G", weights = 0.5) + e <- TwasWeightsRow(variantIds = "chr1:100:A:G", weights = 0.5) expect_identical( pecotmr:::.twasMergeRegionEntries(list(e), "chr1:1-100"), e @@ -2423,7 +2132,7 @@ test_that(".twasMergeRegionEntries returns a single entry unchanged", { test_that(".twasMergeRegionEntries rbinds matrix weights across regions", { mk <- function(vids, w) { - twasWeightsRow(variantIds = vids, weights = w) + TwasWeightsRow(variantIds = vids, weights = w) } m1 <- matrix( c(0.1, 0.2, 0.3, 0.4), @@ -2472,6 +2181,20 @@ test_that(".twasNormalizeCharMethods: fine-mapping-only tokens skip lookup", { expect_equal(res$methodList[["fsusie_weights"]], list()) }) +test_that("twasWeightsPipeline(QtlDataset): region is a GRanges", { + # Given in R, a window is a GRanges; a string or a table is refused rather + # than read, so its base is never in doubt. + expect_error( + twasWeightsPipeline( + .tp_makeQtlDataset(traits = "ENSG_A"), + methods = list(lasso = list()), + region = "chr1:1-2000" + ), + "`region` must be a GRanges (got character)", + fixed = TRUE + ) +}) + test_that("twasWeightsPipeline(QtlDataset): region + cisWindow is rejected", { qd <- .tp_makeQtlDataset(traits = "ENSG_A") expect_error( @@ -2485,7 +2208,7 @@ test_that("twasWeightsPipeline(QtlDataset): region + cisWindow is rejected", { ) }) -test_that("twasWeightsPipeline(QtlDataset): jointRegions=FALSE concatenates per-region weights", { +test_that("twasWeightsPipeline: per-region and joint fits span both regions", { qd <- .tp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") exec( local_mocked_bindings, @@ -2499,9 +2222,63 @@ test_that("twasWeightsPipeline(QtlDataset): jointRegions=FALSE concatenates per- "chr1", IRanges::IRanges(c(50L, 1050L), c(1050L, 2050L)) ) - res <- suppressMessages(twasWeightsPipeline( + # jointRegions = FALSE concatenates per-region weights; TRUE fits one + # concatenated block. + for (jointRegions in c(FALSE, TRUE)) { + info <- str_c("jointRegions = ", jointRegions) + res <- suppressMessages(twasWeightsPipeline( + qd, + methods = list(lasso = list()), + traitId = "ENSG_A", + region = regions, + jointRegions = jointRegions, + estimatePi = FALSE, + verbose = 0, + crossValidationParam = CrossValidationParam(folds = 0), + ensembleParam = EnsembleParam() + )) + expect_true(is(res, "TwasWeights"), info = info) + # 1 ctx x 1 trait x 1 method -> a single row. + expect_equal(nrow(res), 1L, info = info) + w <- weights( + res, + studyName = "study1", + context = "brain", + trait = "ENSG_A", + method = "lasso" + ) + # union of both sub-ranges (v1..v10 + v11..v20). + expect_equal(length(w), 20L, info = info) + } +}) + +test_that("twasWeightsPipeline(QtlDataset): mr.mash jointRegions=FALSE concatenates per-region weights", { + # One trait over two contexts is the multivariate group mr.mash fits. + qd <- .tp_makeQtlDataset(contexts = c("brain", "liver"), traits = "ENSG_A") + exec( + local_mocked_bindings, + !!!c( + list( + extractBlockGenotypes = .tp_mockExtractor(), + mrmashWeights = function(X, Y, ...) { + matrix( + 0, + nrow = ncol(X), + ncol = ncol(Y), + dimnames = list(colnames(X), colnames(Y)) + ) + } + ), + list(.package = "pecotmr") + ) + ) + regions <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(c(50L, 1050L), c(1050L, 2050L)) + ) + res <- suppressMessages(suppressWarnings(twasWeightsPipeline( qd, - methods = list(lasso = list()), + methods = "mrmash", traitId = "ENSG_A", region = regions, jointRegions = FALSE, @@ -2509,97 +2286,10 @@ test_that("twasWeightsPipeline(QtlDataset): jointRegions=FALSE concatenates per- verbose = 0, crossValidationParam = CrossValidationParam(folds = 0), ensembleParam = EnsembleParam() - )) - expect_s4_class(res, "TwasWeights") - # 1 ctx x 1 trait x 1 method -> a single merged row. - expect_equal(nrow(res), 1L) - w <- weights( - res, - studyName = "study1", - context = "brain", - trait = "ENSG_A", - method = "lasso" - ) - # union of both sub-ranges (v1..v10 + v11..v20). - expect_equal(length(w), 20L) -}) - -test_that("twasWeightsPipeline(QtlDataset): jointRegions=TRUE fits one concatenated block", { - qd <- .tp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") - exec( - local_mocked_bindings, - !!!c( - list(extractBlockGenotypes = .tp_mockExtractor()), - .tp_mockIndividualWeights(), - list(.package = "pecotmr") - ) - ) - regions <- GenomicRanges::GRanges( - "chr1", - IRanges::IRanges(c(50L, 1050L), c(1050L, 2050L)) - ) - res <- suppressMessages(twasWeightsPipeline( - qd, - methods = list(lasso = list()), - traitId = "ENSG_A", - region = regions, - jointRegions = TRUE, - estimatePi = FALSE, - verbose = 0, - crossValidationParam = CrossValidationParam(folds = 0), - ensembleParam = EnsembleParam() - )) - expect_equal(nrow(res), 1L) - w <- weights( - res, - studyName = "study1", - context = "brain", - trait = "ENSG_A", - method = "lasso" - ) - expect_equal(length(w), 20L) -}) - -test_that("twasWeightsPipeline(QtlDataset): mr.mash jointRegions=FALSE concatenates per-region weights", { - qd <- .tp_makeQtlDataset( - contexts = c("brain", "liver"), - traits = c("ENSG_A", "ENSG_B") - ) - exec( - local_mocked_bindings, - !!!c( - list( - extractBlockGenotypes = .tp_mockExtractor(), - mrmashWeights = function(X, Y, ...) { - matrix( - 0, - nrow = ncol(X), - ncol = ncol(Y), - dimnames = list(colnames(X), colnames(Y)) - ) - } - ), - list(.package = "pecotmr") - ) - ) - regions <- GenomicRanges::GRanges( - "chr1", - IRanges::IRanges(c(50L, 1050L), c(1050L, 2050L)) - ) - res <- suppressMessages(suppressWarnings(twasWeightsPipeline( - qd, - methods = "mrmash", - traitId = c("ENSG_A", "ENSG_B"), - region = regions, - jointRegions = FALSE, - estimatePi = FALSE, - verbose = 0, - crossValidationParam = CrossValidationParam(folds = 0), - ensembleParam = EnsembleParam() ))) expect_s4_class(res, "TwasWeights") - # 2 contexts x 2 traits = 4 rows, each with weights concatenated over regions. - expect_equal(nrow(res), 4L) + # 2 contexts x 1 trait = 2 rows, each concatenated over the regions. + expect_equal(nrow(res), 2L) w <- weights( res, studyName = "study1", @@ -2612,9 +2302,9 @@ test_that("twasWeightsPipeline(QtlDataset): mr.mash jointRegions=FALSE concatena # =========================================================================== # fineMapping -> TWAS cross-validation handoff: .twasCvResultFor merges the -# per-method cvResult stashed on a fine-mapping tuple's entries, and -# .twasWeightsPipelineMatrix adopts that partition + predictions instead of -# refitting the handed-over methods. +# per-method cvResult stashed on a fine-mapping tuple's entries, so the TWAS +# run adopts that partition + predictions instead of refitting the +# handed-over methods. # =========================================================================== test_that(".twasCvResultFor merges per-method cvResult across a tuple's entries", { @@ -2637,13 +2327,13 @@ test_that(".twasCvResultFor merges per-method cvResult across a tuple's entries" ) ) } - eSusie <- fineMappingRow( + eSusie <- FineMappingRow( "chr1:100:A:G", list(), tl, cvResult = mkCv("susie") ) - eInf <- fineMappingRow( + eInf <- FineMappingRow( "chr1:100:A:G", list(), tl, @@ -2674,7 +2364,7 @@ test_that(".twasCvResultFor returns NULL when no entry carries CV", { pip = 0.5, stringsAsFactors = FALSE ) - e <- fineMappingRow("chr1:100:A:G", list(), tl) + e <- FineMappingRow("chr1:100:A:G", list(), tl) fmr <- QtlFineMappingResult( studyName = "S", context = "C", @@ -2745,7 +2435,7 @@ test_that(".unpackMashPrior routes a MashPrior into the internal CV arguments", context = context, trait = trait, method = method, - entry = list(twasWeightsRow(variantIds = vid, weights = w)) + entry = list(TwasWeightsRow(variantIds = vid, weights = w)) ) } @@ -2865,7 +2555,7 @@ test_that(".twasCvResultFor: a multi-region (per-region list) cvResult is unwrap performance = list(susie_performance = matrix(0, 1, 6)) ) ) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(), topLoci = data.frame(variant_id = "chr1:100:A:G", pip = 0.9), @@ -3264,8 +2954,19 @@ test_that("twasWeightsPipeline(QtlSumStats): named-list methods and invalid type ) }) -test_that("twasWeightsPipeline(QtlSumStats): traitId filter selects matching rows", { - ss <- .tp_makeQtlSumStats() +test_that("twasWeightsPipeline(QtlSumStats): trait selects matching rows", { + # Two traits in one context, so selecting the second must drop the + # first. A trait that matches no row is pinned by "empty contexts/trait + # filter errors" above. + ss <- QtlSumStats( + studyName = c("s1", "s1"), + context = c("c1", "c1"), + trait = c("t1", "t2"), + entry = list(.tp_makeSumstatsEntry(), .tp_makeSumstatsEntry()), + genome = "hg19", + ldReference = .tp_makeHandle(snp_n = 20L), + qcOptions = list(step1 = "ok") + ) exec( local_mocked_bindings, !!!c( @@ -3275,13 +2976,11 @@ test_that("twasWeightsPipeline(QtlSumStats): traitId filter selects matching row ) ) res <- suppressMessages(suppressWarnings( - twasWeightsPipeline(ss, methods = "lasso", traitId = "t1", verbose = 0) + twasWeightsPipeline(ss, methods = "lasso", traitId = "t2", verbose = 0) )) - expect_setequal(traitNames(res), "t1") - expect_error( - twasWeightsPipeline(ss, methods = "lasso", traitId = "absent"), - "no entries matched" - ) + expect_equal(as.character(res$trait), "t2") + expect_equal(as.character(res$context), "c1") + expect_equal(as.character(res$method), "lasso") }) test_that("twasWeightsPipeline(QtlSumStats): multivariate mr.mash returns a column per context", { @@ -3336,7 +3035,9 @@ test_that("twasWeightsPipeline(QtlSumStats): fine-mapping method absent from fin .tp_makeMultiStudy <- function() { qd <- .tp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") # study1 - ss <- .tp_makeQtlSumStats() # s1 + # s1, with a trait position: the collection lays its `cisWindow` there + # too, and 1000 bp around it keeps every variant. + ss <- .tp_makeQtlSumStats(traitPos = GenomicRanges::GRanges("chr1:400")) MultiStudyQtlDataset(qtlDatasets = list(study1 = qd), sumStats = ss) } @@ -3436,7 +3137,10 @@ test_that("MultiStudyQtlDataset takes every component argument", { expect_equal(setdiff(comp, ms), character(0)) expect_equal(setdiff(ms, comp), character(0)) expect_equal( - setdiff(ms, c(.cfgFieldNames(".twasMsCfg"), "jointSpecification")), + setdiff( + ms, + c(.cfgFieldNames(".twasMsCfg"), "jointSpecification") + ), character(0) ) }) @@ -3453,8 +3157,7 @@ test_that("twasWeightsPipeline(MultiStudyQtlDataset): a misspelled option errors ) }) -test_that("twasWeightsPipeline(MultiStudyQtlDataset): recurses into components and rbinds", { - mt <- .tp_makeMultiStudy() +test_that("twasWeightsPipeline(MSQD) rbinds both, lays cisWindow on sumstats", { exec( local_mocked_bindings, !!!c( @@ -3465,16 +3168,35 @@ test_that("twasWeightsPipeline(MultiStudyQtlDataset): recurses into components a ) ) res <- suppressMessages(suppressWarnings(twasWeightsPipeline( - mt, + .tp_makeMultiStudy(), methods = "lasso", - cisWindow = 1000L, + cisWindow = 100L, estimatePi = FALSE, verbose = 0, crossValidationParam = CrossValidationParam(folds = 0), ensembleParam = EnsembleParam() ))) + # It recurses into both components and rbinds what each phase fitted. expect_s4_class(res, "TwasWeights") - expect_setequal(as.character(res$study), c("study1", "s1")) # both phases + expect_setequal(as.character(res$study), c("study1", "s1")) + fromSumStats <- which(res$study == "s1") + expect_identical( + as.character(genomicRegion(res)[fromSumStats]), + "chr1:300-500" + ) + # A summary-statistics study without a trait position is an error, as it + # is on its own. + bare <- MultiStudyQtlDataset( + qtlDatasets = list( + study1 = .tp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + ), + sumStats = .tp_makeQtlSumStats() + ) + expect_error( + twasWeightsPipeline(bare, methods = "lasso", cisWindow = 100L), + "twasWeightsPipeline: `cisWindow` is laid around each tuple's trait", + fixed = TRUE + ) }) test_that("twasWeightsPipeline(MultiStudyQtlDataset): region + cisWindow is rejected", { @@ -3490,6 +3212,40 @@ test_that("twasWeightsPipeline(MultiStudyQtlDataset): region + cisWindow is reje ) }) +test_that("twasWeightsPipeline(MultiStudy): trait selection skips a study", { + # A trait vector applies to every component: one carrying none of the + # traits sits out, and the run is refused only when none carries any. + exec( + local_mocked_bindings, + !!!c( + list(extractBlockGenotypes = .tp_mockExtractor()), + .tp_mockIndividualWeights(), + .tp_mockSumstatWeights(), + list(.package = "pecotmr") + ) + ) + mt <- .tp_makeMultiStudy() + fit <- function(traitId) { + suppressMessages(twasWeightsPipeline( + mt, + methods = "lasso", + traitId = traitId, + cisWindow = 1000L, + estimatePi = FALSE, + verbose = 0, + crossValidationParam = CrossValidationParam(folds = 0), + ensembleParam = EnsembleParam() + )) + } + expect_setequal(as.character(fit("t1")$study), "s1") + expect_setequal(as.character(fit("ENSG_A")$study), "study1") + expect_error( + fit("absent"), + "twasWeightsPipeline(MultiStudyQtlDataset): no traits selected.", + fixed = TRUE + ) +}) + test_that("twasWeightsPipeline(MultiStudyQtlDataset): jointSpec-only mr.mash returns the joint result", { mt <- .tp_makeMultiStudy() jointRes <- .tp_tw( @@ -3502,15 +3258,19 @@ test_that("twasWeightsPipeline(MultiStudyQtlDataset): jointSpec-only mr.mash ret .twasDispatchJointSpecsMultiStudy = function(...) jointRes, .package = "pecotmr" ) - res <- suppressMessages(suppressWarnings(twasWeightsPipeline( - mt, - methods = "mrmash", - jointSpecification = "context", - cisWindow = 1000L, - verbose = 0 - ))) - expect_s4_class(res, "TwasWeights") - expect_setequal(as.character(res$method), "mrmash") + # `methods` naming mr.mash alone, in either accepted shape. + for (methods in list("mrmash", list(mrmash = list()))) { + info <- if (is.list(methods)) "list form" else "character form" + res <- suppressMessages(suppressWarnings(twasWeightsPipeline( + mt, + methods = methods, + jointSpecification = "context", + cisWindow = 1000L, + verbose = 0 + ))) + expect_true(is(res, "TwasWeights"), info = info) + expect_equal(unique(as.character(res$method)), "mrmash", info = info) + } }) test_that("twasWeightsPipeline(MultiStudyQtlDataset): jointSpec mr.mash + univariate lasso are combined", { @@ -3567,7 +3327,7 @@ test_that(".twasCvResultFor: an entry whose nested CV carries no partition is sk nested <- list( region1 = list(prediction = list(susie_predicted = matrix(0, 1, 1))) ) - entry <- fineMappingRow( + entry <- FineMappingRow( variantIds = "chr1:100:A:G", susieFit = list(), topLoci = data.frame(variant_id = "chr1:100:A:G", pip = 0.9), @@ -3580,7 +3340,7 @@ test_that(".twasCvResultFor: an entry whose nested CV carries no partition is sk method = "susie", entry = list(entry) ) - expect_null(pecotmr:::.twasCvResultFor(fmr, "S", "c1", "t1")) # 616 -> next + expect_null(pecotmr:::.twasCvResultFor(fmr, "S", "c1", "t1")) }) test_that("twasWeightsPipeline(QtlSumStats): jointSpec mr.mash-only with no fits errors", { @@ -3596,7 +3356,7 @@ test_that("twasWeightsPipeline(QtlSumStats): jointSpec mr.mash-only with no fits jointSpecification = "context" )), "no joint fits produced" - ) # 1059 + ) }) test_that("twasWeightsPipeline(QtlSumStats): jointSpec mr.mash + univariate lasso combine", { @@ -3624,15 +3384,13 @@ test_that("twasWeightsPipeline(QtlSumStats): jointSpec mr.mash + univariate lass jointSpecification = "context", verbose = 0 ))) - expect_true("mrmash" %in% as.character(res$method)) # 1062-1063 - expect_true("lasso" %in% as.character(res$method)) # 1300-1301 rbind + expect_true("mrmash" %in% as.character(res$method)) # from the joint result + expect_true("lasso" %in% as.character(res$method)) # from the per-tuple loop }) -test_that("twasWeightsPipeline( - QtlSumStats): a single-context (study, - trait -) group is skipped for mr.mash", { - # t1 has 2 contexts (processed); t2 has 1 context (skipped at the < 2 guard). +test_that("twasWeightsPipeline(QtlSumStats): mr.mash skips 1-context traits", { + # t1 has 2 contexts (processed); t2 has 1 context (skipped at the < 2 + # guard). entries <- map(1:3, function(.) .tp_makeSumstatsEntry()) ss <- QtlSumStats( studyName = rep("s1", 3), @@ -3641,7 +3399,7 @@ test_that("twasWeightsPipeline( entry = entries, genome = "hg19", ldReference = .tp_makeHandle(snp_n = 20L), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) local_mocked_bindings( extractBlockGenotypes = .tp_mockExtractor(), @@ -3655,14 +3413,14 @@ test_that("twasWeightsPipeline( res <- suppressMessages(suppressWarnings( twasWeightsPipeline(ss, methods = "mrmash", verbose = 0) )) - expect_setequal(traitNames(res), "t1") # only t1 (1189) + expect_setequal(traitNames(res), "t1") # only t1 }) test_that("twasWeightsPipeline(QtlSumStats): a mismatched SNP order in a multivariate group errors", { ss <- .tp_makeQtlSumStats(n_entries = 2L) # (s1, t1) x 2 ctx calls <- 0L local_mocked_bindings( - as.data.frame = function(x, studyName, context, trait, require, ...) { + .sumStatsDf = function(x, studyName, context, trait, require, ...) { calls <<- calls + 1L vid <- if (calls == 1L) { c("chr1:100:A:G", "chr1:200:A:G") @@ -3685,29 +3443,7 @@ test_that("twasWeightsPipeline(QtlSumStats): a mismatched SNP order in a multiva verbose = 0 )), "identical SNP order" - ) # 1212 -}) - -test_that("twasWeightsPipeline(MultiStudyQtlDataset): list-form methods, joint mr.mash only", { - mt <- .tp_makeMultiStudy() - jointRes <- .tp_tw( - studyName = "s1", - context = "c1", - trait = "t1", - method = "mrmash" ) - local_mocked_bindings( - .twasDispatchJointSpecsMultiStudy = function(...) jointRes, - .package = "pecotmr" - ) - res <- suppressMessages(suppressWarnings(twasWeightsPipeline( - mt, - methods = list(mrmash = list()), - jointSpecification = "context", - cisWindow = 1000L, - verbose = 0 - ))) - expect_setequal(as.character(res$method), "mrmash") # 1360-1377 }) test_that("ensembleWeights: partial sample overlap emits a message", { @@ -3720,7 +3456,7 @@ test_that("ensembleWeights: partial sample overlap emits a message", { expect_message( ensembleWeights(cvResults = list(prediction = pb), Y = y), "common samples" - ) # 1824 + ) }) test_that("ensembleWeights: contextIndex beyond Y matrix columns errors (named path)", { @@ -3737,7 +3473,7 @@ test_that("ensembleWeights: contextIndex beyond Y matrix columns errors (named p contextIndex = 2 ), "exceeds number of columns" - ) # 1830 + ) }) test_that("ensembleWeights: vector (non-matrix) method weights are coerced to a column", { @@ -3768,7 +3504,7 @@ test_that("ensembleWeights: vector (non-matrix) method weights are coerced to a Y = y, twasWeightList = wl ) - expect_length(res$ensembleTwasWeights, 3L) # 1937 / 1947 + expect_length(res$ensembleTwasWeights, 3L) }) test_that(".solveEnsembleNnls: solver failure and all-zero fall back to equal weights", { @@ -3944,31 +3680,55 @@ test_that(".ensembleAccumulateWeights skips a dim-mismatched member", { )))) } -test_that("twasWeightsPipeline(QtlSumStats) filters nothing by default", { - ss <- .twrssf_qcd() - expect_equal(.twrssf_n(ss), sum(lengths(ss))) -}) +# QC'd once: summaryStatsQc() is the costliest step here, and every test +# below only reads its result. +.twrssfQcd <- .twrssf_qcd() -test_that("twasWeightsPipeline(QtlSumStats) drops panel-rare variants", { - ss <- .twrssf_qcd() +test_that("twasWeightsPipeline RSS: no cutoff keeps all, cutoffs match panel", { + ss <- .twrssfQcd full <- .twrssf_n(ss) - loose <- .twrssf_n(ss, mafCutoff = 0.05) - tight <- .twrssf_n(ss, mafCutoff = 0.2) - expect_lt(loose, full) - expect_lt(tight, loose) + # Nothing is filtered by default. + expect_equal(full, sum(lengths(ss))) + ids <- .sumStatsDf( + ss, + studyName = ss$study[[1L]], + context = ss$context[[1L]], + trait = ss$trait[[1L]], + require = c("Z", "N"), + derive = "zFromBetaSe" + )$variant_id + cuts <- c(0.05, 0.2) + kept <- map_int(cuts, function(cut) .twrssf_n(ss, mafCutoff = cut)) + # Each MAF cutoff drops panel-rare variants, the stricter one more ... + expect_lt(kept[[1L]], full) + expect_lt(kept[[2L]], kept[[1L]]) + # ... and exactly the variants the shared filter names: no more (something + # else is filtering) and no fewer (the cutoff silently did nothing). + for (i in seq_along(cuts)) { + expect_equal( + kept[[i]], + length(.panelVariantFilter( + ldReference(ss)[[1L]], + ids, + PanelFilterParam(mafCutoff = cuts[[i]]) + )), + label = str_c("mafCutoff ", cuts[[i]]) + ) + } }) test_that("twasWeightsPipeline(QtlSumStats) fits PRS-CS and SDPR", { # Unmocked: both read the entry's z. They used to read a `b` this path - # never supplies, so every entry failed with a warning. - ss <- .twrssf_qcd() + # never supplies, so every entry failed with a warning. A short chain is + # enough to show each method produces its row. + ss <- .twrssfQcd res <- suppressMessages(twasWeightsPipeline( ss, methods = list( - prsCs = PrsCsOptions(nIter = 40, nBurnin = 10, thin = 1, seed = 1), + prsCs = PrsCsOptions(nIter = 20, nBurnin = 5, thin = 1, seed = 1), dprGibbs = SdprOptions( - iter = 40, - burn = 10, + iter = 20, + burn = 5, thin = 1, verbose = FALSE ) @@ -3978,33 +3738,8 @@ test_that("twasWeightsPipeline(QtlSumStats) fits PRS-CS and SDPR", { expect_setequal(methodNames(res), c("prsCs", "dprGibbs")) }) -test_that("twasWeightsPipeline RSS cutoffs match .panelVariantFilter", { - # Exactly the variants the shared filter names: no more (something else is - # filtering) and no fewer (the cutoff silently did nothing). - ss <- .twrssf_qcd() - ids <- as.data.frame( - ss, - studyName = ss$study[[1L]], - context = ss$context[[1L]], - trait = ss$trait[[1L]], - require = c("Z", "N"), - derive = "zFromBetaSe" - )$variant_id - for (cut in c(0.05, 0.2)) { - expect_equal( - .twrssf_n(ss, mafCutoff = cut), - length(.panelVariantFilter( - ldReference(ss)[[1L]], - ids, - PanelFilterParam(mafCutoff = cut) - )), - label = str_c("mafCutoff ", cut) - ) - } -}) - test_that("twasWeightsPipeline RSS treats MAC as a MAF equivalent", { - ss <- .twrssf_qcd() + ss <- .twrssfQcd nSamp <- ncol(ldReference(ss)[[1L]]) expect_equal( .twrssf_n(ss, macCutoff = 0.1 * 2 * nSamp), @@ -4013,13 +3748,13 @@ test_that("twasWeightsPipeline RSS treats MAC as a MAF equivalent", { }) test_that("twasWeightsPipeline RSS honours a missingness cutoff", { - ss <- .twrssf_qcd() + ss <- .twrssfQcd expect_lt(.twrssf_n(ss, imissCutoff = 0), sum(lengths(ss))) expect_equal(.twrssf_n(ss, imissCutoff = 1), sum(lengths(ss))) }) test_that(".twasQssUnivariateFitCtx keeps z, ids and LD reference aligned", { - ss <- .twrssf_qcd() + ss <- .twrssfQcd sketch <- ldReference(ss)[[1L]] args <- list(ss, ss$study[[1L]], ss$context[[1L]], ss$trait[[1L]], sketch) plain <- exec(pecotmr:::.twasQssUnivariateFitCtx, !!!args) @@ -4281,7 +4016,7 @@ test_that(".fmrAnyCvResult reports whether any row carries cross-validation", { pip = 0.5, stringsAsFactors = FALSE ) - bare <- fineMappingRow("chr1:100:A:G", list(), tl) + bare <- FineMappingRow("chr1:100:A:G", list(), tl) noCv <- QtlFineMappingResult( studyName = "S", context = "C", @@ -4295,7 +4030,7 @@ test_that(".fmrAnyCvResult reports whether any row carries cross-validation", { context = "C", trait = "T", method = "susie", - entry = list(fineMappingRow( + entry = list(FineMappingRow( "chr1:100:A:G", list(), tl, @@ -4376,29 +4111,6 @@ test_that("an entry must come from that method's constructor for that path", { ) }) -test_that("only an engine that takes `...` goes unchecked", { - # An engine is unchecked for exactly one reason: its own signature ends - # in `...`, so every name is legal and there is nothing to reject. - # cv.glmnet, cv.ncvreg and RcppDPR::fit_model do; the rest enumerate. - skip_if_not_installed("glmnet") - skip_if_not_installed("ncvreg") - expect_output(show(GlmnetOptions()), "NOT checked") - expect_output(show(NcvregOptions()), "NOT checked") - # L0Learn enumerates, and so do all four pecotmr RSS solvers -- each has - # its own constructor rather than riding on the individual-level one. - skip_if_not_installed("L0Learn") - expect_output(show(L0learnOptions()), "checked") - expect_failure(expect_output(show(L0learnOptions()), "NOT checked")) - for (ctor in list( - PenalizedRssOptions, - LassosumOptions, - SdprOptions, - PrsCsOptions - )) { - expect_failure(expect_output(show(ctor()), "NOT checked")) - } -}) - test_that("each path takes that path's own constructor", { # lasso fits with glmnet on individual data and with pecotmr's lassosum # solver on summary statistics. The aggregator accepted either for @@ -4427,10 +4139,10 @@ test_that("each path takes that path's own constructor", { ), "options are for QtlSumStats" ) - # enet has no summary-statistics path at all. + # dprVb has no summary-statistics path at all. expect_error( - TwasWeightsMethodsParam(qtlSumStatsMethods = list(enet = list())), - "enet is not a method this pipeline runs on QtlSumStats" + TwasWeightsMethodsParam(qtlSumStatsMethods = list(dprVb = list())), + "dprVb is not a method this pipeline runs on QtlSumStats" ) }) @@ -4579,21 +4291,18 @@ test_that("twasWeightsPipeline(QtlDataset): usePCA adds top-PC rows", { list(.package = "pecotmr") ) ) - run <- function(usePCA) { - suppressMessages(suppressWarnings(twasWeightsPipeline( - qd, - methods = "lasso", - cisWindow = 1000L, - verbose = 0, - usePCA = usePCA, - nPCs = 2L, - crossValidationParam = CrossValidationParam(folds = 0), - ensembleParam = EnsembleParam() - ))) - } - plain <- run(FALSE) - withPc <- run(TRUE) - expect_false(any(str_detect(as.character(traitNames(plain)), "^topPC"))) + withPc <- suppressMessages(suppressWarnings(twasWeightsPipeline( + qd, + methods = "lasso", + cisWindow = 1000L, + verbose = 0, + usePCA = TRUE, + nPCs = 2L, + crossValidationParam = CrossValidationParam(folds = 0), + ensembleParam = EnsembleParam() + ))) + # Without usePCA there are no PC rows: the end-to-end test at the top of + # this file pins a default run's traitNames to the two genes. pcs <- unique(as.character(traitNames(withPc))) expect_true(any(str_detect(pcs, "^topPC"))) # the per-trait rows are still there -- PC rows are additional @@ -4752,41 +4461,17 @@ test_that(".ensembleAssertCv reports the fold count it actually saw", { }) # --------------------------------------------------------------------------- -# The weight SCALE declaration +# The weight SCALE record # # `weight_standardized` is published alongside every weight, and it cannot be # recovered from the numbers: the standardized-to-raw conversion is a # per-variant factor 1/sqrt(2*af*(1-af)), so the two scales differ by an # allele-frequency-dependent amount at every variant and neither is -# recognisable on its own. The pipeline hardcoded FALSE, so an -# individual-level run on genotypes the caller HAD standardized published the -# opposite of the truth with no way to say so. fineMappingPipeline() takes the -# same argument for the same reason -- a posterior effect IS a weight. +# recognisable on its own. The pipelines therefore record it rather than take +# it as an argument: from the residualization settings on individual-level +# data, and always standardized on summary statistics. # --------------------------------------------------------------------------- -test_that("twasWeightsPipeline(QtlDataset) records the standardized scale", { - qd <- .tp_makeQtlDataset() - exec( - local_mocked_bindings, - !!!c( - list(extractBlockGenotypes = .tp_mockExtractor()), - .tp_mockIndividualWeights(), - list(.package = "pecotmr") - ) - ) - res <- suppressMessages(suppressWarnings(twasWeightsPipeline( - qd, - methods = "lasso", - cisWindow = 1000L, - estimatePi = FALSE, - verbose = 0, - crossValidationParam = CrossValidationParam(folds = 0) - ))) - # Derived, not declared: genotypes are standardized on the way to every - # fitter, so there is nothing for a caller to say. - expect_true(all(as.logical(S4Vectors::mcols(res)$standardized))) -}) - test_that("a summary-statistics run records the standardized scale itself", { # The RSS likelihood is written in standardized units, so the scale is not # the caller's to declare there -- the method has no such argument, and @@ -4810,8 +4495,8 @@ test_that("a summary-statistics run records the standardized scale itself", { expect_true(all(as.logical(S4Vectors::mcols(res)$standardized))) }) -test_that("the TWAS genotype scale also comes from the accessor", { - qd <- .tp_makeQtlDataset() +test_that("twasWeightsPipeline(QtlDataset) records the accessor's scale", { + qd <- .tp_makeQtlDataset(traits = "ENSG_A") exec( local_mocked_bindings, !!!c( @@ -4832,7 +4517,10 @@ test_that("the TWAS genotype scale also comes from the accessor", { ))) unique(as.logical(S4Vectors::mcols(res)$standardized)) } + # Derived, not declared: by default genotypes are standardized on the way + # to every fitter, so there is nothing for a caller to say ... expect_true(recorded()) + # ... and turning the scaling off is recorded too. expect_false(recorded(scaleResiduals = FALSE)) }) @@ -4925,7 +4613,7 @@ test_that("MultiStudyQtlDataset: joint fits get every caller setting", { expect_equal(ind$config$fitRetention, "full") expect_equal(ind$config$dataType, "rnaseq") expect_equal(ind$args$methodList$mrmash_weights$max_iter, 5) - expect_equal(mafCutoff(ind$data), 0.05) + expect_equal(ind$args$genotypeFilter$mafCutoff, 0.05) ss <- .capturedCall(cap, "sumstats") expect_equal(ss$config$fitRetention, "full") expect_equal(ss$config$dataType, "rnaseq") @@ -4987,10 +4675,244 @@ test_that("a multivariate TWAS group refuses contexts on two LD references", { entry = list(gr, gr), genome = "hg19", ldReference = list(ldm(0.1), ldm(0.95)), - qcInfo = list(step1 = "ok") + qcOptions = list(step1 = "ok") ) expect_error( suppressMessages(twasWeightsPipeline(ss, methods = "mrmash")), "a joint fit uses one LD matrix" ) }) + +test_that("twasWeightsPipeline(QtlSumStats) lays a cisWindow around traitPos", { + exec( + local_mocked_bindings, + !!!c( + list(extractBlockGenotypes = .tp_mockExtractor()), + .tp_mockSumstatWeights(), + list(.package = "pecotmr") + ) + ) + # The entry's variants sit every 100 bp from chr1:100 to chr1:800 and the + # trait at chr1:400, so the fit keeps the variants within `cisWindow` of + # it; with no window it keeps them all. + ss <- .tp_makeQtlSumStats(traitPos = GenomicRanges::GRanges("chr1:400")) + keptIds <- function(cisWindow) { + res <- suppressMessages(twasWeightsPipeline( + ss, + methods = "lasso", + cisWindow = cisWindow, + verbose = 0 + )) + variantIds( + res, + studyName = "s1", + context = "c1", + trait = "t1", + method = "lasso" + ) + } + expect_equal(keptIds(150), sprintf("chr1:%d:A:G", c(300L, 400L, 500L))) + expect_equal(keptIds(0), "chr1:400:A:G") + expect_equal(keptIds(NULL), sprintf("chr1:%d:A:G", 100L * (1:8))) + # A tuple without a trait position has no window to lay. + expect_error( + twasWeightsPipeline(.tp_makeQtlSumStats(), cisWindow = 1000), + "twasWeightsPipeline: `cisWindow` is laid around each tuple's trait", + fixed = TRUE + ) + # The selection is parsed before the window is laid, so naming a context + # reaches the same check rather than failing on the unparsed selection. + expect_error( + twasWeightsPipeline( + .tp_makeQtlSumStats(), + contexts = "c1", + cisWindow = 1000 + ), + "twasWeightsPipeline: `cisWindow` is laid around each tuple's trait", + fixed = TRUE + ) +}) + +test_that("twasWeightsPipeline(QtlSumStats) records traitPos and its window", { + exec( + local_mocked_bindings, + !!!c( + list(extractBlockGenotypes = .tp_mockExtractor()), + .tp_mockSumstatWeights(), + list(.package = "pecotmr") + ) + ) + # A per-tuple fit's row carries its input's trait position and the window + # the cisWindow laid around it, as a joint fit's row does. + ss <- .tp_makeQtlSumStats(traitPos = GenomicRanges::GRanges("chr1:400")) + res <- suppressMessages(twasWeightsPipeline( + ss, + methods = "lasso", + cisWindow = 150, + verbose = 0 + )) + tp <- traitPosition(res) + rg <- genomicRegion(res) + expect_equal( + as.character(GenomicRanges::seqnames(c(tp, rg))), + c("chr1", "chr1") + ) + expect_equal(GenomicRanges::start(tp), 400L) + expect_equal( + c(GenomicRanges::start(rg), GenomicRanges::end(rg)), + c(250L, 550L) + ) +}) + +test_that("twasWeightsPipeline refuses a phenotype QC its fits cannot take", { + keep <- PhenotypeFilterParam(naAction = "keep") + expect_error( + twasWeightsPipeline( + .tp_makeQtlDataset(), + methods = "lasso", + phenotypeFilterParam = keep + ), + "twasWeightsPipeline: naAction = \"keep\" is not available" + ) + expect_error( + twasWeightsPipeline( + .tp_makeMultiStudy(), + methods = "lasso", + phenotypeFilterParam = keep + ), + "naAction = \"keep\" is not available" + ) +}) + +# =========================================================================== +# Narrowed fine-mapping rows: their fits are reused whole, which warns once +# =========================================================================== + +# The stub fine-mapping result with its rows narrowed to two of their three +# variants. +.tp_narrowedFineMapping <- function(...) { + endoapply(.tp_makeStubFineMappingResult(...), utils::head, 2L) +} + +test_that("each twasWeightsPipeline method warns about narrowed fits", { + qd <- .tp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + fromDataset <- .fitCoverageCondition(twasWeightsPipeline( + qd, + methods = "lasso", + fineMappingResult = .tp_narrowedFineMapping() + )) + expect_s3_class(fromDataset, "pecotmrFitCoverage") + expect_match( + conditionMessage(fromDataset), + "twasWeightsPipeline\\(\\): 1 row" + ) + fromSumStats <- .fitCoverageCondition(twasWeightsPipeline( + .tp_makeQtlSumStats(), + methods = "lasso", + fineMappingResult = .tp_narrowedFineMapping( + studyName = "s1", + contexts = "c1", + traits = "t1" + ) + )) + expect_s3_class(fromSumStats, "pecotmrFitCoverage") + fromStudies <- .fitCoverageCondition(twasWeightsPipeline( + .tp_makeMultiStudy(), + methods = "lasso", + fineMappingResult = .tp_narrowedFineMapping() + )) + expect_s3_class(fromStudies, "pecotmrFitCoverage") +}) + +# A stand-in for one study's run that warns about the rows the collection's +# run has already named. +.tp_warnAndReturn <- function(...) { + warn("twasWeightsPipeline(): narrowed", class = "pecotmrFitCoverage") + "ran" +} + +test_that("each study's run is muffled once the collection has warned", { + local_mocked_bindings( + twasWeightsPipeline = .tp_warnAndReturn, + .package = "pecotmr" + ) + qd <- .tp_makeQtlDataset(contexts = "brain", traits = "ENSG_A") + expect_no_warning(out <- pecotmr:::.twasPerStudy(qd, list())) + expect_equal(out, "ran") + expect_no_warning( + out <- pecotmr:::.twasSumStats(.tp_makeQtlSumStats(), list()) + ) + expect_equal(out, "ran") +}) + +# =========================================================================== +# enet and ridge: glmnet on individual data, the penalized RSS solver on +# summary statistics, with the enet mixing settable on both +# =========================================================================== + +test_that("enet and ridge are registered for both input kinds", { + implFor <- pecotmr:::.twasMethodImplFor + expect_equal(implFor("enet", "QtlDataset"), "enetWeights") + expect_equal(implFor("enet", "QtlSumStats"), "enetRssWeights") + expect_equal(implFor("ridge", "QtlDataset"), "ridgeWeights") + expect_equal(implFor("ridge", "QtlSumStats"), "ridgeRssWeights") + expect_true(is_in( + "alpha", + pecotmr:::.twasChainAccepted("enet", "QtlSumStats") + )) + expect_equal( + pecotmr:::.twasTokensFromMethodList(list(ridge_weights = list())), + "ridge" + ) + expect_true(all(is_in( + c("enet", "ridge"), + pecotmr:::.twasFullDetailTokens("QtlSumStats") + ))) +}) + +test_that("the enet mixing reaches the individual-level wrapper", { + seen <- NULL + mocks <- list( + extractBlockGenotypes = .tp_mockExtractor(), + enetWeights = function( + X, + y, + alpha = 0.5, + methodArgs = GlmnetOptions() + ) { + seen <<- alpha + rep(0, ncol(X)) + } + ) + exec(local_mocked_bindings, !!!c(mocks, list(.package = "pecotmr"))) + res <- suppressMessages(twasWeightsPipeline( + .tp_makeQtlDataset(contexts = "brain", traits = "ENSG_A"), + methods = list(enet = list(alpha = 0.3)), + cisWindow = 1000L, + estimatePi = FALSE, + verbose = 0, + crossValidationParam = CrossValidationParam(folds = 0), + ensembleParam = EnsembleParam() + )) + expect_equal(seen, 0.3) + expect_setequal(methodNames(res), "enet") +}) + +test_that("enet and ridge run on summary statistics, alpha set per method", { + local_mocked_bindings( + extractBlockGenotypes = .tp_mockExtractor(), + .package = "pecotmr" + ) + res <- suppressMessages(suppressWarnings(twasWeightsPipeline( + .tp_makeQtlSumStats(), + methods = list(lasso = list(), enet = list(alpha = 1), ridge = list()), + verbose = 0 + ))) + expect_setequal(methodNames(res), c("lasso", "enet", "ridge")) + # At alpha = 1 the elastic net is the lasso, so the two rows agree. + rowOf <- function(m) { + weights(res, studyName = "s1", context = "c1", trait = "t1", method = m) + } + expect_equal(as.numeric(rowOf("enet")), as.numeric(rowOf("lasso"))) + expect_true(all(rowOf("ridge") != 0)) +}) diff --git a/tests/testthat/test_twasWeightsRow.R b/tests/testthat/test_twasWeightsRow.R index a02b2b54..8c6e5741 100644 --- a/tests/testthat/test_twasWeightsRow.R +++ b/tests/testthat/test_twasWeightsRow.R @@ -1,9 +1,19 @@ -# Tests for R/TwasWeightsRow.R +# Tests for R/twasWeightsRow.R # === Tests migrated from test_s4Constructors.R (TwasWeightsRow) === +test_that("as(row, 'GRanges') carries the weights", { + row <- TwasWeightsRow( + variantIds = c("chr1:100:A:G", "chr1:200:C:T"), + weights = c(0.4, -0.2) + ) + gr <- as(row, "GRanges") + expect_s4_class(gr, "GRanges") + expect_identical(gr$weight, c(0.4, -0.2)) +}) + test_that("TwasWeightsRow: constructor and accessors round-trip", { - e <- twasWeightsRow( + e <- TwasWeightsRow( variantIds = c("chr1:100:A:G", "chr1:200:A:G", "chr1:300:A:G"), weights = c(0.1, -0.2, 0.05), methodFits = list(model = "lasso"), @@ -24,7 +34,7 @@ test_that("TwasWeightsRow: constructor and accessors round-trip", { }) test_that("TwasWeightsRow: resolveWeights returns the aligned (variantIds, weights) pair", { - e <- twasWeightsRow( + e <- TwasWeightsRow( variantIds = c("chr1:100:A:G", "chr1:200:A:G", "chr1:300:A:G"), weights = c(0.1, -0.2, 0.05) ) @@ -35,7 +45,7 @@ test_that("TwasWeightsRow: resolveWeights returns the aligned (variantIds, weigh ) expect_equal(wr$weights, c(0.1, -0.2, 0.05)) # length mismatch (defensive) -> empty - e2 <- twasWeightsRow( + e2 <- TwasWeightsRow( variantIds = c("chr1:100:A:G", "chr1:200:A:G"), weights = c(0.1, -0.2) ) @@ -47,14 +57,14 @@ test_that("TwasWeightsRow: resolveWeights returns the aligned (variantIds, weigh test_that("TwasWeightsRow: standardized is coerced via isTRUE() semantics", { # isTRUE() only returns TRUE for a length-1 logical TRUE. Non-TRUE # input lands as FALSE (the safe default for the standardized flag). - e_logical <- twasWeightsRow( + e_logical <- TwasWeightsRow( variantIds = "chr1:100:A:G", weights = 0.1, weightStandardized = TRUE ) expect_true(isTRUE(weightStandardized(e_logical))) - e_default <- twasWeightsRow( + e_default <- TwasWeightsRow( variantIds = "chr1:100:A:G", weights = 0.1, weightStandardized = "yes-please" @@ -65,7 +75,7 @@ test_that("TwasWeightsRow: standardized is coerced via isTRUE() semantics", { test_that("TwasWeightsRow: validity rejects matrix weights with wrong nrow", { expect_error( - twasWeightsRow( + TwasWeightsRow( variantIds = c("chr1:100:A:G", "chr1:200:A:G"), weights = matrix(0, nrow = 5, ncol = 1) ), @@ -73,40 +83,22 @@ test_that("TwasWeightsRow: validity rejects matrix weights with wrong nrow", { ) }) -# =========================================================================== -# QtlFineMappingResult -# =========================================================================== - -test_that("TwasWeights: rejects non-TwasWeightsRow rows", { +test_that("TwasWeightsRow: rejects mismatched variantIds/weights lengths", { + # The weights are per-variant mcols on the entry's element now, so a + # length mismatch cannot be represented. It is refused at construction + # rather than producing a gene that gets silently dropped downstream. expect_error( - TwasWeights( - studyName = "s1", - context = "c1", - trait = "t1", - method = "lasso", - entry = list("not_an_entry") + TwasWeightsRow( + variantIds = sprintf("chr1:%d:G:A", 100L * 1:5), + weights = c(0.1, 0.2, 0.3) ), - "must be a TWAS-weight row" + "length\\(weights\\) is 3 but 5 variants were supplied" ) }) - -test_that("TwasWeights: validity does not recurse on key subset (#546)", { - # Building the tuple-uniqueness key via `object[, keyCols]` preserves the - # TwasWeights class while dropping the required `entry` column; older - # S4Vectors revalidates that intermediate and fails with "missing columns". - e <- .sc_makeTwasWeightsRow(p = 5L) - res <- TwasWeights( - studyName = "s1", - context = "c1", - trait = "t1", - method = "lasso", - entry = list(e) - ) - expect_s4_class(res, "TwasWeights") - expect_true(validObject(res)) -}) - +# =========================================================================== +# TwasWeights +# =========================================================================== # === Tests migrated from test_showMethods.R (TwasWeightsRow) === @@ -119,7 +111,7 @@ test_that("show.TwasWeightsRow reports standardized flag and CV availability", { ))) expect_true(any(grepl("CV performance: TRUE", out))) - e_no_cv <- twasWeightsRow( + e_no_cv <- TwasWeightsRow( variantIds = c("chr1:100:A:G", "chr1:200:A:G"), weights = c(0.1, 0.2) ) @@ -134,12 +126,12 @@ test_that("show.TwasWeightsRow reports standardized flag and CV availability", { # that rejects ids carrying no coordinates was never executed. # =========================================================================== -test_that("variantIds that encode no coordinates are rejected", { +test_that("variantIds that encode no coordinates are rejected by name", { # An id is a rendering of the variant's range and alleles; "v1" names # nothing, and the failure should bite here rather than later when the # entry is turned into a ranged element. - expect_error( - twasWeightsRow( + err <- tryCatch( + TwasWeightsRow( variantIds = c("chr1:100:A:G", "v1", "v2"), weights = c(0.1, -0.2, 0.05), methodFits = list(model = "lasso"), @@ -147,30 +139,18 @@ test_that("variantIds that encode no coordinates are rejected", { weightStandardized = TRUE, weightsDataType = "expression" ), - "do not encode coordinates" - ) -}) - -test_that("the identity message names the offenders", { - err <- tryCatch( - twasWeightsRow( - variantIds = c("rsX", "rsY"), - weights = c(0.1, -0.2), - methodFits = list(), - cvResult = list(), - weightStandardized = TRUE, - weightsDataType = "expression" - ), error = function(e) conditionMessage(e) ) - expect_match(err, "2 of 2") - expect_match(err, "rsX, rsY") + expect_match(err, "do not encode coordinates") + # The message counts and names the offenders. + expect_match(err, "2 of 3") + expect_match(err, "v1, v2") }) test_that("an empty variant set is allowed", { # Emptiness is a separate concern from malformedness: there is nothing to # parse, so the coordinate rule has nothing to say. - e <- twasWeightsRow( + e <- TwasWeightsRow( variantIds = character(0), weights = numeric(0), methodFits = list(), diff --git a/tests/testthat/test_variantId.R b/tests/testthat/test_variantId.R index 1f90fc78..1d4fc9e6 100644 --- a/tests/testthat/test_variantId.R +++ b/tests/testthat/test_variantId.R @@ -7,22 +7,25 @@ context("variantId") test_that("parseVariantId: canonical colon format with chr prefix", { res <- parseVariantId(c("chr1:100:A:G", "chr2:200:T:C")) expect_s3_class(res, "data.frame") - expect_equal(res$chrom, c("1", "2")) + expect_equal(res$chrom, c("chr1", "chr2")) expect_equal(res$pos, c(100L, 200L)) expect_equal(res$A2, c("A", "T")) expect_equal(res$A1, c("G", "C")) + expect_equal(attr(res, "convention")$alleleSep, ":") }) test_that("parseVariantId: canonical colon format without chr prefix", { res <- parseVariantId(c("1:100:A:G", "2:200:T:C")) - expect_equal(res$chrom, c("1", "2")) + expect_equal(res$chrom, c("chr1", "chr2")) expect_equal(res$pos, c(100L, 200L)) + expect_equal(res$A2, c("A", "T")) + expect_equal(res$A1, c("G", "C")) expect_equal(attr(res, "convention")$hasChr, FALSE) }) test_that("parseVariantId: underscore separator format", { res <- parseVariantId(c("chr1_100_A_G", "1_200_T_C")) - expect_equal(res$chrom, c("1", "1")) + expect_equal(res$chrom, c("chr1", "chr1")) expect_equal(res$pos, c(100L, 200L)) expect_equal(res$A2, c("A", "T")) expect_equal(res$A1, c("G", "C")) @@ -30,7 +33,7 @@ test_that("parseVariantId: underscore separator format", { test_that("parseVariantId: mixed colon-underscore format", { res <- parseVariantId("chr1:100_A_G") - expect_equal(res$chrom, "1") + expect_equal(res$chrom, "chr1") expect_equal(res$pos, 100L) expect_equal(res$A2, "A") expect_equal(res$A1, "G") @@ -39,7 +42,10 @@ test_that("parseVariantId: mixed colon-underscore format", { test_that("parseVariantId: strips build suffix", { res <- parseVariantId(c("chr1:100:A:G:b38", "chr1:200:T:C_b37")) + # The suffix is dropped, not carried as a fifth column. + expect_equal(colnames(res), c("chrom", "pos", "A2", "A1")) expect_equal(res$pos, c(100L, 200L)) + expect_equal(res$A2, c("A", "T")) expect_equal(res$A1, c("G", "C")) expect_equal(attr(res, "convention")$hasBuild, TRUE) }) @@ -51,17 +57,18 @@ test_that("parseVariantId: convention attribute records hasChr", { expect_equal(attr(no_chr, "convention")$hasChr, FALSE) }) -test_that("parseVariantId: data.frame input with chrom/pos/A2/A1 returns as-is", { +test_that("parseVariantId: a chrom/pos/A2/A1 frame is read in UCSC style", { df <- data.frame( - chrom = "chr1", - pos = 100L, - A2 = "A", - A1 = "G", + chrom = c("chr1", "2"), + pos = c(100, 200), + A2 = c("A", "C"), + A1 = c("G", "T"), stringsAsFactors = FALSE ) res <- parseVariantId(df) - expect_equal(res$chrom, "1") - expect_equal(res$pos, 100L) + # A bare chromosome gains the prefix; a double position becomes integer. + expect_equal(res$chrom, c("chr1", "chr2")) + expect_equal(res$pos, c(100L, 200L)) expect_equal(attr(res, "convention")$hasChr, TRUE) }) @@ -75,46 +82,14 @@ test_that("parseVariantId: data.frame input with >=4 columns assigns positional stringsAsFactors = FALSE ) res <- parseVariantId(df) - expect_equal(res$chrom, "1") + # The first four columns are renamed; the rest pass through. + expect_equal(names(res), c("chrom", "pos", "A2", "A1", "extra")) + expect_equal(res$chrom, "chr1") expect_equal(res$pos, 100L) expect_equal(res$A2, "A") expect_equal(res$A1, "G") }) -# =========================================================================== -# normalizeVariantId -# =========================================================================== - -test_that("normalizeVariantId: canonical output adds chr prefix by default", { - res <- normalizeVariantId(c("1:100:A:G", "2:200:T:C")) - expect_equal(res, c("chr1:100:A:G", "chr2:200:T:C")) -}) - -test_that("normalizeVariantId: chrPrefix = FALSE strips the chr prefix", { - res <- normalizeVariantId( - c("chr1:100:A:G", "chr2:200:T:C"), - chrPrefix = FALSE - ) - expect_equal(res, c("1:100:A:G", "2:200:T:C")) -}) - -test_that("normalizeVariantId: convention argument preserves the input format", { - ids <- c("chr1:100_A_G", "chr2:200_T_C") - conv <- attr(parseVariantId(ids), "convention") - res <- normalizeVariantId(c("1:100:A:G", "2:200:T:C"), convention = conv) - expect_equal(res, c("chr1:100_A_G", "chr2:200_T_C")) -}) - -test_that("normalizeVariantId: round-trips underscore-only input", { - res <- normalizeVariantId("1_100_A_G") - expect_equal(res, "chr1:100:A:G") -}) - -test_that("normalizeVariantId: strips build suffix and re-emits canonical", { - res <- normalizeVariantId("chr1:100:A:G:b38") - expect_equal(res, "chr1:100:A:G") -}) - # =========================================================================== # .repairVariantIds # =========================================================================== @@ -182,120 +157,28 @@ test_that(".repairVariantIds: non-DNA alleles on both sides are still kept", { expect_equal(out, ids) }) -# =========================================================================== -# parseRegion -# =========================================================================== - -test_that("parseRegion: canonical chr:start-end string", { - res <- parseRegion("chr1:100-200") - expect_s3_class(res, "data.frame") - expect_equal(res$chrom, "1") - expect_equal(res$start, 100L) - expect_equal(res$end, 200L) -}) - -test_that("parseRegion: handles X chromosome", { - res <- parseRegion("chrX:1000-2000") - expect_equal(res$chrom, "X") - expect_equal(res$start, 1000L) - expect_equal(res$end, 2000L) -}) - -test_that("parseRegion: accepts the underscore form its docs advertise", { - # LD-block / region ids are spelled chr_start_end; the docstring always - # claimed this worked while the regex rejected it. - expect_identical( - parseRegion("chr1_100_200"), - parseRegion("chr1:100-200") - ) - expect_identical( - parseRegion("chr22_49355984_50799822"), - parseRegion("chr22:49355984-50799822") - ) -}) - -test_that("parseRegion: accepts the mitochondrial contig", { - # canonChrom() exists to normalize MT/M, which the old regex made - # unreachable by erroring first. - res <- parseRegion("chrMT:10-20") - expect_identical(as.integer(res$start), 10L) - expect_identical(as.integer(res$end), 20L) -}) - -test_that("parseRegion: rejects malformed input", { - expect_error(parseRegion("notARegion"), "format must be") - expect_error(parseRegion("1:100:200"), "format must be") - # mixed spellings are not a third format - expect_error(parseRegion("chr1:100_200"), "format must be") - expect_error(parseRegion("chr1_100-200"), "format must be") -}) - -test_that("parseRegion: returns non-character input unchanged", { - df_in <- data.frame( - chrom = "1", - start = 100L, - end = 200L, - stringsAsFactors = FALSE - ) - expect_identical(parseRegion(df_in), df_in) - expect_identical(parseRegion(42L), 42L) -}) - -# =========================================================================== -# regionToDf -# =========================================================================== - -test_that("regionToDf: parses chrom_start_end LD region IDs", { - res <- regionToDf(c("1_100_200", "2_300_400")) - expect_equal(res$chrom, c("1", "2")) - expect_equal(res$start, c(100L, 300L)) - expect_equal(res$end, c(200L, 400L)) -}) - -test_that("regionToDf: strips chr prefix from chromosome", { - res <- regionToDf("chr5_1000_2000") - expect_equal(res$chrom, "5") -}) - -test_that("regionToDf: accepts colon/dash separators", { - res <- regionToDf("chr1:100-200") - expect_equal(res$chrom, "1") - expect_equal(res$start, 100L) - expect_equal(res$end, 200L) -}) - -test_that("regionToDf: honours custom column names", { - res <- regionToDf("1_10_20", colnames = c("seq", "from", "to")) - expect_equal(colnames(res), c("seq", "from", "to")) -}) - # =========================================================================== # classifyVariantType # =========================================================================== -test_that("classifyVariantType: identifies SNPs", { - expect_equal( - classifyVariantType(c("chr1:100:A:G", "chr1:200:C:T")), - c("SNP", "SNP") +test_that("classifyVariantType: identifies SNPs, indels and MNPs", { + ids <- c( + "chr1:100:A:G", + "chr1:200:ATG:A", + "chr1:300:A:ATG", + "chr1:400:AT:GC" ) -}) - -test_that("classifyVariantType: identifies insertions and deletions", { - expect_equal(classifyVariantType("chr1:100:A:ATG"), "insertion") - expect_equal(classifyVariantType("chr1:100:ATG:A"), "deletion") -}) - -test_that("classifyVariantType: identifies MNPs (equal-length multi-base)", { - expect_equal(classifyVariantType("chr1:100:AT:GC"), "MNP") + result <- classifyVariantType(ids) + expect_equal(result, c("SNP", "deletion", "insertion", "MNP")) }) test_that("classifyVariantType: accepts data.frame input with A2/A1 columns", { df <- data.frame( - A2 = c("A", "AT"), - A1 = c("G", "GC"), + A2 = c("A", "AT", "ATG"), + A1 = c("G", "GC", "A"), stringsAsFactors = FALSE ) - expect_equal(classifyVariantType(df), c("SNP", "MNP")) + expect_equal(classifyVariantType(df), c("SNP", "MNP", "deletion")) }) test_that("classifyVariantType: errors when given an unsupported input", { @@ -307,17 +190,9 @@ test_that("classifyVariantType: errors when given an unsupported input", { }) # =========================================================================== -# Tests migrated from test_misc.R (variant-id helpers) +# formatVariantId # =========================================================================== -test_that("Test formatVariantId", { - expect_equal( - formatVariantId(c(1, 1), c(123, 132), c("G", "A"), c("C", "T")), - c("chr1:123:G:C", "chr1:132:A:T") - ) -}) - - test_that("formatVariantId uses convention parameter automatically", { expect_equal(pecotmr:::formatVariantId(1, 100, "A", "G"), "chr1:100:A:G") @@ -346,7 +221,6 @@ test_that("formatVariantId uses convention parameter automatically", { ) }) - test_that("formatVariantId constructs canonical IDs", { expect_equal( pecotmr:::formatVariantId( @@ -367,85 +241,6 @@ test_that("formatVariantId constructs canonical IDs", { ) }) -# ============================================================================= -# ============================================================================= -# pvalHmp -# ============================================================================= - -test_that("parseRegion parses valid region string", { - result <- parseRegion("chr1:100-200") - expect_s3_class(result, "data.frame") - expect_equal(result$chrom, "1") - expect_equal(result$start, 100L) - expect_equal(result$end, 200L) -}) - - -test_that("parseRegion handles X chromosome", { - result <- parseRegion("chrX:500-1000") - expect_equal(result$chrom, "X") - expect_equal(result$start, 500L) - expect_equal(result$end, 1000L) -}) - - -test_that("parseRegion errors on invalid format", { - expect_error(parseRegion("1:100-200"), "format must be") - expect_error(parseRegion("chr1-100-200"), "format must be") - expect_error(parseRegion("chr1:abc-200"), "format must be") -}) - - -test_that("parseRegion returns non-string input unchanged", { - df <- data.frame(chrom = 1, start = 100, end = 200) - result <- parseRegion(df) - expect_identical(result, df) -}) - - -test_that("parseRegion returns non-single-string input unchanged", { - input <- c("chr1:100-200", "chr2:300-400") - result <- parseRegion(input) - expect_identical(result, input) -}) - -# ============================================================================= -# parseVariantId -# ============================================================================= - -test_that("parseVariantId parses single variant with chr prefix", { - result <- parseVariantId("chr1:12345:A:G") - expect_equal(result$chrom, "1") - expect_equal(result$pos, 12345L) - expect_equal(result$A2, "A") - expect_equal(result$A1, "G") - conv <- attr(result, "convention") - expect_true(conv$hasChr) - expect_equal(conv$alleleSep, ":") -}) - - -test_that("parseVariantId parses single variant without chr prefix", { - result <- parseVariantId("5:12345:A:G") - expect_equal(result$chrom, "5") - expect_equal(result$pos, 12345L) - expect_equal(result$A2, "A") - expect_equal(result$A1, "G") - conv <- attr(result, "convention") - expect_false(conv$hasChr) -}) - - -test_that("parseVariantId parses multiple variants", { - ids <- c("chr1:100:A:G", "chr2:200:C:T", "chr3:300:G:A") - result <- parseVariantId(ids) - expect_equal(nrow(result), 3) - expect_equal(result$chrom, c("1", "2", "3")) - expect_equal(result$pos, c(100L, 200L, 300L)) - expect_equal(result$A2, c("A", "C", "G")) - expect_equal(result$A1, c("G", "T", "A")) -}) - # ============================================================================= # detectVariantConvention # ============================================================================= @@ -472,6 +267,14 @@ test_that("detectVariantConvention detects chr prefix and allele separators", { expect_equal(conv5$alleleSep, "_") }) +test_that("detectVariantConvention returns defaults for all-NA input", { + result <- detectVariantConvention(c(NA, NA, NA)) + expect_false(result$hasChr) + expect_equal(result$alleleSep, ":") + expect_false(result$hasBuild) + expect_true(is.na(result$example)) +}) + # ============================================================================= # normalizeVariantId # ============================================================================= @@ -493,7 +296,6 @@ test_that("normalizeVariantId normalizes various formats", { ) }) - test_that("normalizeVariantId leaves unparseable ids (rsIDs) unchanged", { expect_equal( normalizeVariantId(c("rs123", "1:100:A:G", "chr2:200_C_T")), @@ -502,144 +304,6 @@ test_that("normalizeVariantId leaves unparseable ids (rsIDs) unchanged", { expect_equal(normalizeVariantId("rs1"), "rs1") # all-unparseable input }) -# ============================================================================= -# parseVariantId — id-format coverage (was the variantIdToDf alias) -# ============================================================================= - -test_that("parseVariantId handles colon-separated format", { - ids <- c("1:100:A:G", "2:200:C:T") - result <- parseVariantId(ids) - expect_equal(nrow(result), 2) - expect_equal(result$chrom, c("1", "2")) - expect_equal(result$pos, c(100L, 200L)) - expect_equal(result$A2, c("A", "C")) - expect_equal(result$A1, c("G", "T")) -}) - - -test_that("parseVariantId handles underscore-separated format", { - ids <- c("1:100_A_G", "2:200_C_T") - result <- parseVariantId(ids) - expect_equal(nrow(result), 2) - expect_equal(result$A2, c("A", "C")) -}) - - -test_that("parseVariantId strips chr prefix", { - ids <- c("chr1:100:A:G", "chr2:200:C:T") - result <- parseVariantId(ids) - expect_equal(result$chrom, c("1", "2")) -}) - - -test_that("parseVariantId handles data.frame input with named columns", { - df <- data.frame( - chrom = c("chr1", "2"), - pos = c(100, 200), - A2 = c("A", "C"), - A1 = c("G", "T") - ) - suppressWarnings(result <- parseVariantId(df)) - expect_equal(result$chrom, c("1", "2")) - expect_equal(result$pos, c(100L, 200L)) -}) - - -test_that("parseVariantId handles 5-part IDs with build suffix", { - ids <- c("chr1:100:A:G:b38", "chr2:200:T:C") - result <- parseVariantId(ids) - expect_equal(ncol(result), 4) - expect_equal(colnames(result), c("chrom", "pos", "A2", "A1")) - expect_equal(result$chrom, c("1", "2")) - expect_equal(result$A2, c("A", "T")) - expect_equal(result$A1, c("G", "C")) -}) - - -test_that("parseVariantId handles mixed 4/5-part IDs", { - ids <- c("1:100:A:G", "chr2:200:T:C:b38", "3:300:G:A:b37") - suppressWarnings(result <- parseVariantId(ids)) - expect_equal(nrow(result), 3) - expect_equal(ncol(result), 4) - expect_equal(result$A1, c("G", "C", "A")) -}) - -# ============================================================================= -# ============================================================================= -# ============================================================================= -# computeLd — uncovered branches -# ============================================================================= - -test_that("detectVariantConvention returns defaults for all-NA input", { - result <- detectVariantConvention(c(NA, NA, NA)) - expect_false(result$hasChr) - expect_equal(result$alleleSep, ":") - expect_false(result$hasBuild) - expect_true(is.na(result$example)) -}) - -# ============================================================================= -# parseVariantId — uncovered line 622 -# ============================================================================= - -test_that("parseVariantId handles data.frame with generic column names", { - df <- data.frame( - col1 = c("chr1", "chr2"), - col2 = c(100, 200), - col3 = c("A", "T"), - col4 = c("G", "C"), - stringsAsFactors = FALSE - ) - result <- parseVariantId(df) - expect_equal(names(result)[1:4], c("chrom", "pos", "A2", "A1")) - expect_equal(result$chrom, c("1", "2")) - expect_equal(result$pos, c(100L, 200L)) - expect_equal(result$A2, c("A", "T")) - expect_equal(result$A1, c("G", "C")) -}) - -# ============================================================================= -# classifyVariantType -# ============================================================================= - -test_that("classifyVariantType identifies SNPs", { - expect_equal(classifyVariantType("chr1:100:A:G"), "SNP") -}) - - -test_that("classifyVariantType identifies insertions", { - expect_equal(classifyVariantType("chr1:100:A:ATG"), "insertion") -}) - - -test_that("classifyVariantType identifies deletions", { - expect_equal(classifyVariantType("chr1:100:ATG:A"), "deletion") -}) - - -test_that("classifyVariantType identifies MNPs", { - expect_equal(classifyVariantType("chr1:100:AT:GC"), "MNP") -}) - - -test_that("classifyVariantType handles vector input", { - ids <- c( - "chr1:100:A:G", - "chr1:200:ATG:A", - "chr1:300:A:ATG", - "chr1:400:AT:GC" - ) - result <- classifyVariantType(ids) - expect_equal(result, c("SNP", "deletion", "insertion", "MNP")) -}) - - -test_that("classifyVariantType accepts data.frame input", { - df <- data.frame(A2 = c("A", "ATG"), A1 = c("G", "A")) - result <- classifyVariantType(df) - expect_equal(result, c("SNP", "deletion")) -}) - # =========================================================================== # canonChrom / chromOrder / non-autosomal chromosomes (string chrom contract) # =========================================================================== @@ -676,7 +340,7 @@ test_that("parseVariantId keeps non-autosomal chromosomes as strings", { "chrM:5:G:A", "chrY:9:C:T" )) - expect_equal(res$chrom, c("X", "X", "MT", "Y")) + expect_equal(res$chrom, c("chrX", "chrX", "chrM", "chrY")) expect_equal(res$pos, c(100L, 200L, 5L, 9L)) }) @@ -689,7 +353,8 @@ test_that("formatVariantId emits non-autosomal ids without 'chrNA'", { test_that("normalizeVariantId round-trips non-autosomal chromosomes", { expect_equal(normalizeVariantId("23:100:A:G"), "chrX:100:A:G") expect_equal(normalizeVariantId("chrX:100:A:G"), "chrX:100:A:G") - expect_equal(normalizeVariantId("chrM:5:G:A"), "chrMT:5:G:A") + expect_equal(normalizeVariantId("chrM:5:G:A"), "chrM:5:G:A") + expect_equal(normalizeVariantId("MT:5:G:A"), "chrM:5:G:A") }) test_that("chromOrder sorts autosomes then X/Y/MT", { @@ -697,13 +362,6 @@ test_that("chromOrder sorts autosomes then X/Y/MT", { expect_equal(as.character(sort(ord)), c("1", "2", "22", "X", "Y", "MT")) }) -test_that("regionToDf keeps chrom as a string and positions as integers", { - res <- regionToDf("chrX_1000_2000") - expect_equal(res$chrom, "X") - expect_type(res$start, "integer") - expect_equal(res$start, 1000L) -}) - # =========================================================================== # matchVariants -- allele-aware matcher (match on chrom/pos/ref/alt) # =========================================================================== @@ -873,15 +531,17 @@ test_that("harmonizeAlleles flipStrand = TRUE runs the strand-flip branch", { test_that("harmonizeAlleles complements colToComplement on an allele swap", { # target G/A is the ref/alt swap of ref A/G, so an effect-allele freq - # complements to 1 - af. - tgt <- .vid_df("1", 100, "G", "A", af = 0.3) + # complements to 1 - af while the signed colToFlip column is negated. + tgt <- .vid_df("1", 100, "G", "A", af = 0.3, z = 2) res <- pecotmr:::harmonizeAlleles( tgt, .vid_df("1", 100, "A", "G"), + colToFlip = "z", colToComplement = "af", matchMinProp = 0 ) expect_equal(res$harmonizedData$af, 0.7) + expect_equal(res$harmonizedData$z, -2) }) test_that("harmonizeAlleles errors when colToFlip / colToComplement are absent", { @@ -926,7 +586,7 @@ test_that("harmonizeAlleles errors on duplicate variant IDs when removeDups = FA .vid_df("1", 100, "A", "G"), matchMinProp = 0 ), - "Duplicated variant IDs" + "Duplicated variant IDs remain" ) }) @@ -939,7 +599,7 @@ test_that("harmonizeAlleles removeDups = TRUE drops duplicates with a warning", removeDups = TRUE, matchMinProp = 0 ), - "duplicate" + "Removed 1 duplicate" ) expect_equal(nrow(res$harmonizedData), 1L) }) @@ -1037,8 +697,110 @@ test_that("harmonizeAlleles counts what it kept, not what it joined", { expect_equal(counts$signFlip, 0L) }) +test_that("harmonizeAlleles surfaces sign/strand/dropped in qcCounts", { + # 4 shared positions: 100 exact, 200 sign-flip, 300 strand-flip (A/G + # unambiguous), 400 allele mismatch (dropped). + target <- data.frame( + chrom = c(1, 1, 1, 1), + pos = c(100, 200, 300, 400), + A2 = c("A", "A", "A", "A"), + A1 = c("G", "G", "G", "G"), + z = c(1, 2, 3, 4), + stringsAsFactors = FALSE + ) + ref <- data.frame( + chrom = c(1, 1, 1, 1), + pos = c(100, 200, 300, 400), + A2 = c("A", "G", "T", "C"), + A1 = c("G", "A", "C", "A"), + stringsAsFactors = FALSE + ) + res <- pecotmr:::harmonizeAlleles( + target, + ref, + colToFlip = "z", + matchMinProp = 0 + ) + # Default return shape unchanged. + expect_named(res, c("harmonizedData", "qcSummary")) + expect_equal(nrow(res$harmonizedData), 3L) + cnt <- attr(res, "qcCounts") + expect_false(is.null(cnt)) + expect_equal(cnt$considered, 4L) + expect_equal(cnt$signFlip, 1L) + expect_equal(cnt$strandFlip, 1L) + expect_equal(cnt$kept, 3L) + expect_equal(cnt$dropped, 1L) +}) + +test_that("harmonizeAlleles: accepts a bare variant-id vector as target", { + res <- pecotmr:::harmonizeAlleles( + c("chr1:100:A:G", "chr1:200:C:T"), + c("chr1:100:A:G", "chr1:200:C:T"), + matchMinProp = 0 + ) + expect_equal(nrow(res$harmonizedData), 2L) +}) + +test_that("harmonizeAlleles: strips a conflicting variant_id from target", { + target <- data.frame( + chrom = c(1, 1), + pos = c(100, 200), + A2 = c("A", "C"), + A1 = c("G", "T"), + variant_id = c("old1", "old2"), + z = c(1, 2), + stringsAsFactors = FALSE + ) + ref <- data.frame( + chrom = c(1, 1), + pos = c(100, 200), + A2 = c("A", "C"), + A1 = c("G", "T"), + stringsAsFactors = FALSE + ) + res <- pecotmr:::harmonizeAlleles( + target, + ref, + colToFlip = "z", + matchMinProp = 0 + ) + expect_equal(nrow(res$harmonizedData), 2L) + # The input variant_id was stripped; the returned id is rebuilt from QC'd alleles. + expect_false(any(c("old1", "old2") %in% res$harmonizedData$variant_id)) +}) + +test_that("harmonizeAlleles renames an empty target column to unnamed_N", { + # 5 columns whose first four are positional (NOT literally named + # chrom/pos/A2/A1), so harmonizeAlleles routes through parseVariantId -- + # which preserves the extra column -- rather than the select()-based path. + # The 5th column has an empty name, so the joined matchResult carries an + # empty-named column and .sanitizeNames() rewrites it to "unnamed_1". + target <- data.frame( + CHR = c(1, 1, 1), + POS = c(100, 200, 300), + ref = c("A", "C", "G"), + alt = c("G", "T", "A"), + extra = c(0.1, 0.2, 0.3), + stringsAsFactors = FALSE + ) + names(target)[5] <- "" + ref <- data.frame( + chrom = c(1, 1, 1), + pos = c(100, 200, 300), + A2 = c("A", "C", "G"), + A1 = c("G", "T", "A"), + stringsAsFactors = FALSE + ) + res <- pecotmr:::harmonizeAlleles(target, ref, matchMinProp = 0) + expect_equal(nrow(res$harmonizedData), 3L) + nm <- colnames(res$harmonizedData) + expect_false(any(nm == "" | is.na(nm))) # the empty name was repaired + expect_true(any(grepl("^unnamed_", nm))) # ... to an "unnamed_*" label +}) + # =========================================================================== -# withChrPrefix + asGranges error paths +# withChrPrefix # =========================================================================== test_that("withChrPrefix adds a lowercase chr prefix case-insensitively", { @@ -1048,22 +810,107 @@ test_that("withChrPrefix adds a lowercase chr prefix case-insensitively", { ) }) -test_that("asGranges errors on malformed input", { - expect_error(pecotmr:::asGranges(data.frame(foo = 1)), "must have columns") - expect_error(pecotmr:::asGranges(list(1)), "character vector or data.frame") +test_that("withChrPrefix spells chromosomes as UCSC does", { + expect_equal( + pecotmr:::withChrPrefix( + c("01", "23", "24", "x", "M", "MT", "chrM", "chrMT", NA) + ), + c("chr1", "chrX", "chrY", "chrX", "chrM", "chrM", "chrM", "chrM", NA) + ) + # A contig outside the standard set keeps its spelling behind the prefix. + expect_equal( + pecotmr:::withChrPrefix(c("chrUn_gl000192", "GL000192.1", "XY")), + c("chrUn_gl000192", "chrGL000192.1", "chrXY") + ) }) -test_that("asGranges (exported) converts region strings and data.frames", { - gr <- asGranges("chr1:100-200") - expect_s4_class(gr, "GRanges") - expect_equal(as.character(GenomicRanges::seqnames(gr)), "chr1") - expect_equal(GenomicRanges::start(gr), 100L) - expect_equal(GenomicRanges::end(gr), 200L) - # numeric chrom gets a chr prefix; data.frame input is accepted too - gr2 <- asGranges(data.frame(chrom = "2", start = 5, end = 9)) - expect_equal(as.character(GenomicRanges::seqnames(gr2)), "chr2") +test_that("withChrPrefix agrees with GenomeInfoDb's UCSC style", { + ncbi <- c(as.character(1:22), "X", "Y", "MT") + expect_identical( + pecotmr:::withChrPrefix(ncbi), + unname(GenomeInfoDb::mapSeqlevels(ncbi, "UCSC")) + ) + gr <- GenomicRanges::GRanges( + pecotmr:::withChrPrefix(ncbi), + IRanges::IRanges(1L, width = 1L) + ) + expect_identical(GenomeInfoDb::seqlevelsStyle(gr), "UCSC") +}) + +test_that(".ucscRanges renames to UCSC and keeps the rest", { + # Anything but ranges passes through for its caller to refuse. + expect_null(pecotmr:::.ucscRanges(NULL)) + expect_identical(pecotmr:::.ucscRanges("chr1"), "chr1") + ucsc <- GenomicRanges::GRanges("chr1", IRanges::IRanges(5L, width = 1L)) + expect_identical(pecotmr:::.ucscRanges(ucsc), ucsc) + gr <- GenomicRanges::GRanges( + c("1", "MT"), + IRanges::IRanges(c(100L, 5L), width = 1L, names = c("a", "b")), + strand = c("+", "-"), + SNP = c("rs1", "rs2") + ) + GenomeInfoDb::genome(gr) <- "hg19" + out <- pecotmr:::.ucscRanges(gr) + expect_identical( + as.character(GenomicRanges::seqnames(out)), + c("chr1", "chrM") + ) + expect_identical(names(out), c("a", "b")) + expect_identical(as.character(GenomicRanges::strand(out)), c("+", "-")) + expect_identical(out$SNP, c("rs1", "rs2")) + expect_identical(unname(GenomeInfoDb::genome(out)), c("hg19", "hg19")) }) +test_that(".ucscRanges merges two spellings of one chromosome", { + gr <- GenomicRanges::GRanges( + c("1", "chr1", "2"), + IRanges::IRanges(c(10L, 20L, 30L), width = 1L), + strand = c("+", "*", "-"), + SNP = c("a", "b", "c") + ) + GenomeInfoDb::genome(gr) <- "hg38" + out <- pecotmr:::.ucscRanges(gr) + expect_identical(GenomeInfoDb::seqlevels(out), c("chr1", "chr2")) + expect_identical( + as.character(GenomicRanges::seqnames(out)), + c("chr1", "chr1", "chr2") + ) + expect_identical(as.character(GenomicRanges::strand(out)), c("+", "*", "-")) + expect_identical(out$SNP, c("a", "b", "c")) + expect_identical(unname(GenomeInfoDb::genome(out)), c("hg38", "hg38")) +}) + +test_that(".ucscEntries renames every element and keeps a NULL one", { + out <- pecotmr:::.ucscEntries(list( + a = GenomicRanges::GRanges("22", IRanges::IRanges(1L, width = 1L)), + b = NULL + )) + expect_identical(names(out), c("a", "b")) + expect_identical(as.character(GenomicRanges::seqnames(out$a)), "chr22") + expect_null(out$b) +}) + +test_that(".ucscExperiment renames an experiment's rowRanges only", { + m <- matrix(1, 1L, 1L, dimnames = list("v", "s")) + plain <- SummarizedExperiment::SummarizedExperiment(list(x = m)) + expect_identical(pecotmr:::.ucscExperiment(plain), plain) + rse <- SummarizedExperiment::SummarizedExperiment( + list(x = m), + rowRanges = GenomicRanges::GRanges( + "X", + IRanges::IRanges(9L, width = 1L) + ) + ) + out <- pecotmr:::.ucscExperiment(rse) + expect_identical(GenomeInfoDb::seqlevels(out), "chrX") + expect_identical(SummarizedExperiment::assay(out), m) + expect_identical(pecotmr:::.ucscExperiment(out), out) +}) + +# =========================================================================== +# matchVariants: data.frame input +# =========================================================================== + test_that("matchVariants allowFlip = FALSE accepts data.frame input", { a <- .vid_df("1", 100, "A", "G") b <- .vid_df("1", 100, "A", "G") @@ -1085,15 +932,10 @@ test_that("matchVariants returns empty for unparseable data.frame input", { # matchVariants: a reference carrying both orientations of one variant # =========================================================================== -test_that("matchVariants drops a target matching both orientations", { +test_that("matchVariants drops a flip-pair target, whatever the row order", { # Two distinct indels at one position that are each other's allele flip is # rare but biologically real. A target then matches one exactly (+1) and # the other as a swap (-1), and nothing can say which it is. - panel <- c("chr1:100:A:AT", "chr1:100:AT:A") - expect_length(matchVariants("chr1:100:A:AT", panel)$idxA, 0L) -}) - -test_that("the drop does not depend on the reference's row order", { # The bug this replaces: `!duplicated()` kept whichever match came first, # so the SIGN -- and with it the effect direction -- was decided by the # panel's row order. @@ -1144,6 +986,9 @@ test_that("the rule applies to SNP flip pairs, not just indels", { expect_length(matchVariants("chr1:200:A:G", panel)$idxA, 0L) }) +# =========================================================================== +# Remaining helpers and argument guards +# =========================================================================== test_that("a convention without an allele separator keeps the default", { f <- pecotmr:::formatVariantId @@ -1264,26 +1109,3 @@ test_that("normalizeVariantId: argument guards fire", { "convention.*Must be of type 'list'" ) }) - -test_that("regionToDf: argument guards fire", { - expect_error(regionToDf(1L), "Must be of type 'character'") - expect_error( - regionToDf("1_100_200", colnames = c("a", "b")), - "colnames.*Must have length 3" - ) -}) - -test_that("asGranges leaves an already chr-prefixed chromosome alone", { - # The prefix is added only when absent; a frame that already carries it - # must not become "chrchr1". - gr <- asGranges(data.frame( - chrom = c("chr1", "chr2"), - start = c(100L, 200L), - end = c(150L, 250L), - stringsAsFactors = FALSE - )) - expect_identical( - as.character(GenomicRanges::seqnames(gr)), - c("chr1", "chr2") - ) -}) diff --git a/vignettes/coloc-pipeline.Rmd b/vignettes/coloc-pipeline.Rmd index 116bd9ef..9c093c1a 100644 --- a/vignettes/coloc-pipeline.Rmd +++ b/vignettes/coloc-pipeline.Rmd @@ -107,6 +107,21 @@ windows. Ultimately this means that the variable selection in the QTL and GWAS fine-mapping will have been done over different variant sets, which may reduce the sensitivity for colocalizations, particuarly in areas with complex LD. +A QTL region that reaches more than one of a GWAS study's LD blocks is still +one colocalization, not one per block. Given a `GwasSumStats`, the blocks the +region reaches are stitched together and fine-mapped once. Given a +`GwasFineMappingResult`, their fits are collapsed into one fit over the +region, assuming no LD between blocks, so each block's effects keep to their +own block. Either way the result's `blockId` names the stretch the blocks +cover. + +So load every block a QTL region reaches. A region whose variants run past +the loaded blocks of a GWAS study it overlaps is an error when those blocks' +windows were given as the study's `region`: the variants past them lie in a +block that was not loaded. When the windows are only the span of the GWAS +variants, the variants past them may be ones the GWAS lacks, so more than one +in a row past a block is a warning. + ## Filtering effects fed into coloc `coloc::coloc.bf_bf` accepts one LBF matrix for the QTL and one for hte GWAS. @@ -133,7 +148,7 @@ colocPipeline( ## Enrichment-aware colocalisation (enloc mode) -Passing a per-`(gwasStudy, qtlContext)` enrichment table --- the output of +Passing a per-pair enrichment table --- the output of `qtlEnrichmentPipeline()` --- switches the pair from coloc to enloc. This is a port of `fastenloc`, not a reweighting of coloc: the priors are *derived* from the enrichment estimate rather than the baseline `p12` being scaled by @@ -278,8 +293,8 @@ The warning above is the diagnostic that rule produces: a within-credible-set sum above 1 means several GWAS credible sets are competing for one QTL signal. The value is clipped to 1, and the pair view shows which pairs were involved. -If you need the flat table the pipeline used to return, `as.data.frame(res)` -gives the pair view. +If you need the flat table the pipeline used to return, `colocPairs(res)` is +the pair view, as a `DataFrame`. # Session info diff --git a/vignettes/colocboost-pipeline.Rmd b/vignettes/colocboost-pipeline.Rmd index e8e45346..46091367 100644 --- a/vignettes/colocboost-pipeline.Rmd +++ b/vignettes/colocboost-pipeline.Rmd @@ -59,7 +59,7 @@ ColocBoost can run three different model flavours in one call. | Flag | Default | What | |---|---|---| | `xqtlColoc` | TRUE | QTL-only colocboost across the QTL contexts. | -| `jointGwas` | FALSE | Single non-focal colocboost model that stacks all QTL contexts/studies with every supplied GWAS study. | +| `jointGwas` | FALSE | All QTL outcomes with every GWAS study in one model; focal on a lone GWAS. | | `separateGwas` | FALSE | One focal colocboost model per GWAS study (the GWAS is the focal outcome). | ## xQTL-only colocalization @@ -93,6 +93,13 @@ res2 <- colocboostPipeline( names(res2) ``` +Each GWAS study is one outcome: the rows of the study that the QTL data +overlap, joined. A study split by chromosome or LD block contributes only the +one or two rows the QTL region reaches, and QTL variants past those blocks are +checked as `colocPipeline()` checks them. With a single GWAS study, as here, the +joint run is focal on it; with several it is non-focal, since only one +outcome can be focal (see below). + ## QTL + GWAS (per-GWAS focal models) When you want one colocboost run per GWAS trait, with that trait as the @@ -143,16 +150,20 @@ resMs <- colocboostPipeline( ) ``` -## Focal trait +## Focal outcome -`focalTrait` makes the xQTL-only run treat one specific trait as the -focal outcome: +`focalOutcome` chooses the focal outcome. A plain string names a GWAS +study, which becomes the joint run's focal outcome. A named vector names a +QTL outcome by its `study`, `context` and `trait`, as many as it takes to +pick out one, and that outcome is focal in both the xQTL-only and the joint +run. `NA` makes every run non-focal. The `separateGwas` runs are always +focal on their own GWAS study. ```{r focal, eval=FALSE} colocboostPipeline( qtlDatasetExample, xqtlColoc = TRUE, - focalTrait = "ENSG_example" + focalOutcome = c(context = "brain", trait = "ENSG_example") ) ``` @@ -164,35 +175,31 @@ colocboostPipeline( gwasSumStats = gwasSumStatsS4Example, contexts = "brain", traitId = "ENSG_example", - region = NULL, # alternative to traitId+cisWindow + region = NULL, # alternative to traitId + cisWindow cisWindow = 5e5, # required with traitId - focalTrait = NULL, + focalOutcome = NULL, # the GWAS study, when there is only one xqtlColoc = TRUE, jointGwas = FALSE, separateGwas = FALSE, - # Forward to colocboost::colocboost - M = 10, - L = 5, - output_level = 1L + # Forwarded to colocboost::colocboost + methodArgs = ColocboostOptions(M = 10) ) ``` -Trait / context / region restrictions are pre-construction concerns on -the `QtlDataset` (`keepSamples`, `keepVariants`, the per-context -`SummarizedExperiment` row selection); the pipeline parameters above -are the per-call refinements. +Which traits, contexts and window to analyse are the pipeline parameters +above; which variants and samples to keep is `genotypeFilterParam`, as in +`fineMappingPipeline()`. ## QC requirements - **Individual-level (`QtlDataset` / `MultiStudyQtlDataset`)**: QC (MAF / MAC - / X-variance / per-sample missingness, sample / variant restrictions) lives - on the `QtlDataset` constructor and is applied lazily inside - `genotypes()` / `residualizedGenotypes()`. The pipeline does not run - a separate pass. + / X-variance / per-sample missingness, sample / variant restrictions) is + the pipeline's `genotypeFilterParam`, applied to each block of genotypes + it extracts. The dataset itself records no filter. - **Summary statistics (`QtlSumStats` / `GwasSumStats`)**: all variant filters, panel harmonization, LD-mismatch detection, and RAISS imputation live in [`summaryStatsQc()`](rss-qc.html). The pipeline rejects inputs - whose `qcInfo()` is empty. + whose `qcOptions()` is empty. # Session info diff --git a/vignettes/constructing-qtl-datasets.Rmd b/vignettes/constructing-qtl-datasets.Rmd index ce0ec4e3..7c83fbab 100644 --- a/vignettes/constructing-qtl-datasets.Rmd +++ b/vignettes/constructing-qtl-datasets.Rmd @@ -43,18 +43,18 @@ are one more: Alongside them the object keeps a `colData` naming every sample and a `sampleMap` recording which of them each experiment observes — so contexts -need not share a sample set — plus its own slots: +need not share a sample set — plus one slot of its own, `studyName`. The +genotype panel (a lazy PLINK1/PLINK2/VCF/GDS/BGEN source, read with +`readGenotypes()`) is the `genotype` experiment, whose dosage assay reads +through it. -* `study` — study identifier (length-1 character). -* `genotypes` — the genotype panel (a lazy PLINK1/PLINK2/VCF/GDS/BGEN source, - read with `readGenotypes()`) that the dosage assay reads through. -* QC thresholds — `mafCutoff`, `macCutoff`, `xvarCutoff`, `imissCutoff`, - `keepIndel`, `keepVariants`, `scaleResiduals`. Stored as **lazy** filters, - applied at genotype-extraction time. +A `QtlDataset` holds data only. Which variants and samples an analysis +keeps (`GenotypeFilterParam`) and how it residualizes +(`ResidualizationParam`) are the pipelines' settings, applied to each block +they extract. To restrict a dataset to a set of samples, subset it: `x[, samples, ]` narrows -`colData` and `sampleMap` together, and keeps the class and its slots. The -`keepSamples` constructor argument is shorthand for the same thing. +`colData` and `sampleMap` together, and keeps the class and its slot. There are two ways to build a `QtlDataset`: @@ -175,18 +175,16 @@ readr::write_tsv(manifest, manifestPath) qd <- loadQtlDatasetFromManifest(manifestPath) ``` -The QC thresholds are ordinary arguments (they are stored as lazy filters, not -applied at load), for example: +Loading applies no QC: the dataset holds the data as read, and a pipeline +filters each block it extracts with its `genotypeFilterParam`, for example: ```{r qtl-manifest-qc} -qdFiltered <- loadQtlDatasetFromManifest( - manifest, - genotypeFilterParam = GenotypeFilterParam( - mafCutoff = 0.01, - imissCutoff = 0.05, - keepIndel = FALSE - ) +qcFilter <- GenotypeFilterParam( + mafCutoff = 0.01, + imissCutoff = 0.05, + keepIndel = FALSE ) +# fineMappingPipeline(qd, methods = "susie", genotypeFilterParam = qcFilter) ``` ## Constructing a QtlDataset manually @@ -272,7 +270,7 @@ A MultiStudyQtlDataset can be manually constructed by building a named list of msdManual <- MultiStudyQtlDataset( qtlDatasets = list(StudyA = qd, StudyB = qdManual) ) -names(qtlDatasets(msdManual)) +names(msdManual) ``` To attach a summary-only study, pass a `QtlSumStats` object to the `sumStats` @@ -322,10 +320,9 @@ Building the description rather than passing a bare list means a misspelled field is an error at the call site instead of a default silently left in place. -The exclusion list is not applied for you — feed it to `keepSamples`, the -constructor argument this vignette introduced above, or subset an existing -dataset with `qd[, unrelated, ]`. Both narrow `colData` and `sampleMap` -together. +The exclusion list is not applied for you — subset the dataset with +`qd[, unrelated, ]`, which narrows `colData` and `sampleMap` together, or +hand it to a pipeline as `GenotypeFilterParam(keepSamples = unrelated)`. `analysisType` changes what is being maximised. The default, `"maximizeUnrelated"`, keeps the largest unrelated set. `"maximizeCases"` @@ -338,16 +335,19 @@ the chunk above is skipped when they are not installed. ## Next steps -Once built, the accessors extract data lazily, applying the stored QC filters -at extraction time: +Once built, the accessors read the data lazily. To read part of it, subset +the dataset first: ```{r accessors} studyName(qd) contexts(qd) -# Cis genotypes around a trait (+/- a window), QC applied on the fly: -dim(genotypes(qd, traitId = "GENE1", cisWindow = 1e6)) -# Phenotype matrix for one context: -dim(SummarizedExperiment::assay(molecularTraits(qd, contexts = "Muscle"))) +# Cis genotypes around a trait (+/- 1 Mb): narrow to the window, then read +cisWindow <- traitPosition(qd, "GENE1") + 1e6 +dim(genotypes(qd[cisWindow, , ])) +# Phenotypes for one context: a list keyed by context, each element the +# context's SummarizedExperiment as stored. +muscle <- molecularTraits(qd, context = "Muscle")[["Muscle"]] +dim(SummarizedExperiment::assay(muscle)) ``` `QtlDataset` and `MultiStudyQtlDataset` are direct inputs to diff --git a/vignettes/constructing-sumstats.Rmd b/vignettes/constructing-sumstats.Rmd index 6cfdc5cb..9ef0d48e 100644 --- a/vignettes/constructing-sumstats.Rmd +++ b/vignettes/constructing-sumstats.Rmd @@ -57,11 +57,11 @@ GWAS, `nCase` / `nControl`. * **Manually** — build the `entry` GRanges yourself and call the `GwasSumStats()` / `QtlSumStats()` constructor. -> **The loaders run no QC.** They build the raw collection with an empty -> `qcInfo` slot. Allele harmonization, MAF/INFO/N filtering, and LD-mismatch QC +> **The loaders run no QC.** They build the raw collection with empty +> `qcOptions()`. Allele harmonization, MAF/INFO/N filtering, and LD-mismatch QC > are a separate, mandatory step — `summaryStatsQc()` — documented in the > *Quality Control for GWAS and QTL Summary Statistics* vignette. Downstream -> pipelines reject collections whose `qcInfo` is empty. +> pipelines reject collections whose `qcOptions()` is empty. ```{r load-packages} library(pecotmr) @@ -305,9 +305,10 @@ length(gwsMapped[[1]]) If a `region` is supplied and the sumstats file is **compressed with bgzip and indexed with tabix** (a `.tbi` must exist in the same directory), only -that region is read. Plain-text files are read whole and the region is ignored -with a warning. The tabix header line must begin with `#` so its column names -can be recovered. +that region is read. Plain-text files are read whole, with a warning, and the +region then selects the variants kept. Given in R, a `region` is a `GRanges`; +the path of a BED file also works, read as BED with a 0-based start. The tabix +header line must begin with `#` so its column names can be recovered. ```{r tabix-region} tabixDf <- sumstatsDf @@ -325,7 +326,7 @@ gwsRegion <- loadGwasSumStatsFromManifest( data.frame(study = "MyGWAS", sumStatsPath = gz), genome = "GRCh38", ldReference = ldReference, - region = "22:14560000-14565000" + which = GenomicRanges::GRanges("22:14560000-14565000") ) length(gwsRegion[[1]]) # only the two variants in the region ``` @@ -398,7 +399,7 @@ study; override the FORMAT tag names with `formatMapping` if they differ from ## Next steps The collections carry no QC yet. Run `summaryStatsQc()` before any downstream -analysis (it populates `qcInfo`; downstream pipelines require it): +analysis (it fills `qcOptions()`; downstream pipelines require it): ```{r qc, eval=FALSE} gws_qcd <- summaryStatsQc(gws, ldMismatchQcMethod = "slalom") diff --git a/vignettes/ctwas-pipeline.Rmd b/vignettes/ctwas-pipeline.Rmd index d30dada2..aee0f94d 100644 --- a/vignettes/ctwas-pipeline.Rmd +++ b/vignettes/ctwas-pipeline.Rmd @@ -51,7 +51,7 @@ Inputs: | `gwasSumStats` | one `GwasSumStats` whose elements are LD blocks | | `twasWeights` | per-gene `TwasWeights` / `QtlFineMappingResult` | | `twasZ` | optional pre-computed per-gene Z from `causalInferencePipeline()` | -| `fineMappingResult` | optional; enables the credible-set and PIP variant rescues | +| `fineMappingResult` | optional `QtlFineMappingResult` for the rescues | ```{r load-packages} library(pecotmr) @@ -61,7 +61,7 @@ library(pecotmr) `gwasSumStats` is **one** `GwasSumStats` object whose elements are LD blocks, keyed by its `blockId` column — not a list of per-block objects. -Build it with `loadGwasSumStatsFromManifest(..., ldBlocks = )` and +Build it with `loadGwasSumStatsFromManifest(..., which = )` and pass it through `summaryStatsQc()`. A single-block input is rejected: cTWAS estimates its group priors by EM @@ -89,8 +89,7 @@ gwasSumStats <- loadGwasSumStatsFromManifest( manifest = data.frame(study = "gwas1", sumStatsPath = gwasTsv), genome = "hg38", ldReference = ldStem, - region = "chr22:10000000-19000000", - ldBlocks = blocks + which = blocks ) gwasByRegion <- summaryStatsQc( gwasSumStats, @@ -106,6 +105,7 @@ data(ctwasWeightsExample) res <- ctwasPipeline( gwasSumStats = gwasByRegion, twasWeights = list(ctwasWeightsExample), + method = "susie", ctwasPriorParam = CtwasPriorParam( thin = 1, niterPrefit = 3, @@ -166,13 +166,17 @@ scales with them. Four arguments trim each gene before cTWAS sees it: `csMinCor` and `pipRescue` mark variants as must-keep, so they survive the `maxVariants` cap. Both need a `fineMappingResult`; without one they -are no-ops and the cap falls back to ordering by `abs(weight)`. +are no-ops and the cap falls back to ordering by `abs(weight)`. With one, +`fineMappingMethod` names which of its fine-mapping methods they read: a +weight's own method, such as an ensemble, names no fine-mapping fit. ```{r ctwas-filters, eval=FALSE} ctwasPipeline( gwasSumStats = gwasByRegion, twasWeights = list(ctwasWeightsExample), + method = "susie", fineMappingResult = fmr, + fineMappingMethod = "susie", variantPruningParam = VariantPruningParam( weightCutoff = 1e-4, maxVariants = 1000, @@ -185,7 +189,8 @@ ctwasPipeline( ## Reading the result `ctwasPipeline()` returns a `CtwasResult`: one row per -`(gwasStudy, study, context, method)` run. +`(gwasStudy, study, context, method)` run and cTWAS region, the way a +`GwasFineMappingResult` holds a genome-wide fit as one row per LD block. ```{r ctwas-identity} methodNames(res) @@ -213,10 +218,11 @@ has no real signal) and `cs` is `NA` because the gene falls in no credible set. `susieAlpha()` returns the per-single-effect alpha matrix behind those -PIPs, and the EM group priors sit on each row's entry: +PIPs, and the run's EM group priors sit in the `groupPriors` column, the +same on every region of the run: ```{r ctwas-param} -param <- ctwasGroupPriors(res$entry[[1]]) +param <- res$groupPriors[[1]] param$group_prior param$group_prior_var param$converged @@ -224,7 +230,7 @@ param$converged By default the context-agnostic SNP background is dropped from the result, since it is the null the genes are being scored against rather than a -finding. Pass `keepSnps = TRUE` to retain it as an extra row +finding. Pass `keepSnps = TRUE` to retain it as extra rows, one per region (`study = context = "SNP"`), which makes the full cTWAS output reconstructable. @@ -237,7 +243,8 @@ re-enter the chain without recomputing what came before. ```{r ctwas-granular} inputs <- assembleCtwasInputs( gwasSumStats = gwasByRegion, - twasWeights = list(ctwasWeightsExample) + twasWeights = list(ctwasWeightsExample), + method = "susie" ) est <- estCtwasGroupPriors( inputs, @@ -270,8 +277,8 @@ carries the SNP rows. `asCtwasResult()` is the step that structures the payload and drops them. ```{r ctwas-as-result} -nrow(ctwasPosteriors(asCtwasResult(finemapped))) -nrow(ctwasPosteriors(asCtwasResult(finemapped, keepSnps = TRUE))) +length(ctwasPosteriors(asCtwasResult(finemapped))) +length(ctwasPosteriors(asCtwasResult(finemapped, keepSnps = TRUE))) ``` Each step's payload is also bundled, so you can enter anywhere: @@ -314,9 +321,9 @@ high-PIP gene actually straddles a boundary. ctwasPipeline( gwasSumStats = gwasByRegion, twasWeights = list(ctwasWeightsExample), - method = NULL, # NULL: "ensemble" if present, else every method + method = NULL, # NULL: the TwasWeights' "ensemble" weights maxNumSingleEffects = 5, - ncore = 1, + BPPARAM = BiocParallel::SerialParam(), keepSnps = FALSE, ctwasPriorParam = CtwasPriorParam( thin = 0.1, @@ -330,9 +337,10 @@ ctwasPipeline( ) ``` -When `method` is `NULL` and several weight methods are present without an -`"ensemble"`, each method runs as its own independent cTWAS run and -contributes its own row-set. +With `method = NULL` a run uses the TwasWeights' pre-combined `"ensemble"` +weights. Weights without an ensemble, and a `QtlFineMappingResult` used as +the weight source, leave the choice open, so the pipeline asks for `method`. +Each run reads one method; compare methods by running each in turn. ## Next steps diff --git a/vignettes/fine-mapping.Rmd b/vignettes/fine-mapping.Rmd index 9659955a..eb2d87e1 100644 --- a/vignettes/fine-mapping.Rmd +++ b/vignettes/fine-mapping.Rmd @@ -56,7 +56,7 @@ data( qtlDatasetExample ``` -The `*_sumstats_example` objects ship with a non-empty `qcInfo` slot so +The `*_sumstats_example` objects ship with non-empty `qcOptions()` so they bypass the `summaryStatsQc()` gate. In a real analysis you'd construct the raw `QtlSumStats` / `GwasSumStats` from your data, then run `summaryStatsQc()` to populate that slot (see the @@ -171,14 +171,17 @@ fineMappingPipeline( maxNumSingleEffects = 10L ), initializeWithSusieInf = TRUE, - naAction = "drop", # "drop" (default) or "impute" + phenotypeFilterParam = PhenotypeFilterParam(naAction = "drop"), verbose = 1 ) ``` -- `naAction` controls how phenotype NAs are handled by - `residualizedPhenotypes()`: `"drop"` removes samples with any NA across - the requested traits, `"impute"` mean-imputes each trait independently. +- `phenotypeFilterParam` is the run's phenotype QC. Its `naAction` says how + phenotype NAs are handled: `"drop"` (the default) removes samples with + any NA across the requested traits, `"impute"` mean-imputes each trait + independently. `outlierAction = "drop"` also removes samples flagged as + multivariate outliers. The QtlDataset accessors apply none of this; it + belongs to the run. - `initializeWithSusieInf = TRUE` runs SuSiE-inf first and uses its result to initialise the susie fit, which improves credible-set purity in regions with background polygenic signal. @@ -255,14 +258,18 @@ length(pipOne) The underlying SuSiE fit is available with `susieFit()` and the cross-validation record with `cvResult()`, both keyed the same way. -Range-based subsetting works directly: +Range-based subsetting uses the standard verbs: subset the collection by its +rows' analysis windows, or narrow a ranged view directly: ```{r fm-range} window <- GenomicRanges::GRanges( "chr22", IRanges::IRanges(20000000, 21000000) ) -sum(lengths(subsetRegion(fmr, window))) +# the fits whose analysis window overlaps it +nrow(fmr[IRanges::overlapsAny(genomicRegion(fmr), window)]) +# the top loci inside it +length(IRanges::subsetByOverlaps(topLoci(fmr), window)) ``` ## Calling a fitter directly diff --git a/vignettes/finemapping-postprocessing.Rmd b/vignettes/finemapping-postprocessing.Rmd index be86bfd9..925e6a97 100644 --- a/vignettes/finemapping-postprocessing.Rmd +++ b/vignettes/finemapping-postprocessing.Rmd @@ -66,12 +66,11 @@ its standard error. They are deliberately *not* called `beta`/`se`: under those names, so sharing them would let the two views be joined into a silent mix of posterior and marginal effects. -Both are on the standardized genotype scale, because the `QtlDataset` -accessors centre and scale every genotype column to unit variance before -fitting — `residualizedGenotypes()` does it, governed by -`ResidualizationParam(scaleResiduals = FALSE)` per call or the dataset's own -`scaleResiduals` slot. The published `weight_standardized` records whichever -way it resolved. +Both are on the standardized genotype scale, because residualization centres +and scales every genotype column to unit variance before fitting — +`residualizedGenotypes()` does it, unless +`ResidualizationParam(scaleResiduals = FALSE)` says otherwise. The published +`weight_standardized` records whichever way it resolved. That is what makes a posterior effect comparable with a TWAS weight from any other method — they are all on the scale of the `X` the fitter was given, and on the same scale as the LD correlations and z-scores a TWAS Z is computed @@ -211,13 +210,14 @@ When the flat tables are not enough — you want the per-effect posterior, or to re-derive PIPs under a different assumption — the underlying fit is available. -`lbf()` returns the log Bayes factors, one row per variant and one +`lbf()` returns the log Bayes factors, one range per variant and one column per single effect: ```{r lbf} lbf <- lbf(qtlFineMappingLbfExample) -unit <- lbf[lbf$trait == lbf$trait[1] & lbf$context == lbf$context[1], ] -lbfMatrix <- as.matrix(unit[, grep("^lbf_L", names(unit))]) +unit <- lbf[lbf$trait == lbf$trait[1] & lbf$context == lbf$context[1]] +effects <- as.data.frame(S4Vectors::mcols(unit)) +lbfMatrix <- as.matrix(effects[, grep("^lbf_L", names(effects))]) dim(lbfMatrix) ``` @@ -284,35 +284,37 @@ object the other helpers expect. ## Writing results out -Two generics cover every published format. `exportToVcf()` serialises a -fine-mapping result — or summary statistics, or TWAS weights — to GWAS-VCF, -the interchange format most external tools read: one record per variant, one -sample per study or fitted model, and the statistics as FORMAT fields. +Two writers cover every published format. `writeGwasVcf()` serialises a +fine-mapping result, or summary statistics, or TWAS weights, to GWAS-VCF, the +interchange format most external tools read: one record per variant, one +sample per study or fitted model, and the statistics as FORMAT fields. It +writes through VariantAnnotation, which has to be installed. ```{r vcf, eval=FALSE} -exportToVcf( +writeGwasVcf( qtlFineMappingExample, - outputPath = "finemapping.vcf.gz", + "finemapping.vcf.gz", context = "context_1" ) ``` -It needs the `VariantAnnotation` package, which is a suggested dependency -rather than a hard one. +A GWAS study fine-mapped block by block is one fit, so its blocks are written +as one sample, with a `BID` field naming each variant's block; +`splitByBlock = TRUE` writes one file per block instead. -`exportToBed()` writes the published long-format tables instead, one row per +`writeBed()` writes the published long-format tables instead, one row per published observation, bgzipped and tabix-indexed when the path ends in `.gz`: ```{r bed, eval=FALSE} # the top-loci table: the posterior view joined to the marginal one -exportToBed(qtlFineMappingExample, "top_loci.bed.gz") +writeBed(qtlFineMappingExample, "top_loci.bed.gz") # every remaining column the view carries, after the published schema -exportToBed(qtlFineMappingExample, "top_loci_full.bed.gz", columns = "all") +writeBed(qtlFineMappingExample, "top_loci_full.bed.gz", columns = "all") # the fSuSiE table: one row per (context, credible set), carrying the fitted # curve at both resolutions -- the wavelet grid and its reinterpolation onto # the trait positions. `levels` keeps only one of the two. -exportToBed(fsusieFineMappingExample, "fsusie.bed.gz", schema = "fsusie") -exportToBed(fsusieFineMappingExample, "fsusie_grid.bed.gz", +writeBed(fsusieFineMappingExample, "fsusie.bed.gz", schema = "fsusie") +writeBed(fsusieFineMappingExample, "fsusie_grid.bed.gz", schema = "fsusie", levels = "wavelet") ``` @@ -329,7 +331,10 @@ file holds. ```{r read, eval=FALSE} res <- readFineMappingResult("top_loci.bed.gz") # only the variants of one region, from a tabix-indexed file -res <- readFineMappingResult("top_loci.bed.gz", region = "chr22:32e6-33e6") +res <- readFineMappingResult( + "top_loci.bed.gz", + which = GenomicRanges::GRanges("chr22:32000000-33000000") +) ``` It requires almost nothing: coordinate-encoding variant ids and a `PIP`. diff --git a/vignettes/heritability.Rmd b/vignettes/heritability.Rmd index 4e2d93c6..fae834df 100644 --- a/vignettes/heritability.Rmd +++ b/vignettes/heritability.Rmd @@ -162,7 +162,7 @@ data. This reference's `r ldPanelNSamples(ldEigenExample)` people are plenty: even at `N = 1e5` HDL recovers about 0.40 for a true 0.4. Against a 1,000-person panel at that `N` it drifts to about 0.57 and warns that the fit sits on a bound. If HDL disagrees sharply with the others, check for that -warning and compare `nSamples()` against `ldPanelNSamples()`. +warning and compare `sampleSize()` against `ldPanelNSamples()`. A standard error of zero, or an estimate pinned at a boundary, almost always means the reference is too small rather than that the trait has no @@ -178,7 +178,7 @@ to cut it into, or one `LdMatrix` per block. One block has no jackknife. ```{r build-ref, eval=FALSE} panel <- readGenotypes(plink2Prefix = "/path/to/reference.chr22") -blocks <- read.delim("/path/to/ld_blocks.tsv") # chrom, start, end +blocks <- "/path/to/ld_blocks.bed" # a BED file, or a GRanges ldEigen <- buildLdEigen(panel, ldBlocks = blocks, genome = "hg38") ldScore <- buildLdScore(panel, ldBlocks = blocks, genome = "hg38") diff --git a/vignettes/ld-infrastructure.Rmd b/vignettes/ld-infrastructure.Rmd index f387ff3b..1d3f7a13 100644 --- a/vignettes/ld-infrastructure.Rmd +++ b/vignettes/ld-infrastructure.Rmd @@ -85,8 +85,8 @@ dim(R) A panel can also be reached through an LD meta file: one row per chromosome or block, giving its coordinates and the genotype files behind it, with -paths relative to the meta file. `readGenotypes(ldMeta = , region = )` opens -the row covering a region. +paths relative to the meta file. `readGenotypes(ldMeta = , block = )` opens +the whole block whose row covers the window. ### An LdMatrix diff --git a/vignettes/rss-qc.Rmd b/vignettes/rss-qc.Rmd index 1fcad17b..b6dde813 100644 --- a/vignettes/rss-qc.Rmd +++ b/vignettes/rss-qc.Rmd @@ -36,10 +36,10 @@ table to an LD reference panel. Two are frequently encountered in practice: The `summaryStatsQc()` function provides a convenient interface to performing many QC tasks to address these issues. It takes a `GwasSumStats` or `QtlSumStats` object (see the *Building QtlSumStats and GwasSumStats objects* -vignette), and returns a new collection of the same class with updated entries -and a populated `qcInfo` slot. Downstream pipelines require the `qcInfo` to be -populated, so QC is mandatory before fine-mapping, TWAS-weight learning, -colocalization, etc. +vignette), and returns a new collection of the same class with updated entries, +the options it ran with recorded in `qcOptions()`, and what it did to each row +in `qcInfo()`. Downstream pipelines require `qcOptions()` to be filled, so QC is +mandatory before fine-mapping, TWAS-weight learning, colocalization, etc. ```{r load-packages} library(pecotmr) @@ -75,15 +75,13 @@ gws_qcd <- summaryStatsQc( ``` `gws_qc` is a new `GwasSumStats` of the same class, with cleaned -entries and a populated `qcInfo` slot. The per-entry audit record is -accessible via `qcInfo()`: +entries. What QC did to each row is a table, `qcInfo()`, and the options it ran +with are `qcOptions()`: ```{r inspect-qcinfo, eval=FALSE} -qc <- qcInfo(gws_qcd) -str(qc$entryAudit[[1]]) # per-entry counts: variantsIn, mungeSumstatsDropped, -# keepVariantsDropped, skipRegionDropped, matchedAgainstLdReference, -# krigingOutliersDropped, ldMismatchOutliersDropped, ... -qc$options # the curated knobs you passed (frozen for provenance) +qcInfo(gws_qcd) # one row per tuple: variantsIn, matchedAgainstLdReference, +# krigingOutliersDropped, ldMismatchOutliersDropped, ..., variantsOut +qcOptions(gws_qcd)$options # the knobs you passed, kept for provenance ``` A non-zero `mafCutoff` requires every entry to carry a `MAF` mcol; non-zero @@ -193,7 +191,7 @@ It uses `susieR`'s kriging RSS diagnostic: ~`N(0, 1)` when the z-scores and LD panel agree. A large residual flags an allele-flip / LD-mismatch outlier; variants below a two-sided p-value threshold (default `5e-8`) are dropped. The number removed is recorded in - the `qcInfo` audit as `krigingOutliersDropped`. + the `qcInfo()` table as `krigingOutliersDropped`. Because it needs a per-region LD matrix and the kriging diagnostic, this is an **RSS-only** check: it draws `R` from each row's LD reference and diff --git a/vignettes/twas-weights.Rmd b/vignettes/twas-weights.Rmd index e732a51d..667846b3 100644 --- a/vignettes/twas-weights.Rmd +++ b/vignettes/twas-weights.Rmd @@ -33,9 +33,9 @@ by `(study, context, trait, method)`, one element per tuple). | Input class | Methods supported | |---|---| -| `QtlDataset` | Univariate: LASSO, elastic net, mr.ash, MCP, SCAD, L0Learn, Bayesian alphabet, DPR. Multivariate: mr.mash, mvsusie | +| `QtlDataset` | Univariate: LASSO, elastic net, ridge, mr.ash, MCP, SCAD, L0Learn, Bayesian alphabet, DPR. Multivariate: mr.mash, mvsusie | | `MultiStudyQtlDataset` | Iterates over embedded studies; same methods as `QtlDataset` | -| `QtlSumStats` | RSS-only: LASSO, mr.ash, MCP, SCAD, L0Learn, DPR, PRS-CS, P+T. Multivariate: mr.mash, mvsusie | +| `QtlSumStats` | RSS-only: LASSO, elastic net, ridge, mr.ash, MCP, SCAD, L0Learn, DPR, PRS-CS, P+T. Multivariate: mr.mash, mvsusie | ```{r load-packages} library(pecotmr) @@ -238,7 +238,7 @@ The families, and the `methods =` name each answers to: | Family | `methods =` | Function | |---|---|---| -| Penalized regression | `lasso`, `enet`, `mcp`, `scad`, `l0learn` | `lassoWeights()`, `enetWeights()`, … | +| Penalized regression | `lasso`, `enet`, `ridge`, `mcp`, `scad`, `l0learn` | `lassoWeights()`, `enetWeights()`, `ridgeWeights()`, … | | Bayesian alphabet | `bayesA` … `bayesR`, `bLasso` | `bayesAWeights()`, `bLassoWeights()`, … | | Dirichlet process regression | `dprVb`, `dprGibbs`, `dprAdaptiveGibbs` | `dprVbWeights()`, `dprGibbsWeights()`, … | | PRS-CS | `prsCs` (sumstats input only) | `prsCsWeights()` | @@ -251,9 +251,11 @@ of known tokens. Most families have an RSS counterpart taking summary statistics and an LD reference instead of `X`/`y` — `lassosumRssWeights()` for `lasso`, +`enetRssWeights()` and `ridgeRssWeights()` for `enet` and `ridge`, `mcpRssWeights()`, `sdprWeights()` (SDPR) for `dprGibbs`, `susieRssWeights()`, -and so on; the Bayesian alphabet, `enet`, `dprVb` and `dprAdaptiveGibbs` have -none. Those are what `twasWeightsPipeline()` calls when the input is a +and so on; the Bayesian alphabet, `dprVb` and `dprAdaptiveGibbs` have none. +`enet` mixes the lasso and ridge penalties at `alpha = 0.5` on either input; +`methods = list(enet = list(alpha = 0.3))` sets another mixing. Those are what `twasWeightsPipeline()` calls when the input is a `QtlSumStats`. The LD reference is the same `ldReference` the rest of the package takes: a genotype panel from `readGenotypes()`, a `GenotypeMixture` or an @@ -325,11 +327,12 @@ twasWeightsPipeline( methods = "susie", contexts = "brain", traitId = "ENSG_example", - region = "chr22:25000000-26000000", cisWindow = 5e5, + # or, in place of traitId + cisWindow, a literal window: + # region = GenomicRanges::GRanges("chr22:25000000-26000000"), crossValidationParam = CrossValidationParam( folds = 5, - numThreads = 1, + BPPARAM = BiocParallel::SerialParam(), samplePartition = NULL, maxVariants = -1 ), @@ -347,14 +350,14 @@ twasWeightsPipeline( genotypeCovariates = NULL ), weightsDataType = NULL, - naAction = "drop" + phenotypeFilterParam = PhenotypeFilterParam(naAction = "drop") ) ``` - `EnsembleParam(enabled = TRUE)` adds an additional `ensembleWeights` row to the collection — a weighted combination of the individual methods' CV predictions, filtered by that bundle's `r2Threshold`. -- `naAction` is forwarded to `residualizedPhenotypes()` (see the +- `phenotypeFilterParam` is the run's phenotype QC (see the [fine-mapping vignette](fine-mapping.html#common-parameters) for semantics). @@ -395,9 +398,9 @@ do.call(weightsDataType, c(list(tw), key)) # tag carried through for reporting `weightStandardized()` is `TRUE` for anything the pipeline fitted: genotypes are centred and scaled to unit variance before every method runs, so all the -weights are on one scale. That scaling lives in the `QtlDataset` accessors, -not in the pipeline — `ResidualizationParam(scaleResiduals = FALSE)` opts out -per call, and the dataset's own `scaleResiduals` slot is the default — so the +weights are on one scale. That scaling is part of residualization — +`ResidualizationParam(scaleResiduals = FALSE)` opts out, and it is on by +default — so the recorded flag reports what was done rather than what you claimed. That is not bookkeeping. Every method here returns coefficients on the scale of the `X` it was handed — exactly so for glmnet, ncvreg, L0Learn, mr.ash, the Bayesian alphabet and `susieWeights()` — while @@ -417,16 +420,16 @@ is the form the downstream TWAS and MR steps consume. ## Publishing the weights -The same two generics that export fine-mapping results export weights. -`exportToVcf()` writes a GWAS-VCF-style file: one record per variant, one +The same two writers that write fine-mapping results write weights. +`writeGwasVcf()` writes a GWAS-VCF-style file: one record per variant, one sample per fitted model, the weight in the `WGT` FORMAT field, and each -model's identity in its own `##SAMPLE` header line. `exportToBed()` writes the +model's identity in its own `##SAMPLE` header line. `writeBed()` writes the same thing as a long table, one row per (variant, model). -```{r tw-export, eval=FALSE} -exportToVcf(tw, "weights.vcf.gz") -exportToVcf(tw, "lasso_weights.vcf.gz", method = "lasso") # one model -exportToBed(tw, "weights.bed.gz") +```{r tw-write, eval=FALSE} +writeGwasVcf(tw, "weights.vcf.gz") +writeGwasVcf(tw, "lasso_weights.vcf.gz", method = "lasso") # one model +writeBed(tw, "weights.bed.gz") ``` Both export the **full-data fit only**, and refuse an object that has none — @@ -453,7 +456,10 @@ and the credible sets. Selecting only such a method, as in ```{r tw-read, eval=FALSE} tw <- readTwasWeights("weights.bed.gz") -tw <- readTwasWeights("weights.bed.gz", region = "chr22:10e6-19e6") +tw <- readTwasWeights( + "weights.bed.gz", + which = GenomicRanges::GRanges("chr22:10000000-19000000") +) ``` A weight is all it requires, so a table converted from another tool reads with diff --git a/vignettes/xqtl-enrichment.Rmd b/vignettes/xqtl-enrichment.Rmd index 9385aa81..090879d3 100644 --- a/vignettes/xqtl-enrichment.Rmd +++ b/vignettes/xqtl-enrichment.Rmd @@ -82,9 +82,11 @@ par(op) ## Perform enrichment analysis `qtlEnrichmentPipeline()` takes the two fine-mapping collections directly and -estimates, for every `(gwasStudy, qtlStudy, qtlContext)` combination, how -enriched the molecular QTLs are among the GWAS causal variants. The GWAS -collection must be RSS-derived (every row carries an LD reference); +estimates, for every combination of GWAS fit `(gwasStudy, gwasMethod)` and QTL +unit `(qtlStudy, qtlContext, qtlMethod)`, how enriched the molecular QTLs are +among the GWAS causal variants. Each fine-mapping method is its own fit: a +GWAS study fine-mapped with two methods gives two PIP vectors, never one. The +GWAS collection must be RSS-derived (every row carries an LD reference); `gwasFineMappingExample` already does. ```{r enrichment} @@ -96,12 +98,11 @@ enrich_res <- qtlEnrichmentPipeline( enrich_res ``` -The result is a data frame with one row per -`(gwasStudy, qtlStudy, qtlContext)` combination, giving the enrichment estimate -(`enrichment`), its standard error (`enrichmentSe`), and the log-odds -(`enrichmentLogOdds`). These enrichment priors can then be supplied to a -colocalization analysis. This synthetic single-region example is for -illustration only; stable enrichment estimates require many fine-mapped +The result is a data frame with one row per such combination, giving the +enrichment estimate (`enrichment`), its standard error (`enrichmentSe`), and +the log-odds (`enrichmentLogOdds`). These enrichment priors can then be +supplied to a colocalization analysis. This synthetic single-region example is +for illustration only; stable enrichment estimates require many fine-mapped regions. ## Session information From 048e57dcdd4a42f5ffd4f6c7aca077d48f17f4ea Mon Sep 17 00:00:00 2001 From: Daniel Nachun Date: Mon, 26 Oct 2026 23:45:06 -0700 Subject: [PATCH 3/5] PlinkMatrix cleanup --- R/GenotypeDosageSeed.R | 4 ++ R/crossValidation.R | 84 ++++++++++++------------ R/fineMappingWrappers.R | 2 - man/buildMvsusieMixturePrior.Rd | 2 - vignettes/constructing-qtl-datasets.Rmd | 10 ++- vignettes/ctwas-pipeline.Rmd | 14 ++-- vignettes/fine-mapping.Rmd | 12 ++-- vignettes/finemapping-postprocessing.Rmd | 20 +++--- vignettes/heritability.Rmd | 2 +- vignettes/ld-infrastructure.Rmd | 4 +- vignettes/mash-pipeline.Rmd | 10 +-- vignettes/twas-weights.Rmd | 44 +++++++------ 12 files changed, 109 insertions(+), 99 deletions(-) diff --git a/R/GenotypeDosageSeed.R b/R/GenotypeDosageSeed.R index 1cb58798..24b819aa 100644 --- a/R/GenotypeDosageSeed.R +++ b/R/GenotypeDosageSeed.R @@ -372,8 +372,12 @@ setMethod("extract_array", "GenotypeDosageSeed", function(x, index) { # pecotmr counts it -- with NA for a missing call. It is not told the sample # count: it counts the .fam itself, and a wrong count would misread silently. # The stem may be a bundled example's portable reference, resolved here. +# PlinkMatrix is checked for here too, not only when the panel is built: a +# panel loaded from a saved object, such as the bundled examples, was built +# elsewhere. # @noRd .plinkBedSeedRead <- function(x, rows, samples) { + .requireReaderPackage("PlinkMatrix", "PLINK1") variant <- start(.gdSeedRecords(x))[.gdSeedRowRecord(x)[rows]] PlinkMatrix::read_bed_subset( .resolveGenotypeResourcePath(.gdSeedBackend(x)), diff --git a/R/crossValidation.R b/R/crossValidation.R index 8d8c4834..13e66390 100644 --- a/R/crossValidation.R +++ b/R/crossValidation.R @@ -586,6 +586,48 @@ NULL ) } +# ============================================================================= +# Cross-validation settings +# ----------------------------------------------------------------------------- +# One bundle for both fineMappingPipeline() and twasWeightsPipeline(). The two +# had drifted on a setting that means the same thing in each: `cvFolds` +# defaulted to 0 in fine-mapping and 5 in TWAS. Folding them into one +# constructor is the rule the joint specification already follows. +# +# `folds` is 0 everywhere. twasWeightsPipeline used to default to 5, so the +# two pipelines disagreed on what an unspecified `cvFolds` meant; converging +# on "off unless asked" makes one bundle mean one thing. The knock-on is that +# the SR-TWAS ensemble, which needs out-of-fold predictions, no longer runs by +# default -- so `EnsembleParam(enabled =)` defaults to FALSE too, and asking +# for an ensemble +# without folds is an error rather than a silently missing row. +# +# `fitFullData` means the same thing in both pipelines: keep only the +# cross-validation results, skipping the full-data fit. +# +# Two of the six fields are honoured by twasWeightsPipeline() only, and are +# IGNORED rather than rejected by fineMappingPipeline() -- one bundle the +# caller can hand to either pipeline without rewriting it: +# +# weightMethods -- selects among TWAS *weight* methods, matching tokens like +# `lasso` / `mrmash` and their `_weights` spellings. Fine mapping's +# `methods=` are fine-mapping methods and its CV refits all of them, so +# there is no weight-method set to select from. It is also the knob that +# decides whether .jointTwasCvBlocked() reaches back for a fold's +# fine-mapping fit -- a TWAS-to-fine-mapping handoff with no counterpart +# in the other direction. +# maxVariants -- caps the CV design matrix for twasWeightsCv(). Fine mapping +# does not use that engine; .fmWeightsCv() has its own loop and only +# mirrors twasWeightsCv()'s output shape. +# +# Both are documented as TWAS-only so the silence is stated, not discovered. +# +# `seed` is not here either. It seeds the whole call in both pipelines +# (fine-mapping wraps the call in withr::local_seed; TWAS also seeds the +# BiocParallel RNG for method fitting), so it is a call-level knob that CV +# happens to benefit from, not a CV setting. +# ============================================================================= + #' @rdname CrossValidationParam #' @aliases CrossValidationParam-class #' @importClassesFrom BiocParallel BiocParallelParam @@ -746,45 +788,3 @@ CrossValidationParam <- function( # folds = 0 (or 1) is the no-op default. !(length(x) == 1L && !is.na(x) && is.numeric(x) && (x == 0 || x == 1)) } - -# ============================================================================= -# Cross-validation settings -# ----------------------------------------------------------------------------- -# One bundle for both fineMappingPipeline() and twasWeightsPipeline(). The two -# had drifted on a setting that means the same thing in each: `cvFolds` -# defaulted to 0 in fine-mapping and 5 in TWAS. Folding them into one -# constructor is the rule the joint specification already follows. -# -# `folds` is 0 everywhere. twasWeightsPipeline used to default to 5, so the -# two pipelines disagreed on what an unspecified `cvFolds` meant; converging -# on "off unless asked" makes one bundle mean one thing. The knock-on is that -# the SR-TWAS ensemble, which needs out-of-fold predictions, no longer runs by -# default -- so `EnsembleParam(enabled =)` defaults to FALSE too, and asking -# for an ensemble -# without folds is an error rather than a silently missing row. -# -# `fitFullData` means the same thing in both pipelines: keep only the -# cross-validation results, skipping the full-data fit. -# -# Two of the six fields are honoured by twasWeightsPipeline() only, and are -# IGNORED rather than rejected by fineMappingPipeline() -- one bundle the -# caller can hand to either pipeline without rewriting it: -# -# weightMethods -- selects among TWAS *weight* methods, matching tokens like -# `lasso` / `mrmash` and their `_weights` spellings. Fine mapping's -# `methods=` are fine-mapping methods and its CV refits all of them, so -# there is no weight-method set to select from. It is also the knob that -# decides whether .jointTwasCvBlocked() reaches back for a fold's -# fine-mapping fit -- a TWAS-to-fine-mapping handoff with no counterpart -# in the other direction. -# maxVariants -- caps the CV design matrix for twasWeightsCv(). Fine mapping -# does not use that engine; .fmWeightsCv() has its own loop and only -# mirrors twasWeightsCv()'s output shape. -# -# Both are documented as TWAS-only so the silence is stated, not discovered. -# -# `seed` is not here either. It seeds the whole call in both pipelines -# (fine-mapping wraps the call in withr::local_seed; TWAS also seeds the -# BiocParallel RNG for method fitting), so it is a call-level knob that CV -# happens to benefit from, not a CV setting. -# ============================================================================= diff --git a/R/fineMappingWrappers.R b/R/fineMappingWrappers.R index 83e5f1da..784930ca 100644 --- a/R/fineMappingWrappers.R +++ b/R/fineMappingWrappers.R @@ -2933,10 +2933,8 @@ MvsusieMixturePriorOptions <- function(...) { #' ready to pass as \code{prior_variance} to \code{\link{fitMvsusie}} or #' \code{\link{fitMvsusieRss}}. #' @examples -#' \donttest{ #' # Canonical uniform mixture over two named conditions. #' buildMvsusieMixturePrior(conditionNames = c("brain", "blood")) -#' } #' @importFrom checkmate assertCount #' @export buildMvsusieMixturePrior <- function( diff --git a/man/buildMvsusieMixturePrior.Rd b/man/buildMvsusieMixturePrior.Rd index e40e6e84..63241fbb 100644 --- a/man/buildMvsusieMixturePrior.Rd +++ b/man/buildMvsusieMixturePrior.Rd @@ -57,8 +57,6 @@ mr.mash covariances --- or leave it NULL for the canonical uniform mixture over \code{R} conditions. } \examples{ -\donttest{ # Canonical uniform mixture over two named conditions. buildMvsusieMixturePrior(conditionNames = c("brain", "blood")) } -} diff --git a/vignettes/constructing-qtl-datasets.Rmd b/vignettes/constructing-qtl-datasets.Rmd index 7c83fbab..6a669004 100644 --- a/vignettes/constructing-qtl-datasets.Rmd +++ b/vignettes/constructing-qtl-datasets.Rmd @@ -17,6 +17,8 @@ knitr::opts_chunk$set( fig.width = 7, fig.height = 4.5 ) +hasRelatednessQc <- requireNamespace("plinkQC", quietly = TRUE) && + requireNamespace("igraph", quietly = TRUE) ``` ## Overview @@ -288,7 +290,7 @@ dataset is built — the pipelines do not model it. `filterRelatedness()` takes a kinship table — one row per pair, the shape PLINK's `--genome` or KING emits — and returns the individuals to **drop**: -```{r relatedness, eval = requireNamespace("plinkQC", quietly = TRUE) && requireNamespace("igraph", quietly = TRUE)} +```{r relatedness, eval = hasRelatednessQc} relatedness <- data.frame( IID1 = c(samples[1], samples[3], samples[5]), IID2 = c(samples[2], samples[4], samples[6]), @@ -312,7 +314,11 @@ is described with `RelatednessColumnsParam()`: ```r filterRelatedness( relatedness, - columns = RelatednessColumnsParam(iid1 = "ID1", iid2 = "ID2", value = "KINSHIP") + columns = RelatednessColumnsParam( + iid1 = "ID1", + iid2 = "ID2", + value = "KINSHIP" + ) ) ``` diff --git a/vignettes/ctwas-pipeline.Rmd b/vignettes/ctwas-pipeline.Rmd index aee0f94d..8adb7071 100644 --- a/vignettes/ctwas-pipeline.Rmd +++ b/vignettes/ctwas-pipeline.Rmd @@ -130,18 +130,18 @@ should carry into a real analysis: - `thin = 1` keeps every SNP (production runs thin to `0.1`). - `niterPrefit` / `niter` are cut to keep the vignette fast. - `min_nonSNP_PIP = 0` disables region screening. The bundled GWAS has no - genome-wide-significant signal, so the default (`0.5`) selects no region at - all and the result comes back empty. On real data, leave it alone. + genome-wide-significant signal, so the default (`0.5`) selects no region at + all and the result comes back empty. On real data, leave it alone. - `fallbackToPrefit = TRUE` recovers from the accurate-EM step returning - `NaN` on underpowered data by keeping the prefit estimates. + `NaN` on underpowered data by keeping the prefit estimates. ## Where genes come from `twasWeights` accepts two shapes: - a **flat** `TwasWeights` or `QtlFineMappingResult` (or a homogeneous list - of them) carrying `region` provenance. Each gene is assigned to its home - LD block by `start(region)`, matching cTWAS's own placement rule. + of them) carrying `region` provenance. Each gene is assigned to its home + LD block by `start(region)`, matching cTWAS's own placement rule. - a **pre-bucketed named list** keyed by `region_id`, used as-is. Blocks with no gene weights still contribute their SNP-level signal to the @@ -346,9 +346,9 @@ Each run reads one method; compare methods by running each in turn. - [TWAS weights](twas-weights.html) — training the weights cTWAS consumes. - [TWAS Z-scores and MR](twas-zscore.html) — the per-gene Z that - `twasZ` optionally supplies here. + `twasZ` optionally supplies here. - [QC for summary statistics](rss-qc.html) — `summaryStatsQc()`, which - `gwasSumStats` must have been through. + `gwasSumStats` must have been through. # Session info diff --git a/vignettes/fine-mapping.Rmd b/vignettes/fine-mapping.Rmd index eb2d87e1..55b37ae4 100644 --- a/vignettes/fine-mapping.Rmd +++ b/vignettes/fine-mapping.Rmd @@ -293,13 +293,13 @@ rather than the coefficients. Two are worth calling out: - `fsusieWrapper()` wraps `fitFsusie()` with the credible-band and - affected-region post-processing, and `fsusieGetCs()`, - `fsusieCredibleBand()` and `fsusieAffectedRegions()` read those out. - fSuSiE needs a *functional* phenotype — a curve per sample, not a scalar — - so it does not accept the same `Y` the other methods do. + affected-region post-processing, and `fsusieGetCs()`, + `fsusieCredibleBand()` and `fsusieAffectedRegions()` read those out. + fSuSiE needs a *functional* phenotype — a curve per sample, not a scalar — + so it does not accept the same `Y` the other methods do. - `fitSusieInfThenSusieRss()` chains the two: `susie_inf` first to estimate - the infinitesimal component, then SuSiE-RSS on the residual signal. That - is what `methods = "susieInf"` runs on summary statistics. + the infinitesimal component, then SuSiE-RSS on the residual signal. That + is what `methods = "susieInf"` runs on summary statistics. ## Next steps diff --git a/vignettes/finemapping-postprocessing.Rmd b/vignettes/finemapping-postprocessing.Rmd index 925e6a97..cb018e71 100644 --- a/vignettes/finemapping-postprocessing.Rmd +++ b/vignettes/finemapping-postprocessing.Rmd @@ -258,10 +258,10 @@ The summaries above are not stored by the fitter — they are derived from the raw SuSiE fit by a short chain that `fineMappingPipeline()` runs for you: ``` -postprocessFinemappingFits() # per-method fits -> a post object - -> computeCsTables() # credible sets from alpha, with purity - -> buildTopLoci() # the flat one-row-per-variant table - -> formatFinemappingOutput() # assemble the result payload +postprocessFinemappingFits() # per-method fits -> a post object + -> computeCsTables() # credible sets from alpha, with purity + -> buildTopLoci() # the flat one-row-per-variant table + -> formatFinemappingOutput() # assemble the result payload ``` Call them directly when you have SuSiE fits from elsewhere and want @@ -274,10 +274,10 @@ Two smaller extractors sit at the row level and are what `credibleSetSummary()` is assembled from: - `extractCsInfo(fmRow, csNames, topLociTable, ldSource)` — per-credible-set - detail for one result row, including the between-variant correlations that - give `purity_min`, which is why it needs an `ldSource`. + detail for one result row, including the between-variant correlations that + give `purity_min`, which is why it needs an `ldSource`. - `extractTopPipInfo(fmRow, sumstats)` — the lead variant and its statistics, - joined against summary statistics. + joined against summary statistics. `susieResult()` unwraps a per-condition fit list into the single SuSiE object the other helpers expect. @@ -359,11 +359,11 @@ which is why both schemas publish it as `WGT`. ## Next steps - [Fine-mapping](fine-mapping.html) — producing the results this vignette - consumes. + consumes. - [Colocalization](coloc-pipeline.html) — the model that answers whether an - overlap reflects a shared causal variant. + overlap reflects a shared causal variant. - [TWAS weights](twas-weights.html) — reusing a fine-mapping fit as a weight - method. + method. # Session info diff --git a/vignettes/heritability.Rmd b/vignettes/heritability.Rmd index fae834df..8b6b78d5 100644 --- a/vignettes/heritability.Rmd +++ b/vignettes/heritability.Rmd @@ -391,7 +391,7 @@ names(h2EstimateToSldscTrait(strat)) ## Next steps - [Molecular QTL enrichment](xqtl-enrichment.html) — the complementary - per-variant QTL/GWAS enrichment analysis. + per-variant QTL/GWAS enrichment analysis. - [QC for summary statistics](rss-qc.html) — preparing the GWAS side. # Session info diff --git a/vignettes/ld-infrastructure.Rmd b/vignettes/ld-infrastructure.Rmd index 1d3f7a13..a018cc3e 100644 --- a/vignettes/ld-infrastructure.Rmd +++ b/vignettes/ld-infrastructure.Rmd @@ -273,9 +273,9 @@ covered in the [QC vignette](rss-qc.html), where the motivation lives. - [QC for summary statistics](rss-qc.html) — matching statistics to a panel. - [Heritability](heritability.html) — `buildLdEigen()` / `buildLdScore()` - turn per-block LD into the statistics the h2 estimators consume. + turn per-block LD into the statistics the h2 estimators consume. - [Fine-mapping](fine-mapping.html) and [TWAS weights](twas-weights.html) — - the RSS methods that consume LD. + the RSS methods that consume LD. # Session info diff --git a/vignettes/mash-pipeline.Rmd b/vignettes/mash-pipeline.Rmd index b894f71a..6ddd4129 100644 --- a/vignettes/mash-pipeline.Rmd +++ b/vignettes/mash-pipeline.Rmd @@ -298,9 +298,9 @@ strong credible set should not carry a condition on its own. The contrast design itself is built from `makePairwiseContrastCol()`, which sets +1 and −1 for a pair of conditions in a zero vector, and -`fitMashContrast()`, which fits one feature's contrast. `mashPosteriorContrast()` -calls both across all features and pairs, so you only need them directly when -building a non-pairwise design. +`fitMashContrast()`, which fits one feature's contrast. +`mashPosteriorContrast()` calls both across all features and pairs, so you only +need them directly when building a non-pairwise design. ## Utilities @@ -320,9 +320,9 @@ The mash track ships a set of helpers for getting real data into shape: ## Next steps - [Building QtlSumStats objects](constructing-sumstats.html) — assembling - the multi-context input. + the multi-context input. - [TWAS weights](twas-weights.html) — where a mash prior is consumed, via - `MashPrior` and mr.mash. + `MashPrior` and mr.mash. # Session info diff --git a/vignettes/twas-weights.Rmd b/vignettes/twas-weights.Rmd index 667846b3..29b38697 100644 --- a/vignettes/twas-weights.Rmd +++ b/vignettes/twas-weights.Rmd @@ -255,15 +255,14 @@ reference instead of `X`/`y` — `lassosumRssWeights()` for `lasso`, `mcpRssWeights()`, `sdprWeights()` (SDPR) for `dprGibbs`, `susieRssWeights()`, and so on; the Bayesian alphabet, `dprVb` and `dprAdaptiveGibbs` have none. `enet` mixes the lasso and ridge penalties at `alpha = 0.5` on either input; -`methods = list(enet = list(alpha = 0.3))` sets another mixing. Those are what `twasWeightsPipeline()` calls when the input is a -`QtlSumStats`. The LD -reference is the same `ldReference` the rest of the package takes: a -genotype panel from `readGenotypes()`, a `GenotypeMixture` or an -`LdMatrix`, matched to the statistics by their `variantNames`. lassosum, -the penalized methods, PRS-CS and SDPR use a genotype reference through its -standardized genotypes without forming the LD matrix; the mr.ash and -mr.mash engines take the matrix, which is formed over the statistics' -variants. +`methods = list(enet = list(alpha = 0.3))` sets another mixing. Those are what +`twasWeightsPipeline()` calls when the input is a `QtlSumStats`. The LD +reference is the same `ldReference` the rest of the package takes: a genotype +panel from `readGenotypes()`, a `GenotypeMixture` or an `LdMatrix`, matched to +the statistics by their `variantNames`. lassosum, the penalized methods, PRS-CS +and SDPR use a genotype reference through its standardized genotypes without +forming the LD matrix; the mr.ash and mr.mash engines take the matrix, which is +formed over the statistics' variants. Several of these engines estimate more than the weights, and `fitRetention = "slim"` keeps it as the `"fit"` attribute of the weights they @@ -400,15 +399,15 @@ do.call(weightsDataType, c(list(tw), key)) # tag carried through for reporting are centred and scaled to unit variance before every method runs, so all the weights are on one scale. That scaling is part of residualization — `ResidualizationParam(scaleResiduals = FALSE)` opts out, and it is on by -default — so the -recorded flag reports what was done rather than what you claimed. That is not bookkeeping. Every method here returns -coefficients on the scale of the `X` it was handed — exactly so for glmnet, -ncvreg, L0Learn, mr.ash, the Bayesian alphabet and `susieWeights()` — while -the DPR samplers are not even scale-equivariant, so rescaling `X` changes -their fit rather than just its units. Standardizing up front removes the -question, and lands on the scale the LD correlations and z-scores behind a -TWAS Z already use. `learnTwasWeights()` still takes `weightStandardized`, -because there you supply `X` yourself. +default — so the recorded flag reports what was done rather than what you +claimed. That is not bookkeeping. Every method here returns coefficients on the +scale of the `X` it was handed — exactly so for glmnet, ncvreg, L0Learn, +mr.ash, the Bayesian alphabet and `susieWeights()` — while the DPR samplers are +not even scale-equivariant, so rescaling `X` changes their fit rather than just +its units. Standardizing up front removes the question, and lands on the scale +the LD correlations and z-scores behind a TWAS Z already use. +`learnTwasWeights()` still takes `weightStandardized`, because there you supply +`X` yourself. `weights()` returns a named numeric vector for univariate methods and a matrix for multivariate ones. The remaining payloads are keyed the same way: @@ -440,8 +439,13 @@ For the same reason neither exporter writes CV metrics. Those stay on the object: ```{r tw-cv, eval=FALSE} -cv <- cvResult(tw, studyName = "s1", context = "brain", trait = "g1", - method = "susie") +cv <- cvResult( + tw, + studyName = "s1", + context = "brain", + trait = "g1", + method = "susie" +) cv$performance # per-method metric matrix: corr, rsq, adj_rsq, pval, RMSE, MAE ``` From 7335622b551c6e83687f0bc24f036392c804d235 Mon Sep 17 00:00:00 2001 From: Daniel Nachun Date: Tue, 27 Oct 2026 11:29:13 -0700 Subject: [PATCH 4/5] more colocboost fixes --- NAMESPACE | 1 + R/AllClasses.R | 39 +++- R/ColocBoostResult.R | 27 ++- R/H2Estimate.R | 30 +++ R/LdStatistic.R | 26 +++ R/QtlDataset.R | 30 ++- R/RangedTupleList.R | 66 ++++++- R/colocboostPipeline.R | 240 ++++++++--------------- R/genotypeIo.R | 112 +++++++++++ R/ld.R | 63 ++++-- R/twasWeights.R | 11 +- inst/scripts/build_examples.R | 72 +++---- man/colocboostPipeline.Rd | 47 ++--- man/updateObject-methods.Rd | 53 ++++- tests/testthat/helper-savedObjects.R | 69 +++++++ tests/testthat/test_AllClasses.R | 42 ++++ tests/testthat/test_ColocBoostResult.R | 3 + tests/testthat/test_H2Estimate.R | 32 +++ tests/testthat/test_LdStatistic.R | 20 ++ tests/testthat/test_QtlDataset.R | 35 ++++ tests/testthat/test_RangedTupleList.R | 68 +++++-- tests/testthat/test_colocboostPipeline.R | 118 +++++------ tests/testthat/test_genotypeIo.R | 106 ++++++++++ tests/testthat/test_twasWeights.R | 14 ++ vignettes/colocboost-pipeline.Rmd | 23 +-- 25 files changed, 983 insertions(+), 364 deletions(-) create mode 100644 tests/testthat/helper-savedObjects.R diff --git a/NAMESPACE b/NAMESPACE index 0ff65792..73488ae1 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -769,6 +769,7 @@ importFrom(purrr, possibly, pwalk, reduce, + reduce2, set_names, walk, walk2, diff --git a/R/AllClasses.R b/R/AllClasses.R index 8364acfd..f3162612 100644 --- a/R/AllClasses.R +++ b/R/AllClasses.R @@ -397,7 +397,9 @@ setMethod( # collection held its whole QC record in a `qcInfo` slot: the options, and # under `entryAudit` one audit per row. An object saved then still carries # that slot as an attribute; it is split into the `qcOptions` slot and the -# `qcAudit` column. +# `qcAudit` column. An object older still held its genome build in a +# `genome` slot (.ssMigrateGenome()). An object that old needs the updates +# every collection shares too, so the inherited update runs either way. #' @rdname updateObject-methods #' @export setMethod( @@ -408,13 +410,31 @@ setMethod( message(str_c("updateObject(object = '", class(object)[[1L]], "')")) } old <- attr(object, "qcInfo", exact = TRUE) - if (is.null(old)) { - return(methods::callNextMethod(object, ..., verbose = verbose)) + if (!is.null(old)) { + object <- .ssMigrateQcInfo(object, old) } - .ssMigrateQcInfo(object, old) + methods::callNextMethod( + .ssMigrateGenome(object), + ..., + verbose = verbose + ) } ) +# Before the genome build moved into seqinfo(), summary statistics held it +# in a `genome` slot; an object saved then still carries it as an +# attribute, and it becomes the build seqinfo() names (none, when the slot +# was left empty). +# @noRd +.ssMigrateGenome <- function(object) { + build <- attr(object, "genome", exact = TRUE) + if (is.null(build)) { + return(object) + } + attr(object, "genome") <- NULL + .withGenome(object, build[1L]) +} + # @noRd .ssMigrateQcInfo <- function(object, old) { attr(object, "qcInfo") <- NULL @@ -1418,7 +1438,8 @@ setMethod( # had no `fitVariants` column. A fine-mapping fit names its own variants, so # each row's are read off it; a row whose fit names none (a # cross-validation-only row, or an unnamed fit) records what it holds, and a -# row with no fit records none. +# row with no fit records none. The inherited update runs either way, for +# the updates every collection shares. #' @rdname updateObject-methods #' @export setMethod( @@ -1428,11 +1449,11 @@ setMethod( if (isTRUE(verbose)) { message(str_c("updateObject(object = '", class(object)[[1L]], "')")) } - if (is_in("fitVariants", .tupleColumnNames(object))) { - return(methods::callNextMethod(object, ..., verbose = verbose)) + if (!is_in("fitVariants", .tupleColumnNames(object))) { + fv <- map(seq_along(object), .fmrBackfillFitVariants, x = object) + object <- `$<-`(object, "fitVariants", IRanges::CharacterList(fv)) } - fv <- map(seq_along(object), .fmrBackfillFitVariants, x = object) - `$<-`(object, "fitVariants", IRanges::CharacterList(fv)) + methods::callNextMethod(object, ..., verbose = verbose) } ) diff --git a/R/ColocBoostResult.R b/R/ColocBoostResult.R index 65554e3b..3002a41a 100644 --- a/R/ColocBoostResult.R +++ b/R/ColocBoostResult.R @@ -205,7 +205,9 @@ setMethod("ldReference", "ColocBoostResult", function(x) x@ldReference) # A ColocBoostResult keys its outcomes, not its sets, to its references, so # its update is its own: the one reference an earlier version recorded was -# the one every summary-statistic outcome was matched against. +# the one every summary-statistic outcome was matched against. A version +# older still recorded it as `ldSketch`. Each reference is brought up to date +# as any collection's is (.updateLdRefOrKeep()). #' @rdname updateObject-methods #' @export setMethod( @@ -222,18 +224,25 @@ setMethod( # @noRd .cbrUpdateLdRefs <- function(object) { + object <- .renameSavedSlots(object, c(ldSketch = "ldReference")) old <- methods::slot(object, "ldReference") info <- .cbrWithLdKeys(object@outcomeInfo) if (is.list(old) && !is.object(old)) { - return(`slot<-`(object, "outcomeInfo", value = info)) + refs <- map(old, .updateLdRefOrKeep) + } else { + dict <- .ldRefDict(list(.updateLdRefOrKeep(old))) + key <- if (length(dict$refs) == 0L) NA_character_ else dict$keys[[1L]] + info <- mutate( + info, + ldReference = if_else( + .data$dataForm == "sumstats", + key, + NA_character_ + ) + ) + refs <- dict$refs } - dict <- .ldRefDict(list(.asLdRef(old))) - key <- if (length(dict$refs) == 0L) NA_character_ else dict$keys[[1L]] - info <- mutate( - info, - ldReference = if_else(.data$dataForm == "sumstats", key, NA_character_) - ) - updated <- `slot<-`(object, "ldReference", check = FALSE, value = dict$refs) + updated <- `slot<-`(object, "ldReference", check = FALSE, value = refs) `slot<-`(updated, "outcomeInfo", value = info) } diff --git a/R/H2Estimate.R b/R/H2Estimate.R index 1f162578..770ec8f0 100644 --- a/R/H2Estimate.R +++ b/R/H2Estimate.R @@ -126,6 +126,36 @@ setMethod("scoreStats", "H2Estimate", function(object) { object@scoreStats }) +# Each slot an H2Estimate was saved under before its slots were renamed, and +# its name now. +# @noRd +.H2_RENAMED_SLOTS <- c( + h2 = "estimate", + h2Se = "estimateSe", + local = "localBlocks", + tauBlocks = "annotationJackknifeCoefs" +) + +# An H2Estimate saved before the rename holds its estimates under the old +# names, which the inherited update would drop as slots the class no longer +# has, leaving the estimate empty; they are moved to the new names first. +#' @rdname updateObject-methods +#' @export +setMethod( + "updateObject", + "H2Estimate", + function(object, ..., verbose = FALSE) { + if (isTRUE(verbose)) { + message("updateObject(object = 'H2Estimate')") + } + methods::callNextMethod( + .renameSavedSlots(object, .H2_RENAMED_SLOTS), + ..., + verbose = verbose + ) + } +) + # ============================================================================= # Show diff --git a/R/LdStatistic.R b/R/LdStatistic.R index 1197cd66..40fd4c17 100644 --- a/R/LdStatistic.R +++ b/R/LdStatistic.R @@ -443,6 +443,32 @@ setMethod("ldBlocks", "LdStatistic", function(x) x@ldBlocks) #' @export setMethod("ldReference", "LdStatistic", function(x) x@ldReference) +# An LdStatistic saved before the reference's sample size was named +# `nSamples` holds it as `nRef`, and one saved before statistics kept their LD +# reference has no `ldReference` slot: it stored what it needs of its blocks' +# LD, which a NULL reference now says. +#' @rdname updateObject-methods +#' @export +setMethod( + "updateObject", + "LdStatistic", + function(object, ..., verbose = FALSE) { + if (isTRUE(verbose)) { + message(str_c("updateObject(object = '", class(object)[[1L]], "')")) + } + object <- .renameSavedSlots(object, c(nRef = "nSamples")) + if (!methods::.hasSlot(object, "ldReference")) { + object <- `slot<-`( + object, + "ldReference", + check = FALSE, + value = NULL + ) + } + methods::callNextMethod(object, ..., verbose = verbose) + } +) + # ============================================================================= # Reading an LD statistic's blocks # ----------------------------------------------------------------------------- diff --git a/R/QtlDataset.R b/R/QtlDataset.R index a2244251..6bef1c80 100644 --- a/R/QtlDataset.R +++ b/R/QtlDataset.R @@ -2309,14 +2309,26 @@ ResidualizationParam <- function( "keepIndel" ) +# A QtlDataset saved before its study's slot was named `studyName` holds it +# as `study`; one saved with run settings has them dropped +# (.QTL_RETIRED_SLOTS); and its genotype panel is brought up to date +# (.qtlUpdateGenotypes()). #' @rdname updateObject-methods #' @export setMethod("updateObject", "QtlDataset", function(object, ..., verbose = FALSE) { if (isTRUE(verbose)) { message("updateObject(object = 'QtlDataset')") } - trimmed <- reduce(.QTL_RETIRED_SLOTS, .qtlDropAttribute, .init = object) - methods::callNextMethod(trimmed, ..., verbose = verbose) + trimmed <- reduce( + .QTL_RETIRED_SLOTS, + .qtlDropAttribute, + .init = .renameSavedSlots(object, c(study = "studyName")) + ) + # Updated here, not as callNextMethod()'s argument: the inherited update + # first reads its argument inside try(), so an error there would be + # swallowed and the update run a second time. + updated <- .qtlUpdateGenotypes(trimmed) + methods::callNextMethod(updated, ..., verbose = verbose) }) # @noRd @@ -2325,6 +2337,20 @@ setMethod("updateObject", "QtlDataset", function(object, ..., verbose = FALSE) { object } +# A dataset whose genotype panel was saved before panels took today's shape +# has it read again (.updatePanel()). Unlike an LD reference it cannot be +# kept as saved when that fails -- the dataset is nothing without its +# genotypes -- so the error stands. +# @noRd +.qtlUpdateGenotypes <- function(x) { + panel <- .qtlGenotypeSe(x) + updated <- .updatePanel(panel) + if (identical(updated, panel)) { + return(x) + } + .qtlWithGenotypeHandle(x, updated) +} + #' @rdname GenotypeFilterParam #' @aliases GenotypeFilterParam-class #' @exportClass GenotypeFilterParam diff --git a/R/RangedTupleList.R b/R/RangedTupleList.R index 37d7104e..c9250442 100644 --- a/R/RangedTupleList.R +++ b/R/RangedTupleList.R @@ -659,7 +659,8 @@ setMethod("trim", "RangedTupleList", function(x, use.names = TRUE, ...) { #' @title Update an Object Saved by an Earlier pecotmr #' @description Bring an object saved by an earlier version of pecotmr up to -#' date. An up-to-date object is returned unchanged. +#' date. An up-to-date object is returned unchanged; an older one gets every +#' update below that applies to it, in the one call. #' #' \itemize{ #' \item Collections keep their LD references per row: each distinct @@ -669,20 +670,52 @@ setMethod("trim", "RangedTupleList", function(x, use.names = TRUE, ...) { #' when it held a single reference for all its rows is converted by #' keying every row to that reference (for a \code{ColocBoostResult}, #' every summary-statistic outcome), and one that held none by marking -#' every row LD-free. +#' every row LD-free. An object saved when the slot was named +#' \code{ldSketch} has it renamed first. +#' \item A genotype panel saved before panels recorded where their +#' genotypes come from (an LD reference, or a \code{QtlDataset}'s +#' genotypes) is read again from its files, as +#' \code{\link{readGenotypes}} reads them, and cut to the variants and +#' samples it held: a VCF, GDS or PLINK1 panel then reads through its +#' format's own backend, and a stochastic sketch records its real +#' sample count and allele frequencies. Only the files' variant and +#' sample lists, and a sketch's \code{.afreq}, are read; no genotypes +#' are, and nothing is written. An LD reference whose files cannot be +#' read again is kept as saved, with a warning, and updating again once +#' they are back finishes the job; a \code{QtlDataset} whose genotypes +#' cannot be is an error. #' \item Collections name their elements by their identity tuple; one #' saved without names gets them. +#' \item Summary statistics keep their QC settings in \code{qcOptions} +#' and each row's QC audit in a \code{qcAudit} column; ones saved with +#' both in one \code{qcInfo} record have it split between the two. +#' Their genome build is in \code{seqinfo()}; ones saved with it in a +#' \code{genome} slot have it moved there. +#' \item Fine-mapping results and TWAS weights record the variants each +#' row was fitted on in a \code{fitVariants} column; ones saved without +#' it have it filled in from their fits. +#' \item A \code{CtwasResult} holds one element per region; one saved as a +#' table of whole runs is rebuilt. #' \item A \code{QtlDataset} no longer stores run settings (genotype #' QC cutoffs, \code{scaleResiduals}); one saved with them has them #' dropped, as the pipelines' \code{\link{GenotypeFilterParam}} and -#' \code{\link{ResidualizationParam}} now carry them. +#' \code{\link{ResidualizationParam}} now carry them. One saved with +#' its study in a \code{study} slot has it moved to \code{studyName}. #' \item A \code{MultiStudyQtlDataset} is now a list of its studies; one #' saved when it held them in a slot is rebuilt as one, its studies #' updated too. +#' \item An \code{LdScore} or \code{LdEigen} saved before it could keep +#' an LD reference stores its blocks' LD itself, and gets none; one +#' saved with the reference's sample size as \code{nRef} has it moved +#' to \code{nSamples}. +#' \item An \code{H2Estimate} saved with its estimates under the slots' +#' earlier names (\code{h2}, \code{h2Se}, \code{local}, +#' \code{tauBlocks}) has them moved to the current ones. #' } #' @param object A collection (summary statistics, fine-mapping results, TWAS -#' weights, a colocalization result), a \code{QtlDataset} or a -#' \code{MultiStudyQtlDataset}. +#' weights, a colocalization or cTWAS result), a \code{QtlDataset}, a +#' \code{MultiStudyQtlDataset}, an \code{LdScore} or \code{LdEigen}, or an +#' \code{H2Estimate}. #' @param ... Passed on to the inherited method. #' @param verbose Report the update. #' @return \code{object} in the current representation. @@ -712,6 +745,29 @@ setMethod( } ) +# `object` with each slot an earlier version saved under another name moved +# to its current one: `renames` maps each old name to the new. The inherited +# update keeps only the slots a class still has, so a value left under its +# old name would be dropped. A name the object was not saved under is +# skipped. +# @noRd +#' @importFrom purrr reduce2 +.renameSavedSlots <- function(object, renames) { + reduce2(names(renames), unname(renames), .renameSavedSlot, .init = object) +} + +# slot() rather than attr(): R stores a NULL slot as a placeholder symbol, +# which slot() reads back as NULL and attr() hands back unconverted. +# @noRd +.renameSavedSlot <- function(object, from, to) { + if (is.null(attr(object, from, exact = TRUE))) { + return(object) + } + value <- methods::slot(object, from) + attr(object, from) <- NULL + `slot<-`(object, to, check = FALSE, value = value) +} + # ----------------------------------------------------------------------------- # Construction helper: enforce one seqname per element # ----------------------------------------------------------------------------- diff --git a/R/colocboostPipeline.R b/R/colocboostPipeline.R index 9f6229a3..f3fca1a3 100644 --- a/R/colocboostPipeline.R +++ b/R/colocboostPipeline.R @@ -55,17 +55,19 @@ #' \code{gwasSumStats}. Works for either data form -- the #' individual-level contexts, the summary-level QTL studies, or #' both together when a \code{MultiStudyQtlDataset} carries a -#' mixture. Focal only on a QTL outcome named by -#' \code{focalOutcome}. -#' \item \code{jointGwas} (default \code{FALSE}): run one colocboost -#' model that combines all QTL contexts/studies with the -#' supplied \code{gwasSumStats} studies. By default it is focal on -#' the GWAS when \code{gwasSumStats} holds a single study, and -#' non-focal when it holds several; \code{focalOutcome} chooses. -#' \item \code{separateGwas} (default \code{FALSE}): run one focal -#' colocboost model per GWAS study, where the GWAS is the -#' focal outcome. +#' mixture. Non-focal unless \code{focalOutcome} names one of its +#' QTL outcomes. +#' \item \code{jointGwas} (default \code{FALSE}): run one non-focal +#' colocboost model (colocboost's disease-agnostic mode) that +#' combines all QTL contexts/studies with the supplied +#' \code{gwasSumStats} studies, however many there are. +#' \item \code{separateGwas} (default \code{FALSE}): run one colocboost +#' model per GWAS study, focal on that study (the +#' disease-prioritized mode), even when there is only one. #' } +#' The flags combine freely, as in colocboost's own pipeline. With one +#' GWAS study, \code{jointGwas} and \code{separateGwas} fit the same +#' outcomes, one non-focal and one focal on the GWAS. #' #' @param qtlData One of \code{QtlDataset}, \code{QtlSumStats}, or #' \code{MultiStudyQtlDataset}. @@ -110,23 +112,14 @@ #' applies it to both kinds of study it holds. #' @param samples Optional character vector of sample IDs to restrict the #' analysis to; \code{NULL} (default) uses all samples. -#' @param focalOutcome The outcome a run treats as focal (colocboost's -#' \code{focal_outcome_idx}). One of: -#' \itemize{ -#' \item \code{NULL} (default): the GWAS study, in the \code{jointGwas} -#' run, when \code{gwasSumStats} holds exactly one. With several -#' there is no one study to choose, so no run is focal. -#' \item A GWAS study name, as a plain string: that study is focal in -#' the \code{jointGwas} run. It must be a study of -#' \code{gwasSumStats}. -#' \item A named character vector with any of \code{study}, -#' \code{context} and \code{trait} that identifies exactly one QTL -#' outcome, e.g. \code{c(context = "brain", trait = "ENSG1")}: that -#' outcome is focal in every run holding it, the \code{xqtlColoc} -#' run and the \code{jointGwas} run. -#' \item \code{NA}: no run is focal. -#' } -#' The \code{separateGwas} runs are always focal on their own GWAS study. +#' @param focalOutcome The QTL outcome the \code{xqtlColoc} run treats as +#' focal (colocboost's \code{focal_outcome_idx}): a named character vector +#' with any of \code{study}, \code{context} and \code{trait} that +#' identifies exactly one QTL outcome, e.g. +#' \code{c(context = "brain", trait = "ENSG1")}. \code{NULL} (default) runs +#' it non-focal. It needs \code{xqtlColoc = TRUE}: the \code{jointGwas} run +#' is never focal, and each \code{separateGwas} run is focal on its own +#' GWAS study. #' @param xqtlColoc,jointGwas,separateGwas Logical flags selecting which #' colocboost variants to run. #' @param signalScreenParam Individual-level pre-filter (ports the legacy @@ -257,113 +250,62 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { )) } -# focalOutcome's shape: NULL, NA, one GWAS study name, or a named character -# vector of `study` / `context` / `trait` naming one QTL outcome. Whether it -# names a real outcome is settled once the outcomes are built -# (.cbResolveFocal()). +# focalOutcome's shape: NULL, or a named character vector of `study` / +# `context` / `trait` naming the xQTL-only run's focal QTL outcome, which only +# that run can have. Whether it names a real outcome is settled once the +# outcomes are built (.cbResolveFocal()). # @noRd -.cbAssertFocalOutcome <- function(focalOutcome) { - if (is.null(focalOutcome) || .cbFocalIsNa(focalOutcome)) { +.cbAssertFocalOutcome <- function(focalOutcome, xqtlColoc) { + if (is.null(focalOutcome)) { return(invisible(NULL)) } - if (.cbFocalShapeOk(focalOutcome)) { - return(invisible(NULL)) + runs <- str_c( + "The `jointGwas` run is never focal, and each `separateGwas` run is ", + "focal on its own GWAS study." + ) + if (!.cbFocalShapeOk(focalOutcome)) { + abort(c( + str_c( + "colocboostPipeline: `focalOutcome` must be NULL or a named ", + "character vector of `study`, `context` and/or `trait` naming ", + "one QTL outcome, e.g. ", + "c(context = \"brain\", trait = \"ENSG1\")." + ), + i = runs + )) } - abort(c( - str_c( - "colocboostPipeline: `focalOutcome` must be NULL, NA, one GWAS ", - "study name, or a named character vector of `study`, `context` ", - "and/or `trait` naming one QTL outcome." - ), - i = str_c( - "e.g. focalOutcome = \"MyGWAS\", or ", - "focalOutcome = c(context = \"brain\", trait = \"ENSG1\")." - ) - )) -} - -# @noRd -.cbFocalIsNa <- function(x) { - is.atomic(x) && length(x) == 1L && is.null(names(x)) && is.na(x) + if (!isTRUE(xqtlColoc)) { + abort(c( + str_c( + "colocboostPipeline: `focalOutcome` names the xQTL-only run's ", + "focal outcome, but `xqtlColoc` is FALSE." + ), + i = runs + )) + } + invisible(NULL) } -# One unnamed string, or a named character vector whose names are distinct -# fields of a QTL outcome. +# A named character vector whose names are distinct fields of a QTL outcome. # @noRd .cbFocalShapeOk <- function(x) { if (!is.character(x) || length(x) == 0L || anyNA(x)) { return(FALSE) } nm <- names(x) - if (is.null(nm)) { - return(length(x) == 1L) - } - !anyDuplicated(nm) && all(is_in(nm, c("study", "context", "trait"))) + !is.null(nm) && + !anyDuplicated(nm) && + all(is_in(nm, c("study", "context", "trait"))) } -# The outcome each run is focal on (NULL for none), from `focalOutcome`. -# `qtlInfo` lists the QTL outcomes (.cbQtlOutcomeInfo()) and `gwasKeys` maps -# each GWAS study that reached the runs to its outcome name (.cbGwasKeys()). -# A GWAS study can be focal only where it is an outcome, the joint run; a QTL -# outcome is focal in both runs that hold it. +# The QTL outcome the xQTL-only run is focal on, from `focalOutcome`; NULL for +# none. `qtlInfo` lists the QTL outcomes (.cbQtlOutcomeInfo()). # @noRd -.cbResolveFocal <- function(focalOutcome, gwasSumStats, qtlInfo, gwasKeys) { - if (.cbFocalIsNa(focalOutcome)) { - return(list(xqtl = NULL, joint = NULL)) - } - studies <- unique(as.character(gwasSumStats$study)) +.cbResolveFocal <- function(focalOutcome, qtlInfo) { if (is.null(focalOutcome)) { - return(list(xqtl = NULL, joint = .cbDefaultFocal(studies, gwasKeys))) - } - if (is.null(names(focalOutcome))) { - return(list( - xqtl = NULL, - joint = .cbFocalGwasKey(focalOutcome, studies, gwasKeys) - )) - } - name <- .cbFocalQtlName(focalOutcome, qtlInfo) - list(xqtl = name, joint = name) -} - -# The default focal outcome: the GWAS, when gwasSumStats holds one study and -# it reached the runs. Several studies leave no one study to choose. -# @noRd -.cbDefaultFocal <- function(studies, gwasKeys) { - if (length(studies) != 1L || !is_in(studies, names(gwasKeys))) { return(NULL) } - unname(gwasKeys[[studies]]) -} - -# The outcome name of GWAS study `study`, which must be a study of -# gwasSumStats and must have reached the runs. -# @noRd -.cbFocalGwasKey <- function(study, studies, gwasKeys) { - if (!is_in(study, studies)) { - known <- if (length(studies) == 0L) { - "no gwasSumStats was given" - } else { - str_c("its studies are ", str_flatten(studies, ", ")) - } - abort(c( - glue( - "colocboostPipeline: focalOutcome '{study}' names no GWAS ", - "study ({known})." - ), - i = str_c( - "Name a QTL outcome by a named vector, e.g. ", - "c(context = \"brain\", trait = \"ENSG1\")." - ) - )) - } - if (!is_in(study, names(gwasKeys))) { - abort(glue( - "colocboostPipeline: focalOutcome names GWAS study '{study}', ", - "but none of its rows overlap the QTL data, so it is not an ", - "outcome of the joint run." - )) - } - unname(gwasKeys[[study]]) + .cbFocalQtlName(focalOutcome, qtlInfo) } # The one QTL outcome a focalOutcome vector identifies. @@ -1319,8 +1261,10 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { # variants `run` (from .cbResolveRuns) switched on. `qtlSumstatBundle` is the # QTL-side subset of `sumstatBundle` (see .cbDriver); only the xQTL-only run # uses it, so that a GWAS study never becomes an xQTL-only outcome. `focal` -# names each run's focal outcome (.cbResolveFocal()). The result is keyed by -# the result slot each run fills; compact() drops what did not run. +# names the xQTL-only run's focal outcome (.cbResolveFocal()); the joint run +# is never focal, and each separate run is focal on its own GWAS. The result +# is keyed by the result slot each run fills; compact() drops what did not +# run. # @noRd .cbDispatchRuns <- function( individualBundle, @@ -1338,7 +1282,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { individualBundle, qtlSumstatBundle, hasInd, - focal$xqtl, + focal, methodArgs ) }, @@ -1348,8 +1292,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { sumstatBundle, hasInd, methodArgs, - gwasNames = names(gwasRunBundles), - focal = focal$joint + gwasNames = names(gwasRunBundles) ) }, separate_gwas = if (run$separate) { @@ -1445,8 +1388,8 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { # Run the requested colocboost analyses over the prepared bundles and fold # them into a ColocBoostResult (an empty one when no QTL input remains). -# `focal` names each run's focal outcome; `resultInfo` carries the outcome -# table and LD references the result records (.cbPrepareInputs()). +# `focal` names the xQTL-only run's focal outcome; `resultInfo` carries the +# outcome table and LD references the result records (.cbPrepareInputs()). # @noRd .cbRunVariants <- function( individualBundle, @@ -1716,30 +1659,32 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { ) } -# Joint QTL + GWAS run -> list(result, time). Focal on `focal`, an outcome -# name, when one was resolved (.cbResolveFocal()); non-focal otherwise. +# Joint QTL + GWAS run -> list(result, time). Non-focal (colocboost's +# disease-agnostic mode) however many GWAS studies it holds: a GWAS-focal fit +# is a separate run. # @noRd .cbRunJointGwas <- function( individualBundle, sumstatBundle, hasInd, methodArgs, - gwasNames = character(), - focal = NULL + gwasNames = character() ) { ssNames <- names(sumstatBundle$sumstat) traits <- c( if (hasInd) individualBundle$outcomeNames else character(), ssNames ) - focalIdx <- .cbFocalIdx(focal, traits) ldArgs <- .cbBuildLdArgs(sumstatBundle$LD, sumstatBundle$ldArg) # The merged bundle holds QTL sumstats as well as GWAS, so split the # labels rather than calling every sumstat a GWAS: a context is any # outcome that is not one of the GWAS studies, whether it arrived as # individual-level data or as summary statistics. nGwas <- length(intersect(ssNames, gwasNames)) - inform(.cbJointMessage(length(traits) - nGwas, nGwas, traits[focalIdx])) + inform(glue( + "====== Performing non-focal GWAS-xQTL ColocBoost on ", + "{length(traits) - nGwas} contexts and {nGwas} GWAS. =====" + )) args <- c( list( X = if (hasInd) individualBundle$X else NULL, @@ -1748,7 +1693,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { dict_YX = if (hasInd) individualBundle$dict_YX else NULL, dict_sumstatLD = sumstatBundle$dict_sumstatLD, outcome_names = traits, - focal_outcome_idx = focalIdx, + focal_outcome_idx = NULL, output_level = 2 ), ldArgs, @@ -1761,22 +1706,6 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { list(result = run$result, time = run$time) } -# The joint run's announcement; `focal` is the focal outcome's name, or empty -# for a non-focal run. -# @noRd -.cbJointMessage <- function(nContexts, nGwas, focal) { - if (length(focal) == 0L) { - return(glue( - "====== Performing non-focal GWAS-xQTL ColocBoost on ", - "{nContexts} contexts and {nGwas} GWAS. =====" - )) - } - glue( - "====== Performing focal GWAS-xQTL ColocBoost on {nContexts} ", - "contexts and {nGwas} GWAS, focal on {focal}. =====" - ) -} - # The position of outcome `focal` among `traits`, the form colocboost's # focal_outcome_idx takes; NULL when there is no focal outcome or the run # does not hold it. @@ -2052,7 +1981,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { # Everything the runs read, from the QTL side and gwasSumStats: each # outcome's (sumstat, LD) pair -- a GWAS study once, over its rows the QTL # data overlap -- allele-harmonized when asked; the bundles each run takes; -# the outcome each run is focal on; and the outcome table and LD references +# the xQTL-only run's focal outcome; and the outcome table and LD references # the result records. The tuples and keys are read before harmonization, # which keeps every pair's name. # @noRd @@ -2082,9 +2011,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { gwasRunBundles = .cbGwasRunBundles(harmonized$pairs, qtlKeys), focal = .cbResolveFocal( focalOutcome, - gwasSumStats, - .cbQtlOutcomeInfo(individualBundle, qtlPairs), - .cbGwasKeys(pairs, names(qtlPairs)) + .cbQtlOutcomeInfo(individualBundle, qtlPairs) ), resultInfo = list( outcomeInfo = .cbOutcomeInfo( @@ -2163,13 +2090,6 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { ) } -# Each GWAS study that reached the runs, mapped to its outcome name. -# @noRd -.cbGwasKeys <- function(pairs, qtlNames) { - gwas <- pairs[setdiff(names(pairs), qtlNames)] - set_names(names(gwas), map_chr(unname(gwas), "study")) -} - # The QTL outcomes a focalOutcome vector is matched against: the # individual-level ones with the (study, context, trait) they were built # from, then each QTL summary-statistic tuple. @@ -2337,7 +2257,7 @@ setMethod( ) { .assertMethodOptions(methodArgs, "ColocboostOptions", "methodArgs") .cbAssertAnyRun(xqtlColoc, jointGwas, separateGwas) - .cbAssertFocalOutcome(focalOutcome) + .cbAssertFocalOutcome(focalOutcome, xqtlColoc) .cbAssertTraitsSelected(qtlData, contexts, traitId) build <- .cbBuild(qtlData, gwasSumStats, region) res <- .cbQtlDatasetDrive( @@ -2385,7 +2305,7 @@ setMethod( ) { .assertMethodOptions(methodArgs, "ColocboostOptions", "methodArgs") .cbAssertAnyRun(xqtlColoc, jointGwas, separateGwas) - .cbAssertFocalOutcome(focalOutcome) + .cbAssertFocalOutcome(focalOutcome, xqtlColoc) .cbRequireSumStatsQc(qtlData, "qtlData") .cbAssertQssRowsSelected(qtlData, contexts, traitId) build <- .cbBuild(qtlData, gwasSumStats) @@ -2440,7 +2360,7 @@ setMethod( ) { .assertMethodOptions(methodArgs, "ColocboostOptions", "methodArgs") .cbAssertAnyRun(xqtlColoc, jointGwas, separateGwas) - .cbAssertFocalOutcome(focalOutcome) + .cbAssertFocalOutcome(focalOutcome, xqtlColoc) # As in fineMappingPipeline: a context no study has is refused, and # one only some lack is skipped for those, with a warning. parseContexts(contexts, qtlData) diff --git a/R/genotypeIo.R b/R/genotypeIo.R index 0ab54c6a..53606e51 100644 --- a/R/genotypeIo.R +++ b/R/genotypeIo.R @@ -409,6 +409,118 @@ extractBlockGenotypes <- function(handle, snpIdx, meanImpute = TRUE) { ) } +# ============================================================================= +# Panels saved by an earlier version +# ----------------------------------------------------------------------------- +# A panel built today records where its genotypes come from +# (metadata$genotypeSource), and one over a VCF, GDS or PLINK1 file reads +# through that format's own backend. A panel saved before either reads +# through a GenotypeHandle's GhSeed, in a format a handle may no longer read, +# and a stochastic sketch saved then lacks the real sample count and allele +# frequencies it is read with today (.withLdProjection()). Such a panel is +# read again from its files, as readGenotypes() reads them, and cut to the +# variants and samples it held. Only the files' variant and sample lists and +# a sketch's sidecar are read, never genotypes, and nothing is written. +# ============================================================================= + +# `panel` as a panel built today: read again from its files when it was +# saved before the changes above, else `panel` itself -- as for one that +# reads through no handle (a VCF, GDS or PLINK1 panel built since, or one +# held in memory). A bare GenotypeHandle, which an LD reference was before +# it was a panel, is taken as the panel over it. +# @noRd +.updatePanel <- function(panel) { + panel <- .asLdRef(panel) + handle <- .ldRefHandle(panel) + if (is.null(handle)) { + return(panel) + } + source <- .genotypeSourceRecord(handle) + recorded <- !is.null(S4Vectors::metadata(panel)$genotypeSource) + if (recorded && !is_in(source$format, .DOSAGE_PANEL_FORMATS)) { + return(panel) + } + .rereadPanel(panel, source) +} + +# `panel` read again from `source`, the record of where its genotypes come +# from, and cut to the variants and samples it held, keeping its sample data +# (a QTL dataset's genotype covariates). Variants are matched on position +# and alleles, which identify them however their names were normalized when +# the panel was saved. A `pecotmrUnreadablePanel` error when the files +# cannot be read or no longer hold them all. +# @noRd +#' @importFrom rlang try_fetch +.rereadPanel <- function(panel, source) { + fresh <- try_fetch( + .readSourcePanel(source), + error = function(cnd) { + .abortUnreadablePanel(source, "they cannot be read", cnd) + } + ) + rows <- match( + .grVariantIds(SummarizedExperiment::rowRanges(panel)), + .grVariantIds(SummarizedExperiment::rowRanges(fresh)) + ) + cols <- match(colnames(panel), colnames(fresh)) + if (length(rows) != nrow(panel) || anyNA(rows) || anyNA(cols)) { + .abortUnreadablePanel( + source, + "they no longer hold every variant and sample it did" + ) + } + SummarizedExperiment::`colData<-`( + .panelCut(fresh, rows, cols), + value = SummarizedExperiment::colData(panel) + ) +} + +# The panel today's readers build over a genotype source: its per-chromosome +# files' panels stacked when it has them, else its one file's. A bundled +# example's portable path resolves under the installed package. +# @noRd +.readSourcePanel <- function(source) { + if (length(source$chromPaths) > 0L) { + return(.chromMetaPanel( + map_chr(source$chromPaths, .resolveGenotypeResourcePath), + format = source$format + )) + } + .readGenotypePanel( + .resolveGenotypeResourcePath(source$path), + format = source$format + ) +} + +# `panel` cut to rows `rows` and columns `cols`, each cut only when it does +# not keep everything in order. +# @noRd +.panelCut <- function(panel, rows, cols) { + if (!identical(rows, seq_len(nrow(panel)))) { + panel <- .ldRefSubset(panel, rows) + } + if (identical(cols, seq_len(ncol(panel)))) { + return(panel) + } + panel[, cols] +} + +# @noRd +.abortUnreadablePanel <- function(source, why, parent = NULL) { + abort( + c( + glue( + "A {source$format} genotype panel saved by an earlier pecotmr ", + "has to be read again from its files at {source$path}, and ", + "{why}." + ), + i = "Put the files back where they were, then update again." + ), + class = "pecotmrUnreadablePanel", + parent = parent + ) +} + # PLINK2 writes the .psam header line with a leading "#" on the first field. # @noRd .psamHeaderNames <- function(nms) str_remove(nms, "^#") diff --git a/R/ld.R b/R/ld.R index fb48f095..99aa904f 100644 --- a/R/ld.R +++ b/R/ld.R @@ -500,25 +500,34 @@ resolveGenotypePathForRegion <- function(metaPath, region) { # so a subset does not report the ones its rows left behind. An object saved # before the references became per-row holds one reference in the slot and no # key column, and read as a list it would pass for LD-free; it is refused -# instead (one that held NULL was LD-free, and still reads that way). +# instead (one that held NULL was LD-free, and still reads that way). So is +# one saved before the slot was renamed, which holds it as `ldSketch`. # @noRd .ldRefsInUse <- function(x) { + if (!methods::.hasSlot(x, "ldReference")) { + .abortSavedLdRef(x) + } refs <- x@ldReference if (is.null(refs)) { return(list()) } if (!is.list(refs) || is.object(refs)) { - abort(c( - glue( - "This {class(x)[[1L]]} was saved before LD references became ", - "per-row, so its rows cannot be matched to its reference." - ), - i = "Bring it up to date with `x <- updateObject(x)`." - )) + .abortSavedLdRef(x) } .ldRefsUsed(refs, .ldRefKeys(x)) } +# @noRd +.abortSavedLdRef <- function(x) { + abort(c( + glue( + "This {class(x)[[1L]]} was saved before LD references became ", + "per-row, so its rows cannot be matched to its reference." + ), + i = "Bring it up to date with `x <- updateObject(x)`." + )) +} + # The entries of `refs` some key in `keys` names. # @noRd .ldRefsUsed <- function(refs, keys) { @@ -560,18 +569,46 @@ resolveGenotypePathForRegion <- function(metaPath, region) { # `object` as saved before its references became per-row -- one reference, # or NULL, in the slot and no row key -- brought up to date: that reference # becomes the slot's one entry and every row is keyed to it (every row is -# LD-free when it held none). A current object -- or a collection that keeps -# no LD references, such as a CtwasResult -- is returned as it is. +# LD-free when it held none). An object saved before the slot was renamed +# holds that reference, a panel or NULL, as `ldSketch`; it is moved to +# `ldReference` first. Every reference is brought up to date too +# (.updateLdRefOrKeep()). A collection that keeps no LD references, such as +# a CtwasResult, is returned as it is. # @noRd .updateRowLdRefs <- function(object) { + object <- .renameSavedSlots(object, c(ldSketch = "ldReference")) if (!methods::.hasSlot(object, "ldReference")) { return(object) } old <- methods::slot(object, "ldReference") - if (is.list(old) && !is.object(old)) { - return(object) + if (!is.list(old) || is.object(old)) { + return(.withRowLdRefs(object, .updateLdRefOrKeep(old))) } - .withRowLdRefs(object, .asLdRef(old)) + `slot<-`( + object, + "ldReference", + check = FALSE, + value = map(old, .updateLdRefOrKeep) + ) +} + +# A collection's LD reference as saved, brought up to date (.updatePanel()). +# One whose files cannot be read again is kept as saved, with a warning, +# rather than failing the update: the rest of the collection is still worth +# having, and updating again once the files are back finishes the job. +# @noRd +#' @importFrom rlang try_fetch +.updateLdRefOrKeep <- function(ref) { + try_fetch( + .updatePanel(ref), + pecotmrUnreadablePanel = function(cnd) { + warn( + "An LD reference is kept as saved: LD cannot be read from it.", + parent = cnd + ) + .asLdRef(ref) + } + ) } # Row `i`'s LD reference, or NULL for an LD-free row. diff --git a/R/twasWeights.R b/R/twasWeights.R index 5a202e52..4a43c4d2 100644 --- a/R/twasWeights.R +++ b/R/twasWeights.R @@ -566,7 +566,8 @@ setMethod( # Before rows recorded the variants their weights were fitted on, a # collection had no `fitVariants` column; a row saved then records the -# variants it holds, and a row with no fit payload records none. +# variants it holds, and a row with no fit payload records none. The +# inherited update runs either way, for the updates every collection shares. #' @rdname updateObject-methods #' @export setMethod( @@ -576,11 +577,11 @@ setMethod( if (isTRUE(verbose)) { message("updateObject(object = 'TwasWeights')") } - if (is_in("fitVariants", .tupleColumnNames(object))) { - return(methods::callNextMethod(object, ..., verbose = verbose)) + if (!is_in("fitVariants", .tupleColumnNames(object))) { + held <- map(seq_along(object), .twrBackfillFitVariants, x = object) + object <- `$<-`(object, "fitVariants", IRanges::CharacterList(held)) } - held <- map(seq_along(object), .twrBackfillFitVariants, x = object) - `$<-`(object, "fitVariants", IRanges::CharacterList(held)) + methods::callNextMethod(object, ..., verbose = verbose) } ) diff --git a/inst/scripts/build_examples.R b/inst/scripts/build_examples.R index 043a39f5..03806e36 100644 --- a/inst/scripts/build_examples.R +++ b/inst/scripts/build_examples.R @@ -77,6 +77,27 @@ snpStats::write.plink( na.code = 0L ) gh <- readGenotypes(plink1Prefix = smallStem) + +# Point the panel at a portable bundled-resource reference +# ("pecotmr://extdata/") before any object is built from it, so the .rda +# objects carry no source-tree absolute path. The panel's seed resolves it via +# system.file() when it reads, so no user-facing fixup step is required. +asResource <- function(p) paste0("pecotmr://extdata/", basename(p)) + +# A PLINK1 panel records its stem twice: as its seed's backend, which reads +# the file, and as its genotype source, which says where it came from. Both +# move together. +asPortablePanel <- function(panel) { + seed <- pecotmr:::.panelSeed(panel) + ref <- asResource(pecotmr:::.gdSeedBackend(seed)) + SummarizedExperiment::assay(panel, "dosage", withDimnames = FALSE) <- + DelayedArray::DelayedArray(methods::initialize(seed, backend = ref)) + md <- S4Vectors::metadata(panel) + md$genotypeSource$path <- ref + S4Vectors::metadata(panel) <- md + panel +} +gh <- asPortablePanel(gh) windowSnpInfo <- pecotmr:::.rangesSnpInfo(SummarizedExperiment::rowRanges(gh)) # Materialise the dosage matrix once for synthetic-phenotype generation. @@ -152,7 +173,7 @@ S4Vectors::mcols(qtlGr) <- S4Vectors::DataFrame( ) qtlSumStatsExample <- QtlSumStats( - study = "study1", + studyName = "study1", context = "brain", trait = "ENSG_example", entry = list(qtlGr), @@ -188,7 +209,7 @@ S4Vectors::mcols(gwasGr) <- S4Vectors::DataFrame( ) gwasSumStatsS4Example <- GwasSumStats( - study = "trait1", + studyName = "trait1", entry = list(gwasGr), genome = "hg19", ldReference = gh, @@ -283,7 +304,7 @@ multiCtxEntries <- map(multiCtxNames, function(ctx) { }) qtlSumStatsMulticontextExample <- QtlSumStats( - study = rep("study1", length(multiCtxNames)), + studyName = rep("study1", length(multiCtxNames)), context = multiCtxNames, trait = rep("ENSG_example", length(multiCtxNames)), entry = multiCtxEntries, @@ -293,50 +314,7 @@ qtlSumStatsMulticontextExample <- QtlSumStats( ) # ----------------------------------------------------------------------------- -# 7. Point the PLINK1 panels at a portable bundled-resource reference -# ("pecotmr://extdata/") so the .rda objects carry no source-tree -# absolute path. The panel's seed resolves it via system.file() when it -# reads, so no user-facing fixup step is required. -# ----------------------------------------------------------------------------- -asResource <- function(p) paste0("pecotmr://extdata/", basename(p)) - -# A PLINK1 panel records its stem twice: as its seed's backend, which reads -# the file, and as its genotype source, which says where it came from. Both -# move together. -asPortablePanel <- function(panel) { - seed <- pecotmr:::.panelSeed(panel) - ref <- asResource(pecotmr:::.gdSeedBackend(seed)) - SummarizedExperiment::assay(panel, "dosage", withDimnames = FALSE) <- - DelayedArray::DelayedArray(methods::initialize(seed, backend = ref)) - md <- S4Vectors::metadata(panel) - md$genotypeSource$path <- ref - S4Vectors::metadata(panel) <- md - panel -} -repointDataset <- function(x) { - pecotmr:::.qtlWithGenotypeHandle( - x, - asPortablePanel(pecotmr:::.qtlGenotypeSe(x)) - ) -} - -qtlDatasetExample <- repointDataset(qtlDatasetExample) -qtlSumStatsExample@ldReference <- asPortablePanel( - qtlSumStatsExample@ldReference -) -qtlSumStatsMulticontextExample@ldReference <- asPortablePanel( - qtlSumStatsMulticontextExample@ldReference -) -gwasSumStatsS4Example@ldReference <- asPortablePanel( - gwasSumStatsS4Example@ldReference -) -multiStudyQtlDatasetExample@qtlDatasets <- map( - multiStudyQtlDatasetExample@qtlDatasets, - repointDataset -) - -# ----------------------------------------------------------------------------- -# 8. Save. +# 7. Save. # ----------------------------------------------------------------------------- usethis::use_data(qtlDatasetExample, overwrite = TRUE, compress = "xz") usethis::use_data(qtlSumStatsExample, overwrite = TRUE, compress = "xz") diff --git a/man/colocboostPipeline.Rd b/man/colocboostPipeline.Rd index 998beccf..530f185a 100644 --- a/man/colocboostPipeline.Rd +++ b/man/colocboostPipeline.Rd @@ -116,23 +116,14 @@ QtlSumStats input: each selected tuple is analysed over its every selected tuple needs a \code{traitPos}. A MultiStudyQtlDataset applies it to both kinds of study it holds.} -\item{focalOutcome}{The outcome a run treats as focal (colocboost's -\code{focal_outcome_idx}). One of: -\itemize{ - \item \code{NULL} (default): the GWAS study, in the \code{jointGwas} - run, when \code{gwasSumStats} holds exactly one. With several - there is no one study to choose, so no run is focal. - \item A GWAS study name, as a plain string: that study is focal in - the \code{jointGwas} run. It must be a study of - \code{gwasSumStats}. - \item A named character vector with any of \code{study}, - \code{context} and \code{trait} that identifies exactly one QTL - outcome, e.g. \code{c(context = "brain", trait = "ENSG1")}: that - outcome is focal in every run holding it, the \code{xqtlColoc} - run and the \code{jointGwas} run. - \item \code{NA}: no run is focal. -} -The \code{separateGwas} runs are always focal on their own GWAS study.} +\item{focalOutcome}{The QTL outcome the \code{xqtlColoc} run treats as +focal (colocboost's \code{focal_outcome_idx}): a named character vector +with any of \code{study}, \code{context} and \code{trait} that +identifies exactly one QTL outcome, e.g. +\code{c(context = "brain", trait = "ENSG1")}. \code{NULL} (default) runs +it non-focal. It needs \code{xqtlColoc = TRUE}: the \code{jointGwas} run +is never focal, and each \code{separateGwas} run is focal on its own +GWAS study.} \item{xqtlColoc, jointGwas, separateGwas}{Logical flags selecting which colocboost variants to run.} @@ -284,17 +275,19 @@ for either side; colocboost has its own variable-selection algorithm. \code{gwasSumStats}. Works for either data form -- the individual-level contexts, the summary-level QTL studies, or both together when a \code{MultiStudyQtlDataset} carries a - mixture. Focal only on a QTL outcome named by - \code{focalOutcome}. - \item \code{jointGwas} (default \code{FALSE}): run one colocboost - model that combines all QTL contexts/studies with the - supplied \code{gwasSumStats} studies. By default it is focal on - the GWAS when \code{gwasSumStats} holds a single study, and - non-focal when it holds several; \code{focalOutcome} chooses. - \item \code{separateGwas} (default \code{FALSE}): run one focal - colocboost model per GWAS study, where the GWAS is the - focal outcome. + mixture. Non-focal unless \code{focalOutcome} names one of its + QTL outcomes. + \item \code{jointGwas} (default \code{FALSE}): run one non-focal + colocboost model (colocboost's disease-agnostic mode) that + combines all QTL contexts/studies with the supplied + \code{gwasSumStats} studies, however many there are. + \item \code{separateGwas} (default \code{FALSE}): run one colocboost + model per GWAS study, focal on that study (the + disease-prioritized mode), even when there is only one. } + The flags combine freely, as in colocboost's own pipeline. With one + GWAS study, \code{jointGwas} and \code{separateGwas} fit the same + outcomes, one non-focal and one focal on the GWAS. } \examples{ diff --git a/man/updateObject-methods.Rd b/man/updateObject-methods.Rd index efea9c46..d6c29fb8 100644 --- a/man/updateObject-methods.Rd +++ b/man/updateObject-methods.Rd @@ -1,7 +1,7 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/RangedTupleList.R, R/AllClasses.R, -% R/ColocBoostResult.R, R/CtwasResult.R, R/QtlDataset.R, -% R/MultiStudyQtlDataset.R, R/twasWeights.R +% R/ColocBoostResult.R, R/CtwasResult.R, R/H2Estimate.R, R/LdStatistic.R, +% R/QtlDataset.R, R/MultiStudyQtlDataset.R, R/twasWeights.R \name{updateObject-methods} \alias{updateObject-methods} \alias{updateObject,RangedTupleList-method} @@ -9,6 +9,8 @@ \alias{updateObject,FineMappingResultBase-method} \alias{updateObject,ColocBoostResult-method} \alias{updateObject,CtwasResult-method} +\alias{updateObject,H2Estimate-method} +\alias{updateObject,LdStatistic-method} \alias{updateObject,QtlDataset-method} \alias{updateObject,MultiStudyQtlDataset-method} \alias{updateObject,TwasWeights-method} @@ -24,6 +26,10 @@ \S4method{updateObject}{CtwasResult}(object, ..., verbose = FALSE) +\S4method{updateObject}{H2Estimate}(object, ..., verbose = FALSE) + +\S4method{updateObject}{LdStatistic}(object, ..., verbose = FALSE) + \S4method{updateObject}{QtlDataset}(object, ..., verbose = FALSE) \S4method{updateObject}{MultiStudyQtlDataset}(object, ..., verbose = FALSE) @@ -32,8 +38,9 @@ } \arguments{ \item{object}{A collection (summary statistics, fine-mapping results, TWAS -weights, a colocalization result), a \code{QtlDataset} or a -\code{MultiStudyQtlDataset}.} +weights, a colocalization or cTWAS result), a \code{QtlDataset}, a +\code{MultiStudyQtlDataset}, an \code{LdScore} or \code{LdEigen}, or an +\code{H2Estimate}.} \item{...}{Passed on to the inherited method.} @@ -44,7 +51,8 @@ weights, a colocalization result), a \code{QtlDataset} or a } \description{ Bring an object saved by an earlier version of pecotmr up to - date. An up-to-date object is returned unchanged. + date. An up-to-date object is returned unchanged; an older one gets every + update below that applies to it, in the one call. \itemize{ \item Collections keep their LD references per row: each distinct @@ -54,16 +62,47 @@ Bring an object saved by an earlier version of pecotmr up to when it held a single reference for all its rows is converted by keying every row to that reference (for a \code{ColocBoostResult}, every summary-statistic outcome), and one that held none by marking - every row LD-free. + every row LD-free. An object saved when the slot was named + \code{ldSketch} has it renamed first. + \item A genotype panel saved before panels recorded where their + genotypes come from (an LD reference, or a \code{QtlDataset}'s + genotypes) is read again from its files, as + \code{\link{readGenotypes}} reads them, and cut to the variants and + samples it held: a VCF, GDS or PLINK1 panel then reads through its + format's own backend, and a stochastic sketch records its real + sample count and allele frequencies. Only the files' variant and + sample lists, and a sketch's \code{.afreq}, are read; no genotypes + are, and nothing is written. An LD reference whose files cannot be + read again is kept as saved, with a warning, and updating again once + they are back finishes the job; a \code{QtlDataset} whose genotypes + cannot be is an error. \item Collections name their elements by their identity tuple; one saved without names gets them. + \item Summary statistics keep their QC settings in \code{qcOptions} + and each row's QC audit in a \code{qcAudit} column; ones saved with + both in one \code{qcInfo} record have it split between the two. + Their genome build is in \code{seqinfo()}; ones saved with it in a + \code{genome} slot have it moved there. + \item Fine-mapping results and TWAS weights record the variants each + row was fitted on in a \code{fitVariants} column; ones saved without + it have it filled in from their fits. + \item A \code{CtwasResult} holds one element per region; one saved as a + table of whole runs is rebuilt. \item A \code{QtlDataset} no longer stores run settings (genotype QC cutoffs, \code{scaleResiduals}); one saved with them has them dropped, as the pipelines' \code{\link{GenotypeFilterParam}} and - \code{\link{ResidualizationParam}} now carry them. + \code{\link{ResidualizationParam}} now carry them. One saved with + its study in a \code{study} slot has it moved to \code{studyName}. \item A \code{MultiStudyQtlDataset} is now a list of its studies; one saved when it held them in a slot is rebuilt as one, its studies updated too. + \item An \code{LdScore} or \code{LdEigen} saved before it could keep + an LD reference stores its blocks' LD itself, and gets none; one + saved with the reference's sample size as \code{nRef} has it moved + to \code{nSamples}. + \item An \code{H2Estimate} saved with its estimates under the slots' + earlier names (\code{h2}, \code{h2Se}, \code{local}, + \code{tauBlocks}) has them moved to the current ones. } } \examples{ diff --git a/tests/testthat/helper-savedObjects.R b/tests/testthat/helper-savedObjects.R new file mode 100644 index 00000000..3b4fbfc0 --- /dev/null +++ b/tests/testthat/helper-savedObjects.R @@ -0,0 +1,69 @@ +# Objects as an earlier pecotmr saved them, for the updateObject() tests of +# the collections (test_RangedTupleList.R, test_AllClasses.R, +# test_twasWeights.R, test_ColocBoostResult.R), test_LdStatistic.R, +# test_H2Estimate.R, test_QtlDataset.R and the panel tests in +# test_genotypeIo.R. + +# `x` with each slot in `renames` (old name = current name) stored under its +# old name, as an object saved before the rename holds it: R stores a slot as +# an attribute, and a NULL one as a placeholder symbol, which `slot<-` writes. +.savedUnder <- function(x, renames) { + reduce2(names(renames), unname(renames), .savedUnderName, .init = x) +} + +.savedUnderName <- function(x, old, new) { + value <- methods::slot(x, new) + attr(x, new) <- NULL + `slot<-`(x, old, check = FALSE, value = value) +} + +# A collection as saved before its references became per-row: one reference +# (or NULL) in the slot and no row key. +.savedWithOneLdRef <- function(x, ref) { + old <- `slot<-`(x, "ldReference", check = FALSE, value = ref) + md <- attr(old, "elementMetadata") + md[["ldReference"]] <- NULL + attr(old, "elementMetadata") <- md + old +} + +# ...and as saved before the slot was renamed, holding that reference as +# `ldSketch`. +.savedWithLdSketch <- function(x, ref) { + .savedUnder(.savedWithOneLdRef(x, ref), c(ldSketch = "ldReference")) +} + +# A genotype panel as saved before panels recorded where their genotypes come +# from: its dosages read through a GenotypeHandle's GhSeed at `path` -- one +# claiming `format`, which may be a format a handle no longer reads -- with +# no metadata and only the SNP / A1 / A2 variant columns, and reading the +# per-chromosome files `chromPaths` when given. Its variants, samples and +# sample data are copied from `panel`, today's panel over the same files. +.savedHandlePanel <- function(panel, path, format, chromPaths = character(0)) { + rr <- SummarizedExperiment::rowRanges(panel) + handle <- methods::new( + "GenotypeHandle", + path = path, + format = "plink2", + snpInfo = data.frame( + SNP = rownames(panel), + CHR = as.character(GenomicRanges::seqnames(rr)), + BP = GenomicRanges::start(rr), + A1 = rr$A1, + A2 = rr$A2 + ), + nSamples = ncol(panel), + sampleIds = colnames(panel), + pgenPtr = NULL, + chromPaths = chromPaths + ) + old <- `slot<-`(handle, "format", check = FALSE, value = format) + SummarizedExperiment::SummarizedExperiment( + assays = list(dosage = genotypeDelayedArray(old)), + rowRanges = S4Vectors::`mcols<-`( + rr, + value = S4Vectors::mcols(rr)[c("SNP", "A1", "A2")] + ), + colData = SummarizedExperiment::colData(panel) + ) +} diff --git a/tests/testthat/test_AllClasses.R b/tests/testthat/test_AllClasses.R index c4412104..ae78338a 100644 --- a/tests/testthat/test_AllClasses.R +++ b/tests/testthat/test_AllClasses.R @@ -293,6 +293,36 @@ test_that("updateObject() drops audits it cannot match to rows, saying so", { expect_null(up$qcAudit) }) +test_that("updateObject() makes every update old summary statistics need", { + # Saved as the oldest versions saved them: the QC record in `qcInfo`, the + # reference in `ldSketch`, and no element names. Each update on its own + # leaves an invalid object, so the one call has to make all of them. + ss <- .alc_makeGwasSumStats() + panel <- ldReference(ss)[["ld1"]] + saved <- .savedWithLdSketch( + .alc_savedWithQcInfo(`names<-`(ss, NULL), list(step1 = "ok")), + panel + ) + up <- updateObject(saved) + expect_true(validObject(up)) + expect_equal(qcOptions(up), list(step1 = "ok")) + expect_identical(ldReference(up), list(ld1 = panel)) + expect_identical(names(up), names(ss)) + expect_identical(updateObject(up), up) +}) + +test_that("updateObject() moves a saved genome slot into seqinfo()", { + ss <- .alc_makeGwasSumStats() + saved <- ss + GenomeInfoDb::genome(saved) <- NA + attr(saved, "genome") <- "hg19" + up <- updateObject(saved) + expect_true(validObject(up)) + expect_null(attr(up, "genome", exact = TRUE)) + expect_identical(unique(unname(GenomeInfoDb::genome(up))), "hg19") + expect_identical(updateObject(up), up) +}) + test_that("updateObject() leaves a current summary-statistics object as is", { ss <- .alc_makeGwasSumStats(qcOptions = list(step1 = "ok")) up <- updateObject(ss, verbose = FALSE) @@ -754,6 +784,18 @@ test_that("updateObject() backfills the variants each fit was made with", { expect_message(updateObject(x, verbose = TRUE), "updateObject") }) +test_that("updateObject() backfills fitVariants and keys LD rows in one call", { + x <- .rc_makeFmr(.rc_vids(1:10)) + saved <- x + saved$fitVariants <- NULL + up <- updateObject(.savedWithLdSketch(saved, NULL)) + expect_true(validObject(up)) + expect_equal(as.character(up$fitVariants[[1L]]), .rc_vids(1:10)) + expect_identical(ldReference(up), list()) + expect_true(is.na(up$ldReference)) + expect_identical(updateObject(up), up) +}) + test_that("updateObject(): an unnamed fit records its row, no fit none", { vids <- .rc_vids(1:3) tl <- data.frame(variant_id = vids, pip = c(0.5, 0.3, 0.2)) diff --git a/tests/testthat/test_ColocBoostResult.R b/tests/testthat/test_ColocBoostResult.R index 76c70e16..4368fc04 100644 --- a/tests/testthat/test_ColocBoostResult.R +++ b/tests/testthat/test_ColocBoostResult.R @@ -551,6 +551,9 @@ test_that("updateObject keys an old result's sumstat outcomes to its ref", { expect_true(methods::validObject(new)) expect_identical(ldReference(new), list(ld1 = ref)) expect_identical(new@outcomeInfo$ldReference, c("ld1", NA)) + # Saved before the slot was renamed, the reference sits in `ldSketch`. + sketched <- .savedUnder(old, c(ldSketch = "ldReference")) + expect_identical(updateObject(sketched), new) # A current result is left as it is. expect_identical(updateObject(x), x) }) diff --git a/tests/testthat/test_H2Estimate.R b/tests/testthat/test_H2Estimate.R index 05cf2c73..20407a6a 100644 --- a/tests/testthat/test_H2Estimate.R +++ b/tests/testthat/test_H2Estimate.R @@ -127,3 +127,35 @@ test_that("accessors return NULL when slots are NULL", { expect_null(stratifiedHeritabilityEnrichment(h2_obj)) expect_null(scoreStats(h2_obj)) }) + +test_that("updateObject() moves an H2Estimate's estimates off the old names", { + h2Obj <- new( + "H2Estimate", + estimate = 0.3, + estimateSe = 0.05, + intercept = 1.0, + interceptSe = 0.01, + localBlocks = data.frame(blockId = "b1", h2Local = 0.1, h2LocalSe = 0), + enrichment = NULL, + annotationJackknifeCoefs = matrix(0.2, nrow = 2L, ncol = 1L), + scoreStats = NULL, + method = "sldsc", + nSnps = 100L, + traitName = "test" + ) + saved <- .savedUnder( + h2Obj, + c( + h2 = "estimate", + h2Se = "estimateSe", + local = "localBlocks", + tauBlocks = "annotationJackknifeCoefs" + ) + ) + # The inherited update alone drops slots the class no longer has, with a + # warning, and leaves the estimate empty. + expect_no_warning(up <- updateObject(saved)) + expect_identical(up, h2Obj) + expect_identical(updateObject(h2Obj), h2Obj) + expect_message(updateObject(h2Obj, verbose = TRUE), "H2Estimate") +}) diff --git a/tests/testthat/test_LdStatistic.R b/tests/testthat/test_LdStatistic.R index 444123ef..d7c40eaf 100644 --- a/tests/testthat/test_LdStatistic.R +++ b/tests/testthat/test_LdStatistic.R @@ -350,3 +350,23 @@ test_that("a block's LD and decomposition are read as stored", { 0L ) }) + +# =========================================================================== +# updateObject(): statistics saved by an earlier version +# =========================================================================== + +test_that("updateObject() renames nRef; an old statistic gets no reference", { + x <- .lds_score() + # Saved before the reference's sample size was named nSamples, and + # before a statistic could keep an LD reference at all. + saved <- .savedUnder(x, c(nRef = "nSamples")) + attr(saved, "ldReference") <- NULL + up <- updateObject(saved) + expect_true(validObject(up)) + expect_identical(up, x) + expect_identical(updateObject(x), x) + expect_message( + updateObject(x, verbose = TRUE), + "updateObject\\(object = 'LdScore'\\)" + ) +}) diff --git a/tests/testthat/test_QtlDataset.R b/tests/testthat/test_QtlDataset.R index b8cb6869..677c8936 100644 --- a/tests/testthat/test_QtlDataset.R +++ b/tests/testthat/test_QtlDataset.R @@ -1813,6 +1813,41 @@ test_that("updateObject drops the slots a QtlDataset no longer has", { ) }) +test_that("updateObject renames study and reads saved genotypes again", { + data(qtlDatasetExample) + current <- .qtlGenotypeSe(qtlDatasetExample) + # Saved by a version that named the slot `study` and read PLINK1 files + # through a GenotypeHandle (helper-savedObjects.R). + saved <- .savedHandlePanel(current, .ldRefSource(current)$path, "plink1") + old <- .savedUnder( + .qtlWithGenotypeHandle(qtlDatasetExample, saved), + c(study = "studyName") + ) + up <- updateObject(old) + expect_true(methods::validObject(up)) + expect_identical(studyName(up), studyName(qtlDatasetExample)) + geno <- .qtlGenotypeSe(up) + expect_s4_class(.panelSeed(geno), "GenotypeDosageSeed") + expect_identical(dimnames(geno), dimnames(current)) + expect_identical( + SummarizedExperiment::colData(geno), + SummarizedExperiment::colData(current) + ) +}) + +test_that("updateObject refuses a QtlDataset whose genotypes cannot be read", { + data(qtlDatasetExample) + current <- .qtlGenotypeSe(qtlDatasetExample) + gone <- .savedHandlePanel( + current, + file.path(tempdir(), "nowhere"), + "plink1" + ) + old <- .qtlWithGenotypeHandle(qtlDatasetExample, gone) + cnd <- tryCatch(updateObject(old), error = identity) + expect_s3_class(cnd, "pecotmrUnreadablePanel") +}) + # =========================================================================== # show() # =========================================================================== diff --git a/tests/testthat/test_RangedTupleList.R b/tests/testthat/test_RangedTupleList.R index e0722143..f8b2b360 100644 --- a/tests/testthat/test_RangedTupleList.R +++ b/tests/testthat/test_RangedTupleList.R @@ -993,38 +993,84 @@ test_that("blockId reads the recorded value, not the variants' span", { # updateObject(): collections saved before references became per-row # =========================================================================== -# A collection as an earlier version saved it: one reference (or NULL) in the -# slot and no row key. -.rtl_asSaved <- function(x, ref) { - old <- `slot<-`(x, "ldReference", check = FALSE, value = ref) - md <- attr(old, "elementMetadata") - md[["ldReference"]] <- NULL - attr(old, "elementMetadata") <- md - old -} +# The collections saved this way are built by helper-savedObjects.R. test_that("updateObject keys every row of an old collection to its reference", { data(qtlSumStatsMulticontextExample) mc <- qtlSumStatsMulticontextExample panel <- ldReference(mc)[[1L]] - old <- .rtl_asSaved(mc, panel) + old <- .savedWithOneLdRef(mc, panel) # Read as it was saved, the old object is refused, not taken as LD-free. expect_error(ldReference(old), "updateObject") new <- updateObject(old) expect_true(methods::validObject(new)) expect_identical(ldReference(new), list(ld1 = panel)) expect_identical(new$ldReference, rep("ld1", nrow(mc))) + # Saved before the slot was renamed, it holds the reference as ldSketch: + # refused the same way, and brought to the same object. + sketched <- .savedWithLdSketch(mc, panel) + expect_error(ldReference(sketched), "updateObject") + expect_identical(updateObject(sketched), new) }) test_that("updateObject marks every row of an old LD-free collection LD-free", { data(qtlFineMappingExample) - old <- .rtl_asSaved(qtlFineMappingExample, NULL) + old <- .savedWithOneLdRef(qtlFineMappingExample, NULL) # Read as it was saved, it already reads LD-free: a NULL slot meant no # reference then too, so there is nothing to refuse. expect_identical(ldReference(old), list()) new <- updateObject(old) expect_identical(ldReference(new), list()) expect_true(all(is.na(new$ldReference))) + # A NULL saved under the old name is read back as NULL, not as the + # placeholder R stores it as. + sketched <- .savedWithLdSketch(qtlFineMappingExample, NULL) + expect_identical(updateObject(sketched), new) +}) + +test_that("updateObject reads a collection's saved PLINK1 reference again", { + data(qtlSumStatsMulticontextExample) + mc <- qtlSumStatsMulticontextExample + current <- ldReference(mc)[[1L]] + saved <- .savedHandlePanel( + current, + "pecotmr://extdata/toy_canonical", + "plink1" + ) + up <- updateObject(.savedWithLdSketch(mc, saved)) + ref <- ldReference(up)[[1L]] + expect_s4_class(.panelSeed(ref), "GenotypeDosageSeed") + expect_identical(dimnames(ref), dimnames(current)) + expect_equal( + as.matrix(SummarizedExperiment::assay(ref)[1:3, 1:4]), + as.matrix(SummarizedExperiment::assay(current)[1:3, 1:4]) + ) +}) + +test_that("updateObject keeps a reference it cannot read again, then retries", { + data(qtlFineMappingExample) + files <- str_c( + test_path("test_data", "test_variants"), + c(".bed", ".bim", ".fam") + ) + stem <- file.path(withr::local_tempdir(), "panel") + moved <- str_c(stem, c(".bed", ".bim", ".fam")) + file.copy(files, moved) + saved <- .savedHandlePanel( + readGenotypes(stem, format = "plink1"), + stem, + "plink1" + ) + unlink(moved) + old <- .savedWithLdSketch(qtlFineMappingExample, saved) + # The rest of the collection is brought up to date; the reference is kept + # as saved, and the warning says why. + expect_warning(up <- updateObject(old), "kept as saved") + expect_identical(ldReference(up), list(ld1 = saved)) + # With the files back, updating again finishes the job. + file.copy(files, moved) + again <- updateObject(up) + expect_s4_class(.panelSeed(ldReference(again)[[1L]]), "GenotypeDosageSeed") }) test_that("updateObject leaves a current collection as it is", { diff --git a/tests/testthat/test_colocboostPipeline.R b/tests/testthat/test_colocboostPipeline.R index 8647c76f..7a827b3b 100644 --- a/tests/testthat/test_colocboostPipeline.R +++ b/tests/testthat/test_colocboostPipeline.R @@ -1750,18 +1750,19 @@ test_that("a GWAS study's overlapped rows must share one LD reference", { ) }) -test_that(".cbAssertFocalOutcome takes a study name or a named QTL vector", { +test_that(".cbAssertFocalOutcome takes NULL or a named QTL vector", { ok <- list( NULL, - NA, - "G1", c(trait = "ENSG1"), c(study = "S1", context = "brain", trait = "ENSG1") ) for (x in ok) { - expect_invisible(pecotmr:::.cbAssertFocalOutcome(x)) + expect_invisible(pecotmr:::.cbAssertFocalOutcome(x, TRUE)) } + # A GWAS study name is not one: its separate run is the focal one. bad <- list( + NA, + "G1", 1, c("G1", "G2"), c(gene = "ENSG1"), @@ -1771,45 +1772,36 @@ test_that(".cbAssertFocalOutcome takes a study name or a named QTL vector", { list(trait = "ENSG1") ) for (x in bad) { - expect_error(pecotmr:::.cbAssertFocalOutcome(x), "focalOutcome") + expect_error( + pecotmr:::.cbAssertFocalOutcome(x, TRUE), + "must be NULL or a named" + ) } + # Only the xQTL-only run is ever focal on a QTL outcome. + expect_error( + pecotmr:::.cbAssertFocalOutcome(c(trait = "ENSG1"), FALSE), + "but .xqtlColoc. is FALSE" + ) + expect_invisible(pecotmr:::.cbAssertFocalOutcome(NULL, FALSE)) }) -test_that(".cbResolveFocal: the lone GWAS by default, a named one, or none", { - one <- .cbp_makeGwasSumStats() - two <- .cbp_makeTwoGwas() +test_that(".cbResolveFocal: the one QTL outcome named, or none", { qtlInfo <- tibble::tibble( name = c("brain_ENSG1", "liver_ENSG1", "Q1:c1:t1"), study = c("S1", "S1", "Q1"), context = c("brain", "liver", "c1"), trait = c("ENSG1", "ENSG1", "t1") ) - resolve <- function(focal, gws, keys) { - pecotmr:::.cbResolveFocal(focal, gws, qtlInfo, keys) - } - keys <- c(G1 = "G1", G2 = "G2") - # One study: the GWAS is the joint run's focal outcome, unless NA. - expect_equal(resolve(NULL, one, keys[1]), list(xqtl = NULL, joint = "G1")) - expect_equal(resolve(NA, one, keys[1]), list(xqtl = NULL, joint = NULL)) - # ...and only when it reached the runs. - expect_null(resolve(NULL, one, character(0))$joint) - # Several studies: none, unless one is named. - expect_equal(resolve(NULL, two, keys), list(xqtl = NULL, joint = NULL)) - expect_equal(resolve("G2", two, keys)$joint, "G2") - expect_error(resolve("G3", two, keys), "names no GWAS study") - expect_error(resolve("G1", NULL, character(0)), "no gwasSumStats") - expect_error(resolve("G2", two, keys[1]), "none of its rows overlap") - # A QTL outcome, by as many parts as it takes, is focal in both runs. - expect_equal( - resolve(c(context = "brain", trait = "ENSG1"), two, keys), - list(xqtl = "brain_ENSG1", joint = "brain_ENSG1") - ) - expect_equal(resolve(c(trait = "t1"), two, keys)$xqtl, "Q1:c1:t1") - expect_error(resolve(c(trait = "ENSG1"), two, keys), "matches 2 QTL") - expect_error(resolve(c(trait = "nope"), two, keys), "matches no QTL") + resolve <- function(focal) pecotmr:::.cbResolveFocal(focal, qtlInfo) + expect_null(resolve(NULL)) + # A QTL outcome, by as many parts as it takes to name one. + expect_equal(resolve(c(context = "brain", trait = "ENSG1")), "brain_ENSG1") + expect_equal(resolve(c(trait = "t1")), "Q1:c1:t1") + expect_error(resolve(c(trait = "ENSG1")), "matches 2 QTL") + expect_error(resolve(c(trait = "nope")), "matches no QTL") }) -test_that("the joint run is focal on a lone GWAS study by default", { +test_that("the joint run is non-focal; focalOutcome reaches xQTL-only", { seen <- list() local_mocked_bindings( extractBlockGenotypes = .cbp_mockExtractor(), @@ -1822,32 +1814,47 @@ test_that("the joint run is focal on a lone GWAS study by default", { }, .package = "colocboost" ) - # Built once: the runs below differ only in their focal outcome. + # Built once: the runs below differ only in their flags. qtl <- .cbp_makeQtlSumStats() oneGwas <- .cbp_makeGwasSumStats() - twoGwas <- .cbp_makeTwoGwas() run <- function(gws, ...) { seen <<- list() - suppressMessages(colocboostPipeline( - qtl, - gwasSumStats = gws, + suppressMessages(colocboostPipeline(qtl, gwasSumStats = gws, ...)) + seen + } + # One GWAS: the joint run and its separate run fit the same outcomes, + # one non-focal and one focal on the GWAS. + calls <- run( + oneGwas, + xqtlColoc = FALSE, + jointGwas = TRUE, + separateGwas = TRUE + ) + expect_length(calls, 2L) + expect_equal(calls[[1L]]$outcome_names, c("Q1:c1:t1", "G1")) + expect_null(calls[[1L]]$focal_outcome_idx) + expect_equal(calls[[2L]]$outcome_names, c("Q1:c1:t1", "G1")) + expect_equal(calls[[2L]]$focal_outcome_idx, 2L) + # Several GWAS studies leave the joint run non-focal too. + twoGwas <- run(.cbp_makeTwoGwas(), xqtlColoc = FALSE, jointGwas = TRUE) + expect_null(twoGwas[[1L]]$focal_outcome_idx) + # A QTL outcome is focal in the xQTL-only run, and only there. + calls <- run(oneGwas, jointGwas = TRUE, focalOutcome = c(trait = "t1")) + expect_equal(calls[[1L]]$focal_outcome_idx, 1L) + expect_null(calls[[2L]]$focal_outcome_idx) + expect_error( + run( + oneGwas, xqtlColoc = FALSE, jointGwas = TRUE, - ... - )) - seen[[1L]] - } - call <- run(oneGwas) - expect_equal(call$outcome_names, c("Q1:c1:t1", "G1")) - expect_equal(call$focal_outcome_idx, 2L) - off <- run(oneGwas, focalOutcome = NA) - expect_null(off$focal_outcome_idx) - toQtl <- run(oneGwas, focalOutcome = c(trait = "t1")) - expect_equal(toQtl$focal_outcome_idx, 1L) - # Two studies: non-focal unless one is named. - expect_null(run(twoGwas)$focal_outcome_idx) - named <- run(twoGwas, focalOutcome = "G2") - expect_equal(named$outcome_names[[named$focal_outcome_idx]], "G2") + focalOutcome = c(trait = "t1") + ), + "but .xqtlColoc. is FALSE" + ) + expect_error( + run(oneGwas, jointGwas = TRUE, focalOutcome = "G1"), + "must be NULL or a named" + ) }) test_that("a QTL sumstat outcome records the tuple it came from", { @@ -1876,12 +1883,7 @@ test_that("a focalOutcome vector with no QTL outcomes to match says so", { trait = character(0) ) expect_error( - pecotmr:::.cbResolveFocal( - c(trait = "t1"), - .cbp_makeGwasSumStats(), - noQtl, - c(G1 = "G1") - ), + pecotmr:::.cbResolveFocal(c(trait = "t1"), noQtl), "The QTL outcomes are: none" ) }) diff --git a/tests/testthat/test_genotypeIo.R b/tests/testthat/test_genotypeIo.R index bca2d94d..af15fef1 100644 --- a/tests/testthat/test_genotypeIo.R +++ b/tests/testthat/test_genotypeIo.R @@ -2452,3 +2452,109 @@ test_that("a set's shards hold the same samples, one chromosome each", { "appears in more than one per-chromosome file" ) }) + +# =========================================================================== +# Panels saved by an earlier version (.updatePanel) +# =========================================================================== + +# The saved panels are built by helper-savedObjects.R. + +test_that(".updatePanel reads a saved PLINK1 panel again through its backend", { + stem <- test_path("test_data", "test_variants") + fresh <- readGenotypes(stem, format = "plink1") + saved <- .savedHandlePanel(fresh, stem, "plink1") + SummarizedExperiment::colData(saved) <- S4Vectors::DataFrame( + age = seq_len(ncol(fresh)), + row.names = colnames(fresh) + ) + # Saved as it was held: a few variants and samples, out of file order. + saved <- saved[c(4L, 2L, 7L), c(3L, 1L)] + # As saved, its dosages go through a reader handles no longer have. + expect_error( + as.matrix(SummarizedExperiment::assay(saved)), + "Unsupported format.*plink1" + ) + up <- .updatePanel(saved) + expect_s4_class(.panelSeed(up), "GenotypeDosageSeed") + expect_identical(dimnames(up), dimnames(saved)) + expect_equal( + as.matrix(SummarizedExperiment::assay(up)), + as.matrix(SummarizedExperiment::assay(fresh))[c(4L, 2L, 7L), c(3L, 1L)] + ) + expect_identical( + SummarizedExperiment::colData(up), + SummarizedExperiment::colData(saved) + ) + expect_identical(.ldRefSource(up)$format, "plink1") + # Brought up to date, it is current, and a second update leaves it be. + expect_identical(.updatePanel(up), up) +}) + +test_that(".updatePanel gives a saved stochastic sketch its real n and AF", { + skip_if_not_installed("pgenlibr") + ref <- "pecotmr://extdata/ld_reference/chr22/protocol_example.LD.chr22" + fresh <- readGenotypes(.resolveGenotypeResourcePath(ref), format = "plink2") + saved <- .savedHandlePanel(fresh, ref, "plink2") + # Saved before sketches recorded them, it passes for real genotypes. + expect_false(.ldRefIsProjection(saved)) + up <- .updatePanel(saved) + expect_true(.ldRefIsProjection(up)) + expect_identical(.ldRefRealNSamples(up), .ldRefRealNSamples(fresh)) + expect_identical(.ldRefAf(up), .ldRefAf(fresh)) + expect_identical(dimnames(up), dimnames(saved)) + expect_identical(.updatePanel(up), up) +}) + +test_that(".updatePanel reads a saved per-chromosome panel again", { + files <- c( + chr21 = test_path("test_data", "test_variants.bed"), + chr22 = test_path("test_data", "test_variants_chr22.bed") + ) + fresh <- readGenotypes(genoMeta = files) + saved <- .savedHandlePanel(fresh, "per-chromosome", "plink1", files) + # One variant from each chromosome. + keep <- c(2L, nrow(fresh) - 1L) + up <- .updatePanel(saved[keep, ]) + expect_identical(dimnames(up), dimnames(fresh[keep, ])) + expect_equal( + as.matrix(SummarizedExperiment::assay(up)), + as.matrix(SummarizedExperiment::assay(fresh)[keep, ]) + ) + expect_identical(.updatePanel(up), up) +}) + +test_that(".updatePanel takes a saved bare handle as the panel over it", { + stem <- test_path("test_data", "test_variants") + fresh <- readGenotypes(stem, format = "plink1") + handle <- .ldRefHandle(.savedHandlePanel(fresh, stem, "plink1")) + up <- .updatePanel(handle) + expect_s4_class(.panelSeed(up), "GenotypeDosageSeed") + expect_identical(dimnames(up), dimnames(fresh)) +}) + +test_that(".updatePanel leaves a current panel, or no panel, as it is", { + expect_null(.updatePanel(NULL)) + stem <- test_path("test_data", "test_variants") + plink1 <- readGenotypes(stem, format = "plink1") + expect_identical(.updatePanel(plink1), plink1) + skip_if_not_installed("pgenlibr") + plink2 <- readGenotypes(stem, format = "plink2") + expect_identical(.updatePanel(plink2), plink2) +}) + +test_that(".updatePanel refuses a saved panel it cannot read again", { + stem <- test_path("test_data", "test_variants") + fresh <- readGenotypes(stem, format = "plink1") + gone <- .savedHandlePanel(fresh, file.path(tempdir(), "nowhere"), "plink1") + cnd <- tryCatch(.updatePanel(gone), error = identity) + expect_s3_class(cnd, "pecotmrUnreadablePanel") + expect_match(conditionMessage(cnd), "nowhere.*cannot be read") + # Its files are where they were, but no longer hold one of its variants. + moved <- .savedHandlePanel(fresh, stem, "plink1") + rr <- SummarizedExperiment::rowRanges(moved) + rr[1L] <- GenomicRanges::shift(rr[1L], 1L) + SummarizedExperiment::rowRanges(moved) <- rr + cnd <- tryCatch(.updatePanel(moved), error = identity) + expect_s3_class(cnd, "pecotmrUnreadablePanel") + expect_match(conditionMessage(cnd), "no longer hold every variant") +}) diff --git a/tests/testthat/test_twasWeights.R b/tests/testthat/test_twasWeights.R index b81882a3..0c11cbd6 100644 --- a/tests/testthat/test_twasWeights.R +++ b/tests/testthat/test_twasWeights.R @@ -2348,6 +2348,20 @@ test_that("updateObject() backfills a fitted row's held variants", { expect_message(updateObject(tw, verbose = TRUE), "TwasWeights") }) +test_that("updateObject() backfills held variants and keys LD rows at once", { + tw <- .tw_collection(list( + TwasWeightsRow(.tw_ids, c(0.1, 0.2, 0.3), cvResult = list(r2 = 0.4)) + )) + saved <- tw + saved$fitVariants <- NULL + up <- updateObject(.savedWithLdSketch(saved, NULL)) + expect_true(validObject(up)) + expect_equal(as.character(up$fitVariants[[1L]]), .tw_ids) + expect_identical(ldReference(up), list()) + expect_true(is.na(up$ldReference)) + expect_identical(updateObject(up), up) +}) + # =========================================================================== # estimateSparsity # =========================================================================== diff --git a/vignettes/colocboost-pipeline.Rmd b/vignettes/colocboost-pipeline.Rmd index 46091367..8583ef0b 100644 --- a/vignettes/colocboost-pipeline.Rmd +++ b/vignettes/colocboost-pipeline.Rmd @@ -59,9 +59,12 @@ ColocBoost can run three different model flavours in one call. | Flag | Default | What | |---|---|---| | `xqtlColoc` | TRUE | QTL-only colocboost across the QTL contexts. | -| `jointGwas` | FALSE | All QTL outcomes with every GWAS study in one model; focal on a lone GWAS. | +| `jointGwas` | FALSE | All QTL outcomes with every GWAS study in one non-focal model. | | `separateGwas` | FALSE | One focal colocboost model per GWAS study (the GWAS is the focal outcome). | +The flags combine freely. With a single GWAS study, `jointGwas` and +`separateGwas` fit the same outcomes, one non-focal and one focal on the GWAS. + ## xQTL-only colocalization The default call runs colocboost over the contexts in the QTL data with no @@ -96,9 +99,9 @@ names(res2) Each GWAS study is one outcome: the rows of the study that the QTL data overlap, joined. A study split by chromosome or LD block contributes only the one or two rows the QTL region reaches, and QTL variants past those blocks are -checked as `colocPipeline()` checks them. With a single GWAS study, as here, the -joint run is focal on it; with several it is non-focal, since only one -outcome can be focal (see below). +checked as `colocPipeline()` checks them. The joint run is non-focal however +many GWAS studies it holds (colocboost's disease-agnostic mode); for a run +focal on a GWAS, use `separateGwas`. ## QTL + GWAS (per-GWAS focal models) @@ -152,12 +155,10 @@ resMs <- colocboostPipeline( ## Focal outcome -`focalOutcome` chooses the focal outcome. A plain string names a GWAS -study, which becomes the joint run's focal outcome. A named vector names a -QTL outcome by its `study`, `context` and `trait`, as many as it takes to -pick out one, and that outcome is focal in both the xQTL-only and the joint -run. `NA` makes every run non-focal. The `separateGwas` runs are always -focal on their own GWAS study. +`focalOutcome` makes one QTL outcome focal in the xQTL-only run. It names +the outcome by its `study`, `context` and `trait`, as many as it takes to +pick out one. The default, `NULL`, leaves that run non-focal. The joint run +is never focal, and each `separateGwas` run is focal on its own GWAS study. ```{r focal, eval=FALSE} colocboostPipeline( @@ -177,7 +178,7 @@ colocboostPipeline( traitId = "ENSG_example", region = NULL, # alternative to traitId + cisWindow cisWindow = 5e5, # required with traitId - focalOutcome = NULL, # the GWAS study, when there is only one + focalOutcome = NULL, # a QTL outcome to make the xQTL-only run focal on xqtlColoc = TRUE, jointGwas = FALSE, separateGwas = FALSE, From 70b010cf8618f93ceffe6c01e16075f364f5e20c Mon Sep 17 00:00:00 2001 From: danielnachun Date: Tue, 27 Oct 2026 21:03:24 +0000 Subject: [PATCH 5/5] Update documentation --- man/{fineMappingRow.Rd => FineMappingRow.Rd} | 0 man/{twasWeightsRow.Rd => TwasWeightsRow.Rd} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename man/{fineMappingRow.Rd => FineMappingRow.Rd} (100%) rename man/{twasWeightsRow.Rd => TwasWeightsRow.Rd} (100%) diff --git a/man/fineMappingRow.Rd b/man/FineMappingRow.Rd similarity index 100% rename from man/fineMappingRow.Rd rename to man/FineMappingRow.Rd diff --git a/man/twasWeightsRow.Rd b/man/TwasWeightsRow.Rd similarity index 100% rename from man/twasWeightsRow.Rd rename to man/TwasWeightsRow.Rd

      Ty%3pbwklKwle%Q6)8GJSgFyQPF2$J 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∋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 diff --git a/data/ctwasWeightsExample.rda b/data/ctwasWeightsExample.rda index 9a847a381c386733ad46dcb9836d888c0bc4fb87..e10a266aee24272620087d4c11b425dba7ef45af 100644 GIT binary patch delta 2383 zcmV-V39$BM6bHKHG&8UpW3z+wl{!-JcV^8wxn%bj2lE{?pFj&_ zA$m`hF&))|Swu+b-BBnkJIBU)$86W1YcGd#aVo5}MOoZcTgS_k8e$Ygk0P8yECN2n zWy*5R5EUcI2)F?WHY+-T+KPV)fjo+vxE6NN9Vl2!mz|wSHl6w zTvzgt@oyjY#xv{8iMQKYb+6hm5}%8l$47&F2_afw-1jetXlq3BCD?y}AoEx2HRrPY zablE8se;_N$gEus*(xnWYx6&1WSy22(6f|Eue00)+*70pyL?Wu>hBZ~`ooHpp!D$g zpm7dE5$UpD^r+OGaxk$_RRS116+V%KZ{cBc`1W9tJ6UO;`GaXrU68KV+3OE%7YS(Z zsxPt)i{tmDJz)Ptc71>D=(Y}Sdz%Q$3C z2v>k~1VJcNWo3I-n{2;(bn*%79-LhjzbIC5GR{^b&55n9-po)Y-M|hsinxo6Mj`pw z1|vKG+``zt9(8~u`qCN~0XU@U#TISv8^wE8%1M$+FsI8!phSOBO2(MU0F25qJ@9?n}l3D1z`)}?vUZ&7# z5hDQ@@ePotsY!psFE4hznG0F;DBh84FF27w38a=v_<+4N=9?K8R3ZQnkwk{^)Sof3 zSTc{E`0(ShxD%!_RBvkX4Mb(ql>qh(zT({)qV4R)beeFtGweE`RYW@eKM3so~swGU8I%gAVH-=rggwVFR_J3$f z^{9c)D9Pm3O_hikrnDg4eZ(I4X3BAlpwv{4bOtS%>??QX-4xT0Xf{Cz9?Y5wINhsf z49S0NdTain9wlH9`KN20tWY?#_`}DLq3P45N8=1OA$fd+xKn%7dzRvb*ka4msB)(i*h|Af^_X zK@*LUz}$fg6Qd>}KeQ{Qoxy|0PketG@=_+gJ38@Oa%$6q*QwT!p^Rs|J3AX& zNaf0%4>_wG8~ncaK0qIXdV}|}DZ*WyuIFEtYhWn3fP3QJXL$@{x7*VoDQW5Hy*~{$^Uv#%tu}v) zhu}+v(2O5`c5DVm2#gv5LJl|dK!66ql2H^qg_7}UX%HnJe_S=sIw(w3R+~M}6UBK9 zUdh~?Dm4Wi9*S-aGdh^;yQQBrf+9n#Mi;f*l6s(M(pgQaQ*s(Jr zFI?z`dkux}tUKueok<-52UzNQ1w>%w<}nZuIz&|kIpZa6$e)w=Fp7Sd*|c*53NUIOjXH>JDCB0l zX{+u((4&3Wz@qe=2TG>|iGPhfm(MeG7aAdbwq6*3cm7(@7A)%IQ&A578AezKZ#IYE zr~r>#0B2x|!`)(E@?w(RaK3+Z(%#zF+FGT?XSe*oae7<5d{klNY`@v8@Ufc<`(l!@ z&+X8qWvr`6+{mFQAQekqaF4G$f1BFvH_!FcQ9s#5bp_&n zN?Ea*u&qdN*n8w~(n4(s#3%kQ*rPndoPdHDhly#1*t>_c6vpTtu2i9Q<(MU&1$r z5E377)2D}Y6bP!0`n8Rd%G7iX|AjB&njGGX<48z=r|-(Y%h~Z~6iU-hPGe1qht#In z5upmInI-)2NLG!-8e@M{;Z=$L3O3r}zDvW*%P}W;&P8>M988SqlM`2NVX+B(xVtr7 zSSpFw5B9^0W~J`!mOziqld;|vajw(v(~xgIx`WKu#E$Ii^8JI$&Z5XxyJ{8HEA{n! zjl*{wcvhu2Q%~-~fQ}iVnZkkxiO<6y`P5JxtlMYr;KJG4~ z%pQ@pxVGbP984um{~dEmh%mWA004kl6;uEL=QFhQ1pqb6KXX1X4T}N*00001Sz6zR BtgHY4 delta 2266 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 delta 21719 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

    2. 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⪚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%0Ad_H)LC?5VaIh6NP&^o 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

    DR|JA65Iue@d3ImSxqo%H^<=eT^{&~fuvoM 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 K000000a;qWG?|A0 diff --git a/data/qtlFineMappingPairedExample.rda b/data/qtlFineMappingPairedExample.rda index a44a5a4fd3938de5aa32fd042cfee27b95d128f3..92c852a1e98427db5ee8ad54c040971545c5265b 100644 GIT binary patch literal 19332 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 D6iuUZ literal 19336 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 delta 8279 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 QVQ0YG%>)!@V2q3c0B9E7{{R30 literal 16384 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%0A<^NMeQbch~ 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 delta 10119 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 diff --git a/inst/scripts/build_ctwas_examples.R b/inst/scripts/build_ctwas_examples.R index 682dff72..b0e9a097 100644 --- a/inst/scripts/build_ctwas_examples.R +++ b/inst/scripts/build_ctwas_examples.R @@ -95,14 +95,14 @@ data(ctwasWeightsExample) # portable "pecotmr://extdata/" form afterwards -- the same two-step # every other bundled example uses. .resolveGenotypeResourcePath() turns it # back into a real path at read time, on whatever machine has the package. -ctwasWeightsExample <- methods::initialize( +ctwasWeightsExample <- pecotmr:::.withRowLdRefs( ctwasWeightsExample, - ldReference = pecotmr:::.asLdRef(.portableHandle(ldStem)) + .portableHandle(ldStem) ) stopifnot( path(pecotmr:::.ldRefHandle( - ldReference(ctwasWeightsExample) + ldReference(ctwasWeightsExample)[[1L]] )) == asBundledResource(ldStem) ) diff --git a/man/ColocBoostResult-class.Rd b/man/ColocBoostResult-class.Rd index 263dc8b4..61eaa447 100644 --- a/man/ColocBoostResult-class.Rd +++ b/man/ColocBoostResult-class.Rd @@ -12,11 +12,20 @@ A collection of ColocBoost results, one element per confidence \section{Slots}{ \describe{ +\item{\code{ldReference}}{A named list of the LD references the summary statistics +were matched against, each a genotype panel, a \code{GenotypeMixture} or +an \code{LdMatrix}, and each stored once however many outcomes used it. +Empty when no summary statistics were analysed.} + \item{\code{outcomeInfo}}{A data frame mapping each outcome \code{name} to its -\code{study}, \code{context}, \code{trait} and \code{dataForm}. ColocBoost -is given outcome names as bare labels, and those labels are lossy -- a -trait is context-qualified only when ambiguous -- so the mapping is -recorded when the names are minted rather than parsed back out later.} +\code{study}, \code{context}, \code{trait}, \code{dataForm} and +\code{ldReference}, the name of the \code{ldReference} entry its +summary statistics were matched against (\code{NA} for an +individual-level outcome, whose LD comes from its own genotypes). +ColocBoost is given outcome names as bare labels, and those labels are +lossy -- a trait is context-qualified only when ambiguous -- so the +mapping is recorded when the names are minted rather than parsed back +out later.} \item{\code{regionVcp}}{A \code{GRanges} of every variant in the analysed region carrying the marginal \code{vcp}. Collection-level: it spans the region, diff --git a/man/ColocBoostResult.Rd b/man/ColocBoostResult.Rd index d7d5e1dd..06381778 100644 --- a/man/ColocBoostResult.Rd +++ b/man/ColocBoostResult.Rd @@ -27,10 +27,15 @@ analysis each element came from.} naming the GWAS study for the per-study \code{separate_gwas} runs.} \item{outcomeInfo}{Data frame mapping outcome \code{name} to \code{study}, -\code{context}, \code{trait} and \code{dataForm}.} +\code{context}, \code{trait} and \code{dataForm}, and optionally to +\code{ldReference}, the name of the \code{ldReference} entry the +outcome's summary statistics were matched against. Without that column +every outcome gets \code{NA}.} -\item{ldReference}{Optional genotype panel (see -\code{\link{readGenotypes}}).} +\item{ldReference}{Optional named list of the LD references the summary +statistics were matched against: genotype panels (see +\code{\link{readGenotypes}}), \code{GenotypeMixture} or \code{LdMatrix} +objects.} \item{computingTime}{Optional list of per-analysis timings.} diff --git a/man/ColocResult-class.Rd b/man/ColocResult-class.Rd index a1eb4c4f..cc6b82ea 100644 --- a/man/ColocResult-class.Rd +++ b/man/ColocResult-class.Rd @@ -11,9 +11,18 @@ A collection of colocalization results, one element per tested \code{\link{colocCredibleSets}} and \code{\link{colocGenes}}. } \details{ -The inherited \code{ldReference} is what - \code{colocCredibleSets()} uses to compute credible-set purity. +The \code{ldReference} is what \code{colocCredibleSets()} uses to + compute credible-set purity, each pair's from its own reference. } +\section{Slots}{ + +\describe{ +\item{\code{ldReference}}{A named list of the LD references the pairs were computed +against, each a genotype panel, a \code{GenotypeMixture} or an +\code{LdMatrix}, stored once apiece; the \code{ldReference} column of +\code{mcols} names the entry each pair used (\code{NA} for none).} +}} + \seealso{ \code{\link{colocPipeline}} } diff --git a/man/ColocResult.Rd b/man/ColocResult.Rd index e20eaf18..69bacd43 100644 --- a/man/ColocResult.Rd +++ b/man/ColocResult.Rd @@ -18,9 +18,11 @@ columns are \code{NA} for it.} \item{variants}{A list, parallel to \code{pairs}' rows, of per-pair data frames with a \code{variant_id} column and a \code{SNP.PP.H4} column.} -\item{ldReference}{Optional genotype panel (see \code{\link{readGenotypes}}) -for the LD reference, used by \code{\link{colocCredibleSets}} to -compute purity.} +\item{ldReference}{Optional LD reference -- a genotype panel (see +\code{\link{readGenotypes}}), a \code{GenotypeMixture} or an +\code{LdMatrix} -- for every pair, or a list with one per pair; used by +\code{\link{colocCredibleSets}} to compute purity. Each distinct +reference is stored once.} } \value{ A \code{ColocResult}. diff --git a/man/ColocResultBase-class.Rd b/man/ColocResultBase-class.Rd index 3c4e20ac..5849da1d 100644 --- a/man/ColocResultBase-class.Rd +++ b/man/ColocResultBase-class.Rd @@ -17,14 +17,9 @@ Virtual base shared by \code{\linkS4class{ColocResult}} (from projection surface: both answer \code{\link{colocPairs}} and \code{\link{colocVariants}}, so code that only needs "which variants colocalized, and how strongly" works against either. -} -\section{Slots}{ - -\describe{ -\item{\code{ldReference}}{The LD reference the underlying fits were computed -against (a genotype panel, a \code{GenotypeMixture} or an -\code{LdMatrix}), or \code{NULL}. Shared by both subclasses: coloc and -ColocBoost report different statistics, but both are computed against a -reference and both are asked for it the same way.} -}} + Each subclass carries its own LD reference, and both answer + \code{\link{ldReference}}: a \code{ColocResult} holds the one reference + its pairs were computed against, a \code{ColocBoostResult} one per + reference its summary statistics were matched against. +} diff --git a/man/FineMappingResultBase-class.Rd b/man/FineMappingResultBase-class.Rd index f41dc3a6..69a67103 100644 --- a/man/FineMappingResultBase-class.Rd +++ b/man/FineMappingResultBase-class.Rd @@ -7,7 +7,8 @@ \description{ Virtual base class for fine-mapping result collections. Concrete subclasses (\code{QtlFineMappingResult}, \code{GwasFineMappingResult}) - carry a \code{DFrame} of per-fit rows and a shared \code{ldReference} slot. + carry a \code{DFrame} of per-fit rows and an \code{ldReference} slot + listing the LD references those fits used. Downstream pipelines should dispatch on \code{FineMappingResultBase} for behaviors that apply to either flavour, and on the concrete subclass when the tuple shape matters. @@ -15,10 +16,11 @@ Virtual base class for fine-mapping result collections. Concrete \section{Slots}{ \describe{ -\item{\code{ldReference}}{The LD reference the fits were computed against (a -genotype panel, a \code{GenotypeMixture} or an \code{LdMatrix}), or -\code{NULL} when the fits were derived from individual-level data. Used -downstream to check that pipelines combining results share one LD -reference.} +\item{\code{ldReference}}{A named list of the LD references the fits were +computed against, each a genotype panel, a \code{GenotypeMixture} or an +\code{LdMatrix}, stored once apiece; the \code{ldReference} column of +\code{mcols} names the entry each row used (\code{NA} for a fit derived +from individual-level data). Used downstream to check that the rows a +pipeline combines share an LD reference.} }} diff --git a/man/GwasFineMappingResult.Rd b/man/GwasFineMappingResult.Rd index 4ce6f050..24bec1f3 100644 --- a/man/GwasFineMappingResult.Rd +++ b/man/GwasFineMappingResult.Rd @@ -45,9 +45,9 @@ derives the window from the span of the variants present.} one per row; \code{NULL} (default) omits the column.} \item{dataSource}{Optional per-row label for the kind of input the fit saw, -\code{"individual"} or \code{"sumstat"}. Recorded rather than derived: a -combined collection can hold rows of both kinds, and its single -\code{ldReference} cannot say which row came from which.} +\code{"individual"} or \code{"sumstat"}. Where it is absent, the result +writers read a row's kind from its LD reference: a row with none saw +individual-level data.} \item{weightStandardized}{Optional per-row flag: whether the posterior effect is on the STANDARDIZED genotype scale. The posterior effect IS the @@ -57,8 +57,11 @@ it standardizes genotypes before fitting, and the posterior mean is reported on the scale of the \code{X} the fit was given. The argument exists for a collection assembled by hand, where only the caller knows.} -\item{ldReference}{An optional genotype panel (see -\code{\link{readGenotypes}}).} +\item{ldReference}{The LD reference the fits were computed against -- a +genotype panel (see \code{\link{readGenotypes}}), a +\code{GenotypeMixture} or an \code{LdMatrix} -- used for every row, or +a list with one per row; \code{NULL} for none. Each distinct reference is +stored once.} } \value{ A \code{GwasFineMappingResult} object. diff --git a/man/GwasSumStats-class.Rd b/man/GwasSumStats-class.Rd index c3980a98..bf89ec67 100644 --- a/man/GwasSumStats-class.Rd +++ b/man/GwasSumStats-class.Rd @@ -12,9 +12,10 @@ S4 collection of GWAS summary statistics keyed by the identity } \details{ Required column: \code{study}, unique across rows. The class-level - slots inherited from \code{\linkS4class{SumStatsBase}} -- - \code{ldReference}, \code{genome} and \code{qcInfo} -- apply uniformly to - every row. + slots inherited from \code{\linkS4class{SumStatsBase}} -- \code{genome} + and \code{qcInfo} -- apply uniformly to every row; \code{ldReference} + holds each distinct LD reference once, and the \code{ldReference} column + names the one each row uses. } \seealso{ \code{\link{GwasSumStats}} for the constructor and diff --git a/man/GwasSumStats.Rd b/man/GwasSumStats.Rd index f0d578fc..778eecf3 100644 --- a/man/GwasSumStats.Rd +++ b/man/GwasSumStats.Rd @@ -26,12 +26,13 @@ GwasSumStats( study.} \item{genome}{Single character string giving the genome build (e.g., -\code{"hg19"}, \code{"hg38"}). Uniform across the collection because all -entries share the same LD reference.} +\code{"hg19"}, \code{"hg38"}). One build per collection.} \item{ldReference}{The LD reference: a genotype panel (see \code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} or an -\code{\link{LdMatrix}}.} +\code{\link{LdMatrix}}, used for every study, or a list with one per +study when they sit on different references. Each distinct reference is +stored once, and the \code{ldReference} column names each row's.} \item{varY}{Optional numeric vector of per-study phenotype variances (\code{NA_real_} entries allowed). Used by the sufficient-statistic @@ -86,8 +87,8 @@ A \code{GwasSumStats} object. \description{ Construct a \code{GwasSumStats} S4 DFrame-subclass collection from per-study tuple vectors and a list of \code{GRanges} entries (one per - study), plus a single LD reference and a single genome build that apply - to the whole collection. + study), plus the LD reference(s) the rows were harmonized against and a + single genome build that applies to the whole collection. Each \code{GRanges} entry must carry per-variant statistics in its mcols (at minimum \code{SNP}, \code{A1}, \code{A2}, \code{Z}, \code{N}; optionally diff --git a/man/QtlFineMappingResult.Rd b/man/QtlFineMappingResult.Rd index c48c3593..5a02e859 100644 --- a/man/QtlFineMappingResult.Rd +++ b/man/QtlFineMappingResult.Rd @@ -61,9 +61,9 @@ derives the window from the span of the variants present.} one per row; \code{NULL} (default) omits the column.} \item{dataSource}{Optional per-row label for the kind of input the fit saw, -\code{"individual"} or \code{"sumstat"}. Recorded rather than derived: a -combined collection can hold rows of both kinds, and its single -\code{ldReference} cannot say which row came from which.} +\code{"individual"} or \code{"sumstat"}. Where it is absent, the result +writers read a row's kind from its LD reference: a row with none saw +individual-level data.} \item{weightStandardized}{Optional per-row flag: whether the posterior effect is on the STANDARDIZED genotype scale. The posterior effect IS the @@ -73,9 +73,11 @@ it standardizes genotypes before fitting, and the posterior mean is reported on the scale of the \code{X} the fit was given. The argument exists for a collection assembled by hand, where only the caller knows.} -\item{ldReference}{An optional genotype panel (see -\code{\link{readGenotypes}}) (the LD reference for RSS-derived fits), or -\code{NULL} for individual-level fits.} +\item{ldReference}{The LD reference RSS-derived fits were computed +against -- a genotype panel (see \code{\link{readGenotypes}}), a +\code{GenotypeMixture} or an \code{LdMatrix} -- used for every row, or +a list with one per row; \code{NULL} for individual-level fits. Each +distinct reference is stored once.} } \value{ A \code{QtlFineMappingResult} object. @@ -83,9 +85,9 @@ A \code{QtlFineMappingResult} object. \description{ Construct a \code{QtlFineMappingResult} DFrame-subclass collection from per-tuple vectors and a list of \code{FineMappingRow} - payloads (one per tuple). The optional \code{ldReference} slot records the - LD reference used for RSS-derived fits; pass \code{NULL} (the default) for - individual-level fits. + payloads (one per tuple). The optional \code{ldReference} records the LD + reference each RSS-derived fit used; leave it \code{NULL} (the default) + for individual-level fits. } \examples{ tl <- data.frame(variant_id = paste0("chr1:", 100 * 1:3, ":A:G"), diff --git a/man/QtlSumStats-class.Rd b/man/QtlSumStats-class.Rd index eb172937..5c2aa7ad 100644 --- a/man/QtlSumStats-class.Rd +++ b/man/QtlSumStats-class.Rd @@ -13,9 +13,11 @@ S4 collection of QTL summary statistics keyed by the identity \details{ Required columns: \code{study}, \code{context} and \code{trait}; the 3-tuple is unique. The class-level slots inherited from - \code{\linkS4class{SumStatsBase}} -- \code{ldReference}, \code{genome} and - \code{qcInfo} -- apply uniformly to every row, and \code{qcInfo} records - which \code{\link{summaryStatsQc}} passes have run. + \code{\linkS4class{SumStatsBase}} -- \code{genome} and \code{qcInfo} -- + apply uniformly to every row, and \code{qcInfo} records which + \code{\link{summaryStatsQc}} passes have run; \code{ldReference} holds + each distinct LD reference once, and the \code{ldReference} column names + the one each row uses. } \seealso{ \code{\link{QtlSumStats}} for the constructor and diff --git a/man/QtlSumStats.Rd b/man/QtlSumStats.Rd index f817cffd..52e822c8 100644 --- a/man/QtlSumStats.Rd +++ b/man/QtlSumStats.Rd @@ -29,12 +29,13 @@ QtlSumStats( Same length as \code{study}, \code{context}, and \code{trait}.} \item{genome}{Single character string giving the genome build (e.g., -\code{"hg19"}, \code{"hg38"}). Uniform across the collection because all -entries share the same LD reference.} +\code{"hg19"}, \code{"hg38"}). One build per collection.} \item{ldReference}{The LD reference: a genotype panel (see \code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} or an -\code{\link{LdMatrix}}.} +\code{\link{LdMatrix}}, used for every tuple, or a list with one per +tuple when they sit on different references. Each distinct reference is +stored once, and the \code{ldReference} column names each row's.} \item{varY}{Optional numeric vector of per-tuple phenotype variances (\code{NA_real_} entries allowed).} @@ -68,8 +69,9 @@ A \code{QtlSumStats} object. \description{ Construct a \code{QtlSumStats} S4 DFrame-subclass collection from per-tuple vectors and a list of \code{GRanges} entries (one per - tuple), plus a single LD reference and a single genome build that apply - to the whole collection. Each \code{GRanges} entry must carry per-variant + tuple), plus the LD reference(s) the rows were harmonized against and a + single genome build that applies to the whole collection. Each + \code{GRanges} entry must carry per-variant statistics in its mcols (\code{SNP}, \code{A1}, \code{A2}, \code{Z}, \code{N}; plus optional \code{MAF}, \code{INFO}, \code{BETA}, \code{SE}, \code{P}). diff --git a/man/SumStatsBase-class.Rd b/man/SumStatsBase-class.Rd index fa0adeb1..d47425fc 100644 --- a/man/SumStatsBase-class.Rd +++ b/man/SumStatsBase-class.Rd @@ -19,12 +19,14 @@ Virtual base class for QTL and GWAS summary statistics \section{Slots}{ \describe{ -\item{\code{ldReference}}{The LD reference the collection was harmonized against -and every pipeline reads LD from: a genotype panel (see -\code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} or an -\code{\link{LdMatrix}}, or \code{NULL}. Optional: LD-free workflows -(e.g. mash, which operates across conditions per variant) carry -\code{NULL}; pipelines that need LD validate its presence when they +\item{\code{ldReference}}{A named list of the LD references the rows were +harmonized against and every pipeline reads LD from, each a genotype +panel (see \code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} +or an \code{\link{LdMatrix}}. Each distinct reference is stored once, and +the \code{ldReference} column of \code{mcols} names the entry each row +uses, so rows can sit on different references. Optional: an LD-free row +(e.g. for mash, which operates across conditions per variant) has +\code{NA} there; pipelines that need LD validate its presence when they consume the collection.} \item{\code{qcInfo}}{A \code{list} recording which QC steps ran. Empty \code{list()} diff --git a/man/TwasWeights-class.Rd b/man/TwasWeights-class.Rd index 575ddc2e..0a6cab95 100644 --- a/man/TwasWeights-class.Rd +++ b/man/TwasWeights-class.Rd @@ -25,10 +25,11 @@ jointly across the identity-tuple columns and any present joint columns. \section{Slots}{ \describe{ -\item{\code{ldReference}}{The LD reference the weights were derived against (a -genotype panel, a \code{GenotypeMixture} or an \code{LdMatrix}), or -\code{NULL} when the weights were learned from individual-level data. -Used downstream to check that pipelines combining results share one LD -reference.} +\item{\code{ldReference}}{A named list of the LD references the weights were +derived against, each a genotype panel, a \code{GenotypeMixture} or an +\code{LdMatrix}, stored once apiece; the \code{ldReference} column of +\code{mcols} names the entry each row used (\code{NA} for weights +learned from individual-level data). Used downstream to check that the +rows a pipeline combines share an LD reference.} }} diff --git a/man/TwasWeights.Rd b/man/TwasWeights.Rd index e69a9560..43e92413 100644 --- a/man/TwasWeights.Rd +++ b/man/TwasWeights.Rd @@ -53,8 +53,11 @@ forward as provenance; not part of the identity key. \code{NULL} (default) omits the column, and \code{\link{genomicRegion}} then derives the window from the span of the variants present.} -\item{ldReference}{An optional genotype panel (see -\code{\link{readGenotypes}}), or \code{NULL} for individual-level fits.} +\item{ldReference}{The LD reference the weights were derived against -- +a genotype panel (see \code{\link{readGenotypes}}), a +\code{GenotypeMixture} or an \code{LdMatrix} -- used for every row, or +a list with one per row; \code{NULL} for individual-level fits. Each +distinct reference is stored once.} } \value{ A \code{TwasWeights} object. diff --git a/man/causalInferencePipeline.Rd b/man/causalInferencePipeline.Rd index 6deb488c..ae6b4169 100644 --- a/man/causalInferencePipeline.Rd +++ b/man/causalInferencePipeline.Rd @@ -16,7 +16,9 @@ causalInferencePipeline( } \arguments{ \item{gwasSumStats}{A \code{\link{GwasSumStats}} object. Must be QC'd -(\code{length(qcInfo(x)) > 0L}).} +(\code{length(qcInfo(x)) > 0L}). A study may span many rows (one per +chromosome or LD block); each QTL tuple is scored once per study, over the +statistics of the rows its window overlaps.} \item{twasWeights}{Optional \code{\link{TwasWeights}} carrying per-(study, context, trait, method) weights. When supplied, drives the TWAS-Z @@ -78,10 +80,13 @@ Per-region pipeline that pairs QTL-derived weight vectors } } \section{LD reference compatibility check}{ - If a QTL input - (TwasWeights or QtlFineMappingResult) carries a non-\code{NULL} - \code{ldReference}, it must be the same LD reference as the - \code{ldReference} on \code{gwasSumStats}. + Per pair of rows scored + together: a QTL input row (TwasWeights or QtlFineMappingResult) that + carries an \code{ldReference} must be the same LD reference as the + \code{gwasSumStats} rows its region overlaps, and the rows of one GWAS + study that a QTL tuple overlaps must share one reference, since its TWAS + z reads one LD matrix. Rows that are never scored together may sit on + different references. The two must be the same kind of reference. Two genotype panels must share their samples and allele orientation; two \code{LdMatrix} objects must agree on the LD they share; two \code{GenotypeMixture} objects must @@ -89,8 +94,8 @@ Per-region pipeline that pairs QTL-derived weight vectors the same variants: QC-ing the two sides separately trims each reference to its own surviving variants, and a partial overlap only warns. A mismatch of any of those, or no shared variant at all, is a hard error. A - QTL input with \code{ldReference = NULL} (the fit was learned from - individual-level data) skips the validation for that input. + QTL input row with no reference (the fit was learned from + individual-level data) skips the validation. } \section{Output shape}{ diff --git a/man/colocBoostOutcomes.Rd b/man/colocBoostOutcomes.Rd index c7d857d0..402b8b0d 100644 --- a/man/colocBoostOutcomes.Rd +++ b/man/colocBoostOutcomes.Rd @@ -17,7 +17,9 @@ colocBoostOutcomes(x, ...) \value{ A tibble with one row per (set, outcome) and the set-level columns repeated, plus \code{outcome}, \code{study}, \code{context}, - \code{trait} and \code{dataForm}. + \code{trait}, \code{dataForm} and \code{ldReference} (the name of the + \code{\link{ldReference}} entry the outcome's summary statistics were + matched against). } \description{ One row per (confidence set, colocalized outcome), joined to diff --git a/man/colocPipeline.Rd b/man/colocPipeline.Rd index 340c58b6..0b842bc8 100644 --- a/man/colocPipeline.Rd +++ b/man/colocPipeline.Rd @@ -179,9 +179,11 @@ This pipeline preserves all three. } \section{LD reference compatibility check}{ - If - \code{ldReference(qtlFineMappingResult)} is non-\code{NULL}, it must be - the same LD reference as the one on \code{gwasInput}. + Rows can sit on different LD + references, so the check is per pair of rows coloc scores against each + other -- a QTL row and a GWAS row whose regions overlap. Where the QTL + row carries a reference, it must be the same LD reference as the GWAS + row's; rows that are never paired may differ. The two must be the same kind of reference. Two genotype panels must share their samples and allele orientation; two \code{LdMatrix} objects must agree on the LD they share; two \code{GenotypeMixture} objects must @@ -190,9 +192,9 @@ This pipeline preserves all three. two sides separately normally leaves each reference trimmed to its own surviving variants, and LD is looked up per variant, so a partial overlap only warns (once per session). No shared variant at all, or a mismatch of - any of those, is a hard error. When the first side's \code{ldReference} is - \code{NULL} (individual-level fit), the validation is skipped on that side - and the second side's panel is what the result carries forward. + any of those, is a hard error. When a first-side row has no reference + (individual-level fit), the validation is skipped for it and the second + side's panel is what the result carries forward for its pairs. } \examples{ diff --git a/man/colocboostPipeline.Rd b/man/colocboostPipeline.Rd index f8982ed0..cd7ce42f 100644 --- a/man/colocboostPipeline.Rd +++ b/man/colocboostPipeline.Rd @@ -66,7 +66,12 @@ colocboostPipeline(qtlData, gwasSumStats = NULL, ...) \code{MultiStudyQtlDataset}.} \item{gwasSumStats}{Optional \code{GwasSumStats} with the GWAS studies to -colocalize against. \code{NULL} to skip GWAS colocalization.} +colocalize against. \code{NULL} to skip GWAS colocalization. Its +\code{ldReference} need not be the QTL side's: every row's summary +statistics are matched against that row's own reference. When some rows' +references are genotype panels and others' are \code{LdMatrix} objects, +the runs that combine them pass colocboost the panels' LD as matrices, +since colocboost takes LD matrices or reference genotypes but not both.} \item{...}{Required by the generic; the methods take no further arguments.} @@ -168,7 +173,10 @@ A \code{\linkS4class{ColocBoostResult}}: one element per \code{as.data.frame}), \code{\link{colocVariants}} or \code{\link{colocBoostOutcomes}}; timings are on \code{\link{computingTime}} and the region-wide marginal - probabilities on \code{\link{regionVcp}}. + probabilities on \code{\link{regionVcp}}. \code{\link{ldReference}} + returns the LD references the summary statistics were matched against, + each stored once, and the \code{ldReference} column of + \code{colocBoostOutcomes()} names the one each outcome used. } \description{ Protocol-level multi-trait colocalization analysis using @@ -178,8 +186,8 @@ Protocol-level multi-trait colocalization analysis using multi-context data. Per-context residualized X / Y are extracted from the dataset (filtering knobs on the constructor apply lazily inside the accessors). - \item \code{QtlSumStats} -- summary-statistic-only QTL data with a - shared LD reference (\code{ldReference}). Must already have + \item \code{QtlSumStats} -- summary-statistic-only QTL data with an + LD reference per row (\code{ldReference}). Must already have been passed through \code{\link{summaryStatsQc}} (the pipeline rejects inputs whose \code{qcInfo()} is empty). Every analysis variant is available on this input, including diff --git a/man/combineFineMappingResults.Rd b/man/combineFineMappingResults.Rd index 5a0d5be7..50213bb5 100644 --- a/man/combineFineMappingResults.Rd +++ b/man/combineFineMappingResults.Rd @@ -10,9 +10,11 @@ combineFineMappingResults(..., ldReference = NULL) \item{...}{Two or more \code{FineMappingResultBase} objects, or a single \code{list} of them.} -\item{ldReference}{Optional genotype panel (see -\code{\link{readGenotypes}}) to attach to the -combined collection. Default \code{NULL}. Applied when combining two or +\item{ldReference}{Optional LD reference -- a genotype panel (see +\code{\link{readGenotypes}}), a \code{GenotypeMixture} or an +\code{LdMatrix} -- that every row of the combined collection uses instead +of its own. Default \code{NULL}: each row keeps the reference it had, +and views of one source are stored once. Applied when combining two or more inputs; a single input is returned unchanged.} } \value{ diff --git a/man/combineGwasSumStats.Rd b/man/combineGwasSumStats.Rd index 40ce8ee1..d75419ee 100644 --- a/man/combineGwasSumStats.Rd +++ b/man/combineGwasSumStats.Rd @@ -10,9 +10,10 @@ combineGwasSumStats(..., ldReference = NULL) \item{...}{Two or more \code{GwasSumStats} objects, or a single \code{list} of them.} -\item{ldReference}{Optional genotype panel (see \code{\link{readGenotypes}}) -to attach to the combined collection, overriding the unioned one. Default -\code{NULL}.} +\item{ldReference}{Optional LD reference -- a genotype panel (see +\code{\link{readGenotypes}}), a \code{GenotypeMixture} or an +\code{LdMatrix} -- that every row of the combined collection uses +instead of its own. Default \code{NULL}.} } \value{ A single combined \code{GwasSumStats}. @@ -29,14 +30,14 @@ The three collection-level slots are merged rather than taken from the first input: \code{genome} and the \code{\link{summaryStatsQc}} options must agree across the inputs (a mismatch is an error, not a silent first-wins), the per-element \code{qcInfo$entryAudit} concatenates in element order so -\code{\link{qcDiagnostics}} keeps addressing the right element, and the -LD references combine: genotype panels union into one panel over the shared -genotype handle. That last one matters: block-parallel pipelines narrow each -piece's panel to its own block, so keeping only the first would leave a -multi-block collection whose LD reference covers one block. An -\code{LdMatrix} or a \code{GenotypeMixture} cannot be unioned that way; -one of the inputs' references must already cover the others, or the -combined one is passed as \code{ldReference}. +\code{\link{qcDiagnostics}} keeps addressing the right element, and every +row keeps its own LD reference. References that are views of one source +are stored once: genotype panels read from the same files union into one +panel over the shared genotype handle (block-parallel pipelines narrow each +piece's panel to its own block, so a multi-block collection would otherwise +hold one panel per block), and an \code{LdMatrix} or +\code{GenotypeMixture} that another input's reference covers gives way to +that one. Inputs on unrelated references keep both. } \examples{ data(gwasSumStatsS4Example) diff --git a/man/combineQtlSumStats.Rd b/man/combineQtlSumStats.Rd index 4ac249b2..09b25154 100644 --- a/man/combineQtlSumStats.Rd +++ b/man/combineQtlSumStats.Rd @@ -10,9 +10,10 @@ combineQtlSumStats(..., ldReference = NULL) \item{...}{Two or more \code{QtlSumStats} objects, or a single \code{list} of them.} -\item{ldReference}{Optional genotype panel (see \code{\link{readGenotypes}}) -to attach to the combined collection, overriding the unioned one. Default -\code{NULL}.} +\item{ldReference}{Optional LD reference -- a genotype panel (see +\code{\link{readGenotypes}}), a \code{GenotypeMixture} or an +\code{LdMatrix} -- that every row of the combined collection uses +instead of its own. Default \code{NULL}.} } \value{ A single combined \code{QtlSumStats}. @@ -27,9 +28,8 @@ lacking an optional column is NA-padded. The three collection-level slots are merged rather than taken from the first input, on the same rules as \code{\link{combineGwasSumStats}}: \code{genome} and the \code{\link{summaryStatsQc}} options must agree, the per-element -\code{qcInfo$entryAudit} concatenates in element order, and the LD -references combine the same way (all-\code{NULL} stays \code{NULL}, which -is the usual case for individual-level QTL data). +\code{qcInfo$entryAudit} concatenates in element order, and the rows keep +their own LD references, stored the same way. } \examples{ data(qtlSumStatsExample) diff --git a/man/combineTwasWeights.Rd b/man/combineTwasWeights.Rd index 5b2f98b9..e8f13575 100644 --- a/man/combineTwasWeights.Rd +++ b/man/combineTwasWeights.Rd @@ -10,9 +10,11 @@ combineTwasWeights(..., ldReference = NULL) \item{...}{Two or more \code{TwasWeights} objects, or a single \code{list} of them.} -\item{ldReference}{Optional genotype panel (see \code{\link{readGenotypes}}) -to attach to the -combined collection. Default \code{NULL}. Applied when combining two or +\item{ldReference}{Optional LD reference -- a genotype panel (see +\code{\link{readGenotypes}}), a \code{GenotypeMixture} or an +\code{LdMatrix} -- that every row of the combined collection uses instead +of its own. Default \code{NULL}: each row keeps the reference it had, +and views of one source are stored once. Applied when combining two or more inputs; a single input is returned unchanged.} } \value{ diff --git a/man/computeLd.Rd b/man/computeLd.Rd index cfcf9374..bef908c5 100644 --- a/man/computeLd.Rd +++ b/man/computeLd.Rd @@ -67,7 +67,7 @@ Correlation between variants, from either a dosage matrix } \examples{ data(qtlSumStatsExample) -panel <- ldReference(qtlSumStatsExample) +panel <- ldReference(qtlSumStatsExample)[[1L]] R <- computeLd(panel, snpIdx = 1:5) dim(R) # A dosage matrix already in memory is correlated directly. diff --git a/man/ctwasPipeline.Rd b/man/ctwasPipeline.Rd index bca7b03b..65b497aa 100644 --- a/man/ctwasPipeline.Rd +++ b/man/ctwasPipeline.Rd @@ -141,9 +141,10 @@ Pipeline that hands a per-block set of } \section{LD reference compatibility check}{ - Per block: - \code{ldReference(twasWeights)} (when non-NULL) must be the same LD - reference as \code{ldReference(gwasSumStats)}. + Per block: the block's GWAS + rows must share one LD reference (a block's LD is one matrix), and every + weight row placed in the block that carries a reference must be the same + LD reference as theirs. Blocks may sit on different references. The two must be the same kind of reference. Two genotype panels must share their samples and allele orientation; two \code{LdMatrix} objects must agree on the LD they share; two \code{GenotypeMixture} objects must diff --git a/man/fineMappingPipeline.Rd b/man/fineMappingPipeline.Rd index 672fceee..0f7b5f5f 100644 --- a/man/fineMappingPipeline.Rd +++ b/man/fineMappingPipeline.Rd @@ -359,10 +359,10 @@ and GWAS methods, built with \code{\link{PanelFilterParam}}. See A \code{QtlFineMappingResult} keyed by \code{(study, context, trait, method)} -- for \code{GwasSumStats} input, a \code{GwasFineMappingResult} keyed by \code{(study, method)} and range. - The \code{ldReference} slot is set automatically: \code{NULL} - for individual-level (QtlDataset / all-individual-level - MultiStudyQtlDataset) fits, the input's \code{ldReference} for RSS-derived - fits. + Each row records the LD reference its fit used: none for + individual-level (QtlDataset / all-individual-level + MultiStudyQtlDataset) fits, the reference of the input row it was fitted + from for RSS-derived fits. } \description{ S4-dispatched per-region fine-mapping entry point that diff --git a/man/gwasSumStatsS4Example.Rd b/man/gwasSumStatsS4Example.Rd index 7713f742..a06c86f2 100644 --- a/man/gwasSumStatsS4Example.Rd +++ b/man/gwasSumStatsS4Example.Rd @@ -13,8 +13,7 @@ A pre-QC'd \code{\link{GwasSumStats}} collection for one synthetic trait (\code{"trait1"}, N = 50,000). The signal pattern shares one causal variant with \code{\link{qtlSumStatsExample}} (for colocalization demos) and adds a second GWAS-only causal variant. -The \code{ldReference} slot references the same toy PLINK1 panel used -for the QTL example. +Its LD reference is the same toy PLINK1 panel the QTL example uses. } \examples{ data(gwasSumStatsS4Example) diff --git a/man/ldReference.Rd b/man/ldReference.Rd index a4c7321a..1a084671 100644 --- a/man/ldReference.Rd +++ b/man/ldReference.Rd @@ -1,11 +1,12 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/AllGenerics.R, R/AllClasses.R, -% R/ColocResult.R, R/LdStatistic.R, R/twasWeights.R +% R/ColocResult.R, R/ColocBoostResult.R, R/LdStatistic.R, R/twasWeights.R \name{ldReference} \alias{ldReference} \alias{ldReference,SumStatsBase-method} \alias{ldReference,FineMappingResultBase-method} -\alias{ldReference,ColocResultBase-method} +\alias{ldReference,ColocResult-method} +\alias{ldReference,ColocBoostResult-method} \alias{ldReference,LdStatistic-method} \alias{ldReference,TwasWeights-method} \title{Get LD Reference} @@ -16,7 +17,9 @@ ldReference(x, ...) \S4method{ldReference}{FineMappingResultBase}(x) -\S4method{ldReference}{ColocResultBase}(x) +\S4method{ldReference}{ColocResult}(x) + +\S4method{ldReference}{ColocBoostResult}(x) \S4method{ldReference}{LdStatistic}(x) @@ -28,22 +31,31 @@ ldReference(x, ...) \item{...}{Unused.} } \value{ -A \code{RangedSummarizedExperiment} genotype panel, a +A named list of LD references; for an \code{LdStatistic}, a + \code{RangedSummarizedExperiment} genotype panel, a \code{GenotypeMixture}, an \code{LdMatrix}, or \code{NULL}. } \description{ -Return the LD reference of this object: a genotype panel - (see \code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} or - an \code{\link{LdMatrix}}. Defined on classes that embed an - \code{ldReference} slot: \code{GwasSumStats}, \code{QtlSumStats}, - \code{FineMappingResultBase}, \code{TwasWeights}, - \code{ColocResultBase} and \code{LdStatistic}, whose reference is the - panel it reads its blocks' LD from. Returns \code{NULL} when the slot is - unset (e.g. a \code{TwasWeights} fit from individual-level data via - \code{QtlDataset}, or an \code{LdStatistic} built from \code{LdMatrix} - blocks). +Return the LD references of this object, each a genotype + panel (see \code{\link{readGenotypes}}), a \code{\link{GenotypeMixture}} + or an \code{\link{LdMatrix}}. + + The collections whose rows can sit on different references -- + \code{GwasSumStats}, \code{QtlSumStats}, \code{FineMappingResultBase}, + \code{TwasWeights}, \code{ColocResult} and \code{ColocBoostResult} -- + return a named list holding each distinct reference their rows use, once. + The \code{ldReference} column of their \code{mcols} (of + \code{outcomeInfo} for a \code{ColocBoostResult}) names the entry each + row used, \code{NA} for one fit without LD (e.g. a \code{TwasWeights} + row learned from individual-level data via \code{QtlDataset}). The list + is empty when no row has a reference. + + An \code{LdStatistic} returns the one panel it reads its blocks' LD from, + or \code{NULL} when it was built from \code{LdMatrix} blocks. } \examples{ data(qtlSumStatsExample) +# One entry per distinct reference; each row names its own. ldReference(qtlSumStatsExample) +qtlSumStatsExample$ldReference } diff --git a/man/loadGwasSumStatsFromManifest.Rd b/man/loadGwasSumStatsFromManifest.Rd index fbedf58b..e07345f2 100644 --- a/man/loadGwasSumStatsFromManifest.Rd +++ b/man/loadGwasSumStatsFromManifest.Rd @@ -20,8 +20,10 @@ loadGwasSumStatsFromManifest( \item{manifest}{A data.frame or path. Columns (snake_case aliases accepted): \code{study} (required, unique), \code{sumStatsPath} (required), \code{columnMapping} (optional), \code{nCase} / \code{nControl} (optional), -\code{nSample} (optional study-level total N), \code{varY} (optional), and -the single-valued \code{genome} / \code{ldReferencePath}. When a row +\code{nSample} (optional study-level total N), \code{varY} (optional), the +single-valued \code{genome}, and \code{ldReferencePath}, which may differ +between studies (each distinct reference is read once, for the +chromosomes its studies cover, and stored once). When a row supplies a study-level scalar (\code{nCase} + \code{nControl}, or \code{nSample}), its sumstats file need not carry a per-variant \code{N} column; @@ -30,8 +32,9 @@ column; \item{genome}{Genome build; reconciled with a \code{genome} column.} \item{ldReference}{A genotype panel (see \code{\link{readGenotypes}}) or a -spec (path/prefix/genoMeta); reconciled with an \code{ldReferencePath} -column.} +spec (path/prefix/genoMeta), used for every study; where a row also names +an \code{ldReferencePath} the two must agree. Omit it to give each study +the reference its \code{ldReferencePath} names.} \item{region}{Optional \code{chr:start-end} string, GRanges, or one-row data.frame restricting the variants read (honoured only for tabix-indexed diff --git a/man/loadQtlSumStatsFromManifest.Rd b/man/loadQtlSumStatsFromManifest.Rd index d3900b65..a1f87db8 100644 --- a/man/loadQtlSumStatsFromManifest.Rd +++ b/man/loadQtlSumStatsFromManifest.Rd @@ -21,8 +21,10 @@ loadQtlSumStatsFromManifest( \item{manifest}{A data.frame or path. Columns (snake_case aliases accepted): \code{study}, \code{context}, \code{trait} (required), \code{sumStatsPath} (required), \code{columnMapping} (optional), \code{nSample} (optional -tuple-level total N), \code{varY} (optional), and the single-valued -\code{genome} / \code{ldReferencePath}. When a row supplies \code{nSample}, +tuple-level total N), \code{varY} (optional), the single-valued +\code{genome}, and \code{ldReferencePath}, which may differ between rows +(each distinct reference is read once, for the chromosomes its rows +cover, and stored once). When a row supplies \code{nSample}, its sumstats file need not carry a per-variant \code{N} column; \code{\link{summaryStatsQc}} fills \code{N} from the scalar. (Unlike the GWAS loader, there are no \code{nCase}/\code{nControl} columns: molecular @@ -31,7 +33,9 @@ QTL traits are quantitative.)} \item{genome}{Genome build; reconciled with a \code{genome} column.} \item{ldReference}{A genotype panel (see \code{\link{readGenotypes}}) or -spec; reconciled with an \code{ldReferencePath} column.} +spec, used for every row; where a row also names an +\code{ldReferencePath} the two must agree. Omit it to give each row the +reference its \code{ldReferencePath} names.} \item{region, minLdOverlapWarn, columnMapping, sampleSelect, formatMapping}{As for \code{\link{loadGwasSumStatsFromManifest}}.} diff --git a/man/qtlEnrichmentPipeline.Rd b/man/qtlEnrichmentPipeline.Rd index a9b0f378..3a9531f7 100644 --- a/man/qtlEnrichmentPipeline.Rd +++ b/man/qtlEnrichmentPipeline.Rd @@ -93,16 +93,18 @@ genome of outcome PIPs and the full collection of annotation fits at once. } \section{LD reference compatibility check}{ - A GWAS outcome collection - must have a non-NULL \code{ldReference} (it should be RSS-derived). Where - both sides carry one, the two must be the same LD reference. + Every row of a GWAS outcome + collection must have an \code{ldReference} (it should be RSS-derived). + For each QTL row and GWAS row whose regions overlap, where both carry + one, the two must be the same LD reference; rows that never overlap may + sit on different references. The two must be the same kind of reference. Two genotype panels must share their samples and allele orientation; two \code{LdMatrix} objects must agree on the LD they share; two \code{GenotypeMixture} objects must average the same panels with the same weights. They need NOT carry the same variants: QC-ing the two sides separately trims each reference to - its own surviving variants, and a partial overlap only warns. A - \code{NULL} on either side (an individual-level fit) skips the check. + its own surviving variants, and a partial overlap only warns. A row with + no reference on either side (an individual-level fit) skips the check. } \examples{ diff --git a/man/qtlSumStatsExample.Rd b/man/qtlSumStatsExample.Rd index d6042aa3..20411622 100644 --- a/man/qtlSumStatsExample.Rd +++ b/man/qtlSumStatsExample.Rd @@ -12,8 +12,8 @@ A \code{QtlSumStats} S4 collection with one row (study1, brain, A pre-QC'd \code{\link{QtlSumStats}} collection covering the same (study, context, trait) tuple as \code{\link{qtlDatasetExample}}; the per-variant Z / BETA / SE / N values were computed from the synthetic -phenotype by per-variant linear regression. The \code{ldReference} slot -references the same toy PLINK1 panel. +phenotype by per-variant linear regression. Its LD reference is the same +toy PLINK1 panel. } \examples{ data(qtlSumStatsExample) diff --git a/man/twasWeightsPipeline.Rd b/man/twasWeightsPipeline.Rd index 4ee09116..efde1f31 100644 --- a/man/twasWeightsPipeline.Rd +++ b/man/twasWeightsPipeline.Rd @@ -265,9 +265,8 @@ above.} } \value{ A \code{\link{TwasWeights}} collection keyed by \code{(study, - context, trait, method)}. The \code{ldReference} slot is \code{NULL} for - individual-level fits and equals the input's \code{ldReference} for - RSS-derived fits. + context, trait, method)}. Each row's LD reference is none for + individual-level fits and that of the input row(s) for RSS-derived fits. } \description{ S4-dispatched per-region pipeline for learning TWAS prediction weights. @@ -299,9 +298,9 @@ A \code{QtlSumStats} input must have been QC'd via \code{\link{summaryStatsQc}} first; otherwise an error is raised pointing at that function. -The returned \code{\link{TwasWeights}} collection's \code{ldReference} slot -is set automatically: \code{NULL} for individual-level fits, the input's -\code{ldReference} for RSS-derived fits. +Each row of the returned \code{\link{TwasWeights}} collection records the +LD reference its weights were learned against: none for individual-level +fits, the reference of the input row(s) for RSS-derived fits. Optionally a \code{QtlFineMappingResult} may be supplied as a source of pre-fit SuSiE / SuSiE-inf / SuSiE-ash objects; their stored fits are passed diff --git a/man/updateObject-methods.Rd b/man/updateObject-methods.Rd new file mode 100644 index 00000000..c0469e41 --- /dev/null +++ b/man/updateObject-methods.Rd @@ -0,0 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/RangedTupleList.R, R/ColocBoostResult.R +\name{updateObject-methods} +\alias{updateObject-methods} +\alias{updateObject,RangedTupleList-method} +\alias{updateObject,ColocBoostResult-method} +\title{Update an Object Saved by an Earlier pecotmr} +\usage{ +\S4method{updateObject}{RangedTupleList}(object, ..., verbose = FALSE) + +\S4method{updateObject}{ColocBoostResult}(object, ..., verbose = FALSE) +} +\arguments{ +\item{object}{A collection: summary statistics, fine-mapping results, TWAS +weights, or a colocalization result.} + +\item{...}{Passed on to the inherited method.} + +\item{verbose}{Report the update.} +} +\value{ +\code{object} in the current representation. +} +\description{ +Bring a collection saved by an earlier version of pecotmr up + to date. Collections now keep their LD references per row: each distinct + reference once in the \code{ldReference} slot, and an \code{ldReference} + column naming the one every row uses (in \code{outcomeInfo} for a + \code{ColocBoostResult}). An object saved when it held a single reference + for all its rows is converted by keying every row to that reference (for + a \code{ColocBoostResult}, every summary-statistic outcome), and one that + held none by marking every row LD-free. An up-to-date object is returned + unchanged. +} +\examples{ +data(qtlSumStatsExample) +# An object built by this version needs nothing. +identical(updateObject(qtlSumStatsExample), qtlSumStatsExample) +} diff --git a/tests/testthat/helper-h2Classes.R b/tests/testthat/helper-h2Classes.R index a685dce5..3c58ebe4 100644 --- a/tests/testthat/helper-h2Classes.R +++ b/tests/testthat/helper-h2Classes.R @@ -148,7 +148,8 @@ makeGwasBlock <- function( start, n = 5L, genome = "hg19", - qcOptions = list(mafCutoff = 0.01) + qcOptions = list(mafCutoff = 0.01), + ldReference = .blockGenotypeHandle(bp) ) { bp <- seq(start, by = 100L, length.out = n) df <- data.frame( @@ -165,7 +166,7 @@ makeGwasBlock <- function( studyName = "trait1", entry = list(.dfToSumstatsGr(df)), genome = genome, - ldReference = .blockGenotypeHandle(bp), + ldReference = ldReference, blockId = blockId, qcInfo = list( timestamp = NA_character_, diff --git a/tests/testthat/test_ColocBoostResult.R b/tests/testthat/test_ColocBoostResult.R index 2f125853..fbe6c5a3 100644 --- a/tests/testthat/test_ColocBoostResult.R +++ b/tests/testthat/test_ColocBoostResult.R @@ -443,6 +443,87 @@ test_that("validity names the outcomeInfo columns that are missing", { ) }) +# A small LdMatrix to stand in for one side's reference. +.cbr_ldm <- function(ids = c("chr1:100:C:T", "chr1:200:A:G")) { + LdMatrix(matrix(c(1, 0.2, 0.2, 1), 2, 2, dimnames = list(ids, ids))) +} + +test_that("ColocBoostResult keeps a named LD reference per side", { + refs <- list( + qtl = .cbr_ldm(), + gwas = .cbr_ldm(c("chr1:300:G:A", "chr1:400:T:C")) + ) + info <- mutate( + .cbr_info(), + dataForm = "sumstats", + ldReference = c("qtl", "gwas") + ) + x <- ColocBoostResult( + list(.cbr_fake()), + "joint_gwas", + outcomeInfo = info, + ldReference = refs + ) + expect_identical(ldReference(x), refs) + out <- colocBoostOutcomes(x) + expect_equal( + out$ldReference[match(c("t1", "t2"), out$outcome)], + c("qtl", "gwas") + ) +}) + +test_that("ColocBoostResult with no LD reference holds an empty list", { + # An outcomeInfo without the column gets it, NA throughout. + x <- ColocBoostResult( + list(.cbr_fake()), + "xqtl_coloc", + outcomeInfo = .cbr_info() + ) + expect_identical(ldReference(x), list()) + expect_true(all(is.na(colocBoostOutcomes(x)$ldReference))) +}) + +test_that("ColocBoostResult refuses a lone LD reference", { + # Its name is what outcomeInfo keys on, so it is not made up. + expect_error( + ColocBoostResult( + list(.cbr_fake()), + "xqtl_coloc", + outcomeInfo = .cbr_info(), + ldReference = .cbr_ldm() + ), + "named list of LD references" + ) +}) + +test_that("ColocBoostResult refuses an outcome keyed to a missing reference", { + info <- mutate(.cbr_info(), ldReference = c("qtl", "gwas")) + expect_error( + ColocBoostResult( + list(.cbr_fake()), + "joint_gwas", + outcomeInfo = info, + ldReference = list(qtl = .cbr_ldm()) + ), + "not in ldReference: gwas" + ) +}) + +test_that("validity wants uniquely named LD references", { + # The shared check every class with per-row references validates with. + problems <- function(refs) .ldRefDictProblems(refs, character(0)) + expect_match(problems(list(.cbr_ldm())), "unique, non-empty names") + expect_match( + problems(list(a = .cbr_ldm(), a = .cbr_ldm())), + "unique, non-empty names" + ) + expect_match( + problems(list(a = .cbr_ldm(), b = "panel")), + "not LD references: b" + ) + expect_null(problems(list(a = .cbr_ldm()))) +}) + test_that("the region vcp skips runs that cannot supply one", { # Two ways a run is unusable: no vcp at all, and a vcp whose names are # missing so the variants cannot be placed. @@ -457,3 +538,22 @@ test_that("the region vcp skips runs that cannot supply one", { expect_s4_class(gr, "GRanges") expect_equal(length(gr), 1L) }) + +test_that("updateObject keys an old result's sumstat outcomes to its ref", { + ref <- .cbr_ldm() + info <- mutate(.cbr_info(), dataForm = c("sumstats", "individual")) + x <- ColocBoostResult(list(.cbr_fake()), "joint_gwas", outcomeInfo = info) + # As an earlier version saved it: one reference, no outcome keys. + old <- `slot<-`(x, "ldReference", check = FALSE, value = ref) + old <- `slot<-`( + old, + "outcomeInfo", + value = select(info, -any_of("ldReference")) + ) + new <- updateObject(old) + expect_true(methods::validObject(new)) + expect_identical(ldReference(new), list(ld1 = ref)) + expect_identical(new@outcomeInfo$ldReference, c("ld1", NA)) + # A current result is left as it is. + expect_identical(updateObject(x), x) +}) diff --git a/tests/testthat/test_ColocResult.R b/tests/testthat/test_ColocResult.R index cd1919f4..2c000ec8 100644 --- a/tests/testthat/test_ColocResult.R +++ b/tests/testthat/test_ColocResult.R @@ -59,6 +59,17 @@ test_that("ColocResult: stores one element per pair with its variants", { expect_equal(x$PP.H4.abf, 0.6) }) +test_that("ColocResult: keeps each pair's LD reference", { + ids <- c("chr1:100:C:T", "chr1:200:A:G") + ldm <- LdMatrix(matrix(c(1, 0.2, 0.2, 1), 2, dimnames = list(ids, ids))) + x <- ColocResult(.cr_pairs(), .cr_variants(), ldReference = ldm) + expect_identical(ldReference(x), list(ld1 = ldm)) + expect_equal(x$ldReference, "ld1") + none <- ColocResult(.cr_pairs(), .cr_variants()) + expect_identical(ldReference(none), list()) + expect_true(is.na(none$ldReference)) +}) + test_that("ColocResult: rejects an element with no per-variant layer", { # The whole point of the class is that SNP.PP.H4 survives; an element # without it must not construct. @@ -298,14 +309,19 @@ test_that("show on an empty ColocResult stops after the header", { )[seq_len(n)] } +# The panel as a pair's LD reference, keyed the way a ColocResult keys it. +.cr_refs <- function() { + list(ld1 = .cr_panel()) +} + test_that("a singleton credible set is pure by definition", { # No pair to correlate; susie treats it as pure rather than unmeasurable. - expect_equal(.crPurityOne(.cr_panelIds(1L), .cr_panel()), 1) + expect_equal(.crPurityOne(.cr_panelIds(1L), "ld1", .cr_refs()), 1) }) test_that("purity is the minimum absolute correlation among members", { ids <- .cr_panelIds(3L) - pur <- .crPurityOne(ids, .cr_panel()) + pur <- .crPurityOne(ids, "ld1", .cr_refs()) R <- computeLd(.cr_panel(), snpIdx = 1:3) expect_equal(pur, min(abs(R[upper.tri(R)])), tolerance = 1e-8) }) @@ -314,29 +330,35 @@ test_that("purity is NA when the panel cannot supply the members", { # Reported honestly rather than defaulted to a passing value: an # unmeasurable purity must not look like a pure set. expect_true(is.na( - .crPurityOne(c("chr9:1:A:G", "chr9:2:C:T"), .cr_panel()) + .crPurityOne(c("chr9:1:A:G", "chr9:2:C:T"), "ld1", .cr_refs()) )) }) -test_that("purity is NA for every set when there is no LD reference", { - out <- tibble(csVariants = list(c("a", "b"), c("c", "d"))) - expect_equal(.crPuritiesFor(out, NULL), c(NA_real_, NA_real_)) +test_that("purity is NA for every set whose pair has no LD reference", { + out <- tibble( + csVariants = list(c("a", "b"), "c"), + ldReference = NA_character_ + ) + expect_equal(.crPuritiesFor(out, list()), c(NA_real_, NA_real_)) }) -test_that("purity is computed per set when an LD reference is supplied", { - # The counterpart of the NULL case above: with a panel in hand each set - # is mapped through .crPurityOne rather than short-circuiting to NA. +test_that("purity is computed per set against its own pair's reference", { + # The counterpart of the no-reference case above: each set is mapped + # through .crPurityOne with the reference its pair names. ids <- .cr_panelIds(3L) - out <- tibble(csVariants = list(ids, ids[[1L]])) - pur <- .crPuritiesFor(out, .cr_panel()) - expect_length(pur, 2L) - expect_false(anyNA(pur)) + out <- tibble( + csVariants = list(ids, ids[[1L]], ids), + ldReference = c("ld1", "ld1", NA_character_) + ) + pur <- .crPuritiesFor(out, .cr_refs()) + expect_length(pur, 3L) expect_equal(pur[[2L]], 1) # singleton is pure by definition expect_equal( pur[[1L]], - .crPurityOne(ids, .cr_panel()), + .crPurityOne(ids, "ld1", .cr_refs()), tolerance = 1e-8 ) + expect_true(is.na(pur[[3L]])) }) # =========================================================================== diff --git a/tests/testthat/test_GwasSumStats.R b/tests/testthat/test_GwasSumStats.R index 53c3a888..be4dc9e9 100644 --- a/tests/testthat/test_GwasSumStats.R +++ b/tests/testthat/test_GwasSumStats.R @@ -327,8 +327,9 @@ test_that("GwasSumStats: ldReference is optional (NULL when LD-free)", { studyName = "g1", entry = list(.sh_makeQtlSumstatsGr()), genome = "hg19" - ) # ldReference omitted -> NULL - expect_null(ldReference(ss)) + ) # ldReference omitted -> LD-free + expect_identical(ldReference(ss), list()) + expect_true(is.na(ss$ldReference)) expect_output(show(ss), "none \\(LD-free\\)") }) @@ -569,13 +570,16 @@ test_that("combineGwasSumStats() unions the per-block LD panels", { b <- makeGwasBlock("chr1_1001_2000", 1100L, n = 3L) out <- combineGwasSumStats(a, b) - # Keeping only the first block's panel would leave a two-block collection - # whose LD reference covers one block. - expect_equal(nrow(ldReference(out)), 8L) + # Each block's panel was narrowed to its own variants, but one panel's + # files back both, so the bound collection holds them once, unioned. + refs <- ldReference(out) + expect_length(refs, 1L) + expect_equal(nrow(refs[[1L]]), 8L) expect_equal( - rownames(ldReference(out)), - c(rownames(ldReference(a)), rownames(ldReference(b))) + rownames(refs[[1L]]), + c(rownames(ldReference(a)[[1L]]), rownames(ldReference(b)[[1L]])) ) + expect_equal(unique(out$ldReference), names(refs)) }) @@ -611,22 +615,31 @@ test_that("combineGwasSumStats() rejects collection-level disagreement", { noQc <- makeGwasBlock("chr1_1001_2000", 1100L) noQc@qcInfo <- list() expect_error(combineGwasSumStats(a, noQc), "carry no QC record") +}) - noLd <- makeGwasBlock("chr1_1001_2000", 1100L) - noLd@ldReference <- NULL - expect_error(combineGwasSumStats(a, noLd), "carry no ldReference") - other <- makeGwasBlock("chr1_1001_2000", 1100L) - other@ldReference <- pecotmr:::.asLdRef( - .blockGenotypeHandle( +test_that("combineGwasSumStats() keeps each row on its own LD reference", { + a <- makeGwasBlock("chr1_1_1000", 100L) + other <- makeGwasBlock( + "chr1_1001_2000", + 1100L, + ldReference = .blockGenotypeHandle( seq(1100L, by = 100L, length.out = 5L), path = "/tmp/other.pgen" ) ) - expect_error( - combineGwasSumStats(a, other), - "different genotype panels" - ) + out <- combineGwasSumStats(a, other) + # Panels read from different files cannot be unioned, so both are kept. + expect_length(ldReference(out), 2L) + expect_identical( + pecotmr:::.rowLdRefs(out), + list(ldReference(a)[[1L]], ldReference(other)[[1L]]) + ) + # An LD-free part's rows stay LD-free beside them. + noLd <- makeGwasBlock("chr1_2001_3000", 2100L, ldReference = NULL) + mixed <- combineGwasSumStats(a, noLd) + expect_equal(is.na(mixed$ldReference), c(FALSE, TRUE)) + expect_length(ldReference(mixed), 1L) }) diff --git a/tests/testthat/test_QtlFineMappingResult.R b/tests/testthat/test_QtlFineMappingResult.R index ba5b4625..e831ac80 100644 --- a/tests/testthat/test_QtlFineMappingResult.R +++ b/tests/testthat/test_QtlFineMappingResult.R @@ -14,7 +14,7 @@ test_that("QtlFineMappingResult: builds a collection keyed by 4-tuple", { ) expect_s4_class(res, "QtlFineMappingResult") expect_equal(nrow(res), 2L) - expect_null(ldReference(res)) + expect_identical(ldReference(res), list()) }) @@ -57,9 +57,11 @@ test_that("QtlFineMappingResult: stores an LD sketch when supplied", { entry = list(e), ldReference = gh ) - # The slot holds the panel; the handle it reads through is its seed. - expect_s4_class(ldReference(res), "RangedSummarizedExperiment") - expect_identical(pecotmr:::.ldRefHandle(ldReference(res)), gh) + # The reference is a panel; the handle it reads through is its seed. + refs <- ldReference(res) + expect_named(refs, res$ldReference) + expect_s4_class(refs[[1L]], "RangedSummarizedExperiment") + expect_identical(pecotmr:::.ldRefHandle(refs[[1L]]), gh) }) diff --git a/tests/testthat/test_RangedTupleList.R b/tests/testthat/test_RangedTupleList.R index 7b454701..6b27e4a3 100644 --- a/tests/testthat/test_RangedTupleList.R +++ b/tests/testthat/test_RangedTupleList.R @@ -898,3 +898,50 @@ test_that("blockId reads the recorded value, not the variants' span", { ) expect_equal(blockId(res), "chr1_1_1000000") }) + +# =========================================================================== +# updateObject(): collections saved before references became per-row +# =========================================================================== + +# A collection as an earlier version saved it: one reference (or NULL) in the +# slot and no row key. +.rtl_asSaved <- function(x, ref) { + old <- `slot<-`(x, "ldReference", check = FALSE, value = ref) + md <- attr(old, "elementMetadata") + md[["ldReference"]] <- NULL + attr(old, "elementMetadata") <- md + old +} + +test_that("updateObject keys every row of an old collection to its reference", { + data(qtlSumStatsMulticontextExample) + mc <- qtlSumStatsMulticontextExample + panel <- ldReference(mc)[[1L]] + old <- .rtl_asSaved(mc, panel) + # Read as it was saved, the old object is refused, not taken as LD-free. + expect_error(ldReference(old), "updateObject") + new <- updateObject(old) + expect_true(methods::validObject(new)) + expect_identical(ldReference(new), list(ld1 = panel)) + expect_identical(new$ldReference, rep("ld1", nrow(mc))) +}) + +test_that("updateObject marks every row of an old LD-free collection LD-free", { + data(qtlFineMappingExample) + old <- .rtl_asSaved(qtlFineMappingExample, NULL) + # Read as it was saved, it already reads LD-free: a NULL slot meant no + # reference then too, so there is nothing to refuse. + expect_identical(ldReference(old), list()) + new <- updateObject(old) + expect_identical(ldReference(new), list()) + expect_true(all(is.na(new$ldReference))) +}) + +test_that("updateObject leaves a current collection as it is", { + data(qtlSumStatsExample) + expect_identical(updateObject(qtlSumStatsExample), qtlSumStatsExample) + expect_message( + updateObject(qtlSumStatsExample, verbose = TRUE), + "updateObject\\(object = 'QtlSumStats'\\)" + ) +}) diff --git a/tests/testthat/test_causalInferencePipeline.R b/tests/testthat/test_causalInferencePipeline.R index ca4767e8..b5147fc5 100644 --- a/tests/testthat/test_causalInferencePipeline.R +++ b/tests/testthat/test_causalInferencePipeline.R @@ -250,16 +250,44 @@ test_that(".cipRequireMatchingLdRefs: differently trimmed panels pass", { # Independent QC of the QTL and GWAS sides leaves one LD reference as two # overlapping-but-unequal panels, which the check reports rather than # refuses. + tw <- .cip_makeTwasWeights() + tw <- pecotmr:::.withRowLdRefs(tw, .cip_makeHandle(snp_n = 6L)) + gwas <- pecotmr:::.withRowLdRefs( + .cip_makeGwasSumstats(), + .cip_makeHandle(snp_n = 7L) + ) expect_warning( expect_null(pecotmr:::.cipRequireMatchingLdRefs( - .cip_makeHandle(snp_n = 6L), - .cip_makeHandle(snp_n = 7L), + tw, + gwas, label = "twasWeights" )), "share 6 variant" ) }) +test_that(".cipRequireMatchingLdRefs: rows that never meet may differ", { + # The check is per pair of rows scored together -- those whose regions + # overlap -- so a weight row elsewhere on the genome is not held to the + # GWAS rows' panel. + elsewhere <- TwasWeights( + studyName = "Q1", + context = "c1", + trait = "t1", + method = "lasso", + entry = list(twasWeightsRow( + variantIds = sprintf("chr2:%d:A:G", 100L * (1:5)), + weights = rep(0.1, 5) + )), + ldReference = .cip_makeHandle(sample_prefix = "other") + ) + expect_null(pecotmr:::.cipRequireMatchingLdRefs( + elsewhere, + .cip_makeGwasSumstats(), + label = "twasWeights" + )) +}) + # =========================================================================== # Happy path: TwasWeights only # =========================================================================== @@ -1398,7 +1426,7 @@ test_that(".cipComputeMrCsAware matches across a chr-prefix difference", { test_that(".cipComputeTwasZ gives a Z from a panel's factor or an LdMatrix", { data(gwasSumStatsS4Example) - panel <- ldReference(gwasSumStatsS4Example) + panel <- ldReference(gwasSumStatsS4Example)[[1L]] ids <- names(SummarizedExperiment::rowRanges(panel))[c(3, 8, 15, 21, 30)] ld <- LdMatrix( unname(computeLd(panel)), @@ -2017,7 +2045,9 @@ test_that(".cipScoreQtlTuple skips a tuple with no weights", { test_that(".cipScoreGwasPair skips a pair with no TWAS z", { local_mocked_bindings( - as.data.frame = function(...) data.frame(SNP = "v1", Z = 1), + .cipRowsLdRef = function(...) NULL, + .ssStitchElements = function(...) GenomicRanges::GRanges(), + .entryToSumstatDf = function(...) data.frame(SNP = "v1", Z = 1), .cipComputeTwasZ = function(...) NULL, .cipPairLabel = function(...) "lab", .package = "pecotmr" @@ -2025,11 +2055,12 @@ test_that(".cipScoreGwasPair skips a pair with no TWAS z", { expect_null( pecotmr:::.cipScoreGwasPair( 1L, + "G1", NULL, list(), NULL, - gwasSumStats = list(study = "G1"), - gwasLd = NULL, + gwasSumStats = NULL, + window = NULL, alleleFlip = FALSE, mrParam = MrParam( method = "csAware", @@ -2126,3 +2157,97 @@ test_that("WeightSelectionParam and MrParam do not overlap", { expect_equal(WeightSelectionParam()$cutoff, 0) expect_equal(MrParam()$method, "ivwPerVariant") }) + +test_that(".cipRowsLdRef refuses overlapped rows on two references", { + # The rows a tuple overlaps are scored together against one LD matrix. + block <- function(start) { + gr <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(seq(start, by = 100L, length.out = 3L), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = sprintf( + "chr1:%d:A:G", + seq(start, by = 100L, length.out = 3L) + ), + A1 = "A", + A2 = "G", + Z = c(1, 2, 3), + N = 1000L + ) + gr + } + two <- GwasSumStats( + studyName = c("G1", "G1"), + entry = list(block(100L), block(5000L)), + genome = "hg19", + ldReference = list( + .cip_makeHandle(), + .cip_makeHandle(sample_prefix = "z") + ), + blockId = c("b1", "b2"), + qcInfo = list(step1 = "ok") + ) + expect_error( + pecotmr:::.cipRowsLdRef(two, 1:2, "G1"), + "GWAS study 'G1' a QTL tuple overlaps use 2 different LD" + ) + # A tuple overlapping one of them reads that row's reference alone. + expect_identical( + pecotmr:::.cipRowsLdRef(two, 2L, "G1"), + ldReference(two)[[2L]] + ) +}) + +test_that("a gene is scored once per GWAS study, over the rows it overlaps", { + # One study split into two LD blocks on chr1 plus a chr2 row on another + # panel: the chr1 gene overlaps only block A, so it is scored once, + # and the chr2 row's reference never enters into it. + idsA <- sprintf("chr1:%d:A:G", 100L * (1:5)) + idsB <- sprintf("chr1:%d:A:G", 100L * (6:10)) + ids2 <- sprintf("chr2:%d:A:G", 100L * (1:5)) + ldm <- function(ids) { + n <- length(ids) + LdMatrix(`dimnames<-`(diag(n) * 0.5 + 0.5, list(ids, ids))) + } + entry <- function(ids, chrom, pos) { + gr <- GenomicRanges::GRanges(chrom, IRanges::IRanges(pos, width = 1L)) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = ids, + A1 = "A", + A2 = "G", + Z = seq(4, 0.5, length.out = length(ids)), + N = 1000L + ) + gr + } + chr1 <- ldm(c(idsA, idsB)) + gws <- GwasSumStats( + studyName = c("G1", "G1", "G1"), + entry = list( + entry(idsA, "chr1", 100L * (1:5)), + entry(idsB, "chr1", 100L * (6:10)), + entry(ids2, "chr2", 100L * (1:5)) + ), + genome = "hg19", + ldReference = list(chr1, chr1, ldm(ids2)), + blockId = c("blockA", "blockB", "chr2"), + qcInfo = list(step1 = "ok") + ) + tw <- TwasWeights( + studyName = "Q1", + context = "c1", + trait = "gene1", + method = "lasso", + entry = list(twasWeightsRow( + variantIds = idsA, + weights = c(0.3, 0.2, 0.1, 0.05, 0) + )), + ldReference = chr1 + ) + out <- suppressMessages(suppressWarnings( + causalInferencePipeline(gwasSumStats = gws, twasWeights = tw) + )) + expect_equal(length(out), 1L) + expect_equal(as.character(S4Vectors::mcols(out)$gwasStudy), "G1") +}) diff --git a/tests/testthat/test_colocPipeline.R b/tests/testthat/test_colocPipeline.R index 9ebfc83a..dc92129b 100644 --- a/tests/testthat/test_colocPipeline.R +++ b/tests/testthat/test_colocPipeline.R @@ -263,11 +263,16 @@ test_that(".colocRequireMatchingLdRefs: sample set mismatch errors", { test_that(".colocRequireMatchingLdRefs: differently trimmed panels pass", { # The two sides QC'd separately keep different subsets of one LD # reference; the panels overlap, so the check warns rather than aborting. + qfmr <- pecotmr:::.withRowLdRefs( + .cp_makeQtlFmr(), + .cp_makeHandle(snp_n = 6L) + ) + gfmr <- pecotmr:::.withRowLdRefs( + .cp_makeGwasFmr(), + .cp_makeHandle(snp_n = 7L) + ) expect_warning( - expect_null(pecotmr:::.colocRequireMatchingLdRefs( - .cp_makeHandle(snp_n = 6L), - .cp_makeHandle(snp_n = 7L) - )), + expect_null(pecotmr:::.colocRequireMatchingLdRefs(qfmr, gfmr)), "share 6 variant" ) }) @@ -502,7 +507,8 @@ test_that("colocPipeline: empty result has the documented schema", { "PP.H3.abf", "PP.H4.abf", "qtlRetainedMass", - "gwasRetainedMass" + "gwasRetainedMass", + "ldReference" ) ) }) @@ -1629,3 +1635,34 @@ test_that("GwasFineMappingParam accessors read and replace every field", { expect_equal(fineMappingMethods(p), "susie") expect_true(initializeWithSusieInf(p)) }) + +# =========================================================================== +# Per-pair LD references +# =========================================================================== + +# An LdMatrix over five variants at 100 bp spacing on `chrom`. +.cp_ldm <- function(rho, chrom = "chr1") { + ids <- sprintf("%s:%d:A:G", chrom, 100L * (1:5)) + LdMatrix(`dimnames<-`(rho^abs(outer(1:5, 1:5, "-")), list(ids, ids))) +} + +test_that("coloc refuses an overlapping pair on two different references", { + qfmr <- pecotmr:::.withRowLdRefs(.cp_makeQtlFmr(), .cp_ldm(0.2)) + gfmr <- pecotmr:::.withRowLdRefs(.cp_makeGwasFmr(), .cp_ldm(0.8)) + expect_error( + pecotmr:::.colocRequireMatchingLdRefs(qfmr, gfmr), + "disagree on the LD" + ) +}) + +test_that("coloc lets rows that never pair sit on different references", { + # The QTL row is on chr1 and the GWAS row on chr2, so coloc never scores + # them against each other and their references need not match. + qfmr <- pecotmr:::.withRowLdRefs(.cp_makeQtlFmr(), .cp_ldm(0.2)) + chr2 <- .cp_makeFmEntry(variant_ids = paste0("chr2:", 100 * (1:5), ":A:G")) + gfmr <- pecotmr:::.withRowLdRefs( + .cp_makeGwasFmr(entries = list(chr2)), + .cp_ldm(0.8, chrom = "chr2") + ) + expect_null(pecotmr:::.colocRequireMatchingLdRefs(qfmr, gfmr)) +}) diff --git a/tests/testthat/test_colocboostPipeline.R b/tests/testthat/test_colocboostPipeline.R index 83b93049..38aa76b2 100644 --- a/tests/testthat/test_colocboostPipeline.R +++ b/tests/testthat/test_colocboostPipeline.R @@ -85,8 +85,8 @@ context("colocboostPipeline (S4 dispatch)") # ---------------------------------------------------------------------------- # colocboost::colocboost is the heavy compute; we mock it to return a stub # result so the pipeline orchestration runs end-to-end. The helpers -# (.cbBuildLdArgs, .cbMergeSumstatBundles, -# .cbRequireMatchingLdRefs, .cbEmptyResult) are exercised directly. +# (.cbBuildLdArgs, .cbMergeSumstatBundles, .cbResultLdRefs, .cbEmptyResult) +# are exercised directly. # =========================================================================== .cbp_makeHandle <- function(snp_n = 6L, n_samples = 30L, sample_prefix = "s") { @@ -216,7 +216,7 @@ context("colocboostPipeline (S4 dispatch)") ) } -.cbp_makeGwasSumStats <- function(qc = TRUE) { +.cbp_makeGwasSumStats <- function(qc = TRUE, ldReference = .cbp_makeHandle()) { gr <- GenomicRanges::GRanges( seqnames = "chr1", ranges = IRanges::IRanges( @@ -235,11 +235,19 @@ context("colocboostPipeline (S4 dispatch)") studyName = "G1", entry = list(gr), genome = "hg19", - ldReference = .cbp_makeHandle(), + ldReference = ldReference, qcInfo = if (qc) list(step1 = "ok") else list() ) } +# An LdMatrix over the fixtures' five variants, so a side can be put on a +# reference other than the shared genotype panel. +.cbp_makeLdMatrix <- function(rho = 0.2) { + ids <- sprintf("chr1:%d:A:G", 100L * (1:5)) + r <- rho^abs(outer(1:5, 1:5, "-")) + LdMatrix(`dimnames<-`(r, list(ids, ids))) +} + # =========================================================================== # Internal helpers (run-anywhere) # =========================================================================== @@ -323,39 +331,6 @@ test_that(".cbRequireSumStatsQc: QCd input passes", { }) -test_that(".cbRequireMatchingLdRefs: NULL sides are allowed", { - expect_silent(pecotmr:::.cbRequireMatchingLdRefs( - NULL, - .cbp_makeHandle() - )) - expect_silent(pecotmr:::.cbRequireMatchingLdRefs( - .cbp_makeHandle(), - NULL - )) -}) - -test_that(".cbRequireMatchingLdRefs: accepts differently trimmed panels", { - # Separate QC of the two sides trims one shared LD reference to two - # overlapping-but-unequal variant sets; the check reports, not refuses. - expect_warning( - expect_null(pecotmr:::.cbRequireMatchingLdRefs( - .cbp_makeHandle(snp_n = 4L), - .cbp_makeHandle(snp_n = 5L) - )), - "share 4 variant" - ) -}) - -test_that(".cbRequireMatchingLdRefs: sample-set mismatch errors", { - expect_error( - pecotmr:::.cbRequireMatchingLdRefs( - .cbp_makeHandle(sample_prefix = "a"), - .cbp_makeHandle(sample_prefix = "b") - ), - "different sample sets" - ) -}) - test_that(".cbMergeSumstatBundles: empty input gives empty dict", { res <- pecotmr:::.cbMergeSumstatBundles(list()) expect_equal(length(res$sumstat), 0L) @@ -375,8 +350,9 @@ test_that(".cbMergeSumstatBundles: identical LD matrices are deduplicated", { expect_identical(res$ldArg, "LD") }) -test_that(".cbMergeSumstatBundles records factors and refuses a mix", { - f <- matrix(c(1, -1, 0.5, -0.5), 2) +test_that(".cbMergeSumstatBundles records factors and turns a mix into LD", { + ids <- c("v1", "v2") + f <- matrix(c(1, -1, 0.5, -0.5), 2, dimnames = list(NULL, ids)) factors <- list( a = list(sumstat = data.frame(z = 1:2), LD = f, isFactor = TRUE), b = list(sumstat = data.frame(z = 3:4), LD = f, isFactor = TRUE) @@ -384,11 +360,18 @@ test_that(".cbMergeSumstatBundles records factors and refuses a mix", { res <- pecotmr:::.cbMergeSumstatBundles(factors) expect_identical(res$ldArg, "X_ref") expect_equal(length(res$LD), 1L) - mixed <- list_assign(factors, b = list_assign(factors$b, isFactor = FALSE)) - expect_error( - pecotmr:::.cbMergeSumstatBundles(mixed), - "mix LD matrices and genotype factors" - ) + # colocboost takes LD or X_ref, never both, so a run whose two sides use + # different kinds of reference gets the factor as its LD matrix. + ld <- matrix(c(1, 0.3, 0.3, 1), 2, dimnames = list(ids, ids)) + mixed <- list_assign( + factors, + b = list(sumstat = data.frame(z = 3:4), LD = ld, isFactor = FALSE) + ) + res <- pecotmr:::.cbMergeSumstatBundles(mixed) + expect_identical(res$ldArg, "LD") + expect_equal(res$LD[[1L]], crossprod(f) / (nrow(f) - 1L)) + expect_identical(res$LD[[2L]], ld) + expect_equal(unname(res$dict_sumstatLD[, "LD"]), 1:2) }) test_that(".cbEmptyResult: is the internal per-analysis accumulator", { @@ -610,49 +593,111 @@ test_that("colocboostPipeline: no analysis flag set is an error", { } }) -test_that("colocboostPipeline: GWAS ldReference mismatch errors in driver", { +test_that("a GWAS on a different LD reference runs, and both are recorded", { + # The two sides need not share a reference: a GWAS panel with another + # sample set is matched against on its own rather than refused. ss <- .cbp_makeQtlSumStats() - # Build a GwasSumStats whose ldReference has a different sample set. - gh_diff <- .cbp_makeHandle(sample_prefix = "z") - gr <- GenomicRanges::GRanges( - seqnames = "chr1", - ranges = IRanges::IRanges( - start = seq(100L, by = 100L, length.out = 5L), - width = 1L - ) + gs <- .cbp_makeGwasSumStats( + ldReference = .cbp_makeHandle(sample_prefix = "z") ) - S4Vectors::mcols(gr) <- S4Vectors::DataFrame( - SNP = sprintf("chr1:%d:A:G", 100L * (1:5)), - A1 = rep("A", 5), - A2 = rep("G", 5), - Z = rnorm(5), - N = rep(1000L, 5) + seen <- list() + local_mocked_bindings( + extractBlockGenotypes = .cbp_mockExtractor(), + .package = "pecotmr" ) - gs <- GwasSumStats( - studyName = "G1", - entry = list(gr), - genome = "hg19", - ldReference = gh_diff, - qcInfo = list(step1 = "ok") + local_mocked_bindings( + colocboost = function(...) { + seen[[length(seen) + 1L]] <<- list(...) + list(jointly_run = TRUE) + }, + .package = "colocboost" ) - # .cbQtlSumStatsBundle reads the qtl sketch via extractBlockGenotypes - # before the LD-sketch mismatch check fires further down the driver, so - # mock the extractor here too. + out <- suppressMessages( + colocboostPipeline( + ss, + gwasSumStats = gs, + xqtlColoc = FALSE, + jointGwas = TRUE + ) + ) + expect_equal(length(seen), 1L) + expect_equal(nrow(seen[[1L]]$dict_sumstatLD), 2L) + # Each outcome keys to the reference it was matched against. + refs <- ldReference(out) + expect_length(refs, 2L) + info <- out@outcomeInfo + keys <- info$ldReference[match(c("Q1:c1:t1", "G1"), info$name)] + expect_identical(refs[[keys[[1L]]]], ldReference(ss)[[1L]]) + expect_identical(refs[[keys[[2L]]]], ldReference(gs)[[1L]]) +}) + +test_that("a panel and an LdMatrix on opposite sides reach colocboost as LD", { + ss <- .cbp_makeQtlSumStats() + ldm <- .cbp_makeLdMatrix() + gs <- .cbp_makeGwasSumStats(ldReference = ldm) + seen <- list() local_mocked_bindings( extractBlockGenotypes = .cbp_mockExtractor(), .package = "pecotmr" ) - expect_error( - suppressMessages( - colocboostPipeline( - ss, - gwasSumStats = gs, - xqtlColoc = FALSE, - jointGwas = TRUE - ) - ), - "different sample sets" + local_mocked_bindings( + colocboost = function(...) { + seen[[length(seen) + 1L]] <<- list(...) + list(jointly_run = TRUE) + }, + .package = "colocboost" + ) + out <- suppressMessages( + colocboostPipeline( + ss, + gwasSumStats = gs, + xqtlColoc = TRUE, + jointGwas = TRUE + ) + ) + nSumstats <- map_int(seen, function(call) length(call$sumstat)) + xqtl <- seen[[which(nSumstats == 1L)]] + joint <- seen[[which(nSumstats == 2L)]] + # The QTL-only run has one kind of reference and keeps the panel's factor. + expect_null(xqtl$LD) + factor <- xqtl$X_ref[[1L]] + # colocboost takes LD or X_ref but not both, so the joint run gets the + # panel's factor as its LD matrix alongside the LdMatrix's own. + expect_null(joint$X_ref) + dict <- joint$dict_sumstatLD + expect_equal( + joint$LD[[dict[1L, "LD"]]], + crossprod(factor) / (nrow(factor) - 1L) + ) + expect_equal( + unname(joint$LD[[dict[2L, "LD"]]]), + 0.2^abs(outer(1:5, 1:5, "-")) + ) + expect_identical( + unname(ldReference(out)), + list(ldReference(ss)[[1L]], ldm) + ) +}) + +test_that(".cbResultLdRefs keys each outcome to its pair's reference", { + panel <- ldReference(.cbp_makeQtlSumStats())[[1L]] + ldm <- .cbp_makeLdMatrix() + pairs <- list( + `Q1:c1:t1` = list(ldReference = panel), + `Q1:c2:t1` = list(ldReference = panel), + G1 = list(ldReference = ldm) + ) + out <- pecotmr:::.cbResultLdRefs(pairs) + # Each distinct reference once, however many outcomes used it. + expect_identical(out$refs, list(ld1 = panel, ld2 = ldm)) + expect_equal( + out$keys, + c(`Q1:c1:t1` = "ld1", `Q1:c2:t1` = "ld1", G1 = "ld2") ) + # No pairs, no references. + none <- pecotmr:::.cbResultLdRefs(list()) + expect_identical(none$refs, list()) + expect_length(none$keys, 0L) }) # =========================================================================== @@ -1097,7 +1142,7 @@ test_that("colocboost RSS cutoffs match .panelVariantFilter", { expect_equal( .cbf_n(ss, mafCutoff = cut), length(.panelVariantFilter( - ldReference(ss), + ldReference(ss)[[1L]], ids, PanelFilterParam(mafCutoff = cut) )), @@ -1108,7 +1153,7 @@ test_that("colocboost RSS cutoffs match .panelVariantFilter", { test_that("colocboost RSS treats MAC as a MAF equivalent", { ss <- .cbf_qcd() - nSamp <- ncol(ldReference(ss)) + nSamp <- ncol(ldReference(ss)[[1L]]) expect_equal( .cbf_n(ss, macCutoff = 0.1 * 2 * nSamp), .cbf_n(ss, mafCutoff = 0.1) @@ -1133,7 +1178,7 @@ test_that(".cbSumstatPair keeps sumstat rows aligned to the LD matrix", { trait = ss$trait[[1L]], require = "Z" ) - sketch <- ldReference(ss) + sketch <- ldReference(ss)[[1L]] pair <- suppressMessages(.cbSumstatPair( df = df, ldReference = sketch, @@ -1157,7 +1202,7 @@ test_that("colocboost reads a panel's factor and its LdMatrix alike", { skip_if_not_installed("colocboost") data(qtlSumStatsMulticontextExample) ss <- suppressMessages(summaryStatsQc(qtlSumStatsMulticontextExample)) - panel <- ldReference(ss) + panel <- ldReference(ss)[[1L]] withLd <- QtlSumStats( studyName = ss$study, context = ss$context, @@ -1189,7 +1234,7 @@ test_that(".cbSumstatPair returns NULL when a cutoff removes everything", { ) expect_null(suppressMessages(.cbSumstatPair( df = df, - ldReference = ldReference(ss), + ldReference = ldReference(ss)[[1L]], cutoffs = list(mafCutoff = 0.99, macCutoff = 0, imissCutoff = 1) ))) }) @@ -1570,8 +1615,7 @@ test_that(".cbAppendGwasPairs disambiguates a colliding study key", { ) out <- pecotmr:::.cbAppendGwasPairs( list(dup = "QTL", other = "X"), - "notNull", - qtlLdReference = NULL + "notNull" ) # The QTL pair keeps its key; the GWAS pair is suffixed rather than # overwriting it. diff --git a/tests/testthat/test_ctwasPipeline.R b/tests/testthat/test_ctwasPipeline.R index 9c3a35a7..7b30649d 100644 --- a/tests/testthat/test_ctwasPipeline.R +++ b/tests/testthat/test_ctwasPipeline.R @@ -444,11 +444,26 @@ test_that(".ctwasRequireMatchingLdRefs: NULL twas-side handle is allowed", { ldReference = NULL ) expect_silent(pecotmr:::.ctwasRequireMatchingLdRefs( - twLd = NULL, - gwasLd = .ctp_makeHandle() + twNoLd, + .ctp_makeGwasSumstats() )) }) +# One weight row on `handle`, for the region-level match checks. +.ctp_weightsOn <- function(handle) { + TwasWeights( + studyName = "Q1", + context = "c1", + trait = "t1", + method = "susie", + entry = list(twasWeightsRow( + variantIds = sprintf("chr1:%d:A:G", 100L * (1:3)), + weights = rep(0.1, 3) + )), + ldReference = handle + ) +} + test_that(".ctwasRequireMatchingLdRefs: differently trimmed panels ok", { # One LD reference QC'd separately on the two sides leaves each sketch # trimmed to its own surviving variants, so the panels overlap without @@ -459,22 +474,27 @@ test_that(".ctwasRequireMatchingLdRefs: differently trimmed panels ok", { # its own variants while the weights carry the whole one), so clear that # budget here rather than depending on which files ran before this. rlang::reset_warning_verbosity("pecotmrLdReferenceOverlap-ctwasPipeline") - twLd <- .ctp_makeHandle(snp_n = 5L) - gwasLd <- .ctp_makeHandle(snp_n = 6L) + tw <- .ctp_weightsOn(.ctp_makeHandle(snp_n = 5L)) + gwas <- pecotmr:::.withRowLdRefs( + .ctp_makeGwasSumstats(), + .ctp_makeHandle(snp_n = 6L) + ) expect_warning( - expect_null(pecotmr:::.ctwasRequireMatchingLdRefs(twLd, gwasLd)), + expect_null(pecotmr:::.ctwasRequireMatchingLdRefs(tw, gwas)), "share 5 variant" ) }) test_that(".ctwasRequireMatchingLdRefs: disjoint panels error", { - twLd <- .ctp_makeHandle(snp_n = 3L) gwasLd <- .ctp_makeHandle(snp_n = 3L) si <- snpInfo(gwasLd) si$BP <- si$BP + 1e6L gwasLd@snpInfo <- si expect_error( - pecotmr:::.ctwasRequireMatchingLdRefs(twLd, gwasLd), + pecotmr:::.ctwasRequireMatchingLdRefs( + .ctp_weightsOn(.ctp_makeHandle(snp_n = 3L)), + pecotmr:::.withRowLdRefs(.ctp_makeGwasSumstats(), gwasLd) + ), "share no variant" ) }) @@ -758,15 +778,15 @@ test_that(".ctwasPickBlock: narrows the collection sketch to the block", { ss <- .ctp_makeGwasSumstats() # The collection's sketch spans both blocks, as combineGwasSumStats # leaves it. - expect_equal(length(pecotmr:::.ldRefRanges(ldReference(ss))), 12L) + expect_equal(length(pecotmr:::.ldRefRanges(ldReference(ss)[[1L]])), 12L) byBlock <- pecotmr:::.ctwasGwasByBlock(ss) sizes <- map_int(byBlock, function(b) { - length(pecotmr:::.ldRefRanges(ldReference(b))) + length(pecotmr:::.ldRefRanges(ldReference(b)[[1L]])) }) expect_equal(unname(sizes), c(6L, 6L)) # Narrowed to DIFFERENT variants: block 1 holds 1..6, block 2 holds 7..12. pos <- map(byBlock, function(b) { - GenomicRanges::start(pecotmr:::.ldRefRanges(ldReference(b))) + GenomicRanges::start(pecotmr:::.ldRefRanges(ldReference(b)[[1L]])) }) expect_equal(pos[[1L]], 100L * (1:6)) expect_equal(pos[[2L]], 100L * (7:12)) @@ -775,7 +795,7 @@ test_that(".ctwasPickBlock: narrows the collection sketch to the block", { test_that(".ctwasRegionLdTokens: one distinct, existing token per region", { ss <- .ctp_makeGwasSumstats() byBlock <- pecotmr:::.ctwasGwasByBlock(ss) - sketches <- map(byBlock, ldReference) + sketches <- map(byBlock, function(b) ldReference(b)[[1L]]) tokens <- pecotmr:::.ctwasRegionLdTokens(names(byBlock), sketches) expect_length(unique(unname(tokens)), 2L) expect_true(all(file.exists(tokens))) @@ -1093,7 +1113,7 @@ test_that(".ctwasBucketWeights: places a flat 2-gene source into its home blocks expect_named(bucketed, c("block1", "block2"), ignore.order = TRUE) expect_equal(as.character(bucketed[["block1"]]$trait), "gA") expect_equal(as.character(bucketed[["block2"]]$trait), "gB") - expect_false(is.null(ldReference(bucketed[["block1"]]))) + expect_length(ldReference(bucketed[["block1"]]), 1L) }) test_that(".ctwasBucketWeights: errors when source lacks traitPos", { @@ -1773,7 +1793,7 @@ test_that(".ctwasGlobalPanelInfo: NULL when the collection has no sketch", { blockId = "block1", qcInfo = list(step1 = "ok") ) - expect_null(ldReference(gs)) + expect_identical(ldReference(gs), list()) # .ctwasRegionGwasLd reports the missing-sketch case with its own # message, so this helper must stay quiet and hand back NULL. expect_null(pecotmr:::.ctwasGlobalPanelInfo(gs)) @@ -4076,7 +4096,7 @@ test_that(".ctwasBuildSingleRegionInfo reports an empty block accurately", { test_that(".ctwasFirstPass requires an LD reference on every region", { byBlock <- pecotmr:::.ctwasGwasByBlock(.ctp_noLdGwas()) - expect_null(ldReference(byBlock[[1L]])) + expect_identical(ldReference(byBlock[[1L]]), list()) expect_error( pecotmr:::.ctwasFirstPass("b1", byBlock, list(b1 = NULL)), "region 'b1' carries no ldReference" @@ -4240,3 +4260,16 @@ test_that("ctwas reads variance and LD from an LdMatrix block", { # An LdMatrix has no file payload to check. expect_null(.ctwasLdPanelKey(bare)) }) + +test_that(".ctwasRegionGwasLd refuses a region whose rows use two references", { + # A region's LD is one matrix, so its GWAS rows must share a reference. + gwas <- .ctp_makeGwasSumstats(blockIds = c("blockA", "blockA")) + gwas <- pecotmr:::.withRowLdRefs( + gwas, + list(.ctp_makeHandle(snp_n = 12L), .ctp_makeHandle(snp_n = 6L)) + ) + expect_error( + pecotmr:::.ctwasRegionGwasLd(1L, list(gwas), list()), + "2 different LD references; a region's LD is one matrix" + ) +}) diff --git a/tests/testthat/test_fineMappingPipeline.R b/tests/testthat/test_fineMappingPipeline.R index 0333eb86..0497f2ba 100644 --- a/tests/testthat/test_fineMappingPipeline.R +++ b/tests/testthat/test_fineMappingPipeline.R @@ -2060,7 +2060,7 @@ test_that("fineMappingPipeline(MultiStudyQtlDataset): aggregates results across expect_equal(nrow(res), 2L) expect_setequal(studyName(res), c("s1", "s2")) # Pure individual-level -> ldReference should be NULL. - expect_null(ldReference(res)) + expect_identical(ldReference(res), list()) }) # A study measured in brain and liver, on the synthetic genotypes. @@ -2311,7 +2311,7 @@ test_that("fineMappingPipeline(MSQD): embedded sumstats record ldReference", { expect_s4_class(res, "QtlFineMappingResult") expect_true(nrow(res) >= 2L) # Embedded sumstats has an LD sketch -> the merged result carries it. - expect_s4_class(ldReference(res), "RangedSummarizedExperiment") + expect_s4_class(ldReference(res)[[1L]], "RangedSummarizedExperiment") }) # =========================================================================== @@ -5001,7 +5001,7 @@ test_that("fineMappingPipeline RSS cutoffs agree with .panelVariantFilter", { ids <- variantIds(ss) for (cut in c(0.05, 0.2)) { expected <- length(.panelVariantFilter( - ldReference(ss), + ldReference(ss)[[1L]], ids, PanelFilterParam(mafCutoff = cut) )) @@ -5015,7 +5015,7 @@ test_that("fineMappingPipeline RSS cutoffs agree with .panelVariantFilter", { test_that("fineMappingPipeline RSS treats MAC as a MAF equivalent", { ss <- .rssf_qcd() - nSamp <- ncol(ldReference(ss)) + nSamp <- ncol(ldReference(ss)[[1L]]) expect_equal( .rssf_n(ss, macCutoff = 0.1 * 2 * nSamp), .rssf_n(ss, mafCutoff = 0.1) @@ -5032,7 +5032,7 @@ test_that("fineMappingPipeline RSS honours a missingness cutoff", { test_that(".fmExtractZn keeps z, ids and n aligned after filtering", { ss <- .rssf_qcd() entry <- pecotmr:::.collectionEntry(ss, 1L) - sketch <- ldReference(ss) + sketch <- ldReference(ss)[[1L]] unfiltered <- pecotmr:::.fmExtractZn(entry, "t") filtered <- suppressMessages(pecotmr:::.fmExtractZn( entry, @@ -6091,8 +6091,8 @@ test_that("MultiStudyQtlDataset: cross-study joint fits get their settings", { # The bundled GWAS collection, with its panel's LD copied into an LdMatrix # and used as the reference instead. -.fmp_withLdMatrix <- function(gss, nSamples = ncol(ldReference(gss))) { - panel <- ldReference(gss) +.fmp_withLdMatrix <- function(gss, nSamples = ncol(ldReference(gss)[[1L]])) { + panel <- ldReference(gss)[[1L]] ld <- LdMatrix( unname(computeLd(panel)), variants = SummarizedExperiment::rowRanges(panel), @@ -6127,13 +6127,13 @@ test_that("fine-mapping with an LdMatrix reference matches its panel", { viaPanel <- .fmp_fitSusie(gss) expect_equal(pip(viaMatrix), pip(viaPanel)) expect_equal(credibleSets(viaMatrix), credibleSets(viaPanel)) - expect_s4_class(ldReference(viaMatrix), "LdMatrix") + expect_s4_class(ldReference(viaMatrix)[[1L]], "LdMatrix") }) test_that("an RSS block reads a genotype reference's factor, not its LD", { data(gwasSumStatsS4Example) gss <- gwasSumStatsS4Example - panel <- ldReference(gss) + panel <- ldReference(gss)[[1L]] ids <- names(SummarizedExperiment::rowRanges(panel))[1:25] plain <- .fmRssLd(panel, ids, "susie", FALSE) expect_null(plain$R) @@ -6147,7 +6147,12 @@ test_that("an RSS block reads a genotype reference's factor, not its LD", { expect_equal(both$R, .ldFromRef(panel, ids, label = "t")) expect_identical(both$X, plain$X) } - ldOnly <- .fmRssLd(ldReference(.fmp_withLdMatrix(gss)), ids, "susie", FALSE) + ldOnly <- .fmRssLd( + ldReference(.fmp_withLdMatrix(gss))[[1L]], + ids, + "susie", + FALSE + ) expect_null(ldOnly$X) expect_equal(ldOnly$R, .ldFromRef(panel, ids, label = "t")) }) @@ -6155,7 +6160,7 @@ test_that("an RSS block reads a genotype reference's factor, not its LD", { test_that("fine-mapping runs on a GenotypeMixture reference", { data(gwasSumStatsS4Example) gss <- gwasSumStatsS4Example - panel <- ldReference(gss) + panel <- ldReference(gss)[[1L]] mix <- GenotypeMixture( list(a = panel[, 1:80], b = panel[, 81:165]), mixtureWeights = c(0.5, 0.5) @@ -6168,7 +6173,7 @@ test_that("fine-mapping runs on a GenotypeMixture reference", { qcInfo = qcInfo(gss) ) res <- .fmp_fitSusie(withMix) - expect_s4_class(ldReference(res), "GenotypeMixture") + expect_s4_class(ldReference(res)[[1L]], "GenotypeMixture") expect_true(all(is.finite(unlist(pip(res))))) }) @@ -6191,3 +6196,71 @@ test_that("the rFinite default needs the reference's size", { expect_identical(.fmResolveRFinite(50, TRUE, "none", unknown), 50) expect_null(.fmResolveRFinite(NULL, FALSE, "none", unknown)) }) + +# =========================================================================== +# Per-row LD references +# =========================================================================== + +# Two QtlSumStats rows (contexts c1, c2) carrying the same z over five +# variants, each on the LD reference given for it. +.fmp_twoRefSs <- function(refs) { + gr <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(100L * (1:5), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = sprintf("chr1:%d:A:G", 100L * (1:5)), + A1 = "A", + A2 = "G", + Z = c(6, 5.5, 1, 0.5, 0.2), + N = 1000L + ) + QtlSumStats( + studyName = c("S", "S"), + context = c("c1", "c2"), + trait = c("t1", "t1"), + entry = list(gr, gr), + genome = "hg19", + ldReference = refs, + qcInfo = list(step1 = "ok") + ) +} + +# An LdMatrix over those five variants, with nSamples recorded. +.fmp_ldm <- function(rho) { + ids <- sprintf("chr1:%d:A:G", 100L * (1:5)) + LdMatrix( + `dimnames<-`(rho^abs(outer(1:5, 1:5, "-")), list(ids, ids)), + nSamples = 1000L + ) +} + +test_that("each QtlSumStats row is fine-mapped against its own LD reference", { + weak <- .fmp_ldm(0.1) + strong <- .fmp_ldm(0.95) + res <- suppressMessages(suppressWarnings( + fineMappingPipeline( + .fmp_twoRefSs(list(weak, strong)), + methods = "susie" + ) + )) + c1 <- which(res$context == "c1") + c2 <- which(res$context == "c2") + # The result keeps each row on the reference its fit read. + expect_identical(pecotmr:::.rowLdRef(res, c1), weak) + expect_identical(pecotmr:::.rowLdRef(res, c2), strong) + # Identical z under different LD gives different fits: each row was fit + # against its own reference, not the first one's. + pip <- function(i) { + pecotmr:::.fmrPartsSusieFit(pecotmr:::.fmrRowParts(res, i))$pip + } + expect_false(isTRUE(all.equal(pip(c1), pip(c2)))) +}) + +test_that("mvsusie on QtlSumStats refuses contexts on two LD references", { + ss <- .fmp_twoRefSs(list(.fmp_ldm(0.1), .fmp_ldm(0.95))) + expect_error( + suppressMessages(fineMappingPipeline(ss, methods = "mvsusie")), + "a joint fit uses one LD matrix" + ) +}) diff --git a/tests/testthat/test_fineMappingWrappers.R b/tests/testthat/test_fineMappingWrappers.R index 048dc90b..564fc52f 100644 --- a/tests/testthat/test_fineMappingWrappers.R +++ b/tests/testthat/test_fineMappingWrappers.R @@ -3182,13 +3182,17 @@ test_that("mergeSusieCs: input that is not a fine-mapping result errors", { test_that("computeCsCorrelation (SumStats) matches get_cs_correlation", { data(qtlSumStatsExample) ss <- qtlSumStatsExample - vids <- rownames(ldReference(ss)) + vids <- rownames(ldReference(ss)[[1L]]) set.seed(1) fe <- .ccMakeEntry(vids, list(L1 = c(1L, 2L, 3L), L2 = c(90L, 91L))) cc <- computeCsCorrelation(fe, ss) # Reference: the same LD (from the sketch, aligned to the fit variables) # fed to the same fit. Equality proves the on-demand path + alignment. - xcorr <- pecotmr:::.ldFromRef(ldReference(ss), vids, onMissing = "error") + xcorr <- pecotmr:::.ldFromRef( + ldReference(ss)[[1L]], + vids, + onMissing = "error" + ) ref <- susieR::get_cs_correlation( list(sets = susieFit(fe)$sets, pip = susieFit(fe)$pip), Xcorr = xcorr @@ -3202,7 +3206,7 @@ test_that("computeCsCorrelation reads a panel's factor or an LdMatrix alike", { # same LD gives the same between-CS correlation. data(gwasSumStatsS4Example) gss <- gwasSumStatsS4Example - panel <- ldReference(gss) + panel <- ldReference(gss)[[1L]] withLd <- GwasSumStats( studyName = studyName(gss), entry = list(pecotmr:::.collectionEntry(gss, 1L)), @@ -3255,11 +3259,11 @@ test_that("computeCsCorrelation reads an fSuSiE fit's sets, from LD", { # latter made every fSuSiE fit look set-less, so this came back NULL. data(qtlSumStatsExample) ss <- qtlSumStatsExample - vids <- rownames(ldReference(ss)) + vids <- rownames(ldReference(ss)[[1L]]) cs <- list(c(1L, 2L, 3L), c(90L, 91L)) set.seed(1) cc <- computeCsCorrelation(.ccMakeFsusieEntry(vids, cs), ss) - R <- pecotmr:::.ldFromRef(ldReference(ss), vids, onMissing = "error") + R <- pecotmr:::.ldFromRef(ldReference(ss)[[1L]], vids, onMissing = "error") expect_equal(cc, .ccMaxCorrelation(R, cs)) expect_equal(diag(cc), c(1, 1)) }) @@ -3280,7 +3284,7 @@ test_that("computeCsCorrelation reads an fSuSiE fit's sets, from genotypes", { test_that("computeCsCorrelation is NULL for fewer than two credible sets", { data(qtlSumStatsExample) ss <- qtlSumStatsExample - vids <- rownames(ldReference(ss)) + vids <- rownames(ldReference(ss)[[1L]]) set.seed(1) expect_null(computeCsCorrelation(.ccMakeEntry(vids, list()), ss)) expect_null( @@ -3290,7 +3294,7 @@ test_that("computeCsCorrelation is NULL for fewer than two credible sets", { test_that("computeCsCorrelation requires a QtlDataset / SumStats ldSource", { data(qtlSumStatsExample) - vids <- rownames(ldReference(qtlSumStatsExample)) + vids <- rownames(ldReference(qtlSumStatsExample)[[1L]]) set.seed(1) fe <- .ccMakeEntry(vids, list(L1 = c(1L, 2L, 3L), L2 = c(90L, 91L))) expect_error(computeCsCorrelation(fe, 42), "requires a QtlDataset") @@ -3303,7 +3307,7 @@ test_that("computeCsCorrelation requires a QtlDataset / SumStats ldSource", { test_that("computeCsCorrelation errors when a fit variant is off-panel", { data(qtlSumStatsExample) ss <- qtlSumStatsExample - vids <- rownames(ldReference(ss)) + vids <- rownames(ldReference(ss)[[1L]]) vids[1] <- "chr22:99999999:A:G" set.seed(1) fe <- .ccMakeEntry(vids, list(L1 = c(1L, 2L, 3L), L2 = c(90L, 91L))) @@ -3534,7 +3538,7 @@ test_that("extractCsInfo extracts single CS correctly", { test_that("extractCsInfo builds correlation columns from the ldSource", { data(qtlSumStatsExample) ss <- qtlSumStatsExample - vids <- rownames(ldReference(ss)) + vids <- rownames(ldReference(ss)[[1L]]) set.seed(1) fit <- list( sets = list(cs = list(L_1 = c(1L, 2L, 3L), L_2 = c(90L, 91L))), @@ -5633,3 +5637,32 @@ test_that("a screen whose marginal z cannot be computed falls back", { # colocboost passes FALSE: it drops an outcome it cannot screen. expect_false(.fmSerScreen(X, y, scr, fallback = FALSE)) }) + +test_that("computeCsCorrelation refuses an ldSource on several references", { + # Nothing in the fit says which of the rows' references it was computed + # against, so a source with several is refused rather than guessed at. + data(qtlSumStatsMulticontextExample) + mc <- qtlSumStatsMulticontextExample + panel <- ldReference(mc)[[1L]] + ids <- c("chr1:100:A:G", "chr1:200:C:T") + refs <- rep(list(panel), nrow(mc)) + refs[[2L]] <- LdMatrix(`dimnames<-`(diag(2), list(ids, ids))) + two <- pecotmr:::.withRowLdRefs(mc, refs) + vids <- rownames(panel) + fe <- .ccMakeEntry(vids, list(L1 = c(1L, 2L, 3L), L2 = c(4L, 5L))) + expect_error( + computeCsCorrelation(fe, two), + "rows use 2 different LD references" + ) +}) + +test_that("computeCsCorrelation refuses an LD-free summary-statistics source", { + data(qtlSumStatsMulticontextExample) + mc <- qtlSumStatsMulticontextExample + vids <- rownames(ldReference(mc)[[1L]]) + fe <- .ccMakeEntry(vids, list(L1 = c(1L, 2L, 3L), L2 = c(4L, 5L))) + expect_error( + computeCsCorrelation(fe, pecotmr:::.withRowLdRefs(mc, NULL)), + "carries no LD reference" + ) +}) diff --git a/tests/testthat/test_jointEngine.R b/tests/testthat/test_jointEngine.R index cd1216f7..448f993f 100644 --- a/tests/testthat/test_jointEngine.R +++ b/tests/testthat/test_jointEngine.R @@ -1501,7 +1501,7 @@ test_that(".enumCrossContextSumstats: groups per (study, trait) with >= 2 contex traits = list(S = "t1") ) local_mocked_bindings( - ldReference = function(x) NULL, + .jointRowsLdRef = function(data, rows, label) NULL, .buildJointSumstatZMatrix = .je_mockJointZ, .ldFromRef = .je_mockLd, .package = "pecotmr" @@ -1514,7 +1514,7 @@ test_that(".enumCrossContextSumstats: groups per (study, trait) with >= 2 contex test_that(".enumCrossContextSumstats: < 2 contexts and < 2 tuple rows skip", { local_mocked_bindings( - ldReference = function(x) NULL, + .jointRowsLdRef = function(data, rows, label) NULL, .buildJointSumstatZMatrix = .je_mockJointZ, .ldFromRef = .je_mockLd, .package = "pecotmr" @@ -1604,7 +1604,7 @@ test_that(".enumCrossTraitSumstats: groups per (study, context) with >= 2 traits traits = list(S = c("t1", "t2")) ) local_mocked_bindings( - ldReference = function(x) NULL, + .jointRowsLdRef = function(data, rows, label) NULL, .buildJointSumstatZMatrix = .je_mockJointZ, .ldFromRef = .je_mockLd, .package = "pecotmr" @@ -1625,7 +1625,7 @@ test_that(".enumCrossStudySumstats: group per (context, trait) in >= 2 studies", traits = list(S1 = "t1", S2 = "t1") ) local_mocked_bindings( - ldReference = function(x) NULL, + .jointRowsLdRef = function(data, rows, label) NULL, .buildJointSumstatZMatrix = .je_mockJointZ, .ldFromRef = .je_mockLd, .package = "pecotmr" @@ -1817,7 +1817,7 @@ test_that(".enumComposedSumstats: one group per fixed-axis row block", { traits = list(S = "t1") ) local_mocked_bindings( - ldReference = function(x) NULL, + .jointRowsLdRef = function(data, rows, label) NULL, .enumerateComposedSumstatGroups = function(spec, data, scope) { list( groups = list(c(1L, 2L)), @@ -1841,7 +1841,7 @@ test_that(".enumComposedSumstats: one group per fixed-axis row block", { test_that(".enumComposedSumstats: NULL group index and singleton blocks skip", { local_mocked_bindings( - ldReference = function(x) NULL, + .jointRowsLdRef = function(data, rows, label) NULL, .enumerateComposedSumstatGroups = function(spec, data, scope) NULL, .package = "pecotmr" ) @@ -1853,7 +1853,7 @@ test_that(".enumComposedSumstats: NULL group index and singleton blocks skip", { 0L ) # gi NULL (646) local_mocked_bindings( - ldReference = function(x) NULL, + .jointRowsLdRef = function(data, rows, label) NULL, .enumerateComposedSumstatGroups = function(spec, data, scope) { list( groups = list(1L), @@ -3363,3 +3363,73 @@ test_that(".jointGroupSelect drops pairs a per-context traitId leaves out", { list(A = list(brain = "g2", liver = "g2")) )) }) + +# =========================================================================== +# A summary-statistics joint group reads one LD matrix +# =========================================================================== + +# Two QtlSumStats rows (contexts c1, c2 of one study and trait) over the same +# five variants, each on the LD reference given for it. +.je_twoRowSs <- function(refs) { + gr <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(100L * (1:5), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = sprintf("chr1:%d:A:G", 100L * (1:5)), + A1 = "A", + A2 = "G", + Z = seq_len(5) / 10, + N = 100L + ) + QtlSumStats( + studyName = c("S", "S"), + context = c("c1", "c2"), + trait = c("t1", "t1"), + entry = list(gr, gr), + genome = "hg19", + ldReference = refs, + qcInfo = list(step1 = "ok") + ) +} + +# An LdMatrix over those five variants. +.je_ldm <- function(rho) { + ids <- sprintf("chr1:%d:A:G", 100L * (1:5)) + LdMatrix(`dimnames<-`(rho^abs(outer(1:5, 1:5, "-")), list(ids, ids))) +} + +test_that(".jointRowsLdRef returns the reference a group's rows share", { + ldm <- .je_ldm(0.2) + expect_identical( + pecotmr:::.jointRowsLdRef(.je_twoRowSs(ldm), 1:2, "probe"), + ldm + ) +}) + +test_that(".jointRowsLdRef refuses rows on different references", { + # A joint fit reads one LD matrix for every condition, so fitting these + # together would put one row against LD it was never harmonized to. + ss <- .je_twoRowSs(list(.je_ldm(0.2), .je_ldm(0.6))) + expect_error( + pecotmr:::.jointRowsLdRef(ss, 1:2, "probe"), + "probe: a joint fit uses one LD matrix" + ) + expect_error( + pecotmr:::.jointRowsLdRef(ss, 1:2, "probe"), + "S:c1:t1 -> ld1; S:c2:t1 -> ld2" + ) +}) + +test_that("a cross-context sumstats group refuses rows on two references", { + ss <- .je_twoRowSs(list(.je_ldm(0.2), .je_ldm(0.6))) + scope <- list( + studies = "S", + contexts = list(S = c("c1", "c2")), + traits = list(S = "t1") + ) + expect_error( + pecotmr:::.enumCrossContextSumstats(ss, scope), + "jointCrossContext \\(QtlSumStats\\): a joint fit uses one LD" + ) +}) diff --git a/tests/testthat/test_jointSpecification.R b/tests/testthat/test_jointSpecification.R index e8886dd2..d4292aa9 100644 --- a/tests/testthat/test_jointSpecification.R +++ b/tests/testthat/test_jointSpecification.R @@ -2371,7 +2371,7 @@ test_that(".mergeEntryForKey gives NULL for a region lacking the tuple", { seq_len(nrow(ss)), as.character(ss$context), "probe", - ldReference = ldReference(ss), + ldReference = ldReference(ss)[[1L]], cutoffs = .panelCutoffs(PanelFilterParam(...)) )) } @@ -2401,7 +2401,7 @@ test_that(".buildJointSumstatZMatrix agrees with .panelVariantFilter", { expect_equal( length(.bjz_build(ss, mafCutoff = cut)$variantIds), length(.panelVariantFilter( - ldReference(ss), + ldReference(ss)[[1L]], ids, PanelFilterParam(mafCutoff = cut) )), diff --git a/tests/testthat/test_ld.R b/tests/testthat/test_ld.R index 1ab2469e..4712ff93 100644 --- a/tests/testthat/test_ld.R +++ b/tests/testthat/test_ld.R @@ -3555,3 +3555,148 @@ test_that("a panel held in memory serves as an LD reference", { expect_equal(dim(pecotmr:::.ldRefSubset(mem, 3:7)), c(5L, ncol(mem))) expect_equal(dim(pecotmr:::.emptyLdRef(mem)), c(0L, 0L)) }) + +# =========================================================================== +# Per-row LD references +# =========================================================================== + +# An LdMatrix over five chr1 variants at 100 bp spacing. +.ldr_ldm <- function(rho = 0.2, chrom = "chr1") { + ids <- sprintf("%s:%d:A:G", chrom, 100L * (1:5)) + r <- rho^abs(outer(1:5, 1:5, "-")) + LdMatrix(`dimnames<-`(r, list(ids, ids))) +} + +# A QtlSumStats of one tuple per reference in `refs`, every tuple over the same +# five variants on `chrom`. +.ldr_qss <- function(refs, chrom = "chr1") { + n <- length(refs) + gr <- GenomicRanges::GRanges( + chrom, + IRanges::IRanges(100L * (1:5), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = sprintf("%s:%d:A:G", chrom, 100L * (1:5)), + A1 = "A", + A2 = "G", + Z = seq_len(5) / 10, + N = 100L + ) + QtlSumStats( + studyName = rep("s1", n), + context = str_c("c", seq_len(n)), + trait = rep("t1", n), + entry = rep(list(gr), n), + genome = "hg19", + ldReference = refs + ) +} + +test_that(".ldRefPerTuple reads one reference or one per tuple", { + a <- .ldr_ldm() + b <- .ldr_ldm(rho = 0.5) + expect_identical(pecotmr:::.ldRefPerTuple(a, 3L), list(a, a, a)) + # What ldReference() returns reads the same way: a one-entry list is that + # reference for every tuple, an empty one is LD-free. + expect_identical(pecotmr:::.ldRefPerTuple(list(ld1 = a), 2L), list(a, a)) + expect_identical(pecotmr:::.ldRefPerTuple(list(), 2L), list(NULL, NULL)) + expect_identical(pecotmr:::.ldRefPerTuple(NULL, 2L), list(NULL, NULL)) + expect_identical(pecotmr:::.ldRefPerTuple(list(a, b), 2L), list(a, b)) + expect_error(pecotmr:::.ldRefPerTuple(list(a, b), 3L), "one per tuple") +}) + +test_that(".ldRefDict stores each distinct reference once and keys every row", { + a <- .ldr_ldm() + b <- .ldr_ldm(rho = 0.5) + # An equal copy built separately is the same reference, not a second one. + dict <- pecotmr:::.ldRefDict(list(a, NULL, b, a, .ldr_ldm())) + expect_identical(dict$refs, list(ld1 = a, ld2 = b)) + expect_identical(dict$keys, c("ld1", NA, "ld2", "ld1", "ld1")) + expect_identical(pecotmr:::.ldRefDict(list(NULL))$refs, list()) +}) + +test_that("a collection keeps each row on its own reference, stored once", { + a <- .ldr_ldm() + b <- .ldr_ldm(rho = 0.5) + qss <- .ldr_qss(list(a, b, a)) + expect_identical(ldReference(qss), list(ld1 = a, ld2 = b)) + expect_identical(qss$ldReference, c("ld1", "ld2", "ld1")) + expect_identical(pecotmr:::.rowLdRefs(qss), list(a, b, a)) + # A subset reports only the references its rows still use. + expect_identical(ldReference(qss[c(1L, 3L)]), list(ld1 = a)) + expect_output(show(qss), "2 references") +}) + +test_that("validity refuses a row keyed to a reference the slot lacks", { + qss <- .ldr_qss(list(.ldr_ldm())) + expect_error( + { + qss$ldReference <- "ld9" + methods::validObject(qss) + }, + "not in ldReference: ld9" + ) +}) + +test_that("an object saved before per-row references is refused", { + # Read as a list, its single reference would pass for LD-free. + old <- .ldr_qss(list(.ldr_ldm())) + attr(old, "ldReference") <- .ldr_ldm() + md <- attr(old, "elementMetadata") + md[["ldReference"]] <- NULL + attr(old, "elementMetadata") <- md + expect_error(ldReference(old), "saved before LD references became") +}) + +test_that(".withRowLdRefs puts every row on one reference", { + a <- .ldr_ldm() + b <- .ldr_ldm(rho = 0.5) + moved <- pecotmr:::.withRowLdRefs(.ldr_qss(list(a, b)), b) + expect_identical(ldReference(moved), list(ld1 = b)) + expect_identical(moved$ldReference, c("ld1", "ld1")) + expect_true(methods::validObject(moved)) +}) + +test_that(".requireMatchingRowLdRefs checks only the pairs it is given", { + a <- .ldr_ldm() + qtl <- .ldr_qss(list(a, .ldr_ldm(rho = 0.5))) + gwas <- .ldr_qss(list(a)) + # QTL row 1 shares the GWAS row's reference; row 2 does not, but is only + # refused when it is paired with it. + expect_null(pecotmr:::.requireMatchingRowLdRefs(qtl, gwas, 1L, 1L, "p")) + expect_error( + pecotmr:::.requireMatchingRowLdRefs(qtl, gwas, 2L, 1L, "p"), + "disagree on the LD" + ) +}) + +test_that(".overlappingRowPairs pairs rows whose regions overlap", { + a <- .ldr_ldm() + qtl <- combineQtlSumStats( + .ldr_qss(list(a)), + .ldr_qss(list(.ldr_ldm(chrom = "chr2")), chrom = "chr2") + ) + pairs <- pecotmr:::.overlappingRowPairs(qtl, .ldr_qss(list(a))) + expect_identical(pairs, list(qtlRows = 1L, gwasRows = 1L)) + # Collections on no common chromosome have no pairs, and say nothing. + expect_silent( + none <- pecotmr:::.overlappingRowPairs( + qtl, + .ldr_qss(list(.ldr_ldm(chrom = "chr3")), chrom = "chr3") + ) + ) + expect_identical(none, list(qtlRows = integer(0), gwasRows = integer(0))) +}) + +test_that(".overlapsOnShared compares ranges on the chromosomes both have", { + q <- GenomicRanges::GRanges( + c("chr1", "chr2"), + IRanges::IRanges(c(100L, 100L), width = 10L) + ) + s <- GenomicRanges::GRanges("chr2", IRanges::IRanges(105L, width = 1L)) + expect_identical(pecotmr:::.overlapsOnShared(q, s), c(FALSE, TRUE)) + # With no chromosome in common nothing overlaps, and nothing is said. + far <- GenomicRanges::GRanges("chr3", IRanges::IRanges(100L, width = 1L)) + expect_silent(none <- pecotmr:::.overlapsOnShared(q, far)) + expect_identical(none, c(FALSE, FALSE)) +}) diff --git a/tests/testthat/test_manifestLoaders.R b/tests/testthat/test_manifestLoaders.R index a34b44f8..55531c74 100644 --- a/tests/testthat/test_manifestLoaders.R +++ b/tests/testthat/test_manifestLoaders.R @@ -1502,19 +1502,61 @@ test_that(".resolveLdRef passes through NULL and a handle", { expect_identical(pecotmr:::.resolveLdRef(h), h) }) -test_that("non-constant ldReferencePath column errors", { +# The toy panel's 200-variant copy keyed by canonical ids: the same samples +# and the toy GWAS variants, read from different files. +.toyCanonicalPrefix <- function() { + sub( + "\\.bed$", + "", + system.file("extdata", "toy_canonical.bed", package = "pecotmr") + ) +} + +test_that("each study's ldReferencePath gives it its own LD reference", { + skip_if_not_installed("PlinkMatrix") + tmp <- withr::local_tempdir() + ss1 <- .writeSumstatsTsv(.toyGwasDf(3), file.path(tmp, "a.tsv")) + ss2 <- .writeSumstatsTsv(.toyGwasDf(3), file.path(tmp, "b.tsv")) + ss3 <- .writeSumstatsTsv(.toyGwasDf(3), file.path(tmp, "c.tsv")) + manifest <- data.frame( + study = c("a", "b", "c"), + sumStatsPath = c(ss1, ss2, ss3), + ldReferencePath = c( + .toyRefPrefix(), + .toyCanonicalPrefix(), + .toyRefPrefix() + ), + stringsAsFactors = FALSE + ) + obj <- suppressWarnings( + loadGwasSumStatsFromManifest(manifest, genome = "hg38") + ) + # Two distinct panels, each read once and stored once; studies a and c + # share the first. + refs <- ldReference(obj) + expect_length(refs, 2L) + keys <- obj$ldReference[match(c("a", "b", "c"), obj$study)] + expect_identical(keys[[1L]], keys[[3L]]) + expect_false(identical(keys[[1L]], keys[[2L]])) + expect_match( + pecotmr:::.ldRefSource(refs[[keys[[2L]]]])$path, + "toy_canonical" + ) +}) + +test_that("a manifest row with no LD reference errors", { tmp <- withr::local_tempdir() ss1 <- .writeSumstatsTsv(.toyGwasDf(3), file.path(tmp, "a.tsv")) ss2 <- .writeSumstatsTsv(.toyGwasDf(3), file.path(tmp, "b.tsv")) manifest <- data.frame( study = c("a", "b"), sumStatsPath = c(ss1, ss2), - ldReferencePath = c(.toyRefPrefix(), "other"), + ldReferencePath = c(.toyRefPrefix(), ""), stringsAsFactors = FALSE ) expect_error( loadGwasSumStatsFromManifest(manifest, genome = "hg38"), - "must be constant" + "row\\(s\\) 2 have no `ldReferencePath`" ) }) diff --git a/tests/testthat/test_qtlEnrichmentPipeline.R b/tests/testthat/test_qtlEnrichmentPipeline.R index 9c3b251e..35202b32 100644 --- a/tests/testthat/test_qtlEnrichmentPipeline.R +++ b/tests/testthat/test_qtlEnrichmentPipeline.R @@ -305,7 +305,7 @@ test_that("qtlEnrichmentPipeline: NULL ldReference on the GWAS side errors", { gwasFineMappingResult = gfmr, qtlFineMappingResult = qfmr ), - "must have a non-NULL ldReference" + "row must have an ldReference" ) }) @@ -1159,3 +1159,16 @@ test_that("qtlEnrichmentPipeline refuses a bare list for qtlEnrichmentParam", { "must be built with QtlEnrichmentParam" ) }) + +test_that("qtlEnrichmentPipeline refuses overlapping rows on two references", { + ids <- sprintf("chr1:%d:A:G", 100L * (1:9)) + ldm <- function(rho) { + LdMatrix(`dimnames<-`(rho^abs(outer(1:9, 1:9, "-")), list(ids, ids))) + } + gfmr <- pecotmr:::.withRowLdRefs(.qep_makeGwasFmr(), ldm(0.2)) + qfmr <- pecotmr:::.withRowLdRefs(.qep_makeQtlFmr(), ldm(0.8)) + expect_error( + pecotmr:::.enrValidateInputs(gfmr, qfmr), + "disagree on the LD" + ) +}) diff --git a/tests/testthat/test_qtlSumStats.R b/tests/testthat/test_qtlSumStats.R index 5b214853..e1e99396 100644 --- a/tests/testthat/test_qtlSumStats.R +++ b/tests/testthat/test_qtlSumStats.R @@ -430,12 +430,14 @@ test_that("subsetChr drops the element when no variants on that chromosome", { empty <- subsetChr(obj, "22") expect_equal(nrow(empty), 0L) expect_equal(length(empty), 0L) - # The collection-level state survives even when nothing is left. + # The collection-level state survives even when nothing is left; no row + # is left to use the reference, so none is reported. expect_equal( unname(GenomeInfoDb::genome(empty)), unname(GenomeInfoDb::genome(obj)) ) - expect_identical(ldReference(empty), ldReference(obj)) + expect_identical(empty@ldReference, obj@ldReference) + expect_identical(ldReference(empty), list()) }) test_that("subsetChr keeps class-level slots (genome, ldReference, qcInfo)", { @@ -484,7 +486,8 @@ test_that("QtlSumStats: ldReference is optional (NULL for LD-free workflows)", { entry = list(.qtlMakeEntryGr(1)), genome = "hg19" ) # ldReference omitted - expect_null(ldReference(obj)) + expect_identical(ldReference(obj), list()) + expect_true(is.na(obj$ldReference)) expect_output(show(obj), "none \\(LD-free\\)") }) @@ -593,7 +596,7 @@ test_that("no traitPos -> no distance columns; existing distance is preserved", # === combineQtlSumStats() === -test_that("combineQtlSumStats() row-binds collections and keeps NULL sketches", { +test_that("combineQtlSumStats() row-binds collections and LD-free rows", { data(qtlSumStatsExample) a <- qtlSumStatsExample b <- a @@ -608,11 +611,23 @@ test_that("combineQtlSumStats() row-binds collections and keeps NULL sketches", unname(GenomeInfoDb::genome(a)) ) - a2 <- a - a2@ldReference <- NULL - b2 <- b - b2@ldReference <- NULL - expect_null(ldReference(combineQtlSumStats(a2, b2))) + # Both parts read the one panel, so it is stored once for every row. + expect_identical(ldReference(out), ldReference(a)) + expect_equal(unique(out$ldReference), names(ldReference(out))) + + ldFree <- function(x) { + QtlSumStats( + studyName = x$study, + context = x$context, + trait = x$trait, + entry = as.list(x), + genome = unname(GenomeInfoDb::genome(x))[[1L]] + ) + } + expect_identical( + ldReference(combineQtlSumStats(ldFree(a), ldFree(b))), + list() + ) }) diff --git a/tests/testthat/test_resultWriters.R b/tests/testthat/test_resultWriters.R index ed18d2da..8dde69f0 100644 --- a/tests/testthat/test_resultWriters.R +++ b/tests/testthat/test_resultWriters.R @@ -1834,7 +1834,7 @@ test_that("a weights export takes AF from the collection's LD panel", { # standardized-to-raw conversion would need, so its absence is worth # seeing rather than faking. data(twasWeightsExample, envir = environment()) - expect_null(ldReference(twasWeightsExample)) + expect_identical(ldReference(twasWeightsExample), list()) out <- withr::local_tempfile(fileext = ".bed") suppressMessages(exportToBed(twasWeightsExample, out)) expect_false(is_in("AF", names(read.delim(out, check.names = FALSE)))) @@ -1930,7 +1930,7 @@ test_that("a weights export reads AF off the collection's LD panel", { # is published; a panel recording none leaves the column absent rather # than faked. data(ctwasWeightsExample, twasWeightsExample, envir = environment()) - panel <- ldReference(ctwasWeightsExample) + panel <- ldReference(ctwasWeightsExample)[[1L]] expect_false(is.null(panel)) lasso <- twasWeightsExample[ as.character(twasWeightsExample$method) == "lasso" @@ -2000,7 +2000,7 @@ test_that("a sumstats collection with no Z publishes no EZ", { # @noRd .pbw_jointWeights <- function(nVariant = 6L) { data(ctwasWeightsExample, envir = environment()) - panel <- ldReference(ctwasWeightsExample) + panel <- ldReference(ctwasWeightsExample)[[1L]] vids <- .grVariantIds(SummarizedExperiment::rowRanges(panel)) SummarizedExperiment::rowRanges(panel)$AF <- seq( 0.05, @@ -2042,7 +2042,7 @@ test_that("AF is published from the LD panel when it records one", { out <- withr::local_tempfile(fileext = ".bed") exportToBed(tw, out) bed <- read.delim(out, check.names = FALSE) - panel <- ldReference(tw) + panel <- ldReference(tw)[[1L]] rr <- SummarizedExperiment::rowRanges(panel) expected <- mcols(rr)$AF[match(bed$ID, .grVariantIds(rr))] expect_equal(bed$AF, expected) @@ -2292,3 +2292,28 @@ test_that("THETA is omitted for collections that never recorded one", { exportToBed(old[1], bed) expect_false(is_in("THETA", strsplit(readLines(bed, n = 1), "\t")[[1]])) }) + +test_that("data_source falls back per row, and to NA for a mixed collection", { + rows <- map(1:2, function(i) { + twasWeightsRow( + variantIds = sprintf("chr1:%d:A:G", 100L * (1:3) + i), + weights = c(0.1, 0.2, 0.3) + ) + }) + ids <- sprintf("chr1:%d:A:G", 100L * (1:3) + 1L) + ldm <- LdMatrix(`dimnames<-`(diag(3), list(ids, ids))) + tw <- TwasWeights( + studyName = c("s1", "s1"), + context = c("c1", "c2"), + trait = c("t1", "t1"), + method = c("lasso", "lasso"), + entry = rows, + ldReference = list(ldm, NULL) + ) + expect_identical( + pecotmr:::.pubDataSourceOf(tw), + c("sumstat", "individual") + ) + expect_identical(pecotmr:::.pubDataSource(tw), NA_character_) + expect_identical(pecotmr:::.pubDataSource(tw[1L]), "sumstat") +}) diff --git a/tests/testthat/test_sumstatsQc.R b/tests/testthat/test_sumstatsQc.R index 58aabf6f..93a87f00 100644 --- a/tests/testthat/test_sumstatsQc.R +++ b/tests/testthat/test_sumstatsQc.R @@ -2761,7 +2761,7 @@ test_that("a tag-named panel entry survives the end-to-end sketch subset", { expect_true("chr1:200:G:A" %in% snp) # the retained sketch keeps the panel row the QC'd entry still refers to expect_true( - "chr1:200:G:A" %in% pecotmr:::.ldRefMatchIds(ldReference(out)) + "chr1:200:G:A" %in% pecotmr:::.ldRefMatchIds(ldReference(out)[[1L]]) ) }) @@ -2789,7 +2789,7 @@ test_that("the sketch survives a chr:pos:A1:A2 panel (PLINK .bim order)", { signalScreenParam = SignalScreenParam(pip = 0), sumstatsFilterParam = SumstatsFilterParam(nCutoff = 0) ) - kept <- pecotmr:::.ldRefMatchIds(ldReference(out)) + kept <- pecotmr:::.ldRefMatchIds(ldReference(out)[[1L]]) expect_length(kept, 4L) expect_setequal( pecotmr:::parseVariantId(kept)$pos, @@ -6957,7 +6957,7 @@ test_that("summaryStatsQc: mafCutoff drops panel-rare observed variants", { expect_equal(length(entry), sum(!is.na(maf) & maf >= cutoff)) # ... and the panel carried on the result -- the seed handle every LD # read keys off, not just the row view -- holds no sub-cutoff variant. - seed <- pecotmr:::.ldRefHandle(ldReference(out)) + seed <- pecotmr:::.ldRefHandle(ldReference(out)[[1L]]) keptMaf <- maf[match( as.character(snpInfo(seed)$SNP), as.character(snpInfo(h)$SNP) @@ -7851,7 +7851,7 @@ test_that(".sumstatsCleaningResolve fills defaults an empty bundle omits", { test_that("summaryStatsQc gives one result from an LdMatrix and its panel", { data(gwasSumStatsS4Example) gss <- gwasSumStatsS4Example - panel <- ldReference(gss) + panel <- ldReference(gss)[[1L]] ld <- LdMatrix( unname(computeLd(panel)), variants = SummarizedExperiment::rowRanges(panel), @@ -7875,8 +7875,11 @@ test_that("summaryStatsQc gives one result from an LdMatrix and its panel", { as.data.frame(unlist(viaPanel)) ) # The reference is trimmed to the surviving variants, still a matrix. - expect_s4_class(ldReference(viaMatrix), "LdMatrix") - expect_equal(length(ldReference(viaMatrix)), length(unlist(viaMatrix))) + expect_s4_class(ldReference(viaMatrix)[[1L]], "LdMatrix") + expect_equal( + length(ldReference(viaMatrix)[[1L]]), + length(unlist(viaMatrix)) + ) }) test_that("DENTIST needs an LdMatrix's size; SLALOM does not", { @@ -7894,7 +7897,7 @@ test_that("DENTIST needs an LdMatrix's size; SLALOM does not", { test_that("RAISS imputation in QC runs on an LdMatrix reference", { data(gwasSumStatsS4Example) gss <- gwasSumStatsS4Example - panel <- ldReference(gss) + panel <- ldReference(gss)[[1L]] ld <- LdMatrix( unname(computeLd(panel)), variants = SummarizedExperiment::rowRanges(panel), @@ -7920,3 +7923,25 @@ test_that("RAISS imputation in QC runs on an LdMatrix reference", { "needs allele frequencies" ) }) + +test_that("summaryStatsQc QCs each row against its own LD reference", { + # One row on the panel, another on the same LD as a matrix: each is + # harmonized against its own and keeps it, cut to its own variants. + data(qtlSumStatsMulticontextExample) + mc <- qtlSumStatsMulticontextExample + panel <- ldReference(mc)[[1L]] + ldm <- LdMatrix( + unname(computeLd(panel)), + variants = SummarizedExperiment::rowRanges(panel) + ) + refs <- rep(list(panel), nrow(mc)) + refs[[2L]] <- ldm + out <- suppressMessages(summaryStatsQc(pecotmr:::.withRowLdRefs(mc, refs))) + expect_length(ldReference(out), 2L) + expect_s4_class( + pecotmr:::.rowLdRef(out, 1L), + "RangedSummarizedExperiment" + ) + expect_s4_class(pecotmr:::.rowLdRef(out, 2L), "LdMatrix") + expect_equal(length(pecotmr:::.rowLdRef(out, 2L)), length(out[[2L]])) +}) diff --git a/tests/testthat/test_tupleSelectors.R b/tests/testthat/test_tupleSelectors.R index 203590bb..076ae464 100644 --- a/tests/testthat/test_tupleSelectors.R +++ b/tests/testthat/test_tupleSelectors.R @@ -579,15 +579,19 @@ test_that("chromosome paths union when they agree and abort when they clash", { test_that("panels read through no handle union their rows", { # A PLINK1, VCF or GDS panel has no handle whose snpInfo could be # widened, so the parts' assays are bound: each variant once, in genomic - # order. A panel from another file is refused, not bound. + # order. A panel from another file is another source, and kept apart. skip_if_not_installed("PlinkMatrix") skip_if_not_installed("pgenlibr") stem <- test_path("test_data", "test_variants") panel <- readGenotypes(plink1Prefix = stem) a <- pecotmr:::.panelSubsetRows(panel, 4:8) b <- pecotmr:::.panelSubsetRows(panel, 1:5) - pecotmr:::.ssCheckSameSource(list(a, b), "combineX") - out <- pecotmr:::.ssUnionPanels(list(a, b), character(0)) + merged <- pecotmr:::.ldRefMergeViews( + pecotmr:::.ldRefDict(list(a, b)), + "combineX" + ) + expect_identical(merged$keys, c("ld1", "ld1")) + out <- merged$refs$ld1 expect_identical(rownames(out), rownames(panel)[1:8]) expect_equal( as.matrix(SummarizedExperiment::assay(out, "dosage")), @@ -599,13 +603,11 @@ test_that("panels read through no handle union their rows", { ) # The same panel twice is that panel. expect_identical(pecotmr:::.ssUnionPanels(list(a, a), character(0)), a) - expect_error( - pecotmr:::.ssCheckSameSource( - list(a, readGenotypes(plink2Prefix = stem)), - "combineX" - ), - "reference different genotype panels" + apart <- pecotmr:::.ldRefMergeViews( + pecotmr:::.ldRefDict(list(a, readGenotypes(plink2Prefix = stem))), + "combineX" ) + expect_length(apart$refs, 2L) }) @@ -785,7 +787,7 @@ test_that(".asAnalysisWindow normalizes strings, GRanges and multi-range input", }) -test_that("collections sharing one LdMatrix combine; differing ones need it", { +test_that("LdMatrix views are stored as the one covering them, in any order", { ids <- c("chr22:100:A:G", "chr22:200:C:T", "chr22:300:G:A") vars <- data.frame( chrom = "chr22", @@ -796,14 +798,75 @@ test_that("collections sharing one LdMatrix combine; differing ones need it", { ) R <- matrix(c(1, 0.5, 0.2, 0.5, 1, 0.3, 0.2, 0.3, 1), 3L, 3L) ld <- LdMatrix(R, variants = vars, nSamples = 100) - # The widest reference covering the others is the combined one. - expect_identical( - pecotmr:::.combineLdMatrixRefs(list(ld, ld[1:2]), "combine"), - ld - ) - # Two subsets neither of which covers the other cannot be unioned. - expect_error( - pecotmr:::.combineLdMatrixRefs(list(ld[1:2], ld[2:3]), "combine"), - "cover different variants" - ) + # Two views neither of which covers the other are both kept: the LD + # between their variants is held by neither. + apart <- pecotmr:::.ldRefMergeViews( + pecotmr:::.ldRefDict(list(ld[1:2], ld[2:3])), + "combine" + ) + expect_length(apart$refs, 2L) + # With the matrix covering both among them, both are stored as it, + # wherever it comes. + orders <- list( + list(ld[1:2], ld, ld[2:3]), + list(ld[1:2], ld[2:3], ld), + list(ld, ld[1:2], ld[2:3]) + ) + for (parts in orders) { + merged <- pecotmr:::.ldRefMergeViews( + pecotmr:::.ldRefDict(parts), + "combine" + ) + expect_identical(merged$refs, list(ld1 = ld)) + expect_identical(merged$keys, rep("ld1", 3L)) + } +}) + +test_that("binding stores an LdMatrix another part's covers as that one", { + ids <- sprintf("chr1:%d:A:G", 100L * (1:6)) + r <- 0.3^abs(outer(1:6, 1:6, "-")) + wide <- LdMatrix(`dimnames<-`(r, list(ids, ids))) + narrow <- LdMatrix(`dimnames<-`(r[4:6, 4:6], list(ids[4:6], ids[4:6]))) + merged <- pecotmr:::.ldRefMergeViews( + pecotmr:::.ldRefDict(list(wide, narrow, wide)), + "probe" + ) + expect_identical(merged$refs, list(ld1 = wide)) + expect_identical(merged$keys, c("ld1", "ld1", "ld1")) + # Matrices that do not nest are different references, and stay apart. + other <- LdMatrix( + `dimnames<-`(0.9^abs(outer(1:6, 1:6, "-")), list(ids, ids)) + ) + apart <- pecotmr:::.ldRefMergeViews( + pecotmr:::.ldRefDict(list(wide, other)), + "probe" + ) + expect_length(apart$refs, 2L) + # A panel and a matrix are never views of one source. + panel <- readGenotypes(test_path("test_data", "test_variants.bed")) + kinds <- pecotmr:::.ldRefMergeViews( + pecotmr:::.ldRefDict(list(wide, panel)), + "probe" + ) + expect_length(kinds$refs, 2L) +}) + +test_that("binding stores a mixture another part's covers as that one", { + panel <- readGenotypes(test_path("test_data", "test_variants.bed")) + halves <- list(a = panel[, 1:40], b = panel[, 41:100]) + mix <- GenotypeMixture(halves, mixtureWeights = c(0.5, 0.5)) + # Two views that overlap only in part are both held by the whole mixture. + merged <- pecotmr:::.ldRefMergeViews( + pecotmr:::.ldRefDict(list(mix[1:200], mix, mix[100:349])), + "probe" + ) + expect_identical(merged$refs, list(ld1 = mix)) + expect_identical(merged$keys, c("ld1", "ld1", "ld1")) + # The same panels weighted differently are another mixture. + reweighted <- GenotypeMixture(halves, mixtureWeights = c(0.4, 0.6)) + apart <- pecotmr:::.ldRefMergeViews( + pecotmr:::.ldRefDict(list(mix, reweighted[1:200])), + "probe" + ) + expect_length(apart$refs, 2L) }) diff --git a/tests/testthat/test_twasWeights.R b/tests/testthat/test_twasWeights.R index dc0ef350..3a5fcb0d 100644 --- a/tests/testthat/test_twasWeights.R +++ b/tests/testthat/test_twasWeights.R @@ -1375,7 +1375,8 @@ test_that("TwasWeights: per-tuple weights/cvResult/methodFits/ldReference", { )$tag, "fitA" ) - expect_s4_class(ldReference(tw), "RangedSummarizedExperiment") + expect_length(ldReference(tw), 1L) + expect_s4_class(ldReference(tw)[[1L]], "RangedSummarizedExperiment") }) # =========================================================================== diff --git a/tests/testthat/test_twasWeightsPipeline.R b/tests/testthat/test_twasWeightsPipeline.R index 87955b57..25139967 100644 --- a/tests/testthat/test_twasWeightsPipeline.R +++ b/tests/testthat/test_twasWeightsPipeline.R @@ -3994,7 +3994,7 @@ test_that("twasWeightsPipeline RSS cutoffs match .panelVariantFilter", { expect_equal( .twrssf_n(ss, mafCutoff = cut), length(.panelVariantFilter( - ldReference(ss), + ldReference(ss)[[1L]], ids, PanelFilterParam(mafCutoff = cut) )), @@ -4005,7 +4005,7 @@ test_that("twasWeightsPipeline RSS cutoffs match .panelVariantFilter", { test_that("twasWeightsPipeline RSS treats MAC as a MAF equivalent", { ss <- .twrssf_qcd() - nSamp <- ncol(ldReference(ss)) + nSamp <- ncol(ldReference(ss)[[1L]]) expect_equal( .twrssf_n(ss, macCutoff = 0.1 * 2 * nSamp), .twrssf_n(ss, mafCutoff = 0.1) @@ -4020,7 +4020,7 @@ test_that("twasWeightsPipeline RSS honours a missingness cutoff", { test_that(".twasQssUnivariateFitCtx keeps z, ids and LD reference aligned", { ss <- .twrssf_qcd() - sketch <- ldReference(ss) + sketch <- ldReference(ss)[[1L]] args <- list(ss, ss$study[[1L]], ss$context[[1L]], ss$trait[[1L]], sketch) plain <- exec(pecotmr:::.twasQssUnivariateFitCtx, !!!args) cut <- suppressMessages(exec( @@ -4222,7 +4222,7 @@ test_that(".twasQssMultivariateFitOne promotes vector weights to a matrix", { test_that(".twasQssAssemble passes the joint result through alone", { jr <- "SENTINEL_JOINT" expect_identical( - pecotmr:::.twasQssAssemble(list(), jr, ldReference = NULL), + pecotmr:::.twasQssAssemble(list(), jr), jr ) }) @@ -4957,3 +4957,40 @@ test_that("refuses full-data weights from a CV-only fineMappingResult", { fitFullData = FALSE )) }) + +# =========================================================================== +# Per-row LD references +# =========================================================================== + +test_that("a multivariate TWAS group refuses contexts on two LD references", { + # mr.mash fits a (study, trait)'s contexts together against one LD + # matrix, so rows on different references cannot share the fit. + gr <- GenomicRanges::GRanges( + "chr1", + IRanges::IRanges(100L * (1:5), width = 1L) + ) + S4Vectors::mcols(gr) <- S4Vectors::DataFrame( + SNP = sprintf("chr1:%d:A:G", 100L * (1:5)), + A1 = "A", + A2 = "G", + Z = c(6, 5.5, 1, 0.5, 0.2), + N = 1000L + ) + ids <- sprintf("chr1:%d:A:G", 100L * (1:5)) + ldm <- function(rho) { + LdMatrix(`dimnames<-`(rho^abs(outer(1:5, 1:5, "-")), list(ids, ids))) + } + ss <- QtlSumStats( + studyName = c("S", "S"), + context = c("c1", "c2"), + trait = c("t1", "t1"), + entry = list(gr, gr), + genome = "hg19", + ldReference = list(ldm(0.1), ldm(0.95)), + qcInfo = list(step1 = "ok") + ) + expect_error( + suppressMessages(twasWeightsPipeline(ss, methods = "mrmash")), + "a joint fit uses one LD matrix" + ) +}) diff --git a/vignettes/coloc-pipeline.Rmd b/vignettes/coloc-pipeline.Rmd index 62f99d92..116bd9ef 100644 --- a/vignettes/coloc-pipeline.Rmd +++ b/vignettes/coloc-pipeline.Rmd @@ -87,9 +87,10 @@ res2 <- colocPipeline( attr(res2, "gwasFineMapping") ``` -If the `QtlFineMappingResult` has an LD reference because it was run on -summary statistics, it must be the same LD reference as the `GwasSumStats` -carries. +If the `QtlFineMappingResult` has LD references because it was run on +summary statistics, each of its rows must use the same LD reference as the +GWAS rows it overlaps. A QTL row with no LD reference, such as a fit to +individual-level data, is not checked. ## QTL FMR + pre-computed GWAS FMR diff --git a/vignettes/colocboost-pipeline.Rmd b/vignettes/colocboost-pipeline.Rmd index 422af3cc..e8e45346 100644 --- a/vignettes/colocboost-pipeline.Rmd +++ b/vignettes/colocboost-pipeline.Rmd @@ -29,7 +29,7 @@ layered on top. It accepts inputs from the QTL input classes: | QTL input | What it is | |---|---| | `QtlDataset` | Single-study, individual-level: per-context residualized X/Y are extracted from the dataset | -| `QtlSumStats` | QTL summary statistics with a shared LD reference (must be QC'd) | +| `QtlSumStats` | QTL summary statistics, LD reference per row (must be QC'd) | | `MultiStudyQtlDataset` | One or more individual-level studies + optional embedded `QtlSumStats` | GWAS input (optional) is always a `GwasSumStats`, passed as the @@ -123,6 +123,15 @@ resSs <- colocboostPipeline( ) ``` +Each row is matched against its own `ldReference`, so the GWAS need not use +the QTL side's reference. `ldReference()` on the result lists the references +used, each once, and the `ldReference` column of `colocBoostOutcomes()` names +the one behind each outcome. + +```{r sumstats-ld} +names(ldReference(resSs)) +``` + ## Multi-study individual-level ```{r multistudy} diff --git a/vignettes/constructing-qtl-datasets.Rmd b/vignettes/constructing-qtl-datasets.Rmd index 49e2c86a..ce0ec4e3 100644 --- a/vignettes/constructing-qtl-datasets.Rmd +++ b/vignettes/constructing-qtl-datasets.Rmd @@ -276,8 +276,8 @@ names(qtlDatasets(msdManual)) ``` To attach a summary-only study, pass a `QtlSumStats` object to the `sumStats` -argument. For the manifest form, supply `sumStatsManifest`, `genome`, and -`ldReference`. +argument. For the manifest form, supply `sumStatsManifest` and `genome`, plus +`ldReference` unless the manifest gives each row an `ldReferencePath`. ## Excluding related samples diff --git a/vignettes/constructing-sumstats.Rmd b/vignettes/constructing-sumstats.Rmd index 9ce9a8b8..6cfdc5cb 100644 --- a/vignettes/constructing-sumstats.Rmd +++ b/vignettes/constructing-sumstats.Rmd @@ -33,15 +33,18 @@ per-variant statistics — annotated by an identity tuple: Every `entry` GRanges must carry these `mcols`: `SNP`, `A1` (effect / dosage-counted allele), `A2` (other allele), `Z`, `N`; optionally `MAF`, -`INFO`, `BETA`, `SE`, `P`. Two settings apply to the whole collection and are -stored in slots, not columns: +`INFO`, `BETA`, `SE`, `P`. Two further settings are not variant columns: -* `genome` — the build label (e.g. `"GRCh38"`). +* `genome` — the build label (e.g. `"GRCh38"`), one for the whole + collection. * `ldReference` — the LD reference used for QC and downstream analyses: a genotype panel (a `RangedSummarizedExperiment`, as returned by `readGenotypes()`), a `GenotypeMixture`, or an `LdMatrix` holding a correlation matrix you built (see the - [LD reference vignette](ld-infrastructure.html)). + [LD reference vignette](ld-infrastructure.html)). One reference serves + every row; pass a list with one per row (one per study for + `GwasSumStats`) when they sit on different references. Each distinct + reference is stored once, and `ldReference()` lists them. Optional per-row columns: `varY` (phenotype variance) and, for case/control GWAS, `nCase` / `nControl`. @@ -104,9 +107,10 @@ readr::write_tsv(sumstatsDf, gwasTsv) ## GwasSumStats from a manifest -The GWAS manifest has **one row per study**. `genome` and `ldReference` are -collection-level, so they are supplied as arguments (or as constant -`genome` / `ldReferencePath` columns). +The GWAS manifest has **one row per study**. `genome` is collection-level, so +it is supplied as an argument (or as a constant `genome` column). The LD +reference is per study: pass one `ldReference` argument for every study, or +give each row its own `ldReferencePath`. | Column | Required | Meaning | |---|---|---| @@ -115,7 +119,8 @@ collection-level, so they are supplied as arguments (or as constant | `columnMapping` (alias `column_mapping`) | no | YAML column map (see below) | | `nCase` / `nControl` | no | case / control counts | | `varY` | no | phenotype variance | -| `genome`, `ldReferencePath` | single-valued | may instead be arguments | +| `genome` | single-valued | may instead be an argument | +| `ldReferencePath` | no | this study's LD reference (or the argument) | ```{r gwas-from-manifest} gwasManifest <- data.frame( @@ -180,7 +185,8 @@ points at a sumstats file for that trait. | `trait` (alias `gene_id`) | yes | molecular trait id | | `sumStatsPath` (alias `path`) | yes | sumstats file for this trait | | `columnMapping`, `varY` | no | as for GWAS | -| `genome`, `ldReferencePath` | single-valued | may instead be arguments | +| `genome` | single-valued | may instead be an argument | +| `ldReferencePath` | no | this row's LD reference (or the argument) | ```{r qtl-from-manifest} qtlManifest <- data.frame( diff --git a/vignettes/fine-mapping.Rmd b/vignettes/fine-mapping.Rmd index 8c8b74ec..9659955a 100644 --- a/vignettes/fine-mapping.Rmd +++ b/vignettes/fine-mapping.Rmd @@ -141,8 +141,9 @@ fmrSs <- fineMappingPipeline(qtlSumStatsExample, methods = "susie") fmrSs ``` -The `QtlSumStats` collection carries an `ldReference` genotype panel; the -pipeline pulls the per-region LD from there automatically. +Each row of the `QtlSumStats` collection names its LD reference (here a +genotype panel); the pipeline pulls each region's LD from its row's reference +automatically. ## GWAS summary-statistics fine-mapping @@ -210,7 +211,9 @@ fineMappingPipeline( ``` The `jointSpecification` argument in `?fineMappingPipeline` gives the full -grammar, including the `study` axis for summary statistics. +grammar, including the `study` axis for summary statistics. On summary +statistics a joint fit uses one LD matrix, so the rows it combines must share +an LD reference; a group whose rows do not is an error. ## Reading the result diff --git a/vignettes/ld-infrastructure.Rmd b/vignettes/ld-infrastructure.Rmd index 5c2a20e7..f387ff3b 100644 --- a/vignettes/ld-infrastructure.Rmd +++ b/vignettes/ld-infrastructure.Rmd @@ -35,8 +35,10 @@ library(pecotmr) ## Two kinds of LD reference -Every pipeline reads LD from one place: the `ldReference` of the collection -it is given. That reference is one of two things (or a mixture of either, +Every pipeline reads LD from one place: the LD reference of the collection +row it is working on. A collection can use one reference for every row or a +different one per row; `ldReference()` lists the distinct references, each +stored once. A reference is one of two things (or a mixture of either, below). - A **genotype panel**, read lazily from disk with `readGenotypes()`. LD is @@ -147,17 +149,21 @@ GenotypeMixture( ### Using a reference -Either kind goes in the same slot, and from there every step reads it the -same way: +Either kind is passed the same way, and from there every step reads it the +same way. One reference serves every row; a list gives each row (each study, +for `GwasSumStats`) its own: ```{r use, eval=FALSE} gwas <- GwasSumStats(..., ldReference = panel) # or ldReference = ld +gwas <- GwasSumStats(..., ldReference = list(panelA, panelB)) # per study ``` When two collections meet in one pipeline — a QTL and a GWAS side in -colocalization, say — their references must be the same: two panels must -share their samples and allele coding, two `LdMatrix` objects must agree on -the LD they share, and a panel never matches a matrix. +colocalization, say — each QTL row and the GWAS rows it is combined with must +use the same reference: two panels must share their samples and allele +coding, two `LdMatrix` objects must agree on the LD they share, and a panel +never matches a matrix. `colocboostPipeline()` is the exception: it reads each +side's LD from that side's own reference, so the two may differ. ## Computing LD from genotypes diff --git a/vignettes/rss-qc.Rmd b/vignettes/rss-qc.Rmd index b6e12048..1fcad17b 100644 --- a/vignettes/rss-qc.Rmd +++ b/vignettes/rss-qc.Rmd @@ -196,7 +196,7 @@ It uses `susieR`'s kriging RSS diagnostic: the `qcInfo` audit as `krigingOutliersDropped`. Because it needs a per-region LD matrix and the kriging diagnostic, this is an -**RSS-only** check: it draws `R` from the collection's `ldReference` and +**RSS-only** check: it draws `R` from each row's LD reference and requires a `susieR` that exports `kriging_rss()` / `estimate_s_rss()` (otherwise it errors — which is why it is off by default). diff --git a/vignettes/twas-weights.Rmd b/vignettes/twas-weights.Rmd index fb30b254..e732a51d 100644 --- a/vignettes/twas-weights.Rmd +++ b/vignettes/twas-weights.Rmd @@ -174,8 +174,8 @@ twSs <- twasWeightsPipeline(qtlSumStatsExample, methods = "lasso") twSs ``` -The RSS path uses the `ldReference` genotype panel inside the -`QtlSumStats` collection to compute LD as needed. The same rule holds for +The RSS path computes LD as needed from each row's LD reference in the +`QtlSumStats` collection. The same rule holds for fine-mapping methods here: they are not re-fit, so run `fineMappingPipeline()` on the `QtlSumStats` first and pass its result as `fineMappingResult`. @@ -196,7 +196,9 @@ twasWeightsPipeline( To choose the axes yourself, pass a `jointSpecification`: a character vector of axes, or `list(axes = , scope = )` to limit the fit to listed studies, contexts or traits. The `jointSpecification` argument in -`?twasWeightsPipeline` gives the full grammar. +`?twasWeightsPipeline` gives the full grammar. On a `QtlSumStats` the +contexts are fitted against one LD matrix, so their rows must share an LD +reference. ```{r joint, eval=FALSE} # `qd`: a QtlDataset whose traits are measured in brain, liver and more. diff --git a/vignettes/twas-zscore.Rmd b/vignettes/twas-zscore.Rmd index 16827ea8..283f7be8 100644 --- a/vignettes/twas-zscore.Rmd +++ b/vignettes/twas-zscore.Rmd @@ -152,14 +152,13 @@ p-value than the normal approximation would. ## LD reference consistency -Both `twasWeights` and `fineMappingResult` carry an `ldReference` slot. -When provided, they must be the same LD reference as `gwasSumStats` -carries. The pipeline errors on mismatch. - -A QTL input with `ldReference = NULL` (e.g. weights learned from -individual-level data without any RSS step) skips the panel check for -that input — useful for analyses that mix individual-level QTL fits -with sumstats GWAS. +Both `twasWeights` and `fineMappingResult` record an LD reference per row. +Where a row has one, it must be the same LD reference as the `gwasSumStats` +rows it overlaps carry. The pipeline errors on mismatch. + +A QTL row with no LD reference (e.g. weights learned from individual-level +data without any RSS step) skips the panel check — useful for analyses that +mix individual-level QTL fits with sumstats GWAS. ## Common parameters diff --git a/vignettes/xqtl-enrichment.Rmd b/vignettes/xqtl-enrichment.Rmd index 2609fd6c..9385aa81 100644 --- a/vignettes/xqtl-enrichment.Rmd +++ b/vignettes/xqtl-enrichment.Rmd @@ -84,7 +84,7 @@ par(op) `qtlEnrichmentPipeline()` takes the two fine-mapping collections directly and estimates, for every `(gwasStudy, qtlStudy, qtlContext)` combination, how enriched the molecular QTLs are among the GWAS causal variants. The GWAS -collection must be RSS-derived (it carries an `ldReference`); +collection must be RSS-derived (every row carries an LD reference); `gwasFineMappingExample` already does. ```{r enrichment} From a003331058835608990ea2341409dba131a5a505 Mon Sep 17 00:00:00 2001 From: Daniel Nachun Date: Mon, 26 Oct 2026 22:24:52 -0700 Subject: [PATCH 2/5] test cleanup and penalized RSS fixes --- .github/environment/pixi.toml | 3 +- .github/workflows/ci.yml | 2 + DESCRIPTION | 2 +- NAMESPACE | 96 +- R/AllClasses.R | 1026 +++--- R/AllGenerics.R | 931 +++--- R/AnnotationMatrix.R | 11 +- R/ColocBoostResult.R | 165 +- R/ColocResult.R | 237 +- R/CtwasResult.R | 469 ++- R/CtwasResultEntry.R | 69 + R/GenotypeHandle.R | 74 +- R/GenotypeMixture.R | 12 +- R/GwasFineMappingResult.R | 192 +- R/LdBlocks.R | 48 +- R/LdEigen.R | 19 +- R/LdMatrix.R | 28 +- R/LdScore.R | 22 +- R/LdStatistic.R | 9 +- R/MashPrior.R | 4 +- R/MethodOptions.R | 45 +- R/MethodParam.R | 92 +- R/MultiStudyQtlDataset.R | 128 +- R/QtlDataset.R | 968 +++--- R/QtlFineMappingResult.R | 161 +- R/RangedTupleList.R | 674 +++- R/SldscData.R | 64 +- R/causalInferencePipeline.R | 174 +- R/colocPipeline.R | 606 +++- R/colocboostPipeline.R | 1071 +++++-- R/cpp11.R | 8 - R/crossValidation.R | 166 +- R/ctwasPipeline.R | 735 ++--- R/ctwasWrapper.R | 51 +- R/fineMappingPipeline.R | 872 +++--- R/fineMappingRow.R | 124 +- R/fineMappingWrappers.R | 103 +- R/genotypeIo.R | 175 +- R/gwasSumStats.R | 407 +-- R/h2Annotations.R | 16 +- R/h2EstimationWrappers.R | 29 +- R/jointEngine.R | 207 +- R/jointSpecification.R | 185 +- R/ld.R | 98 +- R/manifestLoaders.R | 578 ++-- R/mashPipeline.R | 93 +- R/overlapTopLoci.R | 19 +- R/pvalCombineWrappers.R | 25 +- R/qtlAssociationPostprocess.R | 17 +- R/qtlEnrichmentPipeline.R | 127 +- R/qtlSumStats.R | 380 ++- R/regularizedRegressionWrappers.R | 698 +++-- R/relatednessQc.R | 33 +- R/resultReaders.R | 299 +- R/resultWriters.R | 609 ++-- R/sldscPostprocessingPipeline.R | 10 +- R/sldscWrapper.R | 42 +- R/sumstatsQc.R | 563 +++- R/tupleSelectors.R | 936 ++++-- R/twasWeights.R | 331 +- R/twasWeightsPipeline.R | 368 ++- R/twasWeightsRow.R | 41 +- R/variantId.R | 261 +- _pkgdown.yml | 33 +- data/colocboostResultExample.rda | Bin 2968 -> 2980 bytes data/ctwasEstExample.rda | Bin 249636 -> 247640 bytes data/ctwasFinemapExample.rda | Bin 250524 -> 248272 bytes data/ctwasInputsExample.rda | Bin 248948 -> 246876 bytes data/ctwasWeightsExample.rda | Bin 6552 -> 6668 bytes data/fsusieFineMappingExample.rda | Bin 22184 -> 22268 bytes data/gwasFineMappingExample.rda | Bin 650656 -> 650800 bytes data/gwasFineMappingLbfExample.rda | Bin 41292 -> 41384 bytes data/gwasSumStatsS4Example.rda | Bin 7348 -> 7444 bytes data/multiStudyQtlDatasetExample.rda | Bin 7172 -> 7068 bytes data/mvsusieFineMappingExample.rda | Bin 116924 -> 117036 bytes data/qtlDatasetExample.rda | Bin 5640 -> 5572 bytes data/qtlFineMappingExample.rda | Bin 212444 -> 212476 bytes data/qtlFineMappingLbfExample.rda | Bin 78140 -> 78256 bytes data/qtlFineMappingPairedExample.rda | Bin 19332 -> 19428 bytes data/qtlSumStatsExample.rda | Bin 8328 -> 8400 bytes data/qtlSumStatsMulticontextExample.rda | Bin 16436 -> 16512 bytes data/twasWeightsExample.rda | Bin 10136 -> 10324 bytes inst/scripts/build_ctwas_examples.R | 6 +- inst/scripts/build_examples.R | 10 +- man/ColocBoostResult.Rd | 14 +- man/ColocResult.Rd | 6 +- man/CredibleSetParam.Rd | 54 +- man/CrossValidationParam.Rd | 15 +- man/CtwasResult-class.Rd | 19 +- man/CtwasResult.Rd | 39 +- man/CtwasResultEntry-class.Rd | 7 + man/DentistParam.Rd | 7 +- man/FineMappingResultBase-class.Rd | 19 + man/FineMappingRow-class.Rd | 16 +- man/GenotypeFilterParam.Rd | 34 +- man/GenotypeHandle-class.Rd | 28 +- man/GenotypeMixture-class.Rd | 4 + man/GwasFineMappingParam.Rd | 43 +- man/GwasFineMappingResult.Rd | 40 +- man/GwasSumStats-class.Rd | 26 +- man/GwasSumStats.Rd | 69 +- man/LdEigen.Rd | 3 +- man/LdMatrix-class.Rd | 4 + man/LdScore.Rd | 3 +- man/MethodParam-class.Rd | 16 +- man/MultiStudyQtlDataset-class.Rd | 9 +- man/PhenotypeFilterParam.Rd | 58 + man/QtlDataset-class.Rd | 33 +- man/QtlDataset.Rd | 42 +- man/QtlEnrichmentParam.Rd | 2 +- man/QtlFineMappingResult-class.Rd | 16 +- man/QtlFineMappingResult.Rd | 15 +- man/QtlSumStats-class.Rd | 17 +- man/QtlSumStats.Rd | 47 +- man/RaissParam.Rd | 7 +- man/RangedTupleList-class.Rd | 16 + man/RangedTupleList-methods.Rd | 46 +- man/ResidualizationParam.Rd | 10 +- man/SumStatsBase-class.Rd | 14 +- man/TwasWeights-class.Rd | 29 +- man/TwasWeights.Rd | 14 +- man/TwasWeightsRow-class.Rd | 16 +- man/af.Rd | 36 +- man/annotData.Rd | 2 +- man/as.data.frame-ColocBoostResult-method.Rd | 26 - man/as.data.frame-ColocResult-method.Rd | 40 - man/asGranges.Rd | 24 - man/assembleCtwasInputs.Rd | 49 +- man/autoDecision.Rd | 7 +- man/blockId.Rd | 12 +- man/buildLdEigen.Rd | 8 +- man/buildLdScore.Rd | 8 +- man/buildTopLoci.Rd | 3 +- man/causalInferencePipeline.Rd | 17 +- man/chromPaths.Rd | 4 +- man/coef-methods.Rd | 16 +- man/colocBoostOutcomes.Rd | 5 +- man/colocPipeline.Rd | 54 +- man/colocViews.Rd | 44 +- man/colocboostPipeline.Rd | 152 +- man/combineGwasSumStats.Rd | 12 +- man/combineQtlSumStats.Rd | 6 +- man/combineTwasWeights.Rd | 2 +- man/computeCoefficientsGlasso.Rd | 7 +- man/computeCsCorrelation.Rd | 4 +- man/computingTime.Rd | 6 +- man/credibleSetSummary.Rd | 2 +- man/credibleSets.Rd | 13 +- man/ctwasPipeline.Rd | 81 +- man/ctwasPosteriors.Rd | 17 +- man/dentist.Rd | 2 +- man/dentistSingleWindow.Rd | 7 +- man/dot-penalizedRssWeights.Rd | 23 +- man/dot-regionToSnpIdx.Rd | 4 +- man/enetRssWeights.Rd | 94 + man/enetWeights.Rd | 12 +- man/estCtwasGroupPriors.Rd | 7 +- man/exportToVcf.Rd | 115 - man/extractCsInfo.Rd | 4 +- man/extractTopPipInfo.Rd | 4 +- man/fillFromReference.Rd | 61 + man/fineMappingPipeline.Rd | 92 +- man/fineMappingResult.Rd | 32 +- man/fineMappingRow.Rd | 10 +- man/finemapCtwasRegions.Rd | 12 +- man/flattenTupleRanges.Rd | 4 + man/frqData.Rd | 2 +- man/fsusieCredibleBand.Rd | 16 +- man/fsusieTraitEffects.Rd | 2 +- man/genomicRegion.Rd | 24 +- man/genotypes.Rd | 24 +- man/intersectVariants.Rd | 4 +- man/lassosumRss.Rd | 7 +- man/lbf.Rd | 7 +- man/ldClumpByScore.Rd | 2 +- man/ldMatrix.Rd | 10 +- man/learnTwasWeights.Rd | 16 +- man/loadGenotypeRegion.Rd | 8 +- man/loadGwasSumStatsFromManifest.Rd | 42 +- man/loadMultiStudyQtlDatasetFromManifest.Rd | 15 +- man/loadQtlDatasetFromManifest.Rd | 8 - man/loadQtlSumStatsFromManifest.Rd | 27 +- man/maf.Rd | 38 +- man/marginalEffects.Rd | 26 +- man/mashInput.Rd | 3 +- man/mcpRssWeights.Rd | 4 +- man/mergeCtwasBoundaryRegions.Rd | 7 +- man/molecularTraits.Rd | 50 +- man/mrmashWrapper.Rd | 10 +- man/nSamples.Rd | 50 +- man/nSnps.Rd | 15 +- man/nestTupleRanges.Rd | 3 +- man/normalizeVariantId.Rd | 6 +- man/overlapTopLoci.Rd | 4 +- man/parseRegion.Rd | 24 - man/parseVariantId.Rd | 15 +- man/pecotmr-gwas-sumstats.Rd | 5 +- man/pecotmr-qtl-sumstats.Rd | 3 +- man/penalizedRss.Rd | 24 +- man/phenotypeCovariates.Rd | 8 +- man/pip.Rd | 20 +- man/postprocessFinemappingFits.Rd | 4 +- man/pval.Rd | 15 +- man/qcDiagnostics.Rd | 30 +- man/qcInfo.Rd | 18 +- man/qcOptions.Rd | 31 + man/qtlDatasetFilters.Rd | 65 - man/qtlDatasets.Rd | 25 - man/qtlEnrichment.Rd | 11 +- man/qtlEnrichmentPipeline.Rd | 35 +- man/qtlSumStatsFromBetaMatrix.Rd | 2 +- man/qtlSumStatsFromZMatrix.Rd | 4 +- man/raiss.Rd | 12 +- man/readAfreq.Rd | 4 +- man/readAnnotations.Rd | 6 +- man/readFineMappingResult.Rd | 26 +- man/readGenotypes.Rd | 17 +- man/readSldscAnnot.Rd | 4 +- man/readSldscFrq.Rd | 4 +- man/readSldscTrait.Rd | 4 +- man/readTwasWeights.Rd | 20 +- man/refVariantInfo.Rd | 9 +- man/regionToDf.Rd | 26 - man/residualizedGenotypes.Rd | 35 +- man/residualizedPhenotypes.Rd | 43 +- man/resolveWeights.Rd | 7 +- man/retainedMass.Rd | 2 +- man/ridgeRssWeights.Rd | 75 + man/ridgeWeights.Rd | 29 + man/sampleSize.Rd | 40 + man/scadRssWeights.Rd | 4 +- man/scaleResiduals.Rd | 25 - man/screenCtwasRegions.Rd | 11 +- man/sdpr.Rd | 3 - man/se.Rd | 15 +- man/show-methods.Rd | 11 +- man/sldscResults.Rd | 25 +- man/snpsPerBlock.Rd | 3 +- man/subsetChr.Rd | 26 - man/subsetRegion.Rd | 53 - man/sumStats-GwasSumStats-method.Rd | 4 - man/sumStats.Rd | 15 +- man/sumStatsDataFrame.Rd | 74 - man/summaryStatsQc.Rd | 31 +- man/susieAlpha.Rd | 17 +- man/susieFit.Rd | 7 +- man/susieResult.Rd | 4 +- man/topLoci.Rd | 17 +- man/traitPosition.Rd | 13 +- man/twasEngineOptions.Rd | 6 +- man/twasPredict.Rd | 2 +- man/twasWeightsCv.Rd | 19 +- man/twasWeightsEntry.Rd | 2 +- man/twasWeightsPipeline.Rd | 81 +- man/twasWeightsRow.Rd | 10 +- man/updateObject-methods.Rd | 58 +- man/variantColumnReplace.Rd | 53 +- man/variantIds.Rd | 27 +- man/weights-methods.Rd | 2 +- man/weightsDataType.Rd | 2 +- man/{exportToBed.Rd => writeBed.Rd} | 64 +- man/writeGwasVcf.Rd | 134 + man/z.Rd | 15 +- pixi.toml | 7 +- src/cpp11.cpp | 16 - src/lassosum_rss.cpp | 180 -- src/penalized_rss.cpp | 51 +- src/rss_ld.h | 2 +- tests/testthat/helper-collectionAccessors.R | 4 +- tests/testthat/helper-fineMapping.R | 146 + tests/testthat/helper-fitCoverage.R | 20 + tests/testthat/helper-genotypeHandle.R | 43 + tests/testthat/helper-h2Classes.R | 243 +- tests/testthat/helper-mash.R | 6 + tests/testthat/helper-resultIo.R | 81 + tests/testthat/helper-s4Constructors.R | 192 +- tests/testthat/helper-showMethods.R | 8 +- tests/testthat/helper-sldsc.R | 221 +- tests/testthat/helper-vcf.R | 4 - tests/testthat/test_AllClasses.R | 990 +++++- tests/testthat/test_AllGenerics.R | 23 - tests/testthat/test_AnnotationMatrix.R | 59 +- tests/testthat/test_ColocBoostResult.R | 102 +- tests/testthat/test_ColocResult.R | 134 +- tests/testthat/test_CtwasResult.R | 176 +- tests/testthat/test_CtwasResultEntry.R | 49 + tests/testthat/test_GenotypeDosageSeed.R | 8 +- tests/testthat/test_GenotypeMixture.R | 14 +- tests/testthat/test_GwasFineMappingResult.R | 407 ++- tests/testthat/test_GwasSumStats.R | 522 +++- tests/testthat/test_H2Estimate.R | 60 +- tests/testthat/test_LdBlocks.R | 80 +- tests/testthat/test_LdMatrix.R | 7 + tests/testthat/test_LdStatistic.R | 42 +- tests/testthat/test_MethodOptions.R | 22 +- tests/testthat/test_MethodParam.R | 137 +- tests/testthat/test_MultiStudyQtlDataset.R | 92 +- tests/testthat/test_QtlDataset.R | 1171 +++---- tests/testthat/test_QtlFineMappingResult.R | 298 +- tests/testthat/test_RangedTupleList.R | 405 ++- tests/testthat/test_SldscData.R | 37 +- tests/testthat/test_causalInferencePipeline.R | 580 ++-- tests/testthat/test_colocPipeline.R | 681 +++- tests/testthat/test_colocboostPipeline.R | 811 +++-- tests/testthat/test_cpp11.R | 2 - tests/testthat/test_crossValidation.R | 143 +- tests/testthat/test_ctwasPipeline.R | 1164 +++---- tests/testthat/test_ctwasWrapper.R | 4 +- tests/testthat/test_fineMappingPipeline.R | 2308 ++++++-------- tests/testthat/test_fineMappingRow.R | 536 +--- tests/testthat/test_fineMappingWrappers.R | 787 ++--- tests/testthat/test_genotypeHandle.R | 294 +- tests/testthat/test_genotypeIo.R | 1360 ++------ tests/testthat/test_h2Annotations.R | 42 +- tests/testthat/test_h2EstimationWrappers.R | 1249 +++----- tests/testthat/test_jointEngine.R | 186 +- tests/testthat/test_jointSpecification.R | 354 ++- tests/testthat/test_ld.R | 1117 +++---- tests/testthat/test_manifestLoaders.R | 493 ++- tests/testthat/test_mashPipeline.R | 876 ++---- tests/testthat/test_mashWrapper.R | 201 +- tests/testthat/test_overlapTopLoci.R | 43 +- tests/testthat/test_pvalCombineWrappers.R | 242 +- .../testthat/test_qtlAssociationPostprocess.R | 202 +- tests/testthat/test_qtlEnrichmentPipeline.R | 238 +- tests/testthat/test_qtlSumStats.R | 384 ++- .../test_regularizedRegressionWrappers.R | 480 ++- tests/testthat/test_relatednessQc.R | 41 +- tests/testthat/test_resultReaders.R | 296 +- tests/testthat/test_resultWriters.R | 929 +++--- tests/testthat/test_rrBayesAlphabet.R | 19 - tests/testthat/test_rrBglr.R | 24 +- tests/testthat/test_rrDispatch.R | 142 +- tests/testthat/test_rrDpr.R | 13 - tests/testthat/test_rrE2eSolvers.R | 12 +- tests/testthat/test_rrGlmnet.R | 47 +- tests/testthat/test_rrL0learn.R | 50 +- tests/testthat/test_rrLassosum.R | 5 +- tests/testthat/test_rrMrash.R | 15 - tests/testthat/test_rrNcvreg.R | 32 - tests/testthat/test_rrPenalizedRss.R | 454 ++- tests/testthat/test_rrPrsCs.R | 88 +- tests/testthat/test_rrSdpr.R | 103 +- tests/testthat/test_rrSignalRecovery.R | 7 +- tests/testthat/test_rrSusie.R | 156 - .../test_sldscPostprocessingPipeline.R | 33 +- tests/testthat/test_sldscWrapper.R | 175 +- tests/testthat/test_sumstatsQc.R | 2765 +++++++---------- tests/testthat/test_tupleSelectors.R | 647 +++- tests/testthat/test_twasWeights.R | 835 ++--- tests/testthat/test_twasWeightsPipeline.R | 1296 ++++---- tests/testthat/test_twasWeightsRow.R | 94 +- tests/testthat/test_variantId.R | 686 ++-- vignettes/coloc-pipeline.Rmd | 21 +- vignettes/colocboost-pipeline.Rmd | 47 +- vignettes/constructing-qtl-datasets.Rmd | 58 +- vignettes/constructing-sumstats.Rmd | 17 +- vignettes/ctwas-pipeline.Rmd | 42 +- vignettes/fine-mapping.Rmd | 21 +- vignettes/finemapping-postprocessing.Rmd | 51 +- vignettes/heritability.Rmd | 4 +- vignettes/ld-infrastructure.Rmd | 4 +- vignettes/rss-qc.Rmd | 22 +- vignettes/twas-weights.Rmd | 46 +- vignettes/xqtl-enrichment.Rmd | 19 +- 365 files changed, 27201 insertions(+), 22970 deletions(-) create mode 100644 man/PhenotypeFilterParam.Rd delete mode 100644 man/as.data.frame-ColocBoostResult-method.Rd delete mode 100644 man/as.data.frame-ColocResult-method.Rd delete mode 100644 man/asGranges.Rd create mode 100644 man/enetRssWeights.Rd delete mode 100644 man/exportToVcf.Rd create mode 100644 man/fillFromReference.Rd delete mode 100644 man/parseRegion.Rd create mode 100644 man/qcOptions.Rd delete mode 100644 man/qtlDatasetFilters.Rd delete mode 100644 man/qtlDatasets.Rd delete mode 100644 man/regionToDf.Rd create mode 100644 man/ridgeRssWeights.Rd create mode 100644 man/ridgeWeights.Rd create mode 100644 man/sampleSize.Rd delete mode 100644 man/scaleResiduals.Rd delete mode 100644 man/subsetChr.Rd delete mode 100644 man/subsetRegion.Rd delete mode 100644 man/sumStatsDataFrame.Rd rename man/{exportToBed.Rd => writeBed.Rd} (76%) create mode 100644 man/writeGwasVcf.Rd delete mode 100644 src/lassosum_rss.cpp create mode 100644 tests/testthat/helper-fineMapping.R create mode 100644 tests/testthat/helper-fitCoverage.R create mode 100644 tests/testthat/helper-resultIo.R delete mode 100644 tests/testthat/test_rrSusie.R diff --git a/.github/environment/pixi.toml b/.github/environment/pixi.toml index 19aed404..e6c46347 100644 --- a/.github/environment/pixi.toml +++ b/.github/environment/pixi.toml @@ -11,9 +11,10 @@ platforms = [ devtools_document = "cd $GITHUB_WORKSPACE; R -e 'devtools::document()'" devtools_test = "cd $GITHUB_WORKSPACE; R -e 'devtools::test(stop_on_failure = TRUE)'" codecov = "cd $GITHUB_WORKSPACE; R -e 'covr::codecov(quiet = FALSE)'" -rcmdcheck = "cd $GITHUB_WORKSPACE; R -e 'rcmdcheck::rcmdcheck(error_on = \"error\")'" +rcmdcheck = "cd $GITHUB_WORKSPACE; R -e 'rcmdcheck::rcmdcheck(error_on = \"error\", args = c(\"--no-manual\", \"--no-build-vignettes\"))'" bioccheck_git_clone = "cd $GITHUB_WORKSPACE; R -e 'BiocCheck::BiocCheckGitClone(\"quit-with-status\" = TRUE)'" bioccheck = "cd $GITHUB_WORKSPACE; R -e 'BiocCheck::BiocCheck(\"quit-with-status\" = FALSE)'" +goodpractice = "cd $GITHUB_WORKSPACE; R -e 'goodpractice::gp(\".\")'" use_major_version = "cd $GITHUB_WORKSPACE; R -e 'usethis::use_version(which = \"major\", push = FALSE)'" use_minor_version = "cd $GITHUB_WORKSPACE; R -e 'usethis::use_version(which = \"minor\", push = FALSE)'" use_patch_version = "cd $GITHUB_WORKSPACE; R -e 'usethis::use_version(which = \"patch\", push = FALSE)'" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 604ff1a4..0b9aaf02 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,6 +27,8 @@ jobs: - { name: Run R CMD check, task: rcmdcheck, platform: linux-64, runner: ubuntu-latest, environment: r45 } - { name: Run BiocCheckGitClone, task: bioccheck_git_clone, platform: linux-64, runner: ubuntu-latest, environment: r45 } - { name: Run BiocCheck, task: bioccheck, platform: linux-64, runner: ubuntu-latest, environment: r45 } + - { name: Check goodpractice, task: goodpractice, platform: linux-64, runner: ubuntu-latest, environment: r45 } + - { name: Check pkgdown_build, task: pkgdown_build, platform: linux-64, runner: ubuntu-latest, environment: r45 } steps: - name: Checkout pull request branch uses: actions/checkout@v7 diff --git a/DESCRIPTION b/DESCRIPTION index fae439ff..b51051ee 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -133,9 +133,9 @@ Collate: 'AnnotationMatrix.R' 'ColocResult.R' 'ColocBoostResult.R' + 'CtwasResultEntry.R' 'tupleSelectors.R' 'CtwasResult.R' - 'CtwasResultEntry.R' 'GenotypeDosageSeed.R' 'GwasFineMappingResult.R' 'MethodOptions.R' diff --git a/NAMESPACE b/NAMESPACE index 2ba6fc28..0ff65792 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -13,21 +13,8 @@ S3method(postprocessFinemappingFit,susie) S3method(postprocessFinemappingFit,susieInf) S3method(postprocessFinemappingFit,susieRss) export("af<-") -export("credibleSetParam<-") -export("csCoverage<-") -export("fineMappingMethods<-") -export("fitRetention<-") -export("includeAllCs<-") -export("initializeWithSusieInf<-") export("maf<-") -export("medianAbsCorr<-") -export("minAbsCorr<-") -export("nSamples<-") -export("panelFilterParam<-") -export("perCsColumns<-") -export("secondaryCoverage<-") -export("signalCutoff<-") -export("susieRssParam<-") +export("sampleSize<-") export(AnnotationMatrix) export(AspuOptions) export(BglrOptions) @@ -63,6 +50,7 @@ export(DentistParam) export(DprOptions) export(EnsembleParam) export(FineMappingMethodsParam) +export(FineMappingRow) export(FsusieOptions) export(GbjOmniOptions) export(GbjOptions) @@ -102,6 +90,7 @@ export(MvsusieRssOptions) export(NcvregOptions) export(PanelFilterParam) export(PenalizedRssOptions) +export(PhenotypeFilterParam) export(PlinkQcOptions) export(PoolrOptions) export(PrsCsOptions) @@ -134,6 +123,7 @@ export(SusieRssOptions) export(SusieRssParam) export(TwasWeights) export(TwasWeightsMethodsParam) +export(TwasWeightsRow) export(UdFitOptions) export(UdInitOptions) export(VariantPruningParam) @@ -143,7 +133,6 @@ export(annotCols) export(annotData) export(annotationJackknifeCoefs) export(asCtwasResult) -export(asGranges) export(assembleCtwasInputs) export(autoDecision) export(bLassoWeights) @@ -170,6 +159,7 @@ export(colocCredibleSets) export(colocGenes) export(colocPairs) export(colocPipeline) +export(colocPooledVariants) export(colocVariants) export(colocboostPipeline) export(combineFineMappingResults) @@ -204,6 +194,7 @@ export(dprVbWeights) export(dprWeights) export(effectiveN) export(eigenList) +export(enetRssWeights) export(enetWeights) export(enforceDesignFullRank) export(enlocClusterProbabilities) @@ -211,10 +202,9 @@ export(ensembleWeights) export(estCtwasGroupPriors) export(estimateH2) export(estimateSparsity) -export(exportToBed) -export(exportToVcf) export(extractCsInfo) export(extractTopPipInfo) +export(fillFromReference) export(filterInvalidSummaryStat) export(filterMixtureComponents) export(filterRelatedness) @@ -222,7 +212,6 @@ export(filterVariantsByLdReference) export(fineMappingMethods) export(fineMappingPipeline) export(fineMappingResult) -export(fineMappingRow) export(finemapCtwasRegions) export(fitFsusie) export(fitGlmnetCv) @@ -249,15 +238,12 @@ export(heritabilityEstimate) export(heritabilityEstimateSe) export(heritabilityIntercept) export(heritabilityInterceptSe) -export(imissCutoff) export(inSample) export(includeAllCs) export(initializeWithSusieInf) export(intersectVariants) export(invertMinmaxScaling) export(isBinarySldscAnnot) -export(keepIndel) -export(keepVariants) export(krigingOutlierQc) export(l0learnRssWeights) export(l0learnWeights) @@ -280,9 +266,7 @@ export(loadMultiStudyQtlDatasetFromManifest) export(loadQtlDatasetFromManifest) export(loadQtlSumStatsFromManifest) export(localH2Blocks) -export(macCutoff) export(maf) -export(mafCutoff) export(makePairwiseContrastCol) export(marginalEffects) export(mashCovarianceComponents) @@ -324,7 +308,6 @@ export(nestTupleRanges) export(normalizeVariantId) export(overlapTopLoci) export(panelFilterParam) -export(parseRegion) export(parseVariantId) export(perCsColumns) export(phenotypeCovariates) @@ -334,8 +317,8 @@ export(prsCsWeights) export(pval) export(qcDiagnostics) export(qcInfo) +export(qcOptions) export(qtlAssociationPostprocess) -export(qtlDatasets) export(qtlEnrichment) export(qtlEnrichmentPipeline) export(qtlSumStatsFromBetaMatrix) @@ -350,16 +333,17 @@ export(readSldscFrq) export(readSldscTrait) export(readTwasWeights) export(refVariantInfo) -export(regionToDf) export(regionVcp) export(residualizedGenotypes) export(residualizedPhenotypes) export(resolveWeights) export(retainedMass) +export(ridgeRssWeights) +export(ridgeWeights) +export(sampleSize) export(sanitizeMashData) export(scadRssWeights) export(scadWeights) -export(scaleResiduals) export(scoreFromCs) export(scoreStats) export(screenCtwasRegions) @@ -377,8 +361,6 @@ export(sliceMashData) export(standardizeSldscTrait) export(stratifiedHeritabilityEnrichment) export(studyName) -export(subsetChr) -export(subsetRegion) export(sumStats) export(summaryStatsQc) export(susieAlpha) @@ -399,7 +381,6 @@ export(twasPredict) export(twasWeights) export(twasWeightsCv) export(twasWeightsPipeline) -export(twasWeightsRow) export(twasZ) export(updateMashModelCov) export(varY) @@ -407,7 +388,8 @@ export(variantIds) export(waldTestPval) export(weightStandardized) export(weightsDataType) -export(xvarCutoff) +export(writeBed) +export(writeGwasVcf) export(z) exportClasses(AnnotationMatrix) exportClasses(BoundaryMergeParam) @@ -446,6 +428,7 @@ exportClasses(MrParam) exportClasses(MrmashPriorParam) exportClasses(MultiStudyQtlDataset) exportClasses(PanelFilterParam) +exportClasses(PhenotypeFilterParam) exportClasses(PvalMethodsParam) exportClasses(QtlDataset) exportClasses(QtlEnrichmentParam) @@ -474,23 +457,26 @@ exportMethods("[") exportMethods("[[") exportMethods("[[<-") exportMethods("af<-") +exportMethods("elementMetadata<-") exportMethods("maf<-") -exportMethods("nSamples<-") +exportMethods("sampleSize<-") exportMethods(af) exportMethods(annotCols) exportMethods(annotData) exportMethods(annotationJackknifeCoefs) -exportMethods(as.data.frame) exportMethods(as.list) +exportMethods(as.matrix) exportMethods(baselineAnnotations) exportMethods(bindROWS) exportMethods(blockId) exportMethods(coef) +exportMethods(coerce) exportMethods(colnames) exportMethods(colocBoostOutcomes) exportMethods(colocCredibleSets) exportMethods(colocGenes) exportMethods(colocPairs) +exportMethods(colocPooledVariants) exportMethods(colocVariants) exportMethods(colocboostPipeline) exportMethods(computeLdScores) @@ -505,8 +491,6 @@ exportMethods(cvResult) exportMethods(eigenList) exportMethods(endoapply) exportMethods(estimateH2) -exportMethods(exportToBed) -exportMethods(exportToVcf) exportMethods(fineMappingPipeline) exportMethods(fineMappingResult) exportMethods(frqData) @@ -521,11 +505,8 @@ exportMethods(heritabilityEstimate) exportMethods(heritabilityEstimateSe) exportMethods(heritabilityIntercept) exportMethods(heritabilityInterceptSe) -exportMethods(imissCutoff) exportMethods(inSample) exportMethods(intersectVariants) -exportMethods(keepIndel) -exportMethods(keepVariants) exportMethods(lbf) exportMethods(ldBlocks) exportMethods(ldMatrix) @@ -535,9 +516,7 @@ exportMethods(ldReference) exportMethods(length) exportMethods(localH2Blocks) exportMethods(longForm) -exportMethods(macCutoff) exportMethods(maf) -exportMethods(mafCutoff) exportMethods(marginalEffects) exportMethods(methodFits) exportMethods(methodNames) @@ -554,8 +533,8 @@ exportMethods(pip) exportMethods(pval) exportMethods(qcDiagnostics) exportMethods(qcInfo) +exportMethods(qcOptions) exportMethods(qtlAssociationPostprocess) -exportMethods(qtlDatasets) exportMethods(readAnnotations) exportMethods(readGenotypes) exportMethods(regionVcp) @@ -563,16 +542,15 @@ exportMethods(residualizedGenotypes) exportMethods(residualizedPhenotypes) exportMethods(resolveWeights) exportMethods(retainedMass) -exportMethods(scaleResiduals) +exportMethods(sampleSize) exportMethods(scoreStats) exportMethods(se) exportMethods(show) exportMethods(significantQtls) exportMethods(sldscResults) +exportMethods(sort) exportMethods(stratifiedHeritabilityEnrichment) exportMethods(studyName) -exportMethods(subsetChr) -exportMethods(subsetRegion) exportMethods(sumStats) exportMethods(susieAlpha) exportMethods(susieFit) @@ -580,16 +558,20 @@ exportMethods(testedAnnotations) exportMethods(topLoci) exportMethods(traitNames) exportMethods(traitPosition) +exportMethods(trim) exportMethods(twasWeights) exportMethods(twasWeightsPipeline) +exportMethods(unique) exportMethods(updateObject) exportMethods(varY) exportMethods(variantIds) exportMethods(weightStandardized) exportMethods(weights) exportMethods(weightsDataType) -exportMethods(xvarCutoff) +exportMethods(writeBed) +exportMethods(writeGwasVcf) exportMethods(z) +importClassesFrom(BiocParallel,BiocParallelParam) importClassesFrom(GenomicRanges,GRanges) importClassesFrom(MultiAssayExperiment,MultiAssayExperiment) importClassesFrom(S4Vectors,DataFrame) @@ -603,14 +585,19 @@ importFrom(BiocGenerics, ncol, nrow, path, + sort, + unique, + unstrand, updateObject, weights, width ) importFrom(BiocParallel, - MulticoreParam, + "bpRNGseed<-", + SerialParam, + bpRNGseed, bplapply, - multicoreWorkers + bpnworkers ) importFrom(Biostrings, DNAStringSet, @@ -627,7 +614,8 @@ importFrom(IRanges, DataFrameList, IRanges, findOverlaps, - overlapsAny + overlapsAny, + trim ) importFrom(MASS,ginv) importFrom(MultiAssayExperiment, @@ -647,8 +635,12 @@ importFrom(Rsamtools, scanTabix, seqnamesTabix ) -importFrom(S4Arrays,extract_array) +importFrom(S4Arrays, + as.matrix, + extract_array +) importFrom(S4Vectors, + "elementMetadata<-", "mcols<-", "metadata<-", DataFrame, @@ -671,6 +663,7 @@ importFrom(archive,archive_read) importFrom(checkmate, assert, assertCharacter, + assertChoice, assertClass, assertCount, assertDataFrame, @@ -711,6 +704,8 @@ importFrom(dplyr, bind_cols, bind_rows, case_when, + coalesce, + count, desc, distinct, everything, @@ -737,6 +732,7 @@ importFrom(metafor,rma) importFrom(methods, "slot<-", as, + coerce, is, new, setClass, @@ -763,7 +759,6 @@ importFrom(purrr, map, map2, map2_dbl, - map2_lgl, map_chr, map_dbl, map_dfr, @@ -792,6 +787,7 @@ importFrom(rlang, abort, arg_match, arg_match0, + call2, caller_arg, cnd_signal, eval_bare, diff --git a/R/AllClasses.R b/R/AllClasses.R index 83604164..8364acfd 100644 --- a/R/AllClasses.R +++ b/R/AllClasses.R @@ -44,12 +44,12 @@ setClassUnion( # ----------------------------------------------------------------------------- # Shared parent of the QTL and GWAS summary statistics collections. # Concrete subclasses (QtlSumStats, GwasSumStats) inherit from -# RangedTupleList and share the ldReference / qcInfo slots (the genome build +# RangedTupleList and share the ldReference / qcOptions slots (the genome build # lives in seqinfo, not a slot). Each element # is one tuple's per-variant GRanges: x[[i]], formerly x$entry[[i]]. # # z / nSamples / maf / nSnps are -# defined once on SumStatsBase (they only delegate to sumStats); subsetChr / +# defined once on SumStatsBase (they only delegate to sumStats); # varY / sumStats / as.data.frame stay on the concrete subclass because # they rely on the tuple shape (3-tuple QtlSumStats, 1-tuple GwasSumStats). # ============================================================================= @@ -58,7 +58,7 @@ setClassUnion( #' @description Virtual base class for QTL and GWAS summary statistics #' collections. Concrete subclasses (\code{QtlSumStats}, \code{GwasSumStats}) #' inherit from \code{\linkS4class{RangedTupleList}} and share the -#' \code{ldReference} / \code{qcInfo} slots, and the genome build in +#' \code{ldReference} / \code{qcOptions} slots, and the genome build in #' \code{seqinfo()}. #' #' Each element is the per-variant \code{GRanges} of one tuple, so @@ -74,19 +74,19 @@ setClassUnion( #' (e.g. for mash, which operates across conditions per variant) has #' \code{NA} there; pipelines that need LD validate its presence when they #' consume the collection. -#' @slot qcInfo A \code{list} recording which QC steps ran. Empty \code{list()} -#' on construction; populated by \code{summaryStatsQc()} with a per-step audit -#' record (filter names, drop counts, liftover target, RAISS settings, etc.). -#' Fine-mapping and TWAS-weights pipelines reject inputs where -#' \code{length(qcInfo(x)) == 0L} -- the slot serves as both the gating -#' flag and the audit trail. +#' @slot qcOptions A \code{list} recording the QC that ran over the +#' collection: the options \code{summaryStatsQc()} was called with and when. +#' Empty \code{list()} on construction. Pipelines that need QC'd summary +#' statistics refuse inputs where \code{length(qcOptions(x)) == 0L}. What +#' QC did to each row is in the \code{qcAudit} column of \code{mcols()}, +#' read as a table with \code{\link{qcInfo}}. #' @export setClass( "SumStatsBase", contains = c("VIRTUAL", "RangedTupleList"), representation( ldReference = "list", - qcInfo = "list" + qcOptions = "list" ), prototype(ldReference = list()) ) @@ -106,43 +106,54 @@ methods::setValidity("SumStatsBase", function(object) { } md <- mcols(object) tupleKey <- map(tupleCols, .ssKeyColumn, md = md) - spans <- range(object) - rangeKey <- map_chr(as.list(spans), .ssSpanLabel) + rangeKey <- .keyEmptyElements(object, .rtlRangeKeys(object)) keys <- exec(str_c, !!!c(tupleKey, list(rangeKey)), sep = "|") anyDuplicated(keys) > 0L } +# Span keys with every EMPTY element given a key of its own. An empty element +# has no span to key on -- it is a region QC screened out, or one a filter() +# emptied -- and several of them in one study are the normal outcome of a PIP +# screen over a block-split study, not duplicates. Its block names it when +# the collection carries `blockId`; otherwise its position does, so two empty +# elements only collide when they claim the same block. # @noRd -.ssKeyColumn <- function(cn, md) { - as.character(md[[cn]]) +.keyEmptyElements <- function(object, spanKeys) { + empty <- lengths(object) == 0L + if (!any(empty)) { + return(spanKeys) + } + md <- mcols(object, use.names = FALSE) + block <- if (is_in("blockId", colnames(md))) { + as.character(md$blockId) + } else { + rep(NA_character_, length(object)) + } + emptyKey <- if_else( + is.na(block), + str_c("\u0001row:", seq_along(spanKeys)), + str_c("\u0001block:", block) + ) + if_else(empty, emptyKey, spanKeys) } -# A stable label for one element's span; empty elements collapse to "". # @noRd -.ssSpanLabel <- function(g) { - if (length(g) == 0L) { - return("") - } - str_c( - as.character(seqnames(g))[[1L]], - ":", - min(start(g)), - "-", - max(end(g)) - ) +.ssKeyColumn <- function(cn, md) { + as.character(md[[cn]]) } # Stitch a tuple's elements back into one GRanges, optionally restricted to a -# region. The seqname split means one tuple can own several elements, but the -# accessor contract is still "one GRanges per tuple"; `ranges` lets a caller -# pull just the part they want instead of materialising the whole span. +# window. The seqname split means one tuple can own several elements, but the +# accessor contract is still "one GRanges per tuple". `window` is for the +# pipelines, which score a pair over the span its weights reach; the public +# accessors return the whole tuple and leave narrowing to subsetByOverlaps(). # @noRd -.ssStitchElements <- function(x, idx, ranges = NULL) { +.ssStitchElements <- function(x, idx, window = NULL) { gr <- .rtlGatherElements(x, idx) - if (is.null(ranges)) { + if (is.null(window)) { return(gr) } - win <- .asGRegion(ranges) + win <- .assertRegionGRanges(window, "`window`") onWindowChrom <- is_in( as.character(seqnames(gr)), as.character(seqnames(win)) @@ -183,49 +194,245 @@ methods::setValidity("SumStatsBase", function(object) { ) } +# The genome build as one string for a show() line. genome() answers per +# SEQLEVEL, so interpolating it directly prints the line once per chromosome +# of a multi-chromosome collection, and not at all for one spanning none. +# @noRd +.showGenomeBuild <- function(x) { + build <- unique(discard(GenomeInfoDb::genome(x), is.na)) + if (length(build) == 0L) { + return("NA") + } + str_flatten(build, ", ") +} + +# ---- The genome build a result carries -------------------------------------- + +# The builds `x` names: a ranged object's seqinfo genome, a QtlDataset's +# experiments', a MultiStudyQtlDataset's studies' and summary statistics', +# a plain list's elements'. An unset (NA) build names nothing, and neither +# does an object without ranges (NULL, an unranged SummarizedExperiment). +# @noRd +.namedBuilds <- function(x) { + builds <- if (is.list(x) && !is.object(x)) { + list_c(map(x, .namedBuilds), ptype = character()) + } else if (is(x, "MultiStudyQtlDataset")) { + c( + list_c(map(as.list(x), .namedBuilds), ptype = character()), + .namedBuilds(sumStats(x)) + ) + } else if (is(x, "MultiAssayExperiment")) { + list_c( + map(as.list(MultiAssayExperiment::experiments(x)), .namedBuilds), + ptype = character() + ) + } else if (.isRangedInput(x)) { + GenomeInfoDb::genome(x) + } else { + character(0) + } + unique(discard(unname(as.character(builds)), is.na)) +} + +# @noRd +.isRangedInput <- function(x) { + is(x, "GenomicRanges") || + is(x, "GRangesList") || + is(x, "RangedSummarizedExperiment") +} + +# The one build `x` names, or NA when it names none -- or several, which a +# collection assembled from mismatched parts can. +# @noRd +.oneBuild <- function(x) { + builds <- .namedBuilds(x) + if (length(builds) == 1L) builds else NA_character_ +} + +# The build a result computed from `inputs` (a list) carries: the one they +# name, or NA when none names one. Inputs naming different builds are +# refused, as GenomeInfoDb refuses to merge ranges whose genomes differ: +# positions on one build do not place variants on another. +# @noRd +.inputsBuild <- function(inputs, caller) { + builds <- unique(list_c(map(inputs, .namedBuilds), ptype = character())) + if (length(builds) > 1L) { + abort(c( + glue( + "{caller}: the inputs name different genome builds ", + "({str_flatten(builds, ', ')})." + ), + i = str_c( + "Positions on one build do not place variants on another: ", + "lift the inputs onto one build, or, when the names only ", + "spell the same build differently, give them one name with ", + "genome(x) <- \"\"." + ) + )) + } + if (length(builds) == 0L) NA_character_ else builds +} + +# `x` with its seqinfo naming `build` for every sequence, or unchanged when +# the build is unknown (NA). +# @noRd +.withGenome <- function(x, build) { + if (is.null(x) || is.na(build)) { + return(x) + } + GenomeInfoDb::`genome<-`(x, value = build) +} + #' @rdname qcInfo #' @examples #' data(qtlSumStatsExample) #' qcInfo(qtlSumStatsExample) #' @export -setMethod("qcInfo", "SumStatsBase", function(x) x@qcInfo) +setMethod("qcInfo", "SumStatsBase", function(x) { + .asViewDataFrame(.ssQcInfoTable(x)) +}) + +#' @rdname qcOptions +#' @examples +#' data(qtlSumStatsExample) +#' qcOptions(qtlSumStatsExample) +#' @export +setMethod("qcOptions", "SumStatsBase", function(x) x@qcOptions) + +# The per-row QC audit as a table: one row per tuple, its identity columns, +# then each scalar count the audits record, a nested count named by its path +# (contentFilters.nDropped). A row a step did not run on is NA there; the +# per-variant tables an audit can also hold are read with qcDiagnostics(). +# @noRd +.ssQcInfoTable <- function(x) { + ids <- intersect( + c("study", "context", "trait", "blockId"), + .tupleColumnNames(x) + ) + base <- as_tibble(set_names(map(ids, .ssIdentityColumn, x = x), ids)) + audits <- mcols(x, use.names = FALSE)$qcAudit + if (is.null(audits)) { + return(base) + } + bind_cols(base, .qcAuditRows(as.list(audits))) +} + +# @noRd +.ssIdentityColumn <- function(cn, x) { + as.character(.tupleColumn(x, cn)) +} + +# One column per scalar count any audit records, NA for the rows without it. +# @noRd +.qcAuditRows <- function(audits) { + flat <- map(audits, .qcAuditScalars) + cols <- unique(list_c(map(flat, names), ptype = character())) + as_tibble( + set_names(map(cols, .qcAuditColumn, flat = flat), cols), + .rows = length(audits) + ) +} + +# @noRd +.qcAuditColumn <- function(col, flat) { + list_c(map(flat, col, .default = NA)) +} + +# One audit's scalar counts as a flat named list, a nested count named by its +# path. Tables and other non-scalar values are left out. +# @noRd +.qcAuditScalars <- function(a, prefix = "") { + if (!is.list(a) || is.data.frame(a) || length(a) == 0L) { + return(list()) + } + list_flatten(unname(map2(a, str_c(prefix, names(a)), .qcAuditLeaf))) +} + +# @noRd +.qcAuditLeaf <- function(v, name) { + if (is.list(v) && !is.data.frame(v)) { + return(.qcAuditScalars(v, str_c(name, "."))) + } + if (is.atomic(v) && length(v) == 1L) { + return(set_names(list(v), name)) + } + list() +} #' @rdname qcDiagnostics #' @examples #' data(qtlSumStatsExample) #' qcDiagnostics(qtlSumStatsExample) #' @export -setMethod("qcDiagnostics", "SumStatsBase", function(x, entry = 1L) { - qc <- x@qcInfo - if (length(qc) == 0L) { - return(NULL) +setMethod( + "qcDiagnostics", + "SumStatsBase", + function(x, studyName = NULL, context = NULL, trait = NULL) { + audits <- mcols(x, use.names = FALSE)$qcAudit + if (is.null(audits)) { + return(NULL) + } + idx <- .ssRowIndexFor(x, studyName, context, trait) + tables <- compact(map(audits[idx], "ldMismatchDiagnostics")) + if (length(tables) == 0L) { + return(NULL) + } + # A GWAS study split across rows checked each row on its own, so its + # tables stack, one row per variant, as sumStats() stitches them. + DataFrame(bind_rows(tables), check.names = FALSE) } - audits <- qc$entryAudit - if (is.null(audits)) { +) + +# Row `i`'s QC audit, or NULL when QC recorded none for it. +# @noRd +.rowQcAudit <- function(x, i) { + audits <- mcols(x, use.names = FALSE)$qcAudit + if (is.null(audits) || i > length(audits)) { return(NULL) } - if (is.null(entry)) { - out <- map(audits, "ldMismatchDiagnostics") - keep <- !map_lgl(out, is.null) - if (!any(keep)) { - return(NULL) + audits[[i]] +} + +# Before each row's QC audit moved into mcols(), a summary-statistics +# collection held its whole QC record in a `qcInfo` slot: the options, and +# under `entryAudit` one audit per row. An object saved then still carries +# that slot as an attribute; it is split into the `qcOptions` slot and the +# `qcAudit` column. +#' @rdname updateObject-methods +#' @export +setMethod( + "updateObject", + "SumStatsBase", + function(object, ..., verbose = FALSE) { + if (isTRUE(verbose)) { + message(str_c("updateObject(object = '", class(object)[[1L]], "')")) } - set_names(out[keep], seq_along(audits)[keep]) - } else { - if ( - !is.numeric(entry) || - length(entry) != 1L || - entry < 1L || - entry > length(audits) - ) { - msg <- glue( - "`entry` must be a single integer in 1:{length(audits)}." - ) - abort(msg) + old <- attr(object, "qcInfo", exact = TRUE) + if (is.null(old)) { + return(methods::callNextMethod(object, ..., verbose = verbose)) } - audits[[as.integer(entry)]]$ldMismatchDiagnostics + .ssMigrateQcInfo(object, old) } -}) +) + +# @noRd +.ssMigrateQcInfo <- function(object, old) { + attr(object, "qcInfo") <- NULL + attr(object, "qcOptions") <- old[setdiff(names(old), "entryAudit")] + audits <- old$entryAudit + if (length(audits) == 0L) { + return(object) + } + if (length(audits) != length(object)) { + warn(glue( + "updateObject(): the saved QC record holds {length(audits)} row ", + "audit(s) for {length(object)} row(s), so they cannot be matched ", + "to rows and are dropped; qcOptions() keeps the settings." + )) + return(object) + } + `$<-`(object, "qcAudit", S4Vectors::SimpleList(audits)) +} #' @rdname ldReference #' @examples @@ -258,53 +465,35 @@ setMethod("studyName", "SumStatsBase", function(x) { setMethod( "z", "SumStatsBase", - function( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL - ) { - sel <- list( - study = studyName, + function(x, studyName = NULL, context = NULL, trait = NULL) { + mcols(sumStats( + x, + studyName = studyName, context = context, - trait = trait, - annotateSignificance = annotateSignificance, - ranges = ranges - ) - mcols(exec(sumStats, x, !!!sel))$Z + trait = trait + ))$Z } ) -#' @rdname nSamples +#' @rdname sampleSize #' @examples #' data(qtlSumStatsExample) -#' nSamples(qtlSumStatsExample) +#' head(sampleSize(qtlSumStatsExample)) #' @export setMethod( - "nSamples", + "sampleSize", "SumStatsBase", - function( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL - ) { - sel <- list( - study = studyName, + function(x, studyName = NULL, context = NULL, trait = NULL) { + mcols(sumStats( + x, + studyName = studyName, context = context, - trait = trait, - annotateSignificance = annotateSignificance, - ranges = ranges - ) - mcols(exec(sumStats, x, !!!sel))$N + trait = trait + ))$N } ) -# pval / coef / se are first-class alongside z / nSamples: they read the +# pval / coef / se are first-class alongside z / sampleSize: they read the # optional P / BETA / SE mcols and return NULL when the entry does not carry # them (DataFrame `$` semantics), so a p-value-primary sumstats (e.g. TensorQTL # cis output) is an equal citizen to a Z-primary GWAS sumstats. @@ -316,22 +505,13 @@ setMethod( setMethod( "pval", "SumStatsBase", - function( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL - ) { - sel <- list( - study = studyName, + function(x, studyName = NULL, context = NULL, trait = NULL) { + mcols(sumStats( + x, + studyName = studyName, context = context, - trait = trait, - annotateSignificance = annotateSignificance, - ranges = ranges - ) - mcols(exec(sumStats, x, !!!sel))$P + trait = trait + ))$P } ) @@ -343,23 +523,13 @@ setMethod( setMethod( "coef", "SumStatsBase", - function( - object, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL, - ... - ) { - sel <- list( - study = studyName, + function(object, studyName = NULL, context = NULL, trait = NULL, ...) { + mcols(sumStats( + object, + studyName = studyName, context = context, - trait = trait, - annotateSignificance = annotateSignificance, - ranges = ranges - ) - mcols(exec(sumStats, object, !!!sel))$BETA + trait = trait + ))$BETA } ) @@ -371,22 +541,13 @@ setMethod( setMethod( "se", "SumStatsBase", - function( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL - ) { - sel <- list( - study = studyName, + function(x, studyName = NULL, context = NULL, trait = NULL) { + mcols(sumStats( + x, + studyName = studyName, context = context, - trait = trait, - annotateSignificance = annotateSignificance, - ranges = ranges - ) - mcols(exec(sumStats, x, !!!sel))$SE + trait = trait + ))$SE } ) @@ -398,22 +559,13 @@ setMethod( setMethod( "maf", "SumStatsBase", - function( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL - ) { - sel <- list( - study = studyName, + function(x, studyName = NULL, context = NULL, trait = NULL) { + mc <- mcols(sumStats( + x, + studyName = studyName, context = context, - trait = trait, - annotateSignificance = annotateSignificance, - ranges = ranges - ) - mc <- mcols(exec(sumStats, x, !!!sel)) + trait = trait + )) if (is_in("MAF", colnames(mc))) mc$MAF else NULL } ) @@ -426,22 +578,13 @@ setMethod( setMethod( "af", "SumStatsBase", - function( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL - ) { - sel <- list( - study = studyName, + function(x, studyName = NULL, context = NULL, trait = NULL) { + mc <- mcols(sumStats( + x, + studyName = studyName, context = context, - trait = trait, - annotateSignificance = annotateSignificance, - ranges = ranges - ) - mc <- mcols(exec(sumStats, x, !!!sel)) + trait = trait + )) if (is_in("AF", colnames(mc))) mc$AF else NULL } ) @@ -450,9 +593,11 @@ setMethod( # Variant-level replacement # ============================================================================= -# The element index the selectors pin. GwasSumStats is keyed by study alone -# and QtlSumStats by the (study, context, trait) tuple; branching here rather -# than adding an internal generic keeps one copy of each replacement body. +# The element indices the selectors pin: every row of the study for a +# GwasSumStats, which is keyed by study alone and split by chromosome or LD +# block, and the one (study, context, trait) row for a QtlSumStats. Branching +# here rather than adding an internal generic keeps one copy of each +# replacement body. # @noRd .ssRowIndexFor <- function(x, studyName, context, trait) { if (methods::is(x, "QtlSumStats")) { @@ -462,29 +607,45 @@ setMethod( .gwasSelectStudy(x, studyName) } -# Write one per-variant column onto the pinned element and put it back. The -# `[[<-` route rebuilds the collection and re-runs validity, so a write that -# would break the identity invariants is refused rather than stored. +# Write one per-variant column onto the pinned elements and put them back. +# `idx` can name several elements -- a GWAS study split by chromosome or LD +# block -- and `values` runs over them in `idx` order, the order sumStats() +# stitches them in. The rebuild re-runs validity, so a write that would break +# the identity invariants is refused rather than stored. # @noRd .ssWriteVariantColumn <- function(x, idx, column, values) { - el <- x[[idx]] - mcols(el)[[column]] <- values - x[[idx]] <- el - x + pieces <- split( + values, + factor(rep(seq_along(idx), lengths(x)[idx]), levels = seq_along(idx)) + ) + elements <- as.list(x) + elements[idx] <- map2( + elements[idx], + pieces, + .ssSetVariantColumn, + column = column + ) + .rtlRebuild(x, elements, seq_along(x)) } -# Positional replacement. The vector is taken to be in the element's own -# variant order, so length is the only thing checkable -- and it is checked -# hard: a recycled or truncated frequency vector is silently wrong, which is -# exactly the failure the GRanges form exists to avoid. +# @noRd +.ssSetVariantColumn <- function(el, values, column) { + mcols(el)[[column]] <- unname(values) + el +} + +# Positional replacement. The vector is taken to be in sumStats()'s variant +# order for the selection, so length is the only thing checkable -- and it is +# checked hard: a recycled or truncated frequency vector is silently wrong, +# which is exactly the failure fillFromReference() exists to avoid. # @noRd .ssVariantColumnPositional <- function(x, idx, column, value) { - n <- length(x[[idx]]) + n <- sum(lengths(x)[idx]) if (length(value) != n) { abort(glue( "{column}: a positional replacement needs one value per variant ", - "({n}); got {length(value)}. Pass a GRanges carrying A1/A2 to ", - "match on (chrom, pos, A1, A2) instead." + "({n}, in sumStats() order); got {length(value)}. Use ", + "fillFromReference() to match on (chrom, pos, A1, A2) instead." )) } .ssWriteVariantColumn(x, idx, column, as.numeric(value)) @@ -504,24 +665,28 @@ setMethod( ) } -# The payload column of a replacement GRanges. A1/A2 are the match key, so -# exactly one other mcols column is the values; requiring that rather than a -# fixed name keeps the caller from having to know the stored column names. +# The values column of a fillFromReference() reference. A1/A2 are the match +# key; the values are the column named like the target when the reference +# has one (a panel GRanges carries several), else its one other column. # @noRd .ssReplacementPayload <- function(value, column) { mc <- mcols(value) nms <- colnames(mc) if (!all(is_in(c("A1", "A2"), nms))) { abort(glue( - "{column}: a GRanges replacement must carry A1 and A2 in ", + "fillFromReference: `reference` must carry A1 and A2 in ", "mcols() so an allele swap can be detected." )) } + if (is_in(column, nms)) { + return(as.numeric(mc[[column]])) + } payload <- setdiff(nms, c("A1", "A2")) if (length(payload) != 1L) { abort(glue( - "{column}: a GRanges replacement must carry exactly one value ", - "column besides A1/A2 (got {length(payload)}", + "fillFromReference: `reference` has no `{column}` column, so ", + "its values must be the one column besides A1/A2 (got ", + "{length(payload)}", "{if (length(payload)) str_c(': ', str_flatten(payload, ', '))", " else ''})." )) @@ -529,21 +694,23 @@ setMethod( as.numeric(mc[[payload]]) } -# Matched replacement. Ids are rebuilt from both sides and paired with -# matchVariants, so a chr-prefix or separator difference does not read as -# no-overlap. A variant the replacement does not name becomes NA -- its value -# is unknown, not unchanged. `directional` says whether an allele swap -# inverts the quantity: AF goes to 1 - AF, while MAF (min(af, 1 - af)) and N -# are swap-invariant, and complementing those would corrupt them. +# Matched fill. Ids are rebuilt from both sides and paired with matchVariants, +# so a chr-prefix or separator difference does not read as no-overlap. A +# variant the reference does not name becomes NA -- its value is unknown, not +# unchanged. `directional` says whether an allele swap inverts the quantity: +# AF goes to 1 - AF, while MAF (min(af, 1 - af)) and N are swap-invariant, +# and complementing those would corrupt them. # @noRd .ssVariantColumnMatched <- function(x, idx, column, value, directional) { vals <- .ssReplacementPayload(value, column) - el <- x[[idx]] + # The whole selection at once, so a variant the reference names is + # "unused" only when it is in none of the study's rows. + el <- .ssStitchElements(x, idx) m <- matchVariants(.ssVariantKeys(el), .ssVariantKeys(value)) if (length(m$idxA) == 0L) { abort(glue( - "{column}: no variant in the replacement matches this entry on ", - "(chrom, pos, A1, A2)." + "fillFromReference: no variant in `reference` matches the ", + "selection on (chrom, pos, A1, A2)." )) } picked <- vals[m$idxB] @@ -552,21 +719,33 @@ setMethod( } out <- rep(NA_real_, length(el)) out[m$idxA] <- picked - unused <- length(value) - length(m$idxB) + .ssWarnUnmatched( + column, + length(value) - length(m$idxB), + length(value), + length(el) - length(m$idxA), + length(el) + ) + .ssWriteVariantColumn(x, idx, column, out) +} + +# The two ways a matched fill falls short, each said with its count: reference +# variants the selection does not hold, and selected variants left NA. +# @noRd +.ssWarnUnmatched <- function(column, unused, nReference, missed, nSelected) { if (unused > 0L) { warn(glue( - "{column}: {unused} of {length(value)} replacement variant(s) ", - "are not in this entry and were ignored." + "fillFromReference({column}): {unused} of {nReference} reference ", + "variant(s) are not in the selection and were ignored." )) } - missed <- length(el) - length(m$idxA) if (missed > 0L) { warn(glue( - "{column}: {missed} of {length(el)} entry variant(s) are not in ", - "the replacement and were set NA." + "fillFromReference({column}): {missed} of {nSelected} selected ", + "variant(s) are not in `reference` and were set NA." )) } - .ssWriteVariantColumn(x, idx, column, out) + invisible(NULL) } # @noRd @@ -579,22 +758,62 @@ setMethod( ) } -# @noRd -.ssReplaceMatched <- function( +#' @title Fill A Per-Variant Column From A Reference +#' @description Fill the \code{AF}, \code{MAF} or \code{N} column of a +#' \code{GwasSumStats} / \code{QtlSumStats} selection from a reference +#' \code{GRanges}, pairing variants on \code{(chrom, pos, A1, A2)} -- the +#' usual case being effect-allele frequencies the source file did not +#' carry, taken from a reference panel. Order does not matter. +#' +#' An allele swap sends \code{AF} to \code{1 - AF}, so a flipped match is +#' complemented; \code{MAF} is \code{min(af, 1 - af)} and \code{N} is a +#' count, both swap-invariant, so neither is. A selected variant the +#' reference does not name is set \code{NA} -- its value is unknown, not +#' unchanged -- with a warning, and so is a reference variant the selection +#' does not hold; no overlap at all is an error. +#' +#' Values already in \code{\link{sumStats}} order are assigned positionally +#' instead, with \code{af(x) <- value} (see +#' \code{\link{variantColumnReplace}}). +#' @param x A \code{GwasSumStats} or \code{QtlSumStats} object. +#' @param reference A \code{GRanges} carrying \code{A1} and \code{A2} in +#' \code{mcols()} plus the values: a column named like \code{column}, or +#' else its one column besides \code{A1}/\code{A2}. +#' @param column Which column to fill: \code{"AF"} (default), \code{"MAF"} or +#' \code{"N"}. +#' @param studyName,context,trait Selectors pinning one study (every row of a +#' GWAS study) or one \code{QtlSumStats} entry; \code{context} and +#' \code{trait} are \code{QtlSumStats}-only. +#' @return \code{x}, with the selection's column filled. +#' @examples +#' data(qtlSumStatsExample) +#' ref <- sumStats(qtlSumStatsExample) +#' S4Vectors::mcols(ref) <- S4Vectors::DataFrame( +#' A1 = ref$A1, +#' A2 = ref$A2, +#' AF = runif(length(ref)) +#' ) +#' x <- fillFromReference(qtlSumStatsExample, ref, "AF") +#' head(af(x)) +#' @importFrom checkmate assertClass +#' @export +fillFromReference <- function( x, - column, - value, - directional, - studyName, - context, - trait + reference, + column = c("AF", "MAF", "N"), + studyName = NULL, + context = NULL, + trait = NULL ) { + assertClass(x, "SumStatsBase") + assertClass(reference, "GRanges") + column <- arg_match(column) .ssVariantColumnMatched( x, .ssRowIndexFor(x, studyName, context, trait), column, - value, - directional + reference, + directional = identical(column, "AF") ) } @@ -608,24 +827,6 @@ setReplaceMethod( } ) -#' @rdname variantColumnReplace -#' @export -setReplaceMethod( - "af", - signature(x = "SumStatsBase", value = "GRanges"), - function(x, studyName = NULL, context = NULL, trait = NULL, ..., value) { - .ssReplaceMatched( - x, - "AF", - value, - directional = TRUE, - studyName, - context, - trait - ) - } -) - #' @rdname variantColumnReplace #' @export setReplaceMethod( @@ -639,49 +840,13 @@ setReplaceMethod( #' @rdname variantColumnReplace #' @export setReplaceMethod( - "maf", - signature(x = "SumStatsBase", value = "GRanges"), - function(x, studyName = NULL, context = NULL, trait = NULL, ..., value) { - .ssReplaceMatched( - x, - "MAF", - value, - directional = FALSE, - studyName, - context, - trait - ) - } -) - -#' @rdname variantColumnReplace -#' @export -setReplaceMethod( - "nSamples", + "sampleSize", signature(x = "SumStatsBase", value = "numeric"), function(x, studyName = NULL, context = NULL, trait = NULL, ..., value) { .ssReplacePositional(x, "N", value, studyName, context, trait) } ) -#' @rdname variantColumnReplace -#' @export -setReplaceMethod( - "nSamples", - signature(x = "SumStatsBase", value = "GRanges"), - function(x, studyName = NULL, context = NULL, trait = NULL, ..., value) { - .ssReplaceMatched( - x, - "N", - value, - directional = FALSE, - studyName, - context, - trait - ) - } -) - #' @rdname nSnps #' @examples #' data(qtlSumStatsExample) @@ -690,22 +855,13 @@ setReplaceMethod( setMethod( "nSnps", "SumStatsBase", - function( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL - ) { - sel <- list( - study = studyName, + function(x, studyName = NULL, context = NULL, trait = NULL) { + length(sumStats( + x, + studyName = studyName, context = context, - trait = trait, - annotateSignificance = annotateSignificance, - ranges = ranges - ) - length(exec(sumStats, x, !!!sel)) + trait = trait + )) } ) @@ -734,6 +890,22 @@ setMethod( #' \code{mcols} names the entry each row used (\code{NA} for a fit derived #' from individual-level data). Used downstream to check that the rows a #' pipeline combines share an LD reference. +#' @section Narrowed rows: Each row records in its \code{fitVariants} column +#' the ids of the variants its fit was made with (none for a row without a +#' fit). A row narrowed since -- by \code{endoapply()} or \code{[[<-} -- +#' keeps its fit as it was, so every reader of the fit warns, with +#' condition class \code{pecotmrFitCoverage}, when a row holds fewer +#' variants than its fit describes. The readers are the accessors +#' (\code{susieFit()}, \code{lbf()}, \code{cvResult()}, +#' \code{credibleSetSummary()} and the fSuSiE views), +#' \code{computeCsCorrelation()}, \code{susieResult()}, +#' \code{extractCsInfo()}, \code{extractTopPipInfo()}, +#' \code{writeGwasVcf()}, and the pipelines that score the fits: +#' \code{colocPipeline(adjustPips = FALSE)}, \code{qtlEnrichmentPipeline()} +#' and \code{twasWeightsPipeline()}. Values held per variant, such as +#' \code{topLoci()}, are narrowed with the row and do not warn. Nothing is +#' rescaled: \code{\link{intersectVariants}} restricts a fit explicitly, as +#' \code{colocPipeline()} does by default. #' @export setClass( "FineMappingResultBase", @@ -767,7 +939,6 @@ setMethod("methodNames", "FineMappingResultBase", function(x) { unique(as.character(x$method)) }) - #' @noRd setMethod( "adjustPips", @@ -777,8 +948,8 @@ setMethod( return(x) } # Entries sharing no variant with `keepVariants` have nothing to - # renormalize, so they are DROPPED -- matching subsetRegion's rule that - # elements trimming to zero variants go away. Every other failure (a + # renormalize, so they are DROPPED, leaving no entry with zero + # variants. Every other failure (a # fit that cannot be honestly subset, a slot whose width disagrees with # the variant count) PROPAGATES: silently leaving those entries # unadjusted mixes adjusted and unadjusted fits in one object, which is @@ -826,11 +997,16 @@ setMethod( "susieFit", value = S4Vectors::SimpleList(map(entries, susieFit)) ) - `[[<-`( + withCv <- `[[<-`( withFit, "cvResult", value = S4Vectors::SimpleList(map(entries, cvResult)) ) + `[[<-`( + withCv, + "fitVariants", + value = IRanges::CharacterList(map(entries, .fmRowFitVariants)) + ) } # Rebuild a fine-mapping collection from adjusted entries, keeping every @@ -838,7 +1014,7 @@ setMethod( # @noRd .fmrFromEntries <- function(x, entries) { grl <- `mcols<-`( - GenomicRanges::GRangesList(map(entries, variants)), + .rtlBindElements(map(entries, variants)), value = .withEntryPayload(mcols(x, use.names = FALSE), entries) ) # The rows keep their keys in mcols, so the references go across as is. @@ -924,7 +1100,17 @@ setMethod( #' @rdname retainedMass #' @export -setMethod("retainedMass", "FineMappingResultBase", function(x) { +setMethod( + "retainedMass", + "FineMappingResultBase", + function(x) { + .asViewDataFrame(.rcMassTable(x = x)) + } +) + +# retainedMass() as a tibble. +# @noRd +.rcMassTable <- function(x) { if (nrow(x) == 0L) { return(.rcEmptyMass(x)) } @@ -933,7 +1119,7 @@ setMethod("retainedMass", "FineMappingResultBase", function(x) { return(.rcEmptyMass(x)) } bind_rows(parts) -}) +} # The zero-row result, carrying the SAME identity columns the populated one # would. Returning a bare (effect, retainedMass, nVariants) tibble instead @@ -1012,9 +1198,10 @@ setMethod("retainedMass", "FineMappingResultBase", function(x) { as.character(md[[cn]])[[i]] } -# Select the single FineMappingRow addressed by a (tuple / region) key. Each -# concrete subclass implements this with its own row selector; the delegating -# accessors below then live once on the base and route through it. +# Select the single FineMappingRow addressed by a tuple key or a GWAS block's +# `blockId`. Each concrete subclass +# implements this with its own row selector; the delegating accessors below +# then live once on the base and route through it. setGeneric(".fmrSelectEntry", function(x, ...) { standardGeneric(".fmrSelectEntry") }) @@ -1030,7 +1217,7 @@ setMethod( context = NULL, trait = NULL, method = NULL, - region = NULL, + blockId = NULL, coverage = 0.95, minPurity = NULL ) { @@ -1039,27 +1226,32 @@ setMethod( # partial selectors -> aggregate every matching entry's credible sets, # prefixed with the row identity (study/context/trait/blockId/method). # `minPurity` is an independent CS-quality filter, orthogonal to - # coverage. - .fmrAggregateView( + # coverage. Ranged either way, so it narrows with subsetByOverlaps(). + tbl <- .fmrAggregateView( x, studyName = studyName, context = context, trait = trait, method = method, - region = region, + blockId = blockId, perEntry = .fmrRowCs, viewArgs = list( coverage = coverage, minPurity = minPurity ) ) + .withGenome(.variantTableGRanges(tbl), .oneBuild(x)) } ) #' @rdname lbf #' @export setMethod("lbf", "FineMappingResultBase", function(x) { - .fmrAggregateView(x, perEntry = .fmrRowLbf) + .fitCoverageCheckedRows(x, "lbf()") + .withGenome( + .variantTableGRanges(.fmrAggregateView(x, perEntry = .fmrRowLbf)), + .oneBuild(x) + ) }) #' @rdname credibleSetSummary @@ -1068,23 +1260,50 @@ setMethod( "credibleSetSummary", "FineMappingResultBase", function(x, coverage = 0.95) { - .fmrAggregateView( - x, - perEntry = .fmrRowCredibleSetSummary, - viewArgs = list(coverage = coverage) - ) + .fitCoverageCheckedRows(x, "credibleSetSummary()") + .asViewDataFrame(.fmrCredibleSetSummaryTable( + x = x, + coverage = coverage + )) } ) +# credibleSetSummary() as a tibble. +# @noRd +.fmrCredibleSetSummaryTable <- function(x, coverage = 0.95) { + .fmrAggregateView( + x, + perEntry = .fmrRowCredibleSetSummary, + viewArgs = list(coverage = coverage) + ) +} + #' @rdname fsusieCredibleBand #' @export setMethod("fsusieCredibleBand", "FineMappingResultBase", function(x) { - .fmrAggregateView(x, perEntry = .fmrRowFsusieCredibleBand) + .fitCoverageCheckedRows(x, "fsusieCredibleBand()") + .withGenome( + .bandTableGRanges( + .fmrAggregateView(x, perEntry = .fmrRowFsusieCredibleBand) + ), + .oneBuild(x) + ) }) #' @rdname fsusieTraitEffects #' @export -setMethod("fsusieTraitEffects", "FineMappingResultBase", function(x) { +setMethod( + "fsusieTraitEffects", + "FineMappingResultBase", + function(x) { + .fitCoverageCheckedRows(x, "fsusieTraitEffects()") + .asViewDataFrame(.fsusieTraitEffectsTable(x = x)) + } +) + +# fsusieTraitEffects() as a tibble, for the writers. +# @noRd +.fsusieTraitEffectsTable <- function(x) { # Not .fmrAggregateView(): the per-entry payload carries only the fit, and # this view also needs the row's `jointTraits` column for the trait names. meta <- .fmrRowMetadata(x) @@ -1098,17 +1317,18 @@ setMethod("fsusieTraitEffects", "FineMappingResultBase", function(x) { return(bind_cols(slice(meta, integer(0)), .emptyTraitEffects())) } .rbindAligned(parts) -}) +} #' @rdname fsusieAffectedRegions #' @export setMethod("fsusieAffectedRegions", "FineMappingResultBase", function(x) { + .fitCoverageCheckedRows(x, "fsusieAffectedRegions()") perRow <- map(seq_len(nrow(x)), .fsusieEntryAffectedRegions, x = x) grs <- perRow[lengths(perRow) > 0L] if (length(grs) == 0L) { return(GenomicRanges::GRanges()) } - exec(c, !!!grs) + .withGenome(exec(c, !!!grs), .oneBuild(x)) }) #' @rdname topLoci @@ -1123,71 +1343,48 @@ setMethod( context = NULL, trait = NULL, method = NULL, - region = NULL, - minPurity = NULL, - raw = FALSE + blockId = NULL, + minPurity = NULL ) { - # The five selectors travel together to both branches, so they are - # named once and spliced rather than relisted twice. sel <- list( - study = studyName, + studyName = studyName, context = context, trait = trait, method = method, - region = region + blockId = blockId ) - # raw = TRUE hands back the stored canonical table verbatim, which is - # a data.frame by definition -- there is no posterior projection to - # put on a range. - if (isTRUE(raw)) { - return(exec(.fmrbTopLociTable, x, !!!sel, list(raw = TRUE))) - } # The per-variant table first -- bare when the selectors pin one # entry, else the matching rows' tables stacked with row-identity # columns -- then one conversion to ranges. Converting last is what # lets the aggregate form be a GRanges too: the identity columns just # become mcols, where the old type = "GRanges" branch had to refuse # anything but a single pinned entry. - tbl <- exec( - .fmrbTopLociTable, + tbl <- .fmrbTopLociTable( x, - !!!sel, + sel, list(signalCutoff = signalCutoff, minPurity = minPurity) ) - .fmeTopLociGRanges(tbl) + .withGenome(.variantTableGRanges(tbl), .oneBuild(x)) } ) - -# The per-variant top-loci table: the stored table verbatim (raw) or the -# projected posterior view, selected by `viewArgs`. Both stack with -# row-identity columns when the selectors match more than one entry. The +# The per-variant top-loci table: the projected posterior view `viewArgs` +# configures, stacked with row-identity columns when the selectors match more +# than one entry. The # caller converts to ranges; this stays a table so the aggregate form can be # stacked before conversion. # @noRd -.fmrbTopLociTable <- function( - x, - studyName, - context, - trait, - method, - region, - viewArgs -) { - .fmrAggregateView( +.fmrbTopLociTable <- function(x, selectors, viewArgs) { + exec( + .fmrAggregateView, x, - studyName = studyName, - context = context, - trait = trait, - method = method, - region = region, + !!!selectors, perEntry = .fmrRowTopLoci, viewArgs = viewArgs ) } -# raw = TRUE hands back the stored canonical table verbatim, so the -# posterior-view projection does not apply -- and marginal effects are -# not a posterior view, so they stay a table rather than ranges. +# Marginal effects are per variant, so they come back ranged like the +# posterior view. #' @rdname marginalEffects #' @export setMethod( @@ -1195,37 +1392,81 @@ setMethod( "FineMappingResultBase", function( x, - maxPval = NULL, studyName = NULL, context = NULL, trait = NULL, method = NULL, - region = NULL + blockId = NULL ) { # Selectors pinning one entry -> that entry's bare marginal table; no / # partial selectors -> aggregate every matching entry's marginals, # prefixed with the row identity (study/context/trait/blockId/method). - .fmrAggregateView( + tbl <- .fmrAggregateView( x, studyName = studyName, context = context, trait = trait, method = method, - region = region, - perEntry = .fmrRowMarginalEffects, - viewArgs = list(maxPval = maxPval) + blockId = blockId, + perEntry = .fmrRowMarginalEffects ) + .withGenome(.variantTableGRanges(tbl), .oneBuild(x)) } ) -#' @rdname genomicRegion -#' @examples -#' data(qtlFineMappingExample) -#' genomicRegion(qtlFineMappingExample) +# Before rows recorded the variants their fits were made with, a collection +# had no `fitVariants` column. A fine-mapping fit names its own variants, so +# each row's are read off it; a row whose fit names none (a +# cross-validation-only row, or an unnamed fit) records what it holds, and a +# row with no fit records none. +#' @rdname updateObject-methods #' @export -setMethod("genomicRegion", "FineMappingResultBase", function(x) { - .getRegionColumn(x) -}) +setMethod( + "updateObject", + "FineMappingResultBase", + function(object, ..., verbose = FALSE) { + if (isTRUE(verbose)) { + message(str_c("updateObject(object = '", class(object)[[1L]], "')")) + } + if (is_in("fitVariants", .tupleColumnNames(object))) { + return(methods::callNextMethod(object, ..., verbose = verbose)) + } + fv <- map(seq_along(object), .fmrBackfillFitVariants, x = object) + `$<-`(object, "fitVariants", IRanges::CharacterList(fv)) + } +) + +# @noRd +.fmrBackfillFitVariants <- function(i, x) { + md <- mcols(x, use.names = FALSE) + fit <- md$susieFit[[i]] + if (length(fit) == 0L && is.null(md$cvResult[[i]])) { + return(character(0)) + } + named <- .fitNamedVariants(fit) + if (length(named) > 0L) { + return(normalizeVariantId(named)) + } + .grVariantIds(x[[i]]) +} + +# The variant names a fine-mapping fit carries: its PIPs' names, else the +# columns of its effect matrices (SuSiE, mvSuSiE) or of csd_X (fSuSiE); none +# for an unnamed fit. A null_weight fit gives its effect matrices one more +# column, which susieR names "null"; that is no variant. +# @noRd +.fitNamedVariants <- function(fit) { + if (!is.list(fit)) { + return(character(0)) + } + named <- as.character( + names(fit[["pip"]]) %||% + colnames(fit[["alpha"]]) %||% + colnames(fit[["lbf_variable"]]) %||% + names(fit[["csd_X"]]) + ) + named[named != "null"] +} #' @rdname traitPosition #' @examples @@ -1247,16 +1488,17 @@ setMethod( context = NULL, trait = NULL, method = NULL, - region = NULL + blockId = NULL ) { - .fmrPartsSusieFit(.fmrSelectEntry( + parts <- .fmrSelectEntry( x, studyName = studyName, context = context, trait = trait, method = method, - region = region - )) + blockId = blockId + ) + .fmrPartsSusieFit(.fitCoverageChecked(parts, "susieFit()")) } ) @@ -1271,7 +1513,7 @@ setMethod( context = NULL, trait = NULL, method = NULL, - region = NULL + blockId = NULL ) { # The per-variant weight of the row a selector pins. Defined on the # collection because that is what fineMappingResult() now @@ -1279,14 +1521,14 @@ setMethod( # # The selectors are named, not absorbed by `...`: .fmrSelectEntry is the # only consumer, and each concrete class refuses the ones it does not - # index by (a QtlFineMappingResult has no `region` axis). + # index by (a QtlFineMappingResult has no `blockId` axis). .fmrRowResolveWeights(.fmrSelectEntry( x, studyName = studyName, context = context, trait = trait, method = method, - region = region + blockId = blockId )) } ) @@ -1302,7 +1544,7 @@ setMethod( context = NULL, trait = NULL, method = NULL, - region = NULL + blockId = NULL ) { .fmrPartsVariantIds(.fmrSelectEntry( x, @@ -1310,7 +1552,7 @@ setMethod( context = context, trait = trait, method = method, - region = region + blockId = blockId )) } ) @@ -1320,44 +1562,18 @@ setMethod( setMethod( "variantIds", "SumStatsBase", - function( - x, - studyName = NULL, - context = NULL, - trait = NULL, - annotateSignificance = NULL, - ranges = NULL - ) { + function(x, studyName = NULL, context = NULL, trait = NULL) { # One method covers GwasSumStats and QtlSumStats. The selectors are the - # union: GwasSumStats reads only `study` / `ranges` and refuses the + # union: GwasSumStats reads only `studyName` and refuses the # QtlSumStats-only ones rather than accepting and ignoring them. # # Rendered with the same .grVariantIds() the row classes use, so an id # means the same string whichever object produced it. - sel <- list( - study = studyName, + .grVariantIds(sumStats( + x, + studyName = studyName, context = context, - trait = trait, - annotateSignificance = annotateSignificance, - ranges = ranges - ) - .grVariantIds(exec(sumStats, x, !!!sel)) + trait = trait + )) } ) - -#' @rdname subsetChr -#' @export -setMethod("subsetChr", "SumStatsBase", function(x, chr) { - # The whole-seqname special case of subsetRegion(): one verb, one set of - # semantics. Elements on other chromosomes are dropped rather than kept as - # empties, which is what the seqname split makes natural anyway -- after - # splitting, an element belongs to exactly one chromosome. - chrName <- withChrPrefix(chr) - subsetRegion( - x, - GenomicRanges::GRanges( - chrName, - IRanges::IRanges(1L, .Machine$integer.max) - ) - ) -}) diff --git a/R/AllGenerics.R b/R/AllGenerics.R index ed7ec840..e1ab2277 100644 --- a/R/AllGenerics.R +++ b/R/AllGenerics.R @@ -134,7 +134,7 @@ setGeneric("computeLdScores", function(ldRef, annotations = NULL, ...) { #' \code{plink2Prefix} for a triplet stem, \code{bed}/\code{bim}/\code{fam} #' or \code{pgen}/\code{pvar}/\code{psam} for explicit triplet paths, #' \code{genoMeta} for a one-file-per-chromosome panel (optionally narrowed -#' with \code{chroms}), or \code{ldMeta} plus \code{region} to resolve a +#' with \code{chroms}), or \code{ldMeta} plus \code{block} to resolve a #' block out of an LD-meta table. Exactly one source may be given. #' @param path Character, path to a single self-describing genotype file #' (\code{.vcf.gz}, \code{.vcf.bgz}, \code{.gds} or \code{.bgen}). Omit it @@ -180,14 +180,15 @@ setGeneric("computeLdScores", function(ldRef, annotations = NULL, ...) { #' chromosomes, values = payload paths / prefixes). Every file must be of #' one format and hold the same samples in the same order. #' @param chroms Optional character vector of chromosomes. Only the -#' \code{genoMeta} shards whose chromosome is listed are read; chromosome -#' labels are compared canonically. Meaningful only with \code{genoMeta}. +#' \code{genoMeta} shards whose chromosome is listed are read; a label may +#' be in any style (\code{"chr1"} or \code{"1"}). Meaningful only with +#' \code{genoMeta}. #' @param ldMeta Path to an LD-meta TSV (columns \code{chrom}, \code{start}, -#' \code{end}, \code{path}). Requires \code{region}: the row covering it is +#' \code{end}, \code{path}). Requires \code{block}: the row covering it is #' resolved and the file it names is read with the matching backend. -#' @param region Region to resolve out of \code{ldMeta}: a -#' \code{"chr:start-end"} string, or a one-row data.frame with -#' \code{chrom}, \code{start}, \code{end}. +#' @param block The \code{GRanges} window whose LD block to read out of +#' \code{ldMeta}. It chooses a file rather than filtering records: the +#' panel is the whole LD block that covers it. #' @param vcfArgs Optional named list of arguments forwarded to #' \code{VariantAnnotation::readVcf} when a VCF's records are read (its #' genotypes are read a block at a time, as they are needed). @@ -214,7 +215,7 @@ setGeneric("readGenotypes", function(path, format = NULL, ...) { #' @title Read Annotations #' @description Read genomic annotations from files (BED, BigWig, S-LDSC .annot #' format, or GRanges objects) and create an AnnotationMatrix. -#' @param paths Named character vector of file paths, or a named list of GRanges +#' @param path Named character vector of file paths, or a named list of GRanges #' objects. Names become annotation names. #' @param snpRanges A \code{GRanges} object defining SNP positions. #' @param annotationMeta A \code{data.frame} with annotation metadata (name, @@ -231,7 +232,7 @@ setGeneric("readGenotypes", function(path, format = NULL, ...) { #' @export setGeneric( "readAnnotations", - function(paths, snpRanges, annotationMeta = NULL, genome = "hg19", ...) { + function(path, snpRanges, annotationMeta = NULL, genome = "hg19", ...) { standardGeneric("readAnnotations") } ) @@ -289,21 +290,36 @@ setGeneric("scoreStats", function(object) standardGeneric("scoreStats")) #' this context; \code{NULL} matches all contexts. #' @param trait Character (length 1) or \code{NULL}. Restrict the selection to #' this trait; \code{NULL} matches all traits. -#' @param annotateSignificance Optional correction-method name passed through to -#' \code{\link{sumStats}} (QTL only); \code{NULL} applies none. -#' @param ranges A \code{GRanges} or \code{NULL} (default). Return only the -#' variants overlapping these ranges; \code{NULL} returns everything. #' @return Numeric vector of z-scores. #' @export setGeneric("z", function(x, ...) standardGeneric("z")) -#' @title Get Sample Sizes -#' @description Extract sample sizes: the per-variant sample-size vector of a -#' \code{GwasSumStats} or \code{QtlSumStats} entry, selected by its identity -#' tuple, the number of samples carried by a \code{GenotypeHandle}, or the -#' panel size an \code{\link{LdMatrix}} records. -#' @param x A \code{GwasSumStats}, \code{QtlSumStats}, \code{LdMatrix} or -#' \code{GenotypeHandle} object. +#' @title Get the Number of Reference Samples +#' @description The number of samples an LD reference was built from: the +#' samples carried by a \code{GenotypeHandle}, or the panel size an +#' \code{\link{LdMatrix}} records. The per-variant sample size of summary +#' statistics is \code{\link{sampleSize}}. +#' @param x An \code{LdMatrix} or \code{GenotypeHandle} object. +#' @param ... Class-specific selection arguments. +#' @return An integer of length 1 (\code{NA} when an \code{LdMatrix} records +#' no size). +#' @details The genotype handle is the seed layer behind a panel and is not +#' part of the public interface; obtain a panel from +#' \code{readGenotypes()} and ask it directly. +#' @examples +#' data(eqtlRegionExample) +#' X <- eqtlRegionExample$X[, 1:8] +#' nSamples(LdMatrix(cor(X), nSamples = nrow(X))) +#' @export +setGeneric("nSamples", function(x, ...) standardGeneric("nSamples")) + +#' @title Get Per-Variant Sample Sizes +#' @description Extract the per-variant sample-size vector (the \code{N} +#' column) of a \code{GwasSumStats} or \code{QtlSumStats} entry, selected +#' by its identity tuple. Part of the summary-statistic column set alongside +#' \code{\link{z}}, \code{\link{se}} and \code{\link{pval}}; replace it +#' with \code{\link[=variantColumnReplace]{sampleSize<-}}. +#' @param x A \code{GwasSumStats} or \code{QtlSumStats} object. #' @param ... Class-specific selection arguments. #' @param studyName Character (length 1) or \code{NULL}. Restrict the selection #' to this study; \code{NULL} matches all studies. @@ -311,18 +327,10 @@ setGeneric("z", function(x, ...) standardGeneric("z")) #' this context; \code{NULL} matches all contexts. #' @param trait Character (length 1) or \code{NULL}. Restrict the selection to #' this trait; \code{NULL} matches all traits. -#' @param annotateSignificance Optional correction-method name passed through to -#' \code{\link{sumStats}} (QTL only); \code{NULL} applies none. -#' @param ranges A \code{GRanges} or \code{NULL} (default). Return only the -#' variants overlapping these ranges; \code{NULL} returns everything. -#' @return Numeric vector of sample sizes for a summary-statistic entry; -#' integer of length 1 for a \code{GenotypeHandle} or an \code{LdMatrix} -#' (\code{NA} when the matrix records no size). -#' @details The genotype handle is the seed layer behind a panel and is not -#' part of the public interface; obtain a panel from -#' \code{readGenotypes()} and ask it directly. +#' @return Numeric vector of per-variant sample sizes, or \code{NULL} when the +#' entry carries none. #' @export -setGeneric("nSamples", function(x, ...) standardGeneric("nSamples")) +setGeneric("sampleSize", function(x, ...) standardGeneric("sampleSize")) #' @title Get Association P-values #' @description Extract the association p-value vector from a @@ -337,10 +345,6 @@ setGeneric("nSamples", function(x, ...) standardGeneric("nSamples")) #' this context; \code{NULL} matches all contexts. #' @param trait Character (length 1) or \code{NULL}. Restrict the selection to #' this trait; \code{NULL} matches all traits. -#' @param annotateSignificance Optional correction-method name passed through to -#' \code{\link{sumStats}} (QTL only); \code{NULL} applies none. -#' @param ranges A \code{GRanges} or \code{NULL} (default). Return only the -#' variants overlapping these ranges; \code{NULL} returns everything. #' @return Numeric vector of p-values, or \code{NULL} if not available. #' @export setGeneric("pval", function(x, ...) standardGeneric("pval")) @@ -360,10 +364,6 @@ setGeneric("pval", function(x, ...) standardGeneric("pval")) #' this context; \code{NULL} matches all contexts. #' @param trait Character (length 1) or \code{NULL}. Restrict the selection to #' this trait; \code{NULL} matches all traits. -#' @param annotateSignificance Optional correction-method name passed through to -#' \code{\link{sumStats}} (QTL only); \code{NULL} applies none. -#' @param ranges A \code{GRanges} or \code{NULL} (default). Return only the -#' variants overlapping these ranges; \code{NULL} returns everything. #' @return Numeric vector of effect sizes, or \code{NULL} if not available. #' @importFrom stats coef #' @rdname coef-methods @@ -381,36 +381,24 @@ setGeneric("coef") #' this context; \code{NULL} matches all contexts. #' @param trait Character (length 1) or \code{NULL}. Restrict the selection to #' this trait; \code{NULL} matches all traits. -#' @param annotateSignificance Optional correction-method name passed through to -#' \code{\link{sumStats}} (QTL only); \code{NULL} applies none. -#' @param ranges A \code{GRanges} or \code{NULL} (default). Return only the -#' variants overlapping these ranges; \code{NULL} returns everything. #' @return Numeric vector of standard errors, or \code{NULL} if not available. #' @export setGeneric("se", function(x, ...) standardGeneric("se")) #' @title Get Minor Allele Frequencies -#' @description Extract MAF vector from a GwasSumStats object. -#' @param x A \code{GwasSumStats} or \code{QtlDataset} object. -#' @param ... Class-specific selection arguments (e.g., \code{region}, -#' \code{cisWindow} for \code{QtlDataset}). +#' @description Extract the minor-allele-frequency vector from one entry of +#' a summary-statistic collection, or from a \code{QtlDataset} over the +#' whole dataset (narrow it first, with \code{x[i, j, ]}, to read part of +#' it). +#' @param x A \code{GwasSumStats}, \code{QtlSumStats} or \code{QtlDataset} +#' object. +#' @param ... Class-specific selection arguments. #' @param studyName Character (length 1) or \code{NULL}. Restrict the selection #' to this study; \code{NULL} matches all studies. #' @param context Character (length 1) or \code{NULL}. Restrict the selection to #' this context; \code{NULL} matches all contexts. #' @param trait Character (length 1) or \code{NULL}. Restrict the selection to #' this trait; \code{NULL} matches all traits. -#' @param annotateSignificance Optional correction-method name passed through to -#' \code{\link{sumStats}} (QTL only); \code{NULL} applies none. -#' @param ranges A \code{GRanges} or \code{NULL} (default). Return only the -#' variants overlapping these ranges; \code{NULL} returns everything. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' Restrict variants to this region; \code{NULL} uses the full cis window / -#' all regions. -#' @param cisWindow Integer or \code{NULL}. Half-width (bp) of the cis window -#' around the trait; \code{NULL} uses the dataset default. -#' @param samples Character vector or \code{NULL}. Restrict to these sample IDs; -#' \code{NULL} uses all samples. #' @return Numeric vector of MAFs, or NULL if not available. #' @export setGeneric("maf", function(x, ...) standardGeneric("maf")) @@ -419,30 +407,22 @@ setGeneric("maf", function(x, ...) standardGeneric("maf")) #' @description Supply or overwrite one per-variant column of a #' \code{GwasSumStats} / \code{QtlSumStats} entry after construction -- #' the usual case being an effect-allele frequency the source file did not -#' carry. Dispatch is on \code{value}: -#' \describe{ -#' \item{\code{numeric}}{positional: the vector is in the entry's own -#' variant order and must have exactly one value per variant. Length is -#' checked hard, because a recycled or truncated vector is otherwise -#' silently wrong.} -#' \item{\code{GRanges}}{matched: paired to the entry on -#' \code{(chrom, pos, A1, A2)} via \code{matchVariants}, so ordering -#' does not matter. \code{A1}/\code{A2} are \strong{required} in -#' \code{mcols()} so an allele swap can be detected, and exactly one -#' other \code{mcols} column carries the values. Entry variants the -#' replacement does not name are set \code{NA}.} -#' } -#' An allele swap sends \code{af} to \code{1 - af}, so \code{af<-} -#' complements a flipped match. \code{maf} is \code{min(af, 1 - af)} and -#' \code{nSamples} is a count, both swap-invariant, so neither is -#' complemented. +#' carry. The value is positional: a vector in \code{\link{sumStats}} +#' order for the selection -- a GWAS study split across rows is stitched, +#' as \code{sumStats()} returns it -- with exactly one value per variant. +#' Length is checked hard, because a recycled or truncated vector is +#' otherwise silently wrong. To take the values from a reference keyed by +#' variant instead, matched on \code{(chrom, pos, A1, A2)} and oriented to +#' the entry's alleles, use \code{\link{fillFromReference}}. #' @param x A \code{GwasSumStats} or \code{QtlSumStats} object. -#' @param studyName,context,trait Selectors pinning one entry; \code{context} -#' and \code{trait} are \code{QtlSumStats}-only. +#' @param studyName,context,trait Selectors pinning one study (every row of a +#' GWAS study) or one \code{QtlSumStats} entry; \code{context} and +#' \code{trait} are \code{QtlSumStats}-only. #' @param ... Unused. -#' @param value A \code{numeric} vector (positional) or a \code{GRanges} -#' carrying \code{A1}/\code{A2} plus one value column (matched). -#' @return The object, with that entry's column replaced. +#' @param value A \code{numeric} vector, one value per variant in +#' \code{sumStats()} order. +#' @return The object, with the selection's column replaced. \code{sampleSize<-} +#' writes the per-variant \code{N}. #' @examples #' data(qtlSumStatsExample) #' x <- qtlSumStatsExample @@ -459,8 +439,8 @@ setGeneric("maf<-", function(x, ..., value) standardGeneric("maf<-")) #' @rdname variantColumnReplace #' @export -setGeneric("nSamples<-", function(x, ..., value) { - standardGeneric("nSamples<-") +setGeneric("sampleSize<-", function(x, ..., value) { + standardGeneric("sampleSize<-") }) #' @title Get Effect-Allele Frequencies @@ -473,30 +453,17 @@ setGeneric("nSamples<-", function(x, ..., value) { #' \code{af} column report. For a summary-statistic collection this is #' \code{NULL} when the source #' carried no frequency column -- see \code{\link{variantColumnReplace}} -#' for supplying one afterwards. +#' for supplying one afterwards. A \code{QtlDataset} answers over the whole +#' dataset; narrow it first, with \code{x[i, j, ]}, to read part of it. #' @param x A \code{QtlDataset}, \code{LdMatrix}, \code{GwasSumStats} or #' \code{QtlSumStats} object. -#' @param ... Class-specific selection arguments (e.g., \code{traitId}, -#' \code{region}, \code{cisWindow}, \code{samples} for \code{QtlDataset}). -#' @param traitId Character or \code{NULL}. Molecular trait / feature identifier -#' to select; \code{NULL} matches all traits in the dataset. +#' @param ... Class-specific selection arguments. #' @param studyName Character (length 1) or \code{NULL}. Restrict the selection #' to this study; \code{NULL} matches all studies. #' @param context Character (length 1) or \code{NULL}. Restrict the selection to #' this context; \code{NULL} matches all contexts. #' @param trait Character (length 1) or \code{NULL}. Restrict the selection to #' this trait; \code{NULL} matches all traits. -#' @param annotateSignificance Optional correction-method name passed through to -#' \code{\link{sumStats}} (QTL only); \code{NULL} applies none. -#' @param ranges A \code{GRanges} or \code{NULL} (default). Return only the -#' variants overlapping these ranges; \code{NULL} returns everything. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' Restrict variants to this region; \code{NULL} uses the full cis window / -#' all regions. -#' @param cisWindow Integer or \code{NULL}. Half-width (bp) of the cis window -#' around the trait; \code{NULL} uses the dataset default. -#' @param samples Character vector or \code{NULL}. Restrict to these sample IDs; -#' \code{NULL} uses all samples. #' @return Named numeric vector of effect-allele frequencies (names are variant #' IDs), or an empty vector when no variants are selected. #' @examples @@ -518,10 +485,6 @@ setGeneric("af", function(x, ...) standardGeneric("af")) #' this context; \code{NULL} matches all contexts. #' @param trait Character (length 1) or \code{NULL}. Restrict the selection to #' this trait; \code{NULL} matches all traits. -#' @param annotateSignificance Optional correction-method name passed through to -#' \code{\link{sumStats}} (QTL only); \code{NULL} applies none. -#' @param ranges A \code{GRanges} or \code{NULL} (default). Return only the -#' variants overlapping these ranges; \code{NULL} returns everything. #' @return Integer. #' @export setGeneric("nSnps", function(x, ...) standardGeneric("nSnps")) @@ -594,23 +557,12 @@ setGeneric("significantQtls", function(x, ...) { standardGeneric("significantQtls") }) -#' @title Subset by Chromosome -#' @description Extract a chromosome-specific subset of a GwasSumStats object. -#' @param x A \code{GwasSumStats} object. -#' @param chr Character, chromosome name (e.g., "1", "chr1"). -#' @return A \code{GwasSumStats} object. -#' @examples -#' data(gwasSumStatsS4Example) -#' subsetChr(gwasSumStatsS4Example, "chr22") -#' @export -setGeneric("subsetChr", function(x, chr) standardGeneric("subsetChr")) - #' @title Reconcile Two Collections to Their Shared Variants #' @description Restrict two fine-mapping collections to the variants they have #' in common, renormalizing each retained single-effect posterior over the #' variants that survive. -#' @details \code{subsetRegion()} restricts ONE object to a window; this -#' intersects TWO objects against each other. Coloc needs it symmetric -- +#' @details This intersects two objects against each other. Coloc needs it +#' symmetric -- #' both sides must be scored on the same variant set -- while TWAS, MR and #' cTWAS need it one-sided, adjusting the QTL side to the GWAS variant set #' and leaving the GWAS side alone. @@ -660,7 +612,7 @@ setGeneric("intersectVariants", function(x, y, oneSided = FALSE, ...) { #' null. An explicit diagnostic is the only thing that surfaces this. #' @param x A fine-mapping collection. #' @param ... Additional arguments passed to methods. -#' @return A \code{data.frame}, one row per (element, effect), with the +#' @return A \code{DataFrame}, one row per (element, effect), with the #' element's identity columns, the effect index, and its retained mass. #' @examples #' data(qtlFineMappingExample) @@ -674,43 +626,6 @@ setGeneric("retainedMass", function(x, ...) { standardGeneric("retainedMass") }) -#' @title Restrict a Collection to a Region -#' @description Narrow a \code{RangedTupleList} collection to an analysis -#' window: elements that do not overlap it are dropped, and the survivors are -#' trimmed to the overlapping variants. Elements that trim to zero variants -#' are dropped too. -#' @details This is deliberately a new verb rather than a redefinition of a -#' Bioconductor generic, because three genuinely different operations are in -#' play and all three are useful: -#' \describe{ -#' \item{\code{subsetByOverlaps(x, win)}}{selects elements, keeps them -#' whole.} -#' \item{\code{restrict(x, start, end)}}{trims elements, keeps empty ones.} -#' \item{\code{subsetRegion(x, win)}}{selects AND trims AND drops empties.} -#' } -#' \code{subsetChr()} is the whole-seqname special case of this verb. -#' @param x A \code{RangedTupleList} collection. -#' @param region A \code{GRanges}, a \code{"chr:start-end"} string, or a -#' one-row \code{data.frame} with \code{chrom} / \code{start} / \code{end}. -#' @param ... Additional arguments passed to methods. Fine-mapping collections -#' accept \code{adjust} to renormalize PIPs over the retained variants. -#' @return An object of the same class as \code{x}, with the collection-level -#' slots carried over and \code{mcols} narrowed to the surviving elements. -#' @examples -#' data(qtlSumStatsMulticontextExample) -#' mc <- qtlSumStatsMulticontextExample -#' sum(lengths(mc)) -#' # Every element is narrowed to the window; the collection keeps its shape, -#' # so an element with nothing left stays as an empty one rather than a -#' # dropped row. -#' sub <- subsetRegion(mc, "chr22:14560203-15000000") -#' sum(lengths(sub)) -#' nrow(sub) -#' @export -setGeneric("subsetRegion", function(x, region, ...) { - standardGeneric("subsetRegion") -}) - #' @title Get Phenotype Variance #' @description Extract phenotype variance from a \code{GwasSumStats} or #' \code{QtlSumStats} entry, selected by its identity tuple. Returns @@ -751,11 +666,6 @@ setGeneric("varY", function(x, ...) standardGeneric("varY")) #' this context; \code{NULL} matches all contexts. #' @param trait Character (length 1) or \code{NULL}. Restrict the selection to #' this trait; \code{NULL} matches all traits. -#' @param ranges A \code{GRanges} or \code{NULL} (default). A selected tuple can -#' own several elements -- one per chromosome, since a multi-seqname entry is -#' split at construction -- and they are stitched back into a single -#' \code{GRanges}. Pass \code{ranges} to pull only the variants overlapping a -#' region instead of the whole span; \code{NULL} returns everything. #' @return A \code{GRanges}, a \code{QtlSumStats}, or \code{NULL}. #' @examples #' data(qtlSumStatsExample) @@ -763,48 +673,50 @@ setGeneric("varY", function(x, ...) standardGeneric("varY")) #' @export setGeneric("sumStats", function(x, ...) standardGeneric("sumStats")) -#' @title Get the Embedded QtlDataset List -#' @description Return the named list of \code{QtlDataset} objects carried by a -#' \code{MultiStudyQtlDataset}. -#' @param x A \code{MultiStudyQtlDataset} object. -#' @return A named list of \code{QtlDataset} objects. -#' @examples -#' data(multiStudyQtlDatasetExample) -#' qtlDatasets(multiStudyQtlDatasetExample) +#' @title Get the Per-Row QC Audit +#' @description What \code{\link{summaryStatsQc}} did to each row of a +#' summary-statistics collection: one row per tuple, its identity columns, +#' then the variant counts each QC step recorded (\code{variantsIn}, +#' \code{variantsOut}, and so on; a nested count is named by its path, as +#' in \code{contentFilters.nDropped}). A step that did not run on a row is +#' \code{NA} there. Only the identity columns are present before QC has run. +#' The options the QC ran with are \code{\link{qcOptions}}; the per-variant +#' LD-mismatch tables are \code{\link{qcDiagnostics}}. +#' @param x A \code{GwasSumStats} or \code{QtlSumStats} object. +#' @param ... Unused. +#' @return A \code{DataFrame}, one row per tuple. #' @export -setGeneric("qtlDatasets", function(x) standardGeneric("qtlDatasets")) +setGeneric("qcInfo", function(x, ...) standardGeneric("qcInfo")) -#' @title Get QC Audit Record -#' @description Return the audit record of QC steps applied to this collection. -#' An empty \code{list()} (default on construction) means -#' \code{\link{summaryStatsQc}} has not yet been run. Pipelines that require -#' harmonized sumstats (\code{fineMappingPipeline}, -#' \code{twasWeightsPipeline}, and downstream consumers) reject inputs where -#' \code{length(qcInfo(x)) == 0L}. +#' @title Get the QC Options +#' @description The record of the QC that ran over a summary-statistics +#' collection: the options \code{\link{summaryStatsQc}} was called with and +#' when. An empty \code{list()} (the default on construction) means QC has +#' not run; pipelines that need harmonized summary statistics +#' (\code{fineMappingPipeline}, \code{twasWeightsPipeline} and others) +#' refuse such inputs. What QC did to each row is \code{\link{qcInfo}}. #' @param x A \code{GwasSumStats} or \code{QtlSumStats} object. #' @param ... Unused. -#' @return A \code{list} (possibly empty). +#' @return A \code{list}, possibly empty. #' @export -setGeneric("qcInfo", function(x, ...) standardGeneric("qcInfo")) +setGeneric("qcOptions", function(x, ...) standardGeneric("qcOptions")) #' @title Get SLALOM / DENTIST Diagnostics -#' @description Return the per-variant LD-mismatch diagnostics table (SLALOM or -#' DENTIST output) attached to a sumstats entry by -#' \code{\link{summaryStatsQc}} when \code{ldMismatchQcMethod} was not -#' \code{"none"}. -#' Convenience accessor over -#' \code{qcInfo(x)$entryAudit[[entry]]$ldMismatchDiagnostics}. +#' @description Return the per-variant LD-mismatch diagnostics (SLALOM or +#' DENTIST output) that \code{\link{summaryStatsQc}} attached to the +#' selected entry when \code{ldMismatchQcMethod} was not \code{"none"}. +#' The selectors pin one study (every row of a GWAS study, whose rows' +#' tables are stacked) or one \code{QtlSumStats} entry, as for +#' \code{\link{sumStats}}. #' @param x A \code{GwasSumStats} or \code{QtlSumStats} object. -#' @param entry Integer index (default 1) of the entry whose diagnostics table -#' to return. When \code{NULL}, returns a named list of every entry's -#' diagnostics keyed by entry index. +#' @param studyName,context,trait Selectors pinning one study or entry; +#' \code{context} and \code{trait} are \code{QtlSumStats}-only. #' @param ... Unused. -#' @return A \code{data.frame} of per-variant diagnostics (columns include -#' \code{variant_id} plus the SLALOM / DENTIST output columns), \code{NULL} -#' when no diagnostics were preserved for that entry, or a named list of such -#' data.frames when \code{entry = NULL}. +#' @return A \code{DataFrame} of per-variant diagnostics (columns include +#' \code{variant_id} plus the SLALOM / DENTIST output columns), or +#' \code{NULL} when no diagnostics were preserved for the selection. #' @export -setGeneric("qcDiagnostics", function(x, entry = 1L, ...) { +setGeneric("qcDiagnostics", function(x, ...) { standardGeneric("qcDiagnostics") }) @@ -839,34 +751,27 @@ setGeneric("ldReference", function(x, ...) standardGeneric("ldReference")) #' @title Get LD Correlation Matrix #' @description Extract the LD correlation matrix an \code{\link{LdMatrix}} -#' holds, labelled by its variant ids. +#' holds, labelled by its variant ids. \code{as.matrix(x)} and +#' \code{as(x, "matrix")} return the same matrix. #' @param x An \code{LdMatrix}. +#' @param ... Unused. #' @return A correlation matrix. #' @examples #' data(eqtlRegionExample) #' X <- eqtlRegionExample$X[, 1:8] #' ld <- LdMatrix(cor(X), nSamples = nrow(X)) #' ldMatrix(ld)[1:3, 1:3] +#' identical(as.matrix(ld), ldMatrix(ld)) #' @export setGeneric("ldMatrix", function(x) standardGeneric("ldMatrix")) #' @title Get Genotype Matrix #' @description Extract a genotype matrix from an object that carries genotype -#' data. For a \code{QtlDataset}, returns the genotype matrix for a selected -#' set of traits or region (see method documentation for the per-class -#' selection arguments). +#' data. For a \code{QtlDataset}, the whole dataset's dosages (samples x +#' variants), with no QC applied: to read part of it, narrow the dataset +#' first, e.g. \code{genotypes(x[window, samples, ])}. #' @param x The object to extract from. -#' @param ... Class-specific selection arguments (e.g., \code{traitId}, -#' \code{region}, \code{cisWindow} for \code{QtlDataset}). -#' @param traitId Character or \code{NULL}. Molecular trait / feature identifier -#' to select; \code{NULL} matches all traits in the dataset. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' Restrict variants to this region; \code{NULL} uses the full cis window / -#' all regions. -#' @param cisWindow Integer or \code{NULL}. Half-width (bp) of the cis window -#' around the trait; \code{NULL} uses the dataset default. -#' @param samples Character vector or \code{NULL}. Restrict to these sample IDs; -#' \code{NULL} uses all samples. +#' @param ... Passed on to methods. #' @return A numeric matrix, a list of matrices, or \code{NULL}. #' @examples #' data(qtlDatasetExample) @@ -877,7 +782,10 @@ setGeneric("genotypes", function(x, ...) standardGeneric("genotypes")) #' @title Get Variant IDs #' @description Extract variant ID vector from an object that carries one (e.g., #' \code{LdMatrix}, \code{FineMappingRow}, \code{TwasWeightsRow}) or from -#' one entry of a collection class selected by its identity tuple. +#' one entry of a collection class selected by its identity tuple. Every +#' class renders the same canonical \code{chrom:pos:A2:A1} id from each +#' variant's range and alleles; labels a source gave (an rsID, a file's own +#' spelling) stay in the \code{SNP} column of its ranges. #' @param x The object. #' @param ... Class-specific selection arguments. #' @param studyName Character (length 1) or \code{NULL}. Restrict the selection @@ -888,13 +796,8 @@ setGeneric("genotypes", function(x, ...) standardGeneric("genotypes")) #' this trait; \code{NULL} matches all traits. #' @param method Character (length 1) or \code{NULL}. Restrict the selection to #' this fine-mapping / weight method; \code{NULL} matches all methods. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' Restrict variants to this region; \code{NULL} uses the full cis window / -#' all regions. -#' @param annotateSignificance Optional correction-method name passed through to -#' \code{\link{sumStats}} (QTL only); \code{NULL} applies none. -#' @param ranges A \code{GRanges} or \code{NULL} (default). Return only the -#' variants overlapping these ranges; \code{NULL} returns everything. +#' @param blockId GWAS fine-mapping results only: the \code{blockId} naming +#' one LD block of a fit; \code{NULL} matches every block. #' @return Character vector of variant IDs. #' @examples #' data(qtlFineMappingExample) @@ -904,37 +807,25 @@ setGeneric("variantIds", function(x, ...) standardGeneric("variantIds")) #' @title Get Molecular Traits #' @description Extract molecular-trait data from an object that carries it. -#' For a \code{QtlDataset}, the user can optionally select specific contexts, -#' traits, or a region (see method documentation for the per-class selection -#' arguments). +#' For a \code{QtlDataset}, select contexts and, optionally, traits by +#' name. The data come back as stored: missing values and outliers are a +#' run's phenotype QC (\code{\link{PhenotypeFilterParam}}), applied by the +#' pipelines, not by this accessor. #' @param x The object to extract from. -#' @param ... Class-specific selection arguments (e.g., \code{contexts}, -#' \code{traitId}, \code{region}). -#' @param contexts Character vector. Context(s) whose data to extract. -#' @param traitId Character or \code{NULL}. Molecular trait / feature identifier +#' @param ... Class-specific selection arguments (e.g., \code{context}, +#' \code{trait}). +#' @param context Character vector. Context(s) whose data to extract. +#' @param trait Character or \code{NULL}. Molecular trait / feature identifier #' to select; \code{NULL} matches all traits in the dataset. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' Restrict variants to this region; \code{NULL} uses the full cis window / -#' all regions. -#' @param naAction Character. How to handle missing phenotype values: one of -#' \code{"keep"}, \code{"drop"}, or \code{"impute"}. -#' @param outlierAction Character. How to handle phenotype outliers: one of -#' \code{"keep"} or \code{"drop"}. -#' @param outlierPvalThreshold Numeric. Two-sided p-value threshold for flagging -#' phenotype outliers. Default \code{1e-3}. -#' @param outlierArgs Extra arguments for \code{robustbase::covMcd()}, the -#' robust covariance estimator the outlier rule is built on, supplied with -#' \code{\link{CovMcdOptions}} -- \code{alpha} in particular. Only -#' consulted when \code{outlierAction = "drop"}. -#' @return A \code{SummarizedExperiment} when one context is selected, or a -#' named list of them for several. A \code{QtlDataset} is a +#' @return A named list of \code{SummarizedExperiment}s keyed by context, +#' one per selected context. A \code{QtlDataset} is a #' \code{MultiAssayExperiment}, so these are its experiments; take the #' measurement matrix itself with #' \code{SummarizedExperiment::assay()} rather than asking this accessor #' for one. #' @examples #' data(qtlDatasetExample) -#' molecularTraits(qtlDatasetExample, contexts = "brain") +#' molecularTraits(qtlDatasetExample, context = "brain") #' @export setGeneric("molecularTraits", function(x, ...) { standardGeneric("molecularTraits") @@ -943,15 +834,21 @@ setGeneric("molecularTraits", function(x, ...) { # Fine-mapping result accessor generics # ============================================================================= -#' @title Get a Single Fine-Mapping Entry -#' @description Return one row of a \code{QtlFineMappingResult} or -#' \code{GwasFineMappingResult}, selected by its identity, as a single-row -#' collection of the same class. +#' @title Get One Fine-Mapping Fit +#' @description Return the rows of one fit of a \code{QtlFineMappingResult} +#' or \code{GwasFineMappingResult}, selected by its identity, as a +#' collection of the same class. A QTL fit is one row. A GWAS study +#' fine-mapped block by block holds one row per LD block, so its fit is +#' every block of the \code{(study, method)} pair, unless \code{blockId} +#' names one or \code{region} narrows them. #' @param x A \code{QtlFineMappingResult} or \code{GwasFineMappingResult}. -#' @param studyName,context,trait,method Single character identifiers. All -#' required when the collection has more than one row; optional when the -#' collection has a single row. -#' @return A single-row collection of the same class as \code{x}. +#' @param studyName,context,trait,method Single character identifiers. +#' Required when the collection holds more than one fit; optional when it +#' holds one. \code{context} and \code{trait} are QTL-only. +#' @param blockId GWAS only: the \code{blockId} of one LD block, to select +#' that block alone. \code{NULL} (default) selects every block of the fit. +#' @return A collection of the same class as \code{x}: one row for a QTL fit, +#' one row per selected block for a GWAS fit. #' @examples #' data(qtlFineMappingExample) #' fineMappingResult(qtlFineMappingExample, studyName = "study_1", @@ -959,7 +856,14 @@ setGeneric("molecularTraits", function(x, ...) { #' @export setGeneric( "fineMappingResult", - function(x, studyName = NULL, context = NULL, trait = NULL, method = NULL) { + function( + x, + studyName = NULL, + context = NULL, + trait = NULL, + method = NULL, + blockId = NULL + ) { standardGeneric("fineMappingResult") } ) @@ -1006,11 +910,8 @@ setGeneric("adjustPips", function(x, keepVariants, ...) { #' this trait; \code{NULL} matches all traits. #' @param method Character (length 1) or \code{NULL}. Restrict the selection to #' this fine-mapping / weight method; \code{NULL} matches all methods. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' Restrict variants to this region; \code{NULL} uses the full cis window / -#' all regions. -#' @param returnList Logical. If \code{TRUE}, return a per-entry list keyed by -#' identity tuple instead of a single flattened vector. +#' @param blockId GWAS fine-mapping results only: the \code{blockId} naming +#' one LD block of a fit; \code{NULL} matches every block. #' @return A named numeric vector of PIPs. #' @examples #' data(qtlFineMappingExample) @@ -1034,9 +935,8 @@ setGeneric("pip", function(x, ...) standardGeneric("pip")) #' this trait; \code{NULL} matches all traits. #' @param method Character (length 1) or \code{NULL}. Restrict the selection to #' this fine-mapping / weight method; \code{NULL} matches all methods. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' Restrict variants to this region; \code{NULL} uses the full cis window / -#' all regions. +#' @param blockId GWAS fine-mapping results only: the \code{blockId} naming +#' one LD block of a fit; \code{NULL} matches every block. #' @return A list (the SuSiE fit object). #' @examples #' data(qtlFineMappingExample) @@ -1046,12 +946,12 @@ setGeneric("susieFit", function(x, ...) standardGeneric("susieFit")) #' @title Compute Between-Credible-Set Correlation On Demand #' @description Compute the between-credible-set correlation matrix for a -#' \code{\link{fineMappingRow}} on demand from an LD source. The correlation +#' \code{\link{FineMappingRow}} on demand from an LD source. The correlation #' is a view over the fit-time LD, which lives on the data object --- a #' \code{QtlDataset}'s genotypes or a \code{QtlSumStats} / \code{GwasSumStats} #' LD reference --- and is deliberately never stored on the fit. An #' \code{ldSource} is therefore always required. -#' @param x A \code{\link{fineMappingRow}} carrying the fit (credible-set +#' @param x A \code{\link{FineMappingRow}} carrying the fit (credible-set #' membership and PIP) and its variant ids. #' @param ldSource The object supplying the LD: a \code{QtlDataset} #' (individual-level; genotypes via \code{\link{genotypes}}) or a @@ -1117,13 +1017,12 @@ setGeneric("cvResult", function(x, ...) standardGeneric("cvResult")) #' @title Get Marginal Effects #' @description Extract per-variant marginal univariate effects from a -#' fine-mapping entry or result. Returns a \code{data.frame} with identity -#' columns (\code{variant_id, chrom, pos, A1, A2}), context (\code{N, MAF}), -#' and the marginal effect columns (\code{beta, se, z, p}). Populated -#' uniformly across the individual-level and RSS paths. +#' fine-mapping entry or result, one range per variant. Its \code{mcols()} +#' hold the identity columns (\code{variant_id, chrom, pos, A1, A2}), +#' context (\code{N, MAF}), and the marginal effect columns +#' (\code{beta, se, z, p}). Populated uniformly across the +#' individual-level and RSS paths. #' @param x A \code{QtlFineMappingResult} or \code{GwasFineMappingResult}. -#' @param maxPval Optional numeric (length 1). When non-\code{NULL}, filter rows -#' where \code{p > maxPval}. Default \code{NULL} (no filter). #' @param ... Class-specific selection arguments. #' @param studyName Character (length 1) or \code{NULL}. Restrict the selection #' to this study; \code{NULL} matches all studies. @@ -1133,15 +1032,16 @@ setGeneric("cvResult", function(x, ...) standardGeneric("cvResult")) #' this trait; \code{NULL} matches all traits. #' @param method Character (length 1) or \code{NULL}. Restrict the selection to #' this fine-mapping / weight method; \code{NULL} matches all methods. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' Restrict variants to this region; \code{NULL} uses the full cis window / -#' all regions. -#' @return A \code{data.frame}. +#' @param blockId GWAS fine-mapping results only: the \code{blockId} naming +#' one LD block of a fit; \code{NULL} matches every block. +#' @return A \code{GRanges}, one range per variant; when the selectors match +#' more than one entry the row-identity columns are carried in +#' \code{mcols()} too. #' @examples #' data(qtlFineMappingExample) #' marginalEffects(qtlFineMappingExample) #' @export -setGeneric("marginalEffects", function(x, maxPval = NULL, ...) { +setGeneric("marginalEffects", function(x, ...) { standardGeneric("marginalEffects") }) @@ -1166,22 +1066,17 @@ setGeneric("marginalEffects", function(x, maxPval = NULL, ...) { #' this trait; \code{NULL} matches all traits. #' @param method Character (length 1) or \code{NULL}. Restrict the selection to #' this fine-mapping / weight method; \code{NULL} matches all methods. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' Restrict variants to this region; \code{NULL} uses the full cis window / -#' all regions. +#' @param blockId GWAS fine-mapping results only: the \code{blockId} naming +#' one LD block of a fit; \code{NULL} matches every block. #' @param minPurity Numeric or \code{NULL}. Minimum credible-set purity to #' retain; \code{NULL} applies no purity filter. -#' @param raw Logical (length 1). \code{FALSE} (default) returns the posterior -#' view described above. \code{TRUE} hands back the stored canonical table -#' verbatim -- a \code{data.frame}, not a \code{GRanges} -- so neither the -#' projection nor \code{signalCutoff} applies. #' @return A \code{GRanges}, one range per retained variant, carrying the #' per-variant columns in \code{mcols()}; when the selectors match more than #' one entry the row-identity columns are carried there too. Take a table #' with \code{as.data.frame()} (which adds the standard #' \code{seqnames}/\code{start}/... columns) or #' \code{as.data.frame(S4Vectors::mcols(.))} for the per-variant columns -#' alone. \code{raw = TRUE} returns the stored \code{data.frame} instead. +#' alone. #' @examples #' data(qtlFineMappingExample) #' topLoci(qtlFineMappingExample) @@ -1203,14 +1098,17 @@ setGeneric( #' this trait; \code{NULL} matches all traits. #' @param method Character (length 1) or \code{NULL}. Restrict the selection to #' this fine-mapping / weight method; \code{NULL} matches all methods. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' Restrict variants to this region; \code{NULL} uses the full cis window / -#' all regions. +#' @param blockId GWAS fine-mapping results only: the \code{blockId} naming +#' one LD block of a fit; \code{NULL} matches every block. #' @param coverage Numeric in (0, 1). Credible-set coverage level. Default #' \code{0.95}. #' @param minPurity Numeric or \code{NULL}. Minimum credible-set purity to #' retain; \code{NULL} applies no purity filter. -#' @return A data.frame of credible set information. +#' @return A \code{GRanges}, one range per credible-set member, carrying the +#' per-variant columns in \code{mcols()}; when the selectors match more +#' than one entry the row-identity columns are carried there too. Narrow it +#' with \code{subsetByOverlaps()}; take a table with +#' \code{as.data.frame()}. #' @examples #' data(qtlFineMappingExample) #' credibleSets(qtlFineMappingExample) @@ -1233,9 +1131,8 @@ setGeneric("credibleSets", function(x, ...) standardGeneric("credibleSets")) #' @param studyName,context,trait,method Optional length-1 selectors pinning one #' row of a collection, as elsewhere; each \code{NULL} (default) leaves that #' part of the tuple unconstrained. Ignored when \code{x} is already a row. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' A further selector for a fine-mapping result, whose rows also carry a -#' region; \code{NULL} (default) leaves it unconstrained. +#' @param blockId GWAS fine-mapping results only: the \code{blockId} naming +#' one LD block; \code{NULL} (default) leaves it unconstrained. #' @param ... Reserved for future use. #' @return A \code{list} with \code{variantIds} (character) and \code{weights} #' (numeric) of equal length; both empty when no usable weights are present. @@ -1253,7 +1150,12 @@ setGeneric("resolveWeights", function(x, ...) standardGeneric("resolveWeights")) #' collection (aggregated across rows, tagged with run identity). #' @param x A \code{CtwasResultEntry} or \code{CtwasResult}. #' @param ... Class-specific selection arguments. -#' @return A \code{data.frame} of posteriors (or \code{NULL} when absent). +#' @return On a \code{CtwasResultEntry}, the stored posteriors: a +#' \code{GRanges} when the pipeline placed its rows (each table column in +#' \code{mcols()}), the table as given otherwise, or \code{NULL} when +#' absent. On a \code{CtwasResult}, one \code{GRanges} of every row's +#' posteriors with the run identity in \code{mcols()} (empty when no row +#' has any); a row whose payload carries no coordinates is an error. #' @examples #' cre <- CtwasResultEntry( #' posteriors = data.frame(id = c("g1", "g2"), susie_pip = c(0.9, 0.1)), @@ -1272,8 +1174,11 @@ setGeneric("ctwasPosteriors", function(x, ...) { #' cTWAS output retained so the raw run is reconstructable. #' @param x A \code{CtwasResultEntry} or \code{CtwasResult}. #' @param ... Class-specific selection arguments. -#' @return A \code{data.frame} of per-effect alphas (or \code{NULL} when -#' absent). +#' @return On a \code{CtwasResultEntry}, the stored alphas: a +#' \code{GRanges} when the pipeline placed its rows, the table as given +#' otherwise, or \code{NULL} when absent. On a \code{CtwasResult}, one +#' \code{GRanges} of every row's alphas with the run identity in +#' \code{mcols()} (empty when no row has any). #' @examples #' cre <- CtwasResultEntry( #' posteriors = data.frame(id = c("g1", "g2"), susie_pip = c(0.9, 0.1)), @@ -1391,7 +1296,7 @@ setGeneric("methodNames", function(x) standardGeneric("methodNames")) #' this fine-mapping / weight method; \code{NULL} matches all methods. #' @return A character vector or NULL. #' @examples -#' twe <- twasWeightsRow(variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), +#' twe <- TwasWeightsRow(variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), #' weights = rep(0.1, 4), cvResult = list(rsq = 0.5), #' weightStandardized = FALSE) #' weightsDataType(twe) @@ -1404,23 +1309,27 @@ setGeneric("weightsDataType", function(x, ...) { # Published-output generics (VCF/BCF and BED) # ============================================================================= -#' Export a result to VCF/BCF +#' Write a result to VCF/BCF #' #' Writes GWAS summary statistics, fine-mapping results or TWAS weights to a -#' GWAS-VCF-style file via VariantAnnotation and Rsamtools: one record per -#' variant, one SAMPLE per study / fitted model, and the per-variant statistics -#' as FORMAT fields. Supports bgzipped VCF (.vcf.gz/.vcf.bgz); BCF (.bcf) -#' additionally needs a working \code{Rsamtools::asBcf()}, which recent -#' Rsamtools releases disable, so prefer .vcf.bgz. +#' GWAS-VCF-style file: one record per variant, one SAMPLE per study / fitted +#' model, and the per-variant statistics as FORMAT fields. The file is written +#' with VariantAnnotation's \code{\link[VariantAnnotation]{writeVcf}}, so that +#' package must be installed. +#' Supports bgzipped VCF (.vcf.gz/.vcf.bgz); BCF (.bcf) additionally needs a +#' working \code{Rsamtools::asBcf()}, which recent Rsamtools releases disable, +#' so prefer .vcf.bgz. #' #' Which FORMAT fields are written depends on the input: #' \describe{ -#' \item{\code{GwasSumStats}}{\code{ES} / \code{SS} / \code{AF} for one -#' study.} +#' \item{\code{GwasSumStats}}{\code{ES} / \code{SE} / \code{EZ} / +#' \code{NS} / \code{AF} / \code{MAF} for one study, whichever its +#' variants carry.} #' \item{a fine-mapping result}{the marginal fields (\code{ES}, -#' \code{SE}, \code{LP}, \code{SS}, \code{AF}) plus the posterior ones -#' (\code{PIP}, \code{LBF}, \code{LFSR}, and a \code{CS}/\code{PUR} pair -#' per credible-set coverage present).} +#' \code{SE}, \code{EZ}, \code{LP}, \code{NS}), the fit's own +#' (\code{AF}, \code{WGT}, \code{WGTSE}, \code{THETA}) and the +#' posterior ones (\code{PIP}, \code{LBF}, \code{LFSR}, and a +#' \code{CS}/\code{PUR} pair per credible-set coverage present).} #' \item{\code{TwasWeights}}{\code{WGT}, the prediction weight.} #' } #' @@ -1431,17 +1340,28 @@ setGeneric("weightsDataType", function(x, ...) { #' methods for one gene, are compared by reading one file rather than a dozen. #' Each sample is described in its own \code{##SAMPLE} header line, carrying #' the fit's identity tuple and how many variants it contributed. -#' Cross-validation results are not exported -- see \code{\link{exportToBed}} -#' for why -- and an export requires the full-data fit. +#' Cross-validation results are not written -- see \code{\link{writeBed}} for +#' why -- and writing requires the full-data fit. +#' +#' A GWAS study fine-mapped block by block is ONE fit, so its blocks are +#' joined into one sample. A \code{BID} FORMAT field then names each +#' variant's LD block -- credible-set indices are numbered within a block, +#' so a set is the \code{(BID, CS)} pair -- and the per-block header values +#' (block id, analysis window and whether it was given, \code{V}, +#' \code{cs_index}) are packed in block order, separated by \code{|}. +#' \code{\link{readFineMappingResult}} splits such a sample back into its +#' blocks. #' #' \code{splitByContext} / \code{splitByTrait} opt out of that and write one -#' single-sample file per fit, at a path decorated with the axis value. +#' file per context / trait, at a path decorated with the axis value, holding +#' the fits that share it. \code{splitByBlock} writes one file per LD block +#' of a GWAS result, each holding every fit's part of that block. #' -#' @param x A \code{GwasSumStats}, \code{QtlFineMappingResult}, +#' @param obj A \code{GwasSumStats}, \code{QtlFineMappingResult}, #' \code{GwasFineMappingResult} or \code{TwasWeights} object, or a #' \code{list} of fine-mapping results or of \code{TwasWeights} objects to #' combine first. -#' @param outputPath File path for output. Extension determines format: +#' @param filename File path for output. Extension determines format: #' \code{.vcf.gz} or \code{.vcf.bgz} for bgzipped VCF, \code{.bcf} for BCF, #' \code{.vcf} for uncompressed VCF. #' @param sampleName Name(s) for the VCF sample column(s). Default \code{NULL} @@ -1458,26 +1378,28 @@ setGeneric("weightsDataType", function(x, ...) { #' Default \code{FALSE}. #' @param splitByTrait Logical. If \code{TRUE}, write one VCF per trait. Default #' \code{FALSE}. +#' @param splitByBlock Logical. \code{GwasFineMappingResult} only: if +#' \code{TRUE}, write one VCF per LD block instead of joining a study's +#' blocks into one file. Default \code{FALSE}. #' @param ... Additional arguments passed to methods. #' @return Invisible path(s) to the written file(s). -#' @seealso \code{\link{exportToBed}} +#' @seealso \code{\link{writeBed}}, \code{\link{readFineMappingResult}} #' @examples #' data(gwasSumStatsS4Example) -#' exportToVcf( -#' gwasSumStatsS4Example, outputPath = tempfile(fileext = ".vcf")) +#' writeGwasVcf(gwasSumStatsS4Example, tempfile(fileext = ".vcf")) #' @export -setGeneric("exportToVcf", function(x, outputPath, sampleName = NULL, ...) { - standardGeneric("exportToVcf") +setGeneric("writeGwasVcf", function(obj, filename, ...) { + standardGeneric("writeGwasVcf") }) -#' Export a result to a published BED table +#' Write a result to a published BED table #' #' Writes fine-mapping results or TWAS weights to a published FunGen-xQTL BED #' table, bgzipping and tabix-indexing the output when the path ends in #' \code{.gz} / \code{.bgz}. The tabular counterpart of -#' \code{\link{exportToVcf}}: the VCF is one record per variant with the models -#' as samples, while these tables are long-format, one row per published -#' observation. +#' \code{\link{writeGwasVcf}}: the VCF is one record per variant +#' with the models as samples, while these tables are long-format, one row per +#' published observation. #' #' A \code{TwasWeights} writes one table, a row per (variant, weight column). #' A fine-mapping result offers two, selected with \code{schema}: @@ -1494,19 +1416,19 @@ setGeneric("exportToVcf", function(x, outputPath, sampleName = NULL, ...) { #' \code{method} -- because these collections are keyed by that tuple and #' several of them are routinely folded into one output. #' -#' Cross-validation results are NOT exported, in any schema. They describe how +#' Cross-validation results are NOT written, in any schema. They describe how #' a model scored on held-out FOLDS; nothing about them is per-variant, and a #' published file has no data-secure way to express anything fold-level, #' because fold membership is sample-level information and sample names can be #' protected. They remain on the object, where \code{\link{cvResult}} returns -#' them and the caller tabulates whatever they need. For the same reason an -#' export REQUIRES the full-data fit: a cross-validation-only collection (what -#' \code{twasWeightsPipeline(fitFullData = FALSE)} produces) is refused rather -#' than written out empty. +#' them and the caller tabulates whatever they need. For the same reason +#' writing REQUIRES the full-data fit: a cross-validation-only collection +#' (what \code{twasWeightsPipeline(fitFullData = FALSE)} produces) is refused +#' rather than written out empty. #' -#' @param x A \code{QtlFineMappingResult}, \code{GwasFineMappingResult} or +#' @param obj A \code{QtlFineMappingResult}, \code{GwasFineMappingResult} or #' \code{TwasWeights} object, or a \code{list} of them, to combine first. -#' @param outputPath Output path. A \code{.gz} / \code{.bgz} extension selects +#' @param filename Output path. A \code{.gz} / \code{.bgz} extension selects #' bgzip + tabix (via Rsamtools, so no htslib binary is needed); any other #' extension writes a plain table. #' @param schema Fine-mapping results only: which published schema to @@ -1539,8 +1461,7 @@ setGeneric("exportToVcf", function(x, outputPath, sampleName = NULL, ...) { #' (\code{grange_start} / \code{grange_end}, the legacy \code{gene} / #' \code{event} aliases, and whatever a custom build added); a #' \code{TwasWeights} element carries only its alleles and weight, so there -#' is nothing further to add unless the collection was built by hand. Not -#' accepted by the \code{"performance"} schema, which has no variant axis. +#' is nothing further to add unless the collection was built by hand. #' @param extraColumns Optional NAMED list of trailing columns to append after #' the published schema. Each element is either length 1 (recycled across #' every row) or one value per row. For fields no S4 object can know -- the @@ -1548,20 +1469,21 @@ setGeneric("exportToVcf", function(x, outputPath, sampleName = NULL, ...) { #' is the motivating case. Names that collide with a published column are an #' error rather than a silent overwrite. #' @param ... Additional arguments passed to methods. -#' @return \code{outputPath}, invisibly. -#' @seealso \code{\link{exportToVcf}}, \code{\link{genomicOrder}} +#' @return \code{filename}, invisibly. +#' @seealso \code{\link{writeGwasVcf}}, +#' \code{\link{readFineMappingResult}}, \code{\link{genomicOrder}} #' @examples #' data(qtlFineMappingExample) -#' exportToBed(qtlFineMappingExample, tempfile(fileext = ".bed")) -#' exportToBed( +#' writeBed(qtlFineMappingExample, tempfile(fileext = ".bed")) +#' writeBed( #' qtlFineMappingExample, tempfile(fileext = ".bed"), #' schema = "topLoci", columns = "all" #' ) #' data(twasWeightsExample) -#' exportToBed(twasWeightsExample, tempfile(fileext = ".bed")) +#' writeBed(twasWeightsExample, tempfile(fileext = ".bed")) #' @export -setGeneric("exportToBed", function(x, outputPath, ...) { - standardGeneric("exportToBed") +setGeneric("writeBed", function(obj, filename, ...) { + standardGeneric("writeBed") }) # ============================================================================= @@ -1604,10 +1526,13 @@ setGeneric("traitNames", function(x) standardGeneric("traitNames")) #' @title Get Per-Row Analysis Windows #' @description Return the genomic interval each row was analysed over, as a #' \code{GRanges} with one range per row -- the trait's own region for a -#' \code{TwasWeights}, and for a fine-mapping result the window the fit -#' was run over (the requested region, or the trait's cis-window when the fit -#' was driven by \code{traitId} + \code{cisWindow}). This is location -#' provenance (e.g. for cTWAS LD-block placement). +#' \code{TwasWeights}; for a fine-mapping result the window the fit was run +#' over (the requested region, or the trait's cis-window when the fit was +#' driven by \code{traitId} + \code{cisWindow}); for summary statistics the +#' LD block or window the row was loaded for (the \code{region} given to the +#' constructor or loader), else the span of its variants before QC. This is +#' location provenance (e.g. for cTWAS LD-block placement). One method +#' serves every collection. #' #' This is the window that was ANALYSED, not the span of the variants that #' survived into the fit: QC and screening drop variants first, so a fit over @@ -1616,7 +1541,7 @@ setGeneric("traitNames", function(x) standardGeneric("traitNames")) #' recovered from the object; the span can, and is simply \code{range(x)}. #' #' Being a record of what was analysed, it deliberately does NOT change under -#' \code{subsetRegion()} or row subsetting -- a subset of a fit's variants was +#' subsetting -- a subset of a fit's variants was #' still produced by a fit over the original window. Use \code{range(x)} when #' you want the current content instead. #' @@ -1641,11 +1566,13 @@ setGeneric("genomicRegion", function(x, ...) standardGeneric("genomicRegion")) #' on, so the returned vector is always the same length as \code{nrow(x)} #' and can be used to label or join rows directly. #' -#' It keys the external block manifest the blocks were defined in, and so -#' carries the true block BOUNDARIES --- unlike \code{range(x)}, which is -#' the span of the variants that survived QC. A collection with no block -#' axis (every QTL flavour) returns \code{NA} for every row rather than -#' erroring, so code that handles both flavours needs no class test. +#' It keys the external block manifest the blocks were defined in. The +#' block's BOUNDARIES are the \code{region} column, recorded as given or +#' computed in \code{regionGiven} (see \code{\linkS4class{GwasSumStats}}) +#' --- unlike \code{range(x)}, which is the span of the variants that +#' survived QC. A collection with no block axis (every QTL flavour) +#' returns \code{NA} for every row rather than erroring, so code that +#' handles both flavours needs no class test. #' @param x The object. #' @param ... Reserved for future use. #' @return Character, one value per row of \code{x} (\code{NA} where the row @@ -1670,10 +1597,13 @@ setGeneric("blockId", function(x, ...) standardGeneric("blockId")) #' \code{QtlFineMappingResult} and \code{TwasWeights}. #' @param x The object. #' @param ... Reserved for future use. -#' @param traitId Character or \code{NULL}. Molecular trait / feature identifier +#' @param trait Character or \code{NULL}. Molecular trait / feature identifier #' to select; \code{NULL} matches all traits in the dataset. -#' @return A \code{GRanges} with one range per row of \code{x}, or an empty -#' \code{GRanges} when the collection carries no trait-position provenance. +#' @return A \code{GRanges}: one range per row of a collection, or an empty +#' \code{GRanges} when the collection carries no trait-position provenance +#' (or, for a \code{QtlSumStats} with \code{trait} given, none of those +#' traits). For a \code{QtlDataset}, one range per requested trait, named +#' by trait; a trait in no context is an error. #' @export setGeneric("traitPosition", function(x, ...) { standardGeneric("traitPosition") @@ -1681,25 +1611,12 @@ setGeneric("traitPosition", function(x, ...) { #' @title Get Residualized Genotypes #' @description Residualize the genotype matrix against the per-context -#' phenotype covariates and the genotype covariates, optionally subsetting -#' variants to those falling within a trait's cis-window or an explicit -#' region. +#' phenotype covariates and the genotype covariates, over the whole +#' dataset: narrow it first, with \code{x[i, j, ]}, to residualize part +#' of it. #' @param x A \code{QtlDataset} object. -#' @param ... Selection arguments: \code{traitId}, \code{region}, -#' \code{cisWindow}, \code{phenotypeCovariatesToRemove}, -#' \code{genotypeCovariatesToRemove}, and \code{covariateNaAction} -#' (\code{"impute"}, the default, mean-imputes missing covariate cells; -#' \code{"drop"} removes samples with any missing covariate). -#' @param contexts Character vector. Context(s) whose data to extract. -#' @param traitId Character or \code{NULL}. Molecular trait / feature identifier -#' to select; \code{NULL} matches all traits in the dataset. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' Restrict variants to this region; \code{NULL} uses the full cis window / -#' all regions. -#' @param cisWindow Integer or \code{NULL}. Half-width (bp) of the cis window -#' around the trait; \code{NULL} uses the dataset default. -#' @param samples Character vector or \code{NULL}. Restrict to these sample IDs; -#' \code{NULL} uses all samples. +#' @param ... Passed on to methods. +#' @param context Character vector. Context(s) whose data to extract. #' @param residualizationParam What the data is residualized on, built with #' \code{\link{ResidualizationParam}}: \code{phenotypeCovariates} and #' \code{genotypeCovariates} choose the covariate sets, @@ -1710,7 +1627,7 @@ setGeneric("traitPosition", function(x, ...) { #' @return A numeric matrix (samples x variants). #' @examples #' data(qtlDatasetExample) -#' residualizedGenotypes(qtlDatasetExample, contexts = "brain") +#' residualizedGenotypes(qtlDatasetExample, context = "brain") #' @export setGeneric("residualizedGenotypes", function(x, ...) { standardGeneric("residualizedGenotypes") @@ -1719,19 +1636,14 @@ setGeneric("residualizedGenotypes", function(x, ...) { #' @title Get Residualized Phenotypes #' @description Residualize the per-context phenotype matrices against the #' per-context phenotype covariates and the genotype covariates, for one or -#' more requested contexts. +#' more requested contexts. Missing values and outliers are left as they +#' are: they are a run's phenotype QC (\code{\link{PhenotypeFilterParam}}), +#' applied by the pipelines. #' @param x A \code{QtlDataset} object. -#' @param ... Selection arguments: \code{contexts} (required), \code{traitId}, -#' \code{region}, \code{phenotypeCovariatesToRemove}, -#' \code{genotypeCovariatesToRemove}, and \code{covariateNaAction} -#' (\code{"impute"}, the default, mean-imputes missing covariate cells; -#' \code{"drop"} removes samples with any missing covariate). -#' @param contexts Character vector. Context(s) whose data to extract. -#' @param traitId Character or \code{NULL}. Molecular trait / feature identifier +#' @param ... Passed on to methods. +#' @param context Character vector. Context(s) whose data to extract. +#' @param trait Character or \code{NULL}. Molecular trait / feature identifier #' to select; \code{NULL} matches all traits in the dataset. -#' @param region Character (length 1, \code{"chr:start-end"}) or \code{NULL}. -#' Restrict variants to this region; \code{NULL} uses the full cis window / -#' all regions. #' @param residualizationParam What the data is residualized on, built with #' \code{\link{ResidualizationParam}}: \code{phenotypeCovariates} and #' \code{genotypeCovariates} choose the covariate sets, @@ -1739,20 +1651,10 @@ setGeneric("residualizedGenotypes", function(x, ...) { #' side on or off, and \code{covariateNaAction} says how missing #' covariate values are handled. The same record the pipelines take, so a #' setting means the same thing by either route. -#' @param naAction Character. How to handle missing phenotype values: one of -#' \code{"keep"}, \code{"drop"}, or \code{"impute"}. -#' @param outlierAction Character. How to handle phenotype outliers: one of -#' \code{"keep"} or \code{"drop"}. -#' @param outlierPvalThreshold Numeric. Two-sided p-value threshold for flagging -#' phenotype outliers. Default \code{1e-3}. -#' @param outlierArgs Extra arguments for \code{robustbase::covMcd()}, the -#' robust covariance estimator the outlier rule is built on, supplied with -#' \code{\link{CovMcdOptions}} -- \code{alpha} in particular. Only -#' consulted when \code{outlierAction = "drop"}. #' @return A named list of numeric matrices keyed by context. #' @examples #' data(qtlDatasetExample) -#' residualizedPhenotypes(qtlDatasetExample, contexts = "brain") +#' residualizedPhenotypes(qtlDatasetExample, context = "brain") #' @export setGeneric("residualizedPhenotypes", function(x, ...) { standardGeneric("residualizedPhenotypes") @@ -1762,14 +1664,14 @@ setGeneric("residualizedPhenotypes", function(x, ...) { #' @description Return per-context phenotype covariate matrices, taken from the #' \code{colData} of each context's \code{SummarizedExperiment}. #' @param x A \code{QtlDataset} object. -#' @param contexts Character vector of context names (subset of +#' @param context Character vector of context names (subset of #' \code{names(molecularTraits(x))}). #' @return A named list of matrices keyed by context. #' @examples #' data(qtlDatasetExample) -#' phenotypeCovariates(qtlDatasetExample, contexts = "brain") +#' phenotypeCovariates(qtlDatasetExample, context = "brain") #' @export -setGeneric("phenotypeCovariates", function(x, contexts) { +setGeneric("phenotypeCovariates", function(x, context) { standardGeneric("phenotypeCovariates") }) @@ -1786,19 +1688,6 @@ setGeneric("genotypeCovariates", function(x) { standardGeneric("genotypeCovariates") }) -#' @title Get scaleResiduals Flag -#' @description Whether residualization accessors scale residuals to unit -#' variance. -#' @param x A \code{QtlDataset} object. -#' @return Logical (length 1). -#' @examples -#' data(qtlDatasetExample) -#' scaleResiduals(qtlDatasetExample) -#' @export -setGeneric("scaleResiduals", function(x) { - standardGeneric("scaleResiduals") -}) - # ============================================================================= # GenotypeHandle / LD-statistic / LdMatrix / Annotation / H2Estimate accessors # ============================================================================= @@ -1914,7 +1803,6 @@ setGeneric("ldMatrixList", function(x) standardGeneric("ldMatrixList")) #' @export setGeneric("ldBlocks", function(x) standardGeneric("ldBlocks")) - #' @title Get GenotypeHandle #' @description Return the \code{GenotypeHandle} behind a \code{QtlDataset}'s #' genotype experiment. @@ -2040,7 +1928,7 @@ setGeneric("construct", function(pipeline, records, ...) { # ---- SldscData accessors ---- #' @title Get the annotation table from an SldscData #' @param x An \code{\link{SldscData}} object. -#' @return A \code{data.frame} of annotations (CHR, SNP, annotation columns). +#' @return A \code{DataFrame} of annotations (CHR, SNP, annotation columns). #' @rdname annotData #' @examples #' mkRun <- function(cats) { @@ -2072,7 +1960,7 @@ setGeneric("annotData", function(x) standardGeneric("annotData")) #' @title Get the allele-frequency table from an SldscData #' @param x An \code{\link{SldscData}} object. -#' @return A \code{data.frame} of reference-panel frequencies (SNP, MAF). +#' @return A \code{DataFrame} of reference-panel frequencies (SNP, MAF). #' @rdname frqData #' @examples #' mkRun <- function(cats) { @@ -2157,17 +2045,16 @@ setGeneric("testedAnnotations", function(x) { #' @title Get sLDSC Results from an SldscData #' @description Return the stratified LD-score regression runs held by an -#' \code{\link{SldscData}}: every trait's runs when \code{trait} is -#' \code{NULL}, otherwise the selected run(s) for that one trait. +#' \code{\link{SldscData}}, keyed by trait. Each trait's entry holds its +#' \code{single} runs (one per annotation) and its \code{joint} run, read +#' with \code{[[}: \code{sldscResults(x, "T")[["T"]]$joint}. #' @param x An \code{\link{SldscData}} object. -#' @param trait Character trait name, or \code{NULL} (default) to return the -#' named list of per-trait \code{single}/\code{joint} runs for all traits. -#' @param ... Further arguments: \code{mode} (\code{"single"}/\code{"joint"}) -#' and \code{idx} (which single run). -#' @param mode Character. Trait-run selection mode. -#' @param idx Integer. Index of the trait run to select. -#' @return The named list of per-trait runs when \code{trait} is \code{NULL}; -#' otherwise a single run list, the list of single runs, or \code{NULL}. +#' @param trait Character trait name(s), or \code{NULL} (default) for every +#' trait. A name the object does not hold is an error. +#' @param ... Unused. +#' @return A named list keyed by trait, each element a list with +#' \code{single} (a list of runs) and \code{joint} (one run, or +#' \code{NULL} when the trait has none). #' @rdname sldscResults #' @examples #' mkRun <- function(cats) { @@ -2193,14 +2080,14 @@ setGeneric("testedAnnotations", function(x) { #' } #' traits <- setNames(list(mkTrait(), mkTrait()), c("traitX", "traitY")) #' sd <- SldscData(annotData = annot, frqData = frq, traits = traits) -#' sldscResults(sd, "traitX") +#' sldscResults(sd, "traitX")[["traitX"]]$joint$categories #' @export setGeneric("sldscResults", function(x, trait = NULL, ...) { standardGeneric("sldscResults") }) #' @title Colocalization Views -#' @description The four views over a \code{\linkS4class{ColocResult}}. The +#' @description The five views over a \code{\linkS4class{ColocResult}}. The #' object stores one element per tested (QTL credible set, GWAS credible set, #' block) pair; these accessors project it to the granularity a given #' analysis needs, rather than any one of them being the stored shape. @@ -2210,13 +2097,19 @@ setGeneric("sldscResults", function(x, trait = NULL, ...) { #' \code{$summary} granularity. Every testable pair is reported verbatim, #' including both halves of a credible set that straddles a block #' boundary; interpreting them is the caller's decision.} -#' \item{\code{colocVariants()}}{One row per (pair, variant), carrying +#' \item{\code{colocVariants()}}{One range per (pair, variant), carrying #' \code{colocPp = PP.H4.abf * SNP.PP.H4} -- the posterior that this -#' variant is the shared causal one. With \code{pooled = TRUE}, one row -#' per (gene, variant) pooled by the rule below.} -#' \item{\code{colocCredibleSets()}}{One row per coloc credible set: the -#' smallest set of variants whose cumulative \code{SNP.PP.H4} reaches -#' \code{coverage}. This is a THIRD variant set, not guaranteed to be a +#' variant is the shared causal one.} +#' \item{\code{colocPooledVariants()}}{One range per (gene, variant), +#' pooled across pairs by the rule below. A +#' \code{\linkS4class{ColocBoostResult}} pools per (analysis, variant) +#' instead, with the noisy-OR stage only.} +#' \item{\code{colocCredibleSets()}}{One element per coloc credible set: +#' the smallest set of variants whose cumulative \code{SNP.PP.H4} +#' reaches \code{coverage}, as ranges carrying their \code{SNP.PP.H4}, +#' with the set's pair columns, \code{csSize}, \code{csCoverage}, +#' \code{leadVariant}, \code{leadPp} and \code{purity} in +#' \code{mcols()}. This is a THIRD variant set, not guaranteed to be a #' subset of either input credible set, so its purity is recomputed from #' LD rather than inherited.} #' \item{\code{colocGenes()}}{One row per gene, pooled across pairs.} @@ -2231,8 +2124,6 @@ setGeneric("sldscResults", function(x, trait = NULL, ...) { #' combine as \code{1 - prod_i (1 - p_i)}. #' #' @param x A \code{ColocResult}. -#' @param pooled Logical. \code{colocVariants()} only: pool to one row per -#' (gene, variant) instead of per (pair, variant). #' @param coverage Cumulative \code{SNP.PP.H4} the credible set must reach. #' @param minPp4 Optional lower bound on the pair's \code{PP.H4.abf}. Applied #' before any LD work, so a stricter threshold costs strictly less. @@ -2244,7 +2135,10 @@ setGeneric("sldscResults", function(x, trait = NULL, ...) { #' (purity). Requires the object's \code{ldReference}; when that is absent, #' purity is reported as \code{NA} and no set is dropped. #' @param ... Additional arguments passed on to methods. -#' @return A tibble at the requested granularity. +#' @return \code{colocVariants()} and \code{colocPooledVariants()} a +#' \code{GRanges}, its columns in \code{mcols()}; +#' \code{colocCredibleSets()} a \code{GRangesList}, one element per set; +#' the other views a \code{DataFrame}. #' @name colocViews #' @rdname colocViews #' @examples @@ -2256,6 +2150,7 @@ setGeneric("sldscResults", function(x, trait = NULL, ...) { #' ) #' head(colocPairs(res)) #' head(colocVariants(res)) +#' head(colocPooledVariants(res)) #' colocGenes(res) #' head(colocCredibleSets(res, minPp4 = 0.001)) NULL @@ -2268,10 +2163,16 @@ setGeneric("colocPairs", function(x, ...) { #' @rdname colocViews #' @export -setGeneric("colocVariants", function(x, pooled = FALSE, ...) { +setGeneric("colocVariants", function(x, ...) { standardGeneric("colocVariants") }) +#' @rdname colocViews +#' @export +setGeneric("colocPooledVariants", function(x, ...) { + standardGeneric("colocPooledVariants") +}) + #' @rdname colocViews #' @export setGeneric( @@ -2287,54 +2188,6 @@ setGeneric("colocGenes", function(x, ...) { standardGeneric("colocGenes") }) -#' @title QtlDataset Filter Settings -#' @description The variant- and sample-filter settings a -#' \code{\link{QtlDataset}} was built with. They are recorded on the object -#' rather than reapplied per call, so reading them back is how a caller finds -#' out what a dataset already excludes. -#' @param x A \code{QtlDataset}. -#' @param ... Additional arguments passed on to methods. -#' @return \code{mafCutoff()}, \code{macCutoff()}, -#' \code{xvarCutoff()} and \code{imissCutoff()} single numerics; -#' \code{keepVariants()} a character vector (empty when no restriction -#' was requested); \code{keepIndel()} a single logical. The sample set -#' is not among them: it lives in \code{colData(x)} and \code{sampleMap(x)}. -#' @name qtlDatasetFilters -#' @rdname qtlDatasetFilters -#' @examples -#' data(qtlDatasetExample) -#' mafCutoff(qtlDatasetExample) -#' keepIndel(qtlDatasetExample) -NULL - -#' @rdname qtlDatasetFilters -#' @export -setGeneric("mafCutoff", function(x, ...) standardGeneric("mafCutoff")) - -#' @rdname qtlDatasetFilters -#' @export -setGeneric("macCutoff", function(x, ...) standardGeneric("macCutoff")) - -#' @rdname qtlDatasetFilters -#' @export -setGeneric("xvarCutoff", function(x, ...) standardGeneric("xvarCutoff")) - -#' @rdname qtlDatasetFilters -#' @export -setGeneric("imissCutoff", function(x, ...) { - standardGeneric("imissCutoff") -}) - -#' @rdname qtlDatasetFilters -#' @export -setGeneric("keepVariants", function(x, ...) { - standardGeneric("keepVariants") -}) - -#' @rdname qtlDatasetFilters -#' @export -setGeneric("keepIndel", function(x, ...) standardGeneric("keepIndel")) - #' @title Get Per-Chromosome Payload Paths #' @description The chromosome-to-path map of a sharded #' \code{\link{GenotypeHandle}}. Empty (\code{character(0)}) for a @@ -2343,8 +2196,8 @@ setGeneric("keepIndel", function(x, ...) standardGeneric("keepIndel")) #' routed by chromosome. #' @param x A \code{GenotypeHandle}. #' @param ... Additional arguments passed on to methods. -#' @return A named character vector mapping canonical chromosome to path or -#' prefix, possibly empty. +#' @return A named character vector mapping each chromosome, in UCSC style +#' (\code{"chr21"}), to its path or prefix, possibly empty. #' @details The genotype handle is the seed layer behind a panel and #' is not part of the public interface; obtain a panel from #' \code{readGenotypes()} and ask it directly. @@ -2354,7 +2207,7 @@ setGeneric("chromPaths", function(x, ...) standardGeneric("chromPaths")) #' Per-variant per-effect log Bayes factors (wide) #' #' The variant x effect matrix of single-effect log Bayes factors -#' (\code{lbf_variable}, or fSuSiE's \code{lBF}) from the stored fit: one row +#' (\code{lbf_variable}, or fSuSiE's \code{lBF}) from the stored fit: one range #' per variant, one \code{lbf_L} column per effect. The per-variant scalar #' summary (max across effects) is the \code{logBF} column of #' \code{\link{topLoci}}; this accessor keeps the full per-effect breakdown. @@ -2363,8 +2216,9 @@ setGeneric("chromPaths", function(x, ...) standardGeneric("chromPaths")) #' #' @param x A \code{QtlFineMappingResult} or \code{GwasFineMappingResult}. #' @param ... Ignored. -#' @return A \code{tibble}: \code{variant_id} + \code{lbf_L1..lbf_LL} (the -#' collection method also carries the entry identity columns). +#' @return A \code{GRanges}, one range per variant, whose \code{mcols()} +#' hold \code{variant_id} + \code{lbf_L1..lbf_LL} (the collection method +#' also carries the entry identity columns). #' @seealso \code{\link{topLoci}} (the scalar \code{logBF} column) #' @examples #' data(qtlFineMappingExample) @@ -2382,7 +2236,7 @@ setGeneric("lbf", function(x, ...) standardGeneric("lbf")) #' @param x A \code{QtlFineMappingResult} or \code{GwasFineMappingResult}. #' @param coverage Credible-set coverage to summarise. Default 0.95. #' @param ... Ignored. -#' @return A \code{tibble}: \code{cs, effect_id, coverage, n_variants, +#' @return A \code{DataFrame}: \code{cs, effect_id, coverage, n_variants, #' purity_min, purity_mean, V, cs_log10bf} (strongest member logBF), #' \code{cs_log_bf} (true per-effect single-effect log Bayes factor), #' \code{cs_pip} (summed member PIP = inclusion mass captured), @@ -2402,18 +2256,20 @@ setGeneric("credibleSetSummary", function(x, ...) { #' #' For a functional-SuSiE (\code{fsusieR::susiF}) fine-mapping entry, returns #' the fitted effect curve and its credible band over the functional grid, one -#' row per (credible set, grid position). Wraps the upstream fSuSiE band +#' range per (credible set, grid position). Wraps the upstream fSuSiE band #' computation (fsusieR's internal \code{update_cal_credible_band.susiF} + #' \code{get_fitted_effect}). Uses saved bands in trimmed fits, or computes -#' them from an untrimmed fit. Returns zero rows when the functional fields -#' are absent. +#' them from an untrimmed fit. Returns an empty \code{GRanges} when the +#' functional fields are absent. #' #' @param x A \code{QtlFineMappingResult} or \code{GwasFineMappingResult}. #' @param ... Ignored. -#' @return A long \code{tibble}: \code{cs, chrom, pos, effect, lower, upper, -#' halfwidth} -- \code{halfwidth} being \code{(upper - lower) / 2}, the -#' symmetric band half-width publication tables carry (the collection method -#' additionally carries the entry identity columns). +#' @return A \code{GRanges}, one width-1 range per (credible set, grid +#' position), whose \code{mcols()} hold \code{cs, chrom, pos, effect, +#' lower, upper, halfwidth} -- \code{halfwidth} being +#' \code{(upper - lower) / 2}, the symmetric band half-width publication +#' tables carry (the collection method additionally carries the entry +#' identity columns). #' @seealso \code{\link{fsusieTraitEffects}}, #' \code{\link{fsusieAffectedRegions}} #' @examples @@ -2439,7 +2295,7 @@ setGeneric("fsusieCredibleBand", function(x, ...) { #' #' @param x A \code{QtlFineMappingResult} or \code{GwasFineMappingResult}. #' @param ... Ignored. -#' @return A long \code{tibble}: \code{cs, chrom, jointTrait, traitPos, +#' @return A long \code{DataFrame}: \code{cs, chrom, jointTrait, traitPos, #' effect} (the collection method additionally carries the entry identity #' columns). #' @seealso \code{\link{fsusieCredibleBand}}, @@ -2477,29 +2333,22 @@ setGeneric("fsusieAffectedRegions", function(x, ...) { # ============================================================================= # MethodParam accessor generics # ----------------------------------------------------------------------------- -# Only two Param classes carry accessors, and both earn them by being records -# the user HOLDS rather than builds and forgets: +# Every Param is read with `$` / `[[` and written with `$<-` (MethodParam.R), +# which rebuilds the record through its constructor. Two classes also carry +# named getters, because they are records the user HOLDS rather than builds +# and forgets: # # CredibleSetParam postprocessFinemappingFits() and buildTopLoci() take # an already-computed fit, so a stored fit is # re-summarized under changed settings without -# refitting. `L` / `Lgreedy` are deliberately -# get-only: they are seeded onto each SuSiE-family -# token's own arguments, so changing one needs a -# refit and a setter would hand back a record that -# looks applied but is not. -# GwasFineMappingParam the only Param nesting others. Once CredibleSetParam -# is settable, the container has to let the nested -# record back in, or it could be read but not written. -# -# The other 24 Params are construct-and-pass -- handed to one pipeline -# argument and never seen again -- and get none, which is what Bioconductor's -# own PileupParam does with twelve slots. +# refitting. `L` / `Lgreedy` are deliberately fixed: +# they are seeded onto each SuSiE-family token's own +# arguments, so changing one needs a refit, and `$<-` +# refuses them. +# GwasFineMappingParam the only Param nesting others. # -# get*/set* rather than Rsamtools' bamWhich()/bamWhich<-() spelling: pecotmr -# already exports 95 get* accessors, and bare field names are not available -# anyway -- `coverage` is an IRanges generic for read depth and `methods` is -# utils::methods. +# Bare field names are not available as getter names -- `coverage` is an +# IRanges generic for read depth and `methods` is utils::methods. # ============================================================================= #' @rdname CredibleSetParam @@ -2510,85 +2359,42 @@ setGeneric("csCoverage", function(x, ...) { standardGeneric("csCoverage") }) -#' @rdname CredibleSetParam -#' @param value The replacement value for that setting. -#' @export -setGeneric("csCoverage<-", function(x, ..., value) { - standardGeneric("csCoverage<-") -}) - #' @rdname CredibleSetParam #' @export setGeneric("secondaryCoverage", function(x, ...) { standardGeneric("secondaryCoverage") }) -#' @rdname CredibleSetParam -#' @export -setGeneric("secondaryCoverage<-", function(x, ..., value) { - standardGeneric("secondaryCoverage<-") -}) - #' @rdname CredibleSetParam #' @export setGeneric("signalCutoff", function(x, ...) { standardGeneric("signalCutoff") }) -#' @rdname CredibleSetParam -#' @export -setGeneric("signalCutoff<-", function(x, ..., value) { - standardGeneric("signalCutoff<-") -}) - #' @rdname CredibleSetParam #' @export setGeneric("minAbsCorr", function(x, ...) { standardGeneric("minAbsCorr") }) -#' @rdname CredibleSetParam -#' @export -setGeneric("minAbsCorr<-", function(x, ..., value) { - standardGeneric("minAbsCorr<-") -}) - #' @rdname CredibleSetParam #' @export setGeneric("medianAbsCorr", function(x, ...) { standardGeneric("medianAbsCorr") }) -#' @rdname CredibleSetParam -#' @export -setGeneric("medianAbsCorr<-", function(x, ..., value) { - standardGeneric("medianAbsCorr<-") -}) - #' @rdname CredibleSetParam #' @export setGeneric("includeAllCs", function(x, ...) { standardGeneric("includeAllCs") }) -#' @rdname CredibleSetParam -#' @export -setGeneric("includeAllCs<-", function(x, ..., value) { - standardGeneric("includeAllCs<-") -}) - #' @rdname CredibleSetParam #' @export setGeneric("perCsColumns", function(x, ...) { standardGeneric("perCsColumns") }) -#' @rdname CredibleSetParam -#' @export -setGeneric("perCsColumns<-", function(x, ..., value) { - standardGeneric("perCsColumns<-") -}) - #' @rdname CredibleSetParam #' @export setGeneric("maxNumSingleEffects", function(x, ...) { @@ -2609,69 +2415,32 @@ setGeneric("fineMappingMethods", function(x, ...) { standardGeneric("fineMappingMethods") }) -#' @rdname GwasFineMappingParam -#' @param value The replacement value for that setting. -#' @export -setGeneric("fineMappingMethods<-", function(x, ..., value) { - standardGeneric("fineMappingMethods<-") -}) - #' @rdname GwasFineMappingParam #' @export setGeneric("credibleSetParam", function(x, ...) { standardGeneric("credibleSetParam") }) -#' @rdname GwasFineMappingParam -#' @export -setGeneric("credibleSetParam<-", function(x, ..., value) { - standardGeneric("credibleSetParam<-") -}) - #' @rdname GwasFineMappingParam #' @export setGeneric("susieRssParam", function(x, ...) { standardGeneric("susieRssParam") }) -#' @rdname GwasFineMappingParam -#' @export -setGeneric("susieRssParam<-", function(x, ..., value) { - standardGeneric("susieRssParam<-") -}) - #' @rdname GwasFineMappingParam #' @export setGeneric("panelFilterParam", function(x, ...) { standardGeneric("panelFilterParam") }) -#' @rdname GwasFineMappingParam -#' @export -setGeneric("panelFilterParam<-", function(x, ..., value) { - standardGeneric("panelFilterParam<-") -}) - #' @rdname GwasFineMappingParam #' @export setGeneric("initializeWithSusieInf", function(x, ...) { standardGeneric("initializeWithSusieInf") }) -#' @rdname GwasFineMappingParam -#' @export -setGeneric("initializeWithSusieInf<-", function(x, ..., value) { - standardGeneric("initializeWithSusieInf<-") -}) - #' @rdname GwasFineMappingParam #' @export setGeneric("fitRetention", function(x, ...) { standardGeneric("fitRetention") }) - -#' @rdname GwasFineMappingParam -#' @export -setGeneric("fitRetention<-", function(x, ..., value) { - standardGeneric("fitRetention<-") -}) diff --git a/R/AnnotationMatrix.R b/R/AnnotationMatrix.R index 3f066e34..ffaa5ac1 100644 --- a/R/AnnotationMatrix.R +++ b/R/AnnotationMatrix.R @@ -91,7 +91,7 @@ setMethod("show", "AnnotationMatrix", function(object) { .trim = FALSE )) cat(glue( - " Genome build: {GenomeInfoDb::genome(object)}\n", + " Genome build: {.showGenomeBuild(object)}\n", .trim = FALSE )) }) @@ -166,10 +166,11 @@ AnnotationMatrix <- function( "{length(snpRanges)} SNP range(s); the rows must match." )) } + ucsc <- .ucscRanges(snpRanges) named <- if (!is.null(genome) && length(genome) == 1L && !is.na(genome)) { - GenomeInfoDb::`genome<-`(snpRanges, value = genome) + GenomeInfoDb::`genome<-`(ucsc, value = genome) } else { - snpRanges + ucsc } se <- SummarizedExperiment::SummarizedExperiment( assays = list(annotations = annotations), @@ -183,9 +184,7 @@ AnnotationMatrix <- function( row.names = colnames(annotations) ) ) - obj <- methods::new("AnnotationMatrix", se) - validObject(obj) - obj + methods::new("AnnotationMatrix", se) } # ============================================================================= diff --git a/R/ColocBoostResult.R b/R/ColocBoostResult.R index f9c4ea1f..65554e3b 100644 --- a/R/ColocBoostResult.R +++ b/R/ColocBoostResult.R @@ -131,29 +131,21 @@ methods::setValidity("ColocBoostResult", function(object) { } # The per-variant layer is the point of the class, exactly as SNP.PP.H4 is for -# ColocResult: an element without it reproduces the gap this closes. +# ColocResult: an element without it reproduces the gap this closes. The +# elements share one variant metadata table, so they all have the column or +# none does. # @noRd .cbrCheckVcpColumn <- function(object) { - if (length(object) == 0L) { - return(NULL) - } - bad <- which(!map_lgl(as.list(object), .cbrHasVcp)) - if (length(bad) == 0L) { + if (length(object) == 0L || .rtlHasVariantColumn(object, "vcp")) { return(NULL) } str_c( "element(s) ", - str_flatten(bad, ", "), + str_flatten(seq_along(object), ", "), " have no vcp column in their variant metadata" ) } -# @noRd -.cbrHasVcp <- function(g) { - md <- mcols(g, use.names = FALSE) - !is.null(md) && is_in("vcp", colnames(md)) -} - # Every outcome named on an element must be resolvable in outcomeInfo, or the # identity join silently drops rows -- which looks like "this CoS colocalized # fewer traits" rather than like a bookkeeping bug. @@ -269,11 +261,13 @@ setMethod( #' \code{\link{readGenotypes}}), \code{GenotypeMixture} or \code{LdMatrix} #' objects. #' @param computingTime Optional list of per-analysis timings. -#' @param includeUncolocalized Keep the outcome-specific (uncolocalized) sets -#' as elements flagged \code{isColocalized = FALSE}. Default \code{TRUE}: -#' dropping them at write time would make "no colocalization here" and "no -#' signal here" indistinguishable downstream. -#' @return A \code{ColocBoostResult}. +#' @param metadata A list of free-form metadata about the collection, +#' as \code{metadata()} holds on any Bioconductor vector. Default +#' \code{list()}. +#' @return A \code{ColocBoostResult}. The outcome-specific (uncolocalized) +#' sets are kept as elements flagged \code{isColocalized = FALSE}, so "no +#' colocalization here" stays distinct from "no signal here"; +#' \code{x[x$isColocalized]} keeps the colocalized ones. #' @examples #' # Built from `colocboost` objects, which colocboostPipeline() supplies; #' # colocboostResultExample is one such result, from a real run. @@ -296,7 +290,7 @@ ColocBoostResult <- function( outcomeInfo = NULL, ldReference = NULL, computingTime = list(), - includeUncolocalized = TRUE + metadata = list() ) { results <- as.list(results) n <- length(results) @@ -310,18 +304,18 @@ ColocBoostResult <- function( .cbrRowsFor, results = results, analysis = analysis, - gwasStudy = gwasStudy, - includeUncolocalized = includeUncolocalized + gwasStudy = gwasStudy ) |> list_flatten() |> unname() - .cbrAssemble( + assembled <- .cbrAssemble( rows, outcomeInfo = .cbrWithLdKeys(as.data.frame(outcomeInfo)), regionVcp = .cbrRegionVcp(results), ldReference = .cbrAsLdRefList(ldReference), computingTime = computingTime ) + .withMetadata(assembled, metadata) } # The `ldReference` argument as the slot holds it: an empty list for NULL, or @@ -355,18 +349,15 @@ ColocBoostResult <- function( # Every set (colocalized, then uncolocalized) of one colocboost object, as a # list of one-row records. # @noRd -.cbrRowsFor <- function(i, results, analysis, gwasStudy, includeUncolocalized) { +.cbrRowsFor <- function(i, results, analysis, gwasStudy) { res <- results[[i]] if (is.null(res)) { return(list()) } - out <- c( + c( .cbrColocalizedRows(res, analysis[[i]], gwasStudy[[i]]), - if (isTRUE(includeUncolocalized)) { - .cbrUncolocalizedRows(res, analysis[[i]], gwasStudy[[i]]) - } + .cbrUncolocalizedRows(res, analysis[[i]], gwasStudy[[i]]) ) - out } # @noRd @@ -564,19 +555,17 @@ ColocBoostResult <- function( ) { elements <- map(rows, .cbrElementFor) grl <- S4Vectors::`mcols<-`( - GenomicRanges::GRangesList(elements), + .rtlBindElements(elements), value = .cbrMcolsFor(rows) ) - obj <- new( + new( "ColocBoostResult", - grl, + .rtlNamed(grl), ldReference = ldReference, outcomeInfo = outcomeInfo, regionVcp = regionVcp, computingTime = computingTime ) - validObject(obj) - obj } # @noRd @@ -641,7 +630,17 @@ ColocBoostResult <- function( #' @rdname colocViews #' @export -setMethod("colocPairs", "ColocBoostResult", function(x) { +setMethod( + "colocPairs", + "ColocBoostResult", + function(x) { + .asViewDataFrame(.cbrPairsTable(x = x)) + } +) + +# colocPairs() on a ColocBoostResult as a tibble. +# @noRd +.cbrPairsTable <- function(x) { # Named "pairs" for symmetry with ColocResult, but a ColocBoost row is a # SET, not a pair: `outcomes` holds however many outcomes colocalized. md <- mcols(x, use.names = FALSE) @@ -658,24 +657,35 @@ setMethod("colocPairs", "ColocBoostResult", function(x) { outcomes = map_chr(as.list(md$outcomes), str_flatten, collapse = "; "), nOutcomes = lengths(md$outcomes) ) -}) +} #' @rdname colocViews #' @export setMethod( "colocVariants", "ColocBoostResult", - function(x, pooled = FALSE) { + function(x) { + .withGenome(.variantTableGRanges(.cbrLongVariants(x)), .oneBuild(x)) + } +) + +#' @rdname colocViews +#' @export +setMethod( + "colocPooledVariants", + "ColocBoostResult", + function(x) { long <- .cbrLongVariants(x) - if (!isTRUE(pooled) || nrow(long) == 0L) { - return(long) + if (nrow(long) == 0L) { + return(.withGenome(.variantTableGRanges(long), .oneBuild(x))) } # Pooling across sets is noisy-OR only: unlike coloc, ColocBoost's sets # are not per-block slices of one signal, so there is no # mutually-exclusive sum stage to apply first. - long |> + pooledTbl <- long |> group_by(across(all_of(c("analysis", "variant_id")))) |> summarise(vcp = .crNoisyOr(.data$vcp), .groups = "drop") + .withGenome(.variantTableGRanges(pooledTbl), .oneBuild(x)) } ) @@ -709,8 +719,9 @@ setMethod( #' label back, never the study / context / trait behind it. #' @param x A \code{\linkS4class{ColocBoostResult}}. #' @param ... Ignored. -#' @return A tibble with one row per (set, outcome) and the set-level columns -#' repeated, plus \code{outcome}, \code{study}, \code{context}, +#' @return A \code{DataFrame} with one row per (set, outcome), the +#' set-level columns repeated, plus \code{outcome}, \code{study}, +#' \code{context}, #' \code{trait}, \code{dataForm} and \code{ldReference} (the name of the #' \code{\link{ldReference}} entry the outcome's summary statistics were #' matched against). @@ -724,7 +735,17 @@ setGeneric("colocBoostOutcomes", function(x, ...) { #' @rdname colocBoostOutcomes #' @export -setMethod("colocBoostOutcomes", "ColocBoostResult", function(x) { +setMethod( + "colocBoostOutcomes", + "ColocBoostResult", + function(x) { + .asViewDataFrame(.cbrOutcomesTable(x = x)) + } +) + +# colocBoostOutcomes() as a tibble. +# @noRd +.cbrOutcomesTable <- function(x) { if (length(x) == 0L) { return(tibble()) } @@ -748,35 +769,18 @@ setMethod("colocBoostOutcomes", "ColocBoostResult", function(x) { as_tibble(info, .name_repair = "minimal"), by = c(outcome = "name") ) -}) - -# ---- coercion --------------------------------------------------------------- - -#' @title Coerce a ColocBoostResult to a data frame -#' @description Returns the set-level view. New code should call the view it -#' wants (\code{\link{colocViews}}, -#' \code{\link{colocBoostOutcomes}}). -#' @param x A \code{ColocBoostResult}. -#' @param row.names,optional Ignored; present for generic compatibility. -#' @param ... Ignored. -#' @return A data frame with one row per confidence set. -#' @examples -#' methods::existsMethod("as.data.frame", "ColocBoostResult") -#' @export -setMethod( - "as.data.frame", - "ColocBoostResult", - function(x, row.names = NULL, optional = FALSE, ...) { - as.data.frame(colocPairs(x)) - } -) +} #' @title Per-Analysis Timings #' @description The wall-clock timings colocboostPipeline recorded for each #' analysis it ran. #' @param x A \code{\linkS4class{ColocBoostResult}}. #' @param ... Ignored. -#' @return A list of timings, empty when none were recorded. +#' @return A \code{DataFrame}, one row per analysis that ran: +#' \code{analysis} (\code{xqtl_coloc}, \code{joint_gwas} or +#' \code{separate_gwas}), \code{nRuns} (1, or one per GWAS study for +#' \code{separate_gwas}) and \code{seconds}, their total wall-clock time. +#' No rows when none were recorded. #' @examples #' methods::existsMethod("computingTime", "ColocBoostResult") #' @export @@ -787,9 +791,38 @@ setGeneric("computingTime", function(x, ...) { #' @rdname computingTime #' @export setMethod("computingTime", "ColocBoostResult", function(x) { - x@computingTime + .cbrTimingTable(x@computingTime) }) +# The recorded timings, one row per analysis that ran. +# @noRd +.cbrTimingTable <- function(timing) { + runs <- compact(timing$Analysis %||% list()) + S4Vectors::DataFrame( + analysis = names(runs) %||% character(0), + nRuns = map_int(unname(runs), .cbrTimingRuns), + seconds = map_dbl(unname(runs), .cbrTimingSeconds) + ) +} + +# A per-study sweep records its run count; every other analysis is one run. +# @noRd +.cbrTimingRuns <- function(t) { + if (is.list(t)) as.integer(t$n_studies %||% NA_integer_) else 1L +} + +# @noRd +.cbrTimingSeconds <- function(t) { + total <- if (is.list(t)) t$total else t + if (is.null(total)) { + return(NA_real_) + } + if (inherits(total, "difftime")) { + return(as.numeric(total, units = "secs")) + } + as.numeric(total) +} + #' @title Region-Wide Variant Colocalization Probabilities #' @description The marginal \code{vcp} for every variant in the analysed #' region, not just the confidence-set members. Distinct from diff --git a/R/ColocResult.R b/R/ColocResult.R index 6918ec30..e049616d 100644 --- a/R/ColocResult.R +++ b/R/ColocResult.R @@ -144,29 +144,20 @@ methods::setValidity("ColocResult", function(object) { # The per-variant layer is the whole point of the class, so an element without # it is rejected rather than tolerated -- a silently absent SNP.PP.H4 would -# reproduce the exact gap this class exists to close. +# reproduce the exact gap this class exists to close. The elements share one +# variant metadata table, so they all have the column or none does. # @noRd .crCheckVariantColumn <- function(object) { - if (length(object) == 0L) { - return(NULL) - } - bad <- which(!map_lgl(as.list(object), .crHasSnpPp)) - if (length(bad) == 0L) { + if (length(object) == 0L || .rtlHasVariantColumn(object, "SNP.PP.H4")) { return(NULL) } str_c( "element(s) ", - str_flatten(bad, ", "), + str_flatten(seq_along(object), ", "), " have no SNP.PP.H4 column in their variant metadata" ) } -# @noRd -.crHasSnpPp <- function(g) { - md <- mcols(g, use.names = FALSE) - !is.null(md) && is_in("SNP.PP.H4", colnames(md)) -} - # ---- accessors -------------------------------------------------------------- #' @rdname show-methods @@ -208,6 +199,9 @@ setMethod("show", "ColocResult", function(object) { #' \code{LdMatrix} -- for every pair, or a list with one per pair; used by #' \code{\link{colocCredibleSets}} to compute purity. Each distinct #' reference is stored once. +#' @param metadata A list of free-form metadata about the collection, +#' as \code{metadata()} holds on any Bioconductor vector. Default +#' \code{list()}. #' @return A \code{ColocResult}. #' @examples #' pairs <- data.frame( @@ -225,7 +219,12 @@ setMethod("show", "ColocResult", function(object) { #' )) #' ColocResult(pairs, variants) #' @export -ColocResult <- function(pairs, variants, ldReference = NULL) { +ColocResult <- function( + pairs, + variants, + ldReference = NULL, + metadata = list() +) { pairs <- as.data.frame(pairs, stringsAsFactors = FALSE) if (!is.list(variants) || length(variants) != nrow(pairs)) { msg <- glue( @@ -241,15 +240,14 @@ ColocResult <- function(pairs, variants, ldReference = NULL) { # `result$PP.H4.abf` gets NULL exactly when there is nothing to report. cols <- list_assign(as.list(pairs), ldReference = dict$keys) grl <- S4Vectors::`mcols<-`( - GenomicRanges::GRangesList(elements), + .rtlBindElements(elements), value = exec( S4Vectors::DataFrame, !!!c(cols, list(check.names = FALSE)) ) ) - obj <- new("ColocResult", grl, ldReference = dict$refs) - validObject(obj) - obj + obj <- new("ColocResult", .rtlNamed(grl), ldReference = dict$refs) + .withMetadata(obj, metadata) } # One pair's variant table -> a GRanges carrying SNP.PP.H4 in its mcols. @@ -341,22 +339,38 @@ ColocResult <- function(pairs, variants, ldReference = NULL) { #' @rdname colocViews #' @export -setMethod("colocPairs", "ColocResult", function(x) { +setMethod( + "colocPairs", + "ColocResult", + function(x) { + .asViewDataFrame(.crPairsTable(x = x)) + } +) + +# colocPairs() as a tibble, for the views built on it. +# @noRd +.crPairsTable <- function(x) { md <- mcols(x, use.names = FALSE) if (is.null(md) || length(x) == 0L) { return(tibble()) } as_tibble(as.data.frame(md), .name_repair = "minimal") +} + +#' @rdname colocViews +#' @export +setMethod("colocVariants", "ColocResult", function(x) { + # Ranged, placed by each row's variant id, so the view narrows with + # subsetByOverlaps(). + .withGenome(.variantTableGRanges(.crLongVariants(x)), .oneBuild(x)) }) #' @rdname colocViews #' @export -setMethod("colocVariants", "ColocResult", function(x, pooled = FALSE) { +setMethod("colocPooledVariants", "ColocResult", function(x) { long <- .crLongVariants(x) - if (!isTRUE(pooled) || nrow(long) == 0L) { - return(long) - } - .crPoolVariants(long) + pooled <- if (nrow(long) == 0L) long else .crPoolVariants(long) + .withGenome(.variantTableGRanges(pooled), .oneBuild(x)) }) # One row per (pair, variant): the pair's metadata repeated across its @@ -420,8 +434,18 @@ setMethod("colocVariants", "ColocResult", function(x, pooled = FALSE) { #' @rdname colocViews #' @export -setMethod("colocGenes", "ColocResult", function(x) { - pairs <- colocPairs(x) +setMethod( + "colocGenes", + "ColocResult", + function(x) { + .asViewDataFrame(.crGenesTable(x = x)) + } +) + +# colocGenes() as a tibble. +# @noRd +.crGenesTable <- function(x) { + pairs <- .crPairsTable(x) if (nrow(pairs) == 0L) { return(tibble()) } @@ -442,7 +466,7 @@ setMethod("colocGenes", "ColocResult", function(x) { nPairs = sum(.data$nPairs), .groups = "drop" ) -}) +} # ---- credible-set view ------------------------------------------------------ @@ -458,25 +482,82 @@ setMethod( minAbsCorr = 0.8, requireMaxH4 = FALSE ) { - keep <- .crPairFilter(x, minPp4, requireMaxH4) - if (length(keep) == 0L) { - return(tibble()) - } - # Filtering happens BEFORE any LD work, so a stricter threshold costs - # strictly less -- which is the reason purity lives on the accessor - # rather than being precomputed at construction. - sets <- compact(map(keep, .crCsForPair, x = x, coverage = coverage)) - if (length(sets) == 0L) { - return(tibble()) - } - out <- bind_rows(sets) - .crApplyPurityFilter( - mutate(out, purity = .crPuritiesFor(out, ldReference(x))), - minAbsCorr + sets <- .crCredibleSets( + x = x, + coverage = coverage, + minPp4 = minPp4, + minAbsCorr = minAbsCorr, + requireMaxH4 = requireMaxH4 ) + .withGenome(.crSetsAsList(sets), .oneBuild(x)) } ) +# The coloc credible sets: one record per set, its members' ranges and its +# set-level row, filtered on the pair and then on purity. +# @noRd +.crCredibleSets <- function( + x, + coverage = 0.95, + minPp4 = NULL, + minAbsCorr = 0.8, + requireMaxH4 = FALSE +) { + pairs <- .crPairFilter(x, minPp4, requireMaxH4) + # Filtering happens BEFORE any LD work, so a stricter threshold costs + # strictly less -- which is the reason purity lives on the accessor + # rather than being precomputed at construction. + sets <- compact(map(pairs, .crCsForPair, x = x, coverage = coverage)) + if (length(sets) == 0L) { + return(list()) + } + purity <- map_dbl(sets, .crSetPurity, refs = ldReference(x)) + sets <- map2(sets, purity, .crWithPurity) + if (is.null(minAbsCorr)) { + return(sets) + } + # An unmeasurable purity does not drop a set: with no LD reference there is + # no evidence the set is impure, and silently discarding it would make the + # view depend on whether a sketch happened to be attached. + keep(sets, .crPureEnough, minAbsCorr = minAbsCorr) +} + +# The sets as one GRangesList: each set's members its element, its set-level +# columns that element's mcols. +# @noRd +.crSetsAsList <- function(sets) { + if (length(sets) == 0L) { + return(GenomicRanges::GRangesList()) + } + S4Vectors::`mcols<-`( + .rtlBindElements(map(sets, "members")), + value = S4Vectors::DataFrame( + bind_rows(map(sets, "row")), + check.names = FALSE + ) + ) +} + +# Purity of one set: the minimum absolute correlation among its members, one +# LD extraction per set (section 3.7), against its own pair's reference. NA +# when the pair has no LD reference to extract from -- reported honestly +# rather than defaulted to a passing value. +# @noRd +.crSetPurity <- function(set, refs) { + .crPurityOne(.grVariantIds(set$members), set$row$ldReference, refs) +} + +# @noRd +.crWithPurity <- function(set, purity) { + list_assign(set, row = mutate(set$row, purity = purity)) +} + +# @noRd +.crPureEnough <- function(set, minAbsCorr) { + p <- set$row$purity + is.na(p) || p >= minAbsCorr +} + # Which pairs survive the pair-level filters. Both conditions read columns # already stored on the pair, so neither costs anything to evaluate. # @noRd @@ -519,13 +600,15 @@ setMethod( members <- ord[seq_len(nKeep)] ids <- .grVariantIds(g[members]) md <- as.data.frame(mcols(x, use.names = FALSE))[i, , drop = FALSE] - mutate( - as_tibble(md, .name_repair = "minimal"), - csSize = length(members), - csCoverage = cum[[nKeep]], - leadVariant = ids[[1L]], - leadPp = pp[ord][[1L]], - csVariants = list(ids) + list( + members = g[members], + row = mutate( + as_tibble(md, .name_repair = "minimal"), + csSize = length(members), + csCoverage = cum[[nKeep]], + leadVariant = ids[[1L]], + leadPp = pp[ord][[1L]] + ) ) } @@ -541,15 +624,6 @@ setMethod( if (length(hit) == 0L) length(cum) else hit[[1L]] } -# Purity per credible set: the minimum absolute correlation among its members, -# one LD extraction per set (section 3.7), each against its own pair's -# reference. NA when the pair has no LD reference to extract from -- reported -# honestly rather than defaulted to a passing value. -# @noRd -.crPuritiesFor <- function(out, refs) { - map2_dbl(out$csVariants, out$ldReference, .crPurityOne, refs = refs) -} - # @noRd #' @importFrom rlang try_fetch .crPurityOne <- function(ids, key, refs) { @@ -575,50 +649,3 @@ setMethod( } min(abs(ld[upper.tri(ld)])) } - -# @noRd -.crApplyPurityFilter <- function(out, minAbsCorr) { - if (is.null(minAbsCorr)) { - return(out) - } - # An unmeasurable purity does not drop a set: with no LD reference there is - # no evidence the set is impure, and silently discarding it would make the - # view depend on whether a sketch happened to be attached. - keep <- is.na(out$purity) | out$purity >= minAbsCorr - out[keep, , drop = FALSE] -} - -# ---- coercion --------------------------------------------------------------- - -#' @title Coerce a ColocResult to a data frame -#' @description Returns the pair-level view, which is the flat table -#' \code{colocPipeline()} used to return directly. Provided so existing -#' consumers keep working; new code should call the view it actually wants -#' (see \code{\link{colocViews}}). -#' @param x A \code{ColocResult}. -#' @param row.names,optional Ignored; present for generic compatibility. -#' @param ... Ignored. -#' @return A data frame with one row per tested pair. -#' @examples -#' pairs <- data.frame( -#' study = "s1", context = "c1", trait = "g1", method = "susie", -#' gwasStudy = "G1", gwasContext = NA_character_, -#' gwasTrait = NA_character_, gwasMethod = "susie", -#' blockId = "chr1_1_1000", -#' qtlCs = 1L, gwasCs = 1L, nSnps = 2L, -#' PP.H0.abf = 0.1, PP.H1.abf = 0.1, PP.H2.abf = 0.1, -#' PP.H3.abf = 0.1, PP.H4.abf = 0.6 -#' ) -#' variants <- list(data.frame( -#' variant_id = c("chr1:100:A:G", "chr1:200:C:T"), -#' SNP.PP.H4 = c(0.7, 0.3) -#' )) -#' as.data.frame(ColocResult(pairs, variants)) -#' @export -setMethod( - "as.data.frame", - "ColocResult", - function(x, row.names = NULL, optional = FALSE, ...) { - as.data.frame(colocPairs(x)) - } -) diff --git a/R/CtwasResult.R b/R/CtwasResult.R index cbe7b156..c691fe46 100644 --- a/R/CtwasResult.R +++ b/R/CtwasResult.R @@ -1,48 +1,72 @@ # ============================================================================= # CtwasResult S4 class # ----------------------------------------------------------------------------- -# DFrame-subclass collection of cTWAS runs, keyed by the identity tuple -# (gwasStudy, study, context, method). Each row holds a CtwasResultEntry -# payload (fine-mapping posteriors + group priors + region metadata) for one -# run. Unlike the QTL family, `trait` is NOT a key -- cTWAS is multi-gene per -# run, so genes live inside the payload. Optional joint columns (jointStudies, +# RangedTupleList collection of cTWAS runs. A run is keyed by the identity +# tuple (gwasStudy, study, context, method) and, as a genome-wide GWAS fit is +# in a GwasFineMappingResult, split into one element per cTWAS region: the +# element holds that region's gene (and, with keepSnps, SNP) posteriors as +# ranges, and mcols carry the run identity, the region (`blockId`, cTWAS's +# region_id), the region's per-effect susie alpha table (`susieAlpha`), its +# region metadata (`regionInfo`) and the run's jointly-estimated group priors +# (`groupPriors`, repeated on each of the run's rows, as a GWAS fit's +# settings repeat on its blocks). +# +# Unlike the QTL family, `trait` is NOT a key -- cTWAS is multi-gene per run, +# so genes live inside the elements. Optional joint columns (jointStudies, # jointContexts) tag rows born from a multi-study / multi-context cTWAS run and # participate in the uniqueness key, exactly as in the TwasWeights / # FineMappingResultBase families. # ============================================================================= -#' @include AllGenerics.R tupleSelectors.R +#' @include AllGenerics.R tupleSelectors.R RangedTupleList.R CtwasResultEntry.R NULL #' @title cTWAS Result Collection -#' @description S4 collection of cTWAS runs keyed by the identity tuple -#' \code{(gwasStudy, study, context, method)}. Each row holds a -#' \code{\linkS4class{CtwasResultEntry}} payload -- fine-mapping posteriors, -#' the jointly-estimated group priors, and region metadata -- for one run. +#' @description S4 collection of cTWAS runs, each keyed by the identity tuple +#' \code{(gwasStudy, study, context, method)} and split into one element per +#' cTWAS region, the way a \code{\linkS4class{GwasFineMappingResult}} holds +#' a genome-wide fit as one element per LD block. An element is a +#' \code{GRanges} of that region's gene (and, with \code{keepSnps}, SNP) +#' posteriors; \code{mcols()} carry the run identity, the region +#' (\code{blockId}), the region's per-effect susie alpha table +#' (\code{susieAlpha}), its region metadata (\code{regionInfo}) and the +#' run's jointly-estimated group priors (\code{groupPriors}), which repeat +#' on each of the run's rows. #' @details Unlike the QTL family, \code{trait} is not part of the key: a cTWAS -#' run is multi-gene, so genes live inside the payload. The optional +#' run is multi-gene, so genes live inside the elements. The optional #' \code{jointStudies} / \code{jointContexts} columns tag rows born from a #' multi-study or multi-context run and participate in the uniqueness key, #' exactly as in the \code{\linkS4class{TwasWeights}} and fine-mapping -#' families. +#' families. \code{\link{ctwasPosteriors}} and \code{\link{susieAlpha}} +#' stack every region back into one \code{GRanges}. #' @seealso \code{\link{CtwasResult}} for the constructor and #' \code{\link{ctwasPipeline}} for the pipeline that builds one. #' @export -setClass("CtwasResult", contains = "DFrame", validity = function(object) { - .validateCtwasResult(object) -}) +setClass( + "CtwasResult", + contains = "RangedTupleList", + validity = function(object) .validateCtwasResult(object) +) + +# The run identity every row carries, and the per-region payload columns. +# @noRd +.CTWAS_ID_COLS <- c("gwasStudy", "study", "context", "method") + +# @noRd +.CTWAS_PAYLOAD_COLS <- c("susieAlpha", "regionInfo", "groupPriors") # ---- CtwasResult validity helpers ------------------------------------------ -# Collect all contract violations (empty vector = valid). Entry checks run only -# once the required columns are present. +# Collect all contract violations (TRUE when there are none). The identity and +# uniqueness checks run only once the required columns are present. # @noRd #' @importFrom checkmate makeAssertCollection assertNames .validateCtwasResult <- function(object) { + cols <- colnames(mcols(object, use.names = FALSE)) coll <- makeAssertCollection() assertNames( - names(object), - must.include = c("gwasStudy", "study", "context", "method", "entry"), + cols, + must.include = c(.CTWAS_ID_COLS, "blockId", .CTWAS_PAYLOAD_COLS), what = "colnames", .var.name = "columns", add = coll @@ -52,40 +76,12 @@ setClass("CtwasResult", contains = "DFrame", validity = function(object) { if (!coll$isEmpty()) { return(coll$getMessages()) } - coll$push(.ctwasResCheckEntries(object)) - coll$getMessages() -} - -# @noRd -.ctwasResCheckEntries <- function(object) { - jointCols <- intersect(c("jointStudies", "jointContexts"), names(object)) - c( - .ctwasResCheckEntryLength(object), - .ctwasResCheckEntryTypes(object), + jointCols <- intersect(c("jointStudies", "jointContexts"), cols) + problems <- c( .ctwasResCheckJointCols(object, jointCols), .ctwasResCheckTupleUniqueness(object, jointCols) ) -} - -# @noRd -.ctwasResCheckEntryLength <- function(object) { - if (length(object$entry) != nrow(object)) { - return("length(entry) must equal nrow(.) for CtwasResult") - } - NULL -} - -# @noRd -.ctwasResCheckEntryTypes <- function(object) { - if (!all(map_lgl(object$entry, .ctwasResIsEntry))) { - return("every element of the `entry` column must be a CtwasResultEntry") - } - NULL -} - -# @noRd -.ctwasResIsEntry <- function(e) { - methods::is(e, "CtwasResultEntry") + if (length(problems) == 0L) TRUE else problems } # @noRd @@ -95,24 +91,26 @@ setClass("CtwasResult", contains = "DFrame", validity = function(object) { # @noRd .ctwasResJointColError <- function(jc, object) { - if (!is.character(object[[jc]])) { + value <- .ctwasResColOf(jc, object) + if (!is.character(value)) { return(glue( - "'{jc}' column must be character (got {class(object[[jc]])[[1L]]})" + "'{jc}' column must be character (got {class(value)[[1L]]})" )) } NULL } +# One row per (run, region): the region joins the run identity in the key. # @noRd .ctwasResCheckTupleUniqueness <- function(object, jointCols) { - keyCols <- c("gwasStudy", "study", "context", "method", jointCols) + keyCols <- c(.CTWAS_ID_COLS, jointCols, "blockId") keyTbl <- as_tibble(set_names( map(keyCols, .ctwasResColOf, object = object), keyCols )) if (nrow(distinct(keyTbl)) < nrow(keyTbl)) { return(str_c( - "(gwasStudy, study, context, method[, joint*]) ", + "(gwasStudy, study, context, method[, joint*], region) ", "tuple uniqueness violated" )) } @@ -121,10 +119,10 @@ setClass("CtwasResult", contains = "DFrame", validity = function(object) { # @noRd .ctwasResColOf <- function(cn, object) { - object[[cn]] + mcols(object, use.names = FALSE)[[cn]] } -# Each joint-provenance column must be one value per row. +# Each joint-provenance column must be one value per run. # @noRd .ctwasCheckJointColLength <- function(nm, val, n) { if (length(val) == n) { @@ -135,28 +133,41 @@ setClass("CtwasResult", contains = "DFrame", validity = function(object) { } #' @title Create a CtwasResult Collection -#' @description Construct a \code{CtwasResult} DFrame-subclass collection of -#' cTWAS runs from per-tuple vectors and a list of -#' \code{\link{CtwasResultEntry}} payloads (one per run). A single-context run -#' is one row; a multi-context run emits per-context rows sharing the same -#' \code{jointContexts} set and jointly-estimated group priors. +#' @description Construct a \code{CtwasResult} collection of cTWAS runs from +#' per-run identity vectors and a list of \code{\link{CtwasResultEntry}} +#' payloads (one per run). Each run is split into one element per cTWAS +#' region -- by the payloads' \code{region_id}, or by chromosome when they +#' carry none -- so a single-context run is one row per region, and a +#' multi-context run emits per-context rows sharing the same +#' \code{jointContexts} set and jointly-estimated group priors. A run whose +#' payload holds no posteriors is kept as one empty element. #' @param gwasStudy Character vector of GWAS (disease) study identifiers. #' @param studyName Character vector of QTL study identifiers. -#' @param context Character vector of context labels (scalar per row). +#' @param context Character vector of context labels (scalar per run). #' @param method Character vector of weight-method names. -#' @param entry List / \code{SimpleList} of \code{CtwasResultEntry} objects. +#' @param entry List / \code{SimpleList} of \code{CtwasResultEntry} objects, +#' one per run; their posteriors and susie alpha tables must be +#' \code{GRanges}, which the pipeline builds them as. #' @param jointStudies Optional character vector (length #' \code{length(gwasStudy)}) listing the joined studies for a multi-study run, #' \code{NA_character_} otherwise. \code{NULL} (default) omits the column. #' @param jointContexts Optional character vector for multi-context runs. Same #' shape as \code{jointStudies}. +#' @param metadata A list of free-form metadata about the collection, +#' as \code{metadata()} holds on any Bioconductor vector. Default +#' \code{list()}. #' @return A \code{CtwasResult} object. #' @examples +#' at <- IRanges::IRanges(c(100L, 200L), width = 1L) #' cre <- CtwasResultEntry( -#' posteriors = data.frame(id = c("g1", "g2"), susie_pip = c(0.9, 0.1)), -#' susieAlpha = data.frame(id = c("g1", "g2"), alpha = c(0.9, 0.1))) -#' cr <- CtwasResult(gwasStudy = "gwas1", studyName = "s1", context = "brain", -#' method = "susie", entry = list(cre)) +#' posteriors = GenomicRanges::GRanges("chr1", at, +#' id = c("g1", "g2"), region_id = "chr1_1_1000", +#' susie_pip = c(0.9, 0.1)), +#' susieAlpha = GenomicRanges::GRanges("chr1", at, +#' id = c("g1", "g2"), region_id = "chr1_1_1000", +#' susie_alpha = c(0.9, 0.1))) +#' cr <- CtwasResult(gwasStudy = "gwas1", studyName = "s1", +#' context = "brain", method = "susie", entry = list(cre)) #' cr #' @export CtwasResult <- function( @@ -166,44 +177,207 @@ CtwasResult <- function( method, entry, jointStudies = NULL, - jointContexts = NULL + jointContexts = NULL, + metadata = list() ) { n <- length(gwasStudy) - if ( - length(studyName) != n || - length(context) != n || - length(method) != n || - length(entry) != n - ) { - msg <- glue( - "`gwasStudy`, `study`, `context`, `method`, and `entry` must all ", - "have the same length." - ) - abort(msg) - } - cols <- list( - gwasStudy = as.character(gwasStudy), - study = as.character(studyName), - context = as.character(context), - method = as.character(method), - entry = S4Vectors::SimpleList(entry) - ) + .ctwasCheckRunLengths(n, studyName, context, method, entry) supplied <- compact(list( jointStudies = jointStudies, jointContexts = jointContexts )) walk2(names(supplied), supplied, .ctwasCheckJointColLength, n = n) - dfArgs <- c( - cols, - map(supplied, as.character), - list(check.names = FALSE) + entries <- as.list(entry) + walk(seq_along(entries), .ctwasAssertEntry, entries = entries) + identity <- exec( + S4Vectors::DataFrame, + !!!c( + list( + gwasStudy = as.character(gwasStudy), + study = as.character(studyName), + context = as.character(context), + method = as.character(method) + ), + map(supplied, as.character), + list(check.names = FALSE) + ) + ) + .withMetadata( + .ctwasNewResult(identity, map(entries, .ctwasSplitRun)), + metadata ) - df <- exec(S4Vectors::DataFrame, !!!dfArgs) - obj <- new("CtwasResult", df) - validObject(obj) - obj } +# @noRd +.ctwasCheckRunLengths <- function(n, studyName, context, method, entry) { + if ( + length(studyName) == n && + length(context) == n && + length(method) == n && + length(entry) == n + ) { + return(invisible(NULL)) + } + abort(str_c( + "`gwasStudy`, `studyName`, `context`, `method`, and `entry` must ", + "all have the same length." + )) +} + +# A run's payload must be a CtwasResultEntry whose posteriors and susie alpha +# table, when present, are ranges: an element is a GRanges, so a table whose +# ids carry no position has nowhere to go and is refused rather than dropped. +# @noRd +.ctwasAssertEntry <- function(i, entries) { + e <- entries[[i]] + if (!methods::is(e, "CtwasResultEntry")) { + abort(glue( + "CtwasResult: run {i}'s payload must be a CtwasResultEntry ", + "(got {class(e)[[1L]]})." + )) + } + parts <- list(posteriors = e@posteriors, susieAlpha = e@susieAlpha) + tables <- names(parts)[!map_lgl(parts, .ctwasIsRangedOrEmpty)] + if (length(tables) > 0L) { + abort(glue( + "CtwasResult: run {i}'s {str_flatten(tables, ' and ')} carry no ", + "genomic coordinates, so they cannot be placed in a ranged ", + "collection. Build them as GRanges." + )) + } + invisible(NULL) +} + +# @noRd +.ctwasIsRangedOrEmpty <- function(x) { + is.null(x) || methods::is(x, "GRanges") +} + +# ---- splitting a run into its regions --------------------------------------- + +# One run's per-region pieces: the region ids, and for each region its +# posteriors (the element), susie alpha table and region metadata. A run with +# no posteriors at all is one empty region, so it still shows up as a row. +# @noRd +.ctwasSplitRun <- function(e) { + post <- e@posteriors %||% GenomicRanges::GRanges() + sa <- e@susieAlpha %||% GenomicRanges::GRanges() + regions <- unique(c(.ctwasRegionKeys(post), .ctwasRegionKeys(sa))) + if (length(regions) == 0L) { + regions <- NA_character_ + } + list( + blockId = regions, + elements = map(regions, .ctwasRegionSlice, gr = post), + susieAlpha = map(regions, .ctwasRegionSlice, gr = sa), + regionInfo = map(regions, .ctwasRegionInfoSlice, ri = e@regionInfo), + groupPriors = rep(list(e@groupPriors), length(regions)) + ) +} + +# Which region each range belongs to: cTWAS's region_id, or, for a payload +# built without one, the chromosome it sits on. +# @noRd +.ctwasRegionKeys <- function(gr) { + if (is_in("region_id", colnames(mcols(gr)))) { + return(as.character(mcols(gr)$region_id)) + } + as.character(seqnames(gr)) +} + +# @noRd +.ctwasRegionSlice <- function(region, gr) { + if (is.na(region)) { + return(gr[0L]) + } + gr[.ctwasRegionKeys(gr) == region] +} + +# The region's own metadata row, or the run's table as given when it is not +# keyed by region_id. +# @noRd +.ctwasRegionInfoSlice <- function(region, ri) { + table <- .ctwasRegionInfoTable(ri) + if ( + is.null(table) || !is_in("region_id", colnames(table)) || is.na(region) + ) { + return(ri) + } + hit <- as.character(table$region_id) == region + if (methods::is(ri, "GRanges")) { + return(ri[hit]) + } + ri[hit, , drop = FALSE] +} + +# Region metadata's columns, whichever form it was built in. +# @noRd +.ctwasRegionInfoTable <- function(ri) { + if (methods::is(ri, "GRanges")) mcols(ri) else ri +} + +# Every run's regions as one collection: the run identity repeated across +# its regions, the region's payload columns beside it. +# @noRd +.ctwasNewResult <- function(identity, runs) { + reps <- rep(seq_along(runs), map_int(runs, .ctwasRunSize)) + pieces <- c("susieAlpha", "regionInfo", "groupPriors") + payload <- set_names(map(pieces, .ctwasPayloadColumn, runs = runs), pieces) + md <- cbind( + identity[reps, , drop = FALSE], + exec( + S4Vectors::DataFrame, + !!!c( + list(blockId = list_c(map(runs, "blockId")) %||% character(0)), + payload, + list(check.names = FALSE) + ) + ) + ) + elements <- list_flatten(map(runs, "elements")) + grl <- S4Vectors::`mcols<-`(.rtlBindElements(unname(elements)), value = md) + new("CtwasResult", .rtlNamed(grl)) +} + +# @noRd +.ctwasRunSize <- function(run) { + length(run$blockId) +} + +# @noRd +.ctwasPayloadColumn <- function(piece, runs) { + S4Vectors::SimpleList(list_flatten(map(runs, piece))) +} + +# Before it held one element per region, a CtwasResult was a DFrame of whole +# runs, one CtwasResultEntry per row in an `entry` column; an object saved +# then still carries that table as its `listData` attribute. It is rebuilt +# through the constructor, which splits each run into its regions. +#' @rdname updateObject-methods +#' @export +setMethod( + "updateObject", + "CtwasResult", + function(object, ..., verbose = FALSE) { + if (isTRUE(verbose)) { + message("updateObject(object = 'CtwasResult')") + } + old <- attr(object, "listData", exact = TRUE) + if (is.null(old)) { + return(methods::callNextMethod(object, ..., verbose = verbose)) + } + CtwasResult( + gwasStudy = old$gwasStudy, + studyName = old$study, + context = old$context, + method = old$method, + entry = as.list(old$entry), + jointStudies = old$jointStudies, + jointContexts = old$jointContexts + ) + } +) + #' @rdname methodNames #' @export setMethod("methodNames", "CtwasResult", function(x) { @@ -220,40 +394,53 @@ setMethod("contexts", "CtwasResult", function(x) { unique(as.character(x$context)) }) -# Aggregate a per-entry table (finemap or susieAlpha) across all rows, prefixing -# each with the row's (gwasStudy, study, context, method) run identity. +# Stack a per-region ranged payload (the posteriors, or the susie alpha +# tables) across all rows: every row's ranges, its columns kept as mcols and +# prefixed with the row's (gwasStudy, study, context, method) run identity. +# Columns a row lacks are NA-filled. # @noRd -.ctwasAggregateRows <- function(x, getter) { - n <- nrow(x) - if (n == 0L) { - return(NULL) - } +.ctwasAggregateRows <- function(x, payloads) { parts <- compact( - map(seq_len(n), .ctwasAggregateRow, x = x, getter = getter) + map(seq_along(payloads), .ctwasAggregateRow, x = x, payloads = payloads) ) if (length(parts) == 0L) { - return(NULL) + return(GenomicRanges::GRanges()) } - .rbindAligned(parts) + ranges <- exec(c, !!!map(unname(parts), GenomicRanges::granges)) + out <- S4Vectors::`mcols<-`( + ranges, + value = S4Vectors::DataFrame( + .rbindAligned(map(parts, .ctwasRowTable)), + check.names = FALSE + ) + ) + .withGenome(out, .oneBuild(x)) } #' @rdname ctwasPosteriors #' @export setMethod("ctwasPosteriors", "CtwasResult", function(x) { - .ctwasAggregateRows(x, ctwasPosteriors) + .ctwasAggregateRows(x, as.list(x)) }) #' @rdname susieAlpha #' @export setMethod("susieAlpha", "CtwasResult", function(x) { - .ctwasAggregateRows(x, susieAlpha) + .ctwasAggregateRows(x, as.list(x$susieAlpha)) }) #' @rdname show-methods #' @export setMethod("show", "CtwasResult", function(object) { - cat(glue("CtwasResult: {nrow(object)} run(s)\n", .trim = FALSE)) - if (nrow(object) > 0L) { + runs <- distinct(as_tibble( + as.data.frame(mcols(object, use.names = FALSE)[, .CTWAS_ID_COLS]) + )) + cat(glue( + "CtwasResult: {nrow(runs)} run(s) over {length(object)} region ", + "row(s)\n", + .trim = FALSE + )) + if (length(object) > 0L) { cat(glue( " {n_distinct(object$gwasStudy)} GWAS stud(y/ies), ", "{n_distinct(object$method)} method(s): ", @@ -265,45 +452,41 @@ setMethod("show", "CtwasResult", function(object) { # ---- map/apply helpers (lambda-free callbacks) --------------------------- -# A finemap / susieAlpha payload as a flat table. The payloads are ranged now -# (GRanges with the original columns as mcols), so the aggregate view unpacks -# the coordinates back into columns rather than dropping them. +# One row's payload with its run identity attached, ranges and all; NULL when +# the row has none. # @noRd -.ctwasPayloadAsDf <- function(tb) { - if (is.null(tb)) { - return(NULL) - } - if (!methods::is(tb, "GRanges")) { - return(tb) - } - if (length(tb) == 0L) { +.ctwasAggregateRow <- function(i, x, payloads) { + payload <- payloads[[i]] + if (is.null(payload) || length(payload) == 0L) { return(NULL) } - cbind( - data.frame( - chrom = as.character(seqnames(tb)), - start = as.integer(start(tb)), - end = as.integer(GenomicRanges::end(tb)), - stringsAsFactors = FALSE - ), - as.data.frame(mcols(tb)) + md <- mcols(x, use.names = FALSE) + identity <- tibble( + gwasStudy = as.character(md$gwasStudy)[[i]], + study = as.character(md$study)[[i]], + context = as.character(md$context)[[i]], + method = as.character(md$method)[[i]] + ) + # The row identity is authoritative: a payload column of the same name + # (cTWAS's own `context`) gives way to it rather than being duplicated. + own <- .ctwasRowTable(payload) + S4Vectors::`mcols<-`( + payload, + value = S4Vectors::DataFrame( + bind_cols( + slice(identity, rep(1L, length(payload))), + select(own, !any_of(names(identity))) + ), + check.names = FALSE + ) ) } -# One aggregated ctwas row block for entry `i`: `getter`'s per-entry table -# prefixed with the row identity columns; NULL when the entry is empty. +# A ranged row part's columns as a table, for stacking across rows. # @noRd -.ctwasAggregateRow <- function(i, x, getter) { - tb <- .ctwasPayloadAsDf(getter(x$entry[[i]])) - if (is.null(tb) || nrow(tb) == 0L) { - return(NULL) - } - as_tibble(tb) |> - mutate( - gwasStudy = as.character(x$gwasStudy)[[i]], - study = as.character(x$study)[[i]], - context = as.character(x$context)[[i]], - method = as.character(x$method)[[i]], - .before = 1 - ) +.ctwasRowTable <- function(part) { + as_tibble( + as.data.frame(mcols(part), optional = TRUE), + .name_repair = "minimal" + ) } diff --git a/R/CtwasResultEntry.R b/R/CtwasResultEntry.R index f651d7ff..059a8aba 100644 --- a/R/CtwasResultEntry.R +++ b/R/CtwasResultEntry.R @@ -27,6 +27,9 @@ NULL #' \code{group_prior_var} for #' this run, or \code{NULL}. #' @slot regionInfo Per-region metadata, or \code{NULL}. +#' @section Coercion: \code{as(x, "GRanges")} gives the per-gene (and, with +#' SNPs kept, per-SNP) posteriors as ranges -- an error when they could not +#' be placed on the genome and are still a table. #' @seealso \code{\link{CtwasResultEntry}} for the constructor. #' @export setClass( @@ -92,6 +95,31 @@ setMethod("ctwasPosteriors", "CtwasResultEntry", function(x) x@posteriors) #' @export setMethod("susieAlpha", "CtwasResultEntry", function(x) x@susieAlpha) +#' @rdname CtwasResultEntry-class +#' @name coerce,CtwasResultEntry,GRanges-method +#' @aliases coerce,CtwasResultEntry,GRanges-method +#' @usage NULL +#' @exportMethod coerce +setAs("CtwasResultEntry", "GRanges", function(from) { + .ctwasEntryRanges(from@posteriors) +}) + +# Posteriors as ranges: an absent table is no ranges; one the pipeline could +# not place on the genome has no ranges to give. +# @noRd +.ctwasEntryRanges <- function(posteriors) { + if (is.null(posteriors)) { + return(GenomicRanges::GRanges()) + } + if (methods::is(posteriors, "GRanges")) { + return(posteriors) + } + abort(str_c( + "These cTWAS posteriors were not placed on the genome, so they have ", + "no ranges; ctwasPosteriors(x) returns them as a table." + )) +} + #' @rdname ctwasGroupPriors #' @export setMethod( @@ -99,3 +127,44 @@ setMethod( "CtwasResultEntry", function(x) x@groupPriors ) + +#' @rdname show-methods +#' @export +setMethod("show", "CtwasResultEntry", function(object) { + post <- .ctwasPosteriorTable(object@posteriors) + priors <- if (is.null(object@groupPriors)) "not set" else "set" + cat(glue( + "CtwasResultEntry: {.ctwasGeneCount(post)} gene(s) in ", + "{.ctwasRegionCount(post)} region(s); group priors {priors}\n", + .trim = FALSE + )) + invisible(NULL) +}) + +# The posterior table whichever form it is held in: a ranged payload's +# columns, or the table itself. +# @noRd +.ctwasPosteriorTable <- function(posteriors) { + if (methods::is(posteriors, "GRanges")) { + return(as.data.frame(mcols(posteriors))) + } + posteriors %||% data.frame() +} + +# The genes a posterior table scores: its rows that are not SNPs. +# @noRd +.ctwasGeneCount <- function(post) { + if (!is_in("id", colnames(post))) { + return(0L) + } + genes <- if (is_in("type", colnames(post))) post$type != "SNP" else TRUE + length(unique(as.character(post$id[genes]))) +} + +# @noRd +.ctwasRegionCount <- function(post) { + if (!is_in("region_id", colnames(post))) { + return(0L) + } + length(unique(as.character(post$region_id))) +} diff --git a/R/GenotypeHandle.R b/R/GenotypeHandle.R index 133fe441..d52e1eef 100644 --- a/R/GenotypeHandle.R +++ b/R/GenotypeHandle.R @@ -20,15 +20,16 @@ NULL #' the chrom-meta file path (a display/provenance value); the per-chromosome #' payload files live in \code{chromPaths}. #' @slot format Character, \code{"plink2"} or \code{"bgen"}. -#' @slot snpInfo data.frame, SNP metadata read from the index/sidecar. For a -#' sharded handle this is the union across chromosomes (row-bound in the order -#' the shards were supplied), so \code{snpIdx} stays a single global index -#' space. +#' @slot snpInfo data.frame, SNP metadata read from the index/sidecar, its +#' \code{CHR} in UCSC style whatever the file writes. For a sharded handle +#' this is the union across chromosomes (row-bound in the order the shards +#' were supplied), so \code{snpIdx} stays a single global index space. #' @slot nSamples Integer, number of samples. #' @slot sampleIds Character vector of sample identifiers. #' @slot pgenPtr Opaque pointer for PLINK2 reader state (NULL otherwise). -#' @slot chromPaths Named character vector mapping canonical chromosome (e.g. -#' \code{"21"}, \code{"X"}) to the per-chromosome payload path/prefix. Empty +#' @slot chromPaths Named character vector mapping each chromosome, in UCSC +#' style (e.g. \code{"chr21"}, \code{"chrX"}), to the per-chromosome +#' payload path/prefix. Empty #' (\code{character(0)}) for a single-file handle; non-empty marks a #' one-file-per-chromosome (sharded) handle whose extraction is routed by #' chromosome. @@ -133,16 +134,15 @@ setMethod("show", "GenotypeHandle", function(object) { #' \code{NULL}. #' @param ldMeta Path to an LD-meta TSV file (columns \code{chrom}, #' \code{start}, \code{end}, \code{path}; the \code{path} column may be -#' comma-separated as \code{ld_file,bim_file}). Requires \code{region}. The -#' constructor resolves the row covering \code{region}, then delegates to the +#' comma-separated as \code{ld_file,bim_file}). Requires \code{block}. The +#' constructor resolves the row covering \code{block}, then delegates to the #' appropriate file-based handler. When the resolved row points at PLINK2 #' or BGEN files, the corresponding reader is used; a row pointing #' at a pre-computed LD matrix (\code{.cor.xz}) is refused, as pecotmr reads #' no pre-computed LD from disk -- wrap such a matrix in an #' \code{\link{LdMatrix}} instead. -#' @param region Region specification for \code{ldMeta} lookup: -#' \code{"chr:start-end"} string or a one-row data.frame with \code{chrom}, -#' \code{start}, \code{end}. +#' @param block The \code{GRanges} window to look up in \code{ldMeta}; the +#' whole file of the row covering it is opened. #' @param genoMeta One-file-per-chromosome specification: a path to a #' \code{#chr,path} meta file or a named character vector (names = #' chromosomes, values = payload paths/prefixes). Optionally pass @@ -150,8 +150,8 @@ setMethod("show", "GenotypeHandle", function(object) { #' @param chroms Optional character vector of chromosomes. With \code{genoMeta} #' (a sharded, one-file-per-chromosome panel) only the shards whose chromosome #' is listed are read, skipping the rest -- an I/O optimisation when the panel -#' is genome-wide but only a few chromosomes are needed. Chromosome labels are -#' compared canonically (\code{"chr1"}/\code{"1"} match, \code{23}/\code{X} +#' is genome-wide but only a few chromosomes are needed. Chromosome labels may +#' be in any style (\code{"chr1"}/\code{"1"} match, \code{23}/\code{X} #' etc.). If none of the requested chromosomes are present in the panel, every #' shard is read (so the caller's own absence check can report the mismatch). #' Only meaningful with \code{genoMeta}; supplying it with any other source is @@ -169,7 +169,7 @@ GenotypeHandle <- function( pvar = NULL, psam = NULL, ldMeta = NULL, - region = NULL, + block = NULL, genoMeta = NULL, chroms = NULL, format = NULL @@ -182,7 +182,7 @@ GenotypeHandle <- function( pvar = pvar, psam = psam, ldMeta = ldMeta, - region = region + block = block ) sources <- .ghResolveSources( path = path, @@ -198,26 +198,25 @@ GenotypeHandle <- function( path = .readGenotypeHandle(path, format = format), plink2Prefix = .makePlink2Handle(plink2Prefix), plink2Triplet = .genotypeHandleFromPlink2Triplet(pgen, pvar, psam), - ldMeta = .genotypeHandleFromLdMeta(ldMeta, region), + ldMeta = .genotypeHandleFromLdMeta(ldMeta, block), genoMeta = .genotypeHandleFromChromMeta(genoMeta, chroms, format) ) } # Validate the bed/bim/fam + pgen/pvar/psam triplet completeness and the -# ldMeta<->region coupling. Returns list(bedComplete, pgenComplete). +# ldMeta<->block coupling. Returns list(bedComplete, pgenComplete). # @noRd -.ghValidateArgs <- function(bed, bim, fam, pgen, pvar, psam, ldMeta, region) { +.ghValidateArgs <- function(bed, bim, fam, pgen, pvar, psam, ldMeta, block) { bedComplete <- .ghTrioComplete(bed, bim, fam, "bed/bim/fam") pgenComplete <- .ghTrioComplete(pgen, pvar, psam, "pgen/pvar/psam") - if (!is.null(ldMeta) && is.null(region)) { - msg <- glue( - "`ldMeta` requires a `region` (a 'chr:start-end' string or a ", - "one-row data.frame with chrom/start/end)." - ) - abort(msg) + if (!is.null(ldMeta) && is.null(block)) { + abort("`ldMeta` requires `block`, the GRanges window to look up.") } - if (is.null(ldMeta) && !is.null(region)) { - abort("`region` is only meaningful when `ldMeta` is supplied.") + if (is.null(ldMeta) && !is.null(block)) { + abort("`block` is only meaningful when `ldMeta` is supplied.") + } + if (!is.null(block)) { + .assertRegionGRanges(block, "`block`") } list(bedComplete = bedComplete, pgenComplete = pgenComplete) } @@ -288,7 +287,7 @@ GenotypeHandle <- function( .ghResolveLdPath <- function(ldMeta, region) { ldPaths <- regionalLdMeta(ldMeta, region)$intersections$LD_file_paths if (length(ldPaths) == 0L) { - regionStr <- deparse(region) + regionStr <- str_flatten(as.character(region), ", ") msg <- glue( "ldMeta: no LD-meta row covers region {regionStr} ", "in {ldMeta}." @@ -296,7 +295,7 @@ GenotypeHandle <- function( abort(msg) } if (length(ldPaths) > 1L) { - regionStr <- deparse(region) + regionStr <- str_flatten(as.character(region), ", ") msg <- glue( "ldMeta: region {regionStr} spans multiple LD-meta rows; ", "only a region within one row is resolved. Restrict the region ", @@ -306,7 +305,7 @@ GenotypeHandle <- function( } ldPath <- ldPaths[[1L]] if (str_detect(ldPath, regex("\\.cor(\\.xz)?$", ignore_case = TRUE))) { - regionStr <- deparse(region) + regionStr <- str_flatten(as.character(region), ", ") msg <- glue( "ldMeta: the LD-meta row for region {regionStr} points at a ", "pre-computed correlation matrix ({ldPath}). pecotmr does not ", @@ -397,9 +396,9 @@ GenotypeHandle <- function( # One-file-per-chromosome (sharded) handle support # --------------------------------------------------------------------------- -# Chromosome labels are canonicalized via canonChrom() (variantId.R) -- the -# single chromosome normalizer used for @chromPaths routing keys and for -# @snpInfo$CHR lookups, so both sides stay consistent (and X/Y/MT survive). +# Chromosome labels are spelled in UCSC style (withChrPrefix(), variantId.R) +# as a meta or a shard is read, so the @chromPaths routing keys and the +# @snpInfo$CHR lookups compare exactly (and X/Y/M survive). # Per-chromosome shard map, tolerant of GenotypeHandle objects deserialized # from before the `chromPaths` slot existed (e.g. an RDS saved by an older @@ -456,7 +455,7 @@ GenotypeHandle <- function( !is.null(names(genoMeta)) ) { return(.metaCheckUniqueChrom(tibble( - chrom = names(genoMeta), + chrom = withChrPrefix(names(genoMeta)), path = unname(genoMeta) ))) } @@ -506,7 +505,7 @@ GenotypeHandle <- function( ) base <- dirname(normalizePath(genoMeta)) .metaCheckUniqueChrom(tibble( - chrom = as.character(meta[[chromCol]]), + chrom = withChrPrefix(meta[[chromCol]]), path = .metaResolvePaths(as.character(meta[[pathCol]]), base) )) } @@ -608,10 +607,7 @@ GenotypeHandle <- function( if (is.null(chroms)) { return(parsed) } - keep <- is_in( - canonChrom(as.character(parsed$chrom)), - canonChrom(as.character(chroms)) - ) + keep <- is_in(parsed$chrom, withChrPrefix(chroms)) if (any(keep)) filter(parsed, keep) else parsed } @@ -650,7 +646,7 @@ GenotypeHandle <- function( # One shard's chromosome -> path mapping. # @noRd .chromShardPaths <- function(shard) { - chroms <- unique(canonChrom(snpInfo(shard)$CHR)) + chroms <- unique(snpInfo(shard)$CHR) set_names(rep(path(shard), length(chroms)), chroms) } diff --git a/R/GenotypeMixture.R b/R/GenotypeMixture.R index 196e84ef..584276da 100644 --- a/R/GenotypeMixture.R +++ b/R/GenotypeMixture.R @@ -130,7 +130,7 @@ setValidity("GenotypeMixture", function(object) { #' @export GenotypeMixture <- function(panels, mixtureWeights) { .gmAssertPanels(panels) - panels <- map(panels, .asLdRef) + panels <- map(map(panels, .asLdRef), .ucscExperiment) if (!all(map_lgl(panels, .gmIsPanel))) { abort("Every element of `panels` must be a genotype panel.") } @@ -154,9 +154,7 @@ GenotypeMixture <- function(panels, mixtureWeights) { sampleMap = .gmSampleMap(experiments), metadata = list(mixtureWeights = w) ) - obj <- methods::new("GenotypeMixture", mae) - validObject(obj) - obj + methods::new("GenotypeMixture", mae) } # @noRd @@ -335,14 +333,18 @@ setMethod("mixtureWeights", "GenotypeMixture", function(x) { S4Vectors::metadata(x)$mixtureWeights }) +# The canonical chrom:pos:A2:A1 id every class renders; the panels' own labels +# stay in the SNP column of the mixture's ranges. #' @rdname variantIds #' @export setMethod("variantIds", "GenotypeMixture", function(x, ...) { - .ldRefVariantIds(x) + .grVariantIds(.gmRanges(x)) }) #' @rdname GenotypeMixture-class #' @param object A \code{GenotypeMixture}. +#' @return \code{show} is called for its side effect and returns +#' \code{invisible(NULL)}. #' @export setMethod("show", "GenotypeMixture", function(object) { w <- mixtureWeights(object) diff --git a/R/GwasFineMappingResult.R b/R/GwasFineMappingResult.R index ca186b65..4b985caf 100644 --- a/R/GwasFineMappingResult.R +++ b/R/GwasFineMappingResult.R @@ -84,8 +84,8 @@ setClass( .gfmrCheckTupleUniqueness <- function(object) { # Keyed on the element's RANGE rather than on a region_id label. The range # is intrinsic -- it cannot drift out of step with the variants the way a - # stored label can, and it stays correct after subsetRegion() narrows an - # element. Extract key columns directly rather than via `object[, keyCols]`: + # stored label can, and it stays correct after an element is narrowed. + # Extract key columns directly rather than via `object[, keyCols]`: # column-subsetting preserves the class, and older S4Vectors revalidates # that intermediate, spuriously failing. if (length(object) == 0L) { @@ -96,7 +96,7 @@ setClass( map(keyCols, .gfmrColOf, object = object), keyCols )) |> - mutate(range = .rtlRangeKeys(object)) + mutate(range = .keyEmptyElements(object, .rtlRangeKeys(object))) if (nrow(distinct(keyTbl)) < nrow(keyTbl)) { return("(study, method, range) tuple uniqueness violated") } @@ -118,16 +118,18 @@ setClass( #' #' Rows are identified by (\code{study}, \code{method}) plus the element's #' own range, which is derived from the variants rather than stored, so it -#' cannot drift out of step with them and stays correct after -#' \code{\link{subsetRegion}}. +#' cannot drift out of step with them and stays correct when an element's +#' variants are narrowed. #' @param studyName Character vector of study identifiers (per tuple). #' @param method Character vector of fine-mapping method names (per tuple). #' @param entry List / \code{SimpleList} of \code{FineMappingRow} objects. -#' @param blockId Optional character vector (per tuple) keying the external LD -#' block manifest, e.g. \code{"chr22_10516173_17414263"}. Provenance only, -#' not part of the identity key. Supply it when the block BOUNDARIES matter: -#' those are the one thing not recoverable from the variants, since adjacent -#' blocks' spans leave gaps. +#' @param blockId Optional character vector (per tuple) naming each row's +#' block, e.g. \code{"chr22_10516173_17414263"}. Provenance only, not part +#' of the identity key, and a name only: a block's boundaries, which the +#' variants cannot give since adjacent blocks' spans leave gaps, go in +#' \code{region}. Where it is \code{NULL}, or \code{NA} for a row, the +#' row's \code{blockId} is its own span, as \code{"chrom_start_end"}, so +#' every row is named by its block. #' @param dataType Optional assay / modality label ("bulk_rnaseq", #' "methylation"), recorded as a per-row provenance column. Length 1 or #' one per row; \code{NULL} (default) omits the column. @@ -152,14 +154,24 @@ setClass( #' \code{NULL} (default) omits the column. #' @param region Optional per-row analysis WINDOW (a \code{GRanges} or #' \code{NULL}) -- the interval each row's fit was run over, carried -#' forward as provenance; not part of the identity key. \code{NULL} -#' (default) omits the column, and \code{\link{genomicRegion}} then -#' derives the window from the span of the variants present. -#' @return A \code{GwasFineMappingResult} object. +#' forward as provenance; not part of the identity key. It is recorded as +#' given, so each range must contain its row's variants. +#' \code{\link{fineMappingPipeline}} always sets it, from the window of the +#' input row. \code{NULL} (default) omits the column, and +#' \code{\link{genomicRegion}} then derives the window from the span of the +#' variants present. +#' @param metadata A list of free-form metadata about the collection, +#' as \code{metadata()} holds on any Bioconductor vector. Default +#' \code{list()}. +#' @return A \code{GwasFineMappingResult} object. Its logical +#' \code{regionGiven} column says, per row, whether the window was given +#' or is the span of the variants; \code{\link{fineMappingPipeline}} +#' carries it over from the input. See \code{\linkS4class{GwasSumStats}} +#' for how the pipelines use it. #' @examples #' tl <- data.frame(variant_id = paste0("chr1:", 100 * 1:3, ":A:G"), #' pip = c(0.9, 0.5, 0.1), cs = c(1L, 1L, NA)) -#' fe <- fineMappingRow( +#' fe <- FineMappingRow( #' variantIds = tl$variant_id, susieFit = list(), topLoci = tl) #' GwasFineMappingResult(studyName = "t1", method = "susie", entry = list(fe)) #' @export @@ -173,38 +185,112 @@ GwasFineMappingResult <- function( dataType = NULL, dataSource = NULL, weightStandardized = NULL, - ldReference = NULL + ldReference = NULL, + metadata = list() ) { n <- length(studyName) if (length(method) != n || length(entry) != n) { - abort("`study`, `method`, and `entry` must all have the same length.") + abort( + "`studyName`, `method`, and `entry` must all have the same length." + ) } entry <- map(entry, .asFmRowPayload) .checkRowPayloads(entry, "FineMappingRow", "fine-mapping") + .gfmrRefuseSplitFits(entry) cols <- list( study = as.character(studyName), method = as.character(method), susieFit = S4Vectors::SimpleList(map(entry, susieFit)), - cvResult = S4Vectors::SimpleList(map(entry, cvResult)) + cvResult = S4Vectors::SimpleList(map(entry, cvResult)), + fitVariants = IRanges::CharacterList(map(entry, .fmRowFitVariants)) ) |> - .appendBlockIdCol(blockId, n) |> + .appendBlockIdCol(blockId %||% rep(NA_character_, n), n) |> .appendTraitPosCol(traitPos, n) |> .appendRegionCol(region, n) |> .appendFmProvenanceCols(dataType, dataSource, weightStandardized, n) + .withMetadata(.gfmrBuild(entry, cols, region, ldReference), metadata) +} + +# The validated collection from its entries and metadata columns. Each +# entry's variants become one ELEMENT, its topLoci that element's inner +# mcols, and its fit/cv payload outer mcols. A multi-seqname entry -- only a +# fit-less one gets this far -- splits by chromosome with its metadata row +# replicated. +# @noRd +.gfmrBuild <- function(entry, cols, region, ldReference) { + n <- length(entry) dict <- .ldRefDict(.ldRefPerTuple(ldReference, n)) dfArgs <- c(cols, list(ldReference = dict$keys, check.names = FALSE)) - # Each entry's variants become one ELEMENT, its topLoci that element's - # inner mcols, and its fit/cv payload outer mcols. A multi-seqname entry - # splits by chromosome with its metadata row replicated. split <- .rtlSplitBySeqname(map(entry, variants)) - md <- exec(S4Vectors::DataFrame, !!!dfArgs) + pieces <- .rtlBindElements(split$entry) grl <- S4Vectors::`mcols<-`( - GenomicRanges::GRangesList(split$entry), - value = md[split$fromIdx, , drop = FALSE] + pieces, + value = .gfmrPieceMetadata( + exec(S4Vectors::DataFrame, !!!dfArgs), + split, + .gfmrGivenRegions(region, n), + pieces + ) ) - obj <- new("GwasFineMappingResult", grl, ldReference = dict$refs) - validObject(obj) - obj + new("GwasFineMappingResult", .rtlNamed(grl), ldReference = dict$refs) +} + +# The window each entry was given: its `region`, when the caller passed one. +# A `blockId` is a name, and gives no window. +# @noRd +.gfmrGivenRegions <- function(region, n) { + if (is.null(region)) { + return(list(ranges = .placeholderRanges(n), given = rep(FALSE, n))) + } + list(ranges = .bareRanges(region), given = rep(TRUE, n)) +} + +# Each piece's metadata row: its entry's, replicated across the pieces a +# multi-chromosome entry splits into, and a blockId for every piece -- the +# caller's, else the piece's own span as "chrom_start_end" -- so each row is +# named by its block whether or not the caller named it. An empty piece spans +# nothing and keeps NA. `regionGiven` records which pieces were given their +# range. A row given none stores no `region`, where genomicRegion() reads its +# span, unless another row was given one and the column has to exist. +# @noRd +.gfmrPieceMetadata <- function(md, split, given, pieces) { + out <- md[split$fromIdx, , drop = FALSE] + out$blockId <- coalesce(as.character(out$blockId), .rtlRangeKeys(pieces)) + ranges <- given$ranges[split$fromIdx] + has <- given$given[split$fromIdx] + .refuseUncontainedRegions(ranges, has, pieces, "GwasFineMappingResult") + cols <- .regionColumns(ranges, has, .rowSpanRanges(pieces)) + if (any(cols$regionGiven)) { + out$region <- cols$region + } + out$regionGiven <- cols$regionGiven + out +} + +# A multi-chromosome entry is split into one row per chromosome, its metadata +# copied onto each. Variants and their top-loci split cleanly, but a fit does +# not: its effects span every variant it was given, so each piece would carry +# the whole fit, and coloc and the enrichment would read it once per piece. An +# entry carrying a fit must therefore lie on one chromosome -- one LD block, +# as fineMappingPipeline's entries do. +# @noRd +.gfmrRefuseSplitFits <- function(entry) { + multi <- .multiChromosomeEntries(entry) + bad <- multi[map_lgl(entry[multi], .fmRowCarriesFit)] + if (length(bad) == 0L) { + return(invisible(NULL)) + } + abort(glue( + "GwasFineMappingResult: `entry` element(s) ", + "{str_flatten(utils::head(bad, 5L), ', ')} span more than one ", + "chromosome but carry a single fit, which cannot be split across ", + "rows. Fine-map each LD block separately and pass one entry per block." + )) +} + +# @noRd +.fmRowCarriesFit <- function(e) { + length(susieFit(e)) > 0L || !is.null(cvResult(e)) } # Internal: return integer row indices of `x` where every (column, value) @@ -223,19 +309,27 @@ setMethod("contexts", "GwasFineMappingResult", function(x) NULL) #' @export setMethod("traitNames", "GwasFineMappingResult", function(x) NULL) -# Per-tuple lookup keyed by (study, method, blockId). The generic -# accepts the full set of selectors; `context` / `trait` are QTL-only and a +# One fit, keyed by (study, method): a study fine-mapped block by block is one +# row per LD block, so the fit is all of them; `blockId` picks one block by +# name. The generic accepts +# the full set of selectors; `context` / `trait` are QTL-only and a # GwasFineMappingResult refuses them rather than ignoring them, the same way -# sumStats(GwasSumStats) does. `region` is the per-block disambiguator -# for multi-block genome-wide collections. +# sumStats(GwasSumStats) does. #' @rdname fineMappingResult #' @export setMethod( "fineMappingResult", "GwasFineMappingResult", - function(x, studyName = NULL, context = NULL, trait = NULL, method = NULL) { + function( + x, + studyName = NULL, + context = NULL, + trait = NULL, + method = NULL, + blockId = NULL + ) { .gwasFmrRefuseQtlSelectors(context, trait) - x[.tupleSelectRowGwasFmr(x, studyName, method)] + x[.tupleSelectRowsGwasFmr(x, studyName, method, blockId)] } ) @@ -250,24 +344,11 @@ setMethod( context = NULL, trait = NULL, method = NULL, - region = NULL, - returnList = FALSE + blockId = NULL ) { .gwasFmrRefuseQtlSelectors(context, trait) - idx <- .tupleSelectRowGwasFmr(x, studyName, method, region) - pip <- .fmrRowPip(.fmrRowParts(x, idx)) - if (!isTRUE(returnList)) { - return(pip) - } - # Documented as "a per-entry list keyed by identity tuple"; the QTL - # method has always honoured it and this one silently returned the - # flat vector. A GWAS row is keyed by (study, method). - set_names( - list(pip), - glue( - "{as.character(x$study)[idx]}|{as.character(x$method)[idx]}" - ) - ) + idx <- .tupleSelectRowGwasFmr(x, studyName, method, blockId) + .fmrRowPip(.fmrRowParts(x, idx)) } ) @@ -291,7 +372,7 @@ setMethod( "GwasFineMappingResult has no context or trait axis, so ", "{str_flatten(sprintf('`%s`', bad), ' and ')} ", "{if (length(bad) == 1L) 'does' else 'do'} not select anything. ", - "Select with `study`, `method` and `region`." + "Select with `studyName`, `method` and `blockId`." )) } @@ -302,7 +383,7 @@ setMethod( # Row selector for the base delegating accessors (credibleSets / topLoci / # marginalEffects / susieFit / variantIds live on -# FineMappingResultBase, AllClasses.R). The Gwas selector threads `region`. +# FineMappingResultBase, AllClasses.R). The Gwas selector threads `blockId`. setMethod( ".fmrSelectEntry", "GwasFineMappingResult", @@ -312,14 +393,17 @@ setMethod( context = NULL, trait = NULL, method = NULL, - region = NULL + blockId = NULL ) { # No refusal here, unlike the public accessors: this is the blind # delegation point for the shared base accessors, and callers such # as the VCF writer thread a whole selector record through it # without knowing the class. The user-facing entry points are where # a QTL-only selector is a mistake worth reporting. - .fmrRowParts(x, .tupleSelectRowGwasFmr(x, studyName, method, region)) + .fmrRowParts( + x, + .tupleSelectRowGwasFmr(x, studyName, method, blockId) + ) } ) diff --git a/R/LdBlocks.R b/R/LdBlocks.R index 25c2401b..a18f98e6 100644 --- a/R/LdBlocks.R +++ b/R/LdBlocks.R @@ -11,50 +11,10 @@ #' @include AllGenerics.R NULL -# Coerce an LD-block specification to the GRanges the splitters consume. -# -# Accepts a `GRanges`, a data.frame with chrom/start/end (plus an optional -# `blockId`), or a path to a delimited file holding those columns. +# Coerce an LD-block specification to the GRanges the splitters consume: a +# GRanges, or the path of a BED file, read as BED. The rules are those of +# every window argument (.asRegionRanges()). # @noRd .asLdBlockRanges <- function(x) { - if (methods::is(x, "GRanges")) { - return(x) - } - if (is.character(x) && length(x) == 1L) { - x <- .readManifest(x) - } - if (!is.data.frame(x)) { - msg <- glue( - "`ldBlocks` must be a GRanges, a data.frame with ", - "chrom/start/end, or a path to one (got {class(x)[[1L]]})." - ) - abort(msg) - } - .ldBlockTableToRanges(x) -} - -# One block per row. `blockId` is carried into mcols when present so the key -# survives; without it the splitter falls back to the block's coordinates. -# @noRd -#' @importFrom checkmate assertNames -.ldBlockTableToRanges <- function(df) { - assertNames( - colnames(df), - must.include = c("chrom", "start", "end"), - what = "colnames", - .var.name = "ldBlocks table" - ) - exec( - GenomicRanges::GRanges, - seqnames = as.character(df$chrom), - ranges = IRanges::IRanges( - start = as.integer(df$start), - end = as.integer(df$end) - ), - !!!compact(list( - blockId = if (is_in("blockId", colnames(df))) { - as.character(df$blockId) - } - )) - ) + .asRegionRanges(x, "`ldBlocks`") } diff --git a/R/LdEigen.R b/R/LdEigen.R index b1daeb3d..29ae76d0 100644 --- a/R/LdEigen.R +++ b/R/LdEigen.R @@ -82,7 +82,8 @@ setClass( #' @param snpInfo A \code{data.frame} with columns \code{SNP}, \code{CHR}, #' \code{BP}, \code{A1}, \code{A2} (and optionally \code{MAF}). #' @param eigenList A list with one entry per LD block. -#' @param ldBlocks A \code{GRanges} of LD block intervals. +#' @param ldBlocks The LD block intervals: a \code{GRanges}, or the path +#' of a BED file, read as BED with a 0-based start. #' @param nSamples Integer, sample size of the LD reference panel. #' @param inSample Logical, whether the reference is the GWAS cohort. #' @param genome Character, genome build; recorded in \code{seqinfo()}. @@ -115,7 +116,7 @@ LdEigen <- function( assertDataFrame(snpInfo) assertList(eigenList) assertCount(nSamples, positive = TRUE) - obj <- methods::new( + methods::new( "LdEigen", .ldStatRanges(snpInfo, genome), ldBlocks = .asLdBlockRanges(ldBlocks), @@ -124,8 +125,6 @@ LdEigen <- function( eigenList = eigenList, eigenvalueTruncation = as.numeric(eigenvalueTruncation) ) - validObject(obj) - obj } #' @importFrom checkmate assertCount assertFlag @@ -148,8 +147,8 @@ LdEigen <- function( #' standard error from a delete-one-block jackknife, so it requires at #' least two blocks and wants many more. #' @param ldBlocks With a genotype panel, the LD blocks to cut it into: a -#' \code{GRanges}, or a data frame with columns \code{chrom}, \code{start} -#' and \code{end}. Each block's LD is computed from the panel variants +#' \code{GRanges}, or the path of a BED file, read as BED with a 0-based +#' start. Each block's LD is computed from the panel variants #' inside it; variants outside every block are left out. Not used with #' \code{LdMatrix} blocks. #' @param nSamples Integer, the number of samples the reference's LD was @@ -172,8 +171,8 @@ LdEigen <- function( #' panel <- readGenotypes(plink2Prefix = file.path(system.file("extdata", #' "ld_reference", "chr22", package = "pecotmr"), #' "protocol_example.LD.chr22")) -#' blocks <- data.frame(chrom = "chr22", start = c(10000000, 15000001), -#' end = c(15000000, 19000000)) +#' blocks <- GenomicRanges::GRanges("chr22", +#' IRanges::IRanges(c(10000000, 15000001), c(15000000, 19000000))) #' ldEigen <- buildLdEigen(panel, ldBlocks = blocks, genome = "hg38") #' ldEigen #' length(eigenList(ldEigen)) @@ -217,7 +216,7 @@ buildLdEigen <- function( .ldEigenFromPanel <- function(prep, inSample, truncation) { gr <- .ldStatRanges(prep$snpInfo, prep$genome) S4Vectors::mcols(gr)$panelRow <- prep$panelRow - obj <- methods::new( + methods::new( "LdEigen", gr, ldBlocks = .asLdBlockRanges(prep$ldBlocks), @@ -227,8 +226,6 @@ buildLdEigen <- function( eigenvalueTruncation = as.numeric(truncation), ldReference = prep$ldReference ) - validObject(obj) - obj } # One block's decomposition, truncated to the leading components carrying diff --git a/R/LdMatrix.R b/R/LdMatrix.R index 59023495..25e4db19 100644 --- a/R/LdMatrix.R +++ b/R/LdMatrix.R @@ -253,15 +253,13 @@ LdMatrix <- function( # @noRd .ldmNew <- function(gr, R, nSamples, mixtureWeights) { - obj <- methods::new( + methods::new( "LdMatrix", gr, correlation = R, nSamples = as.integer(round(nSamples)), mixtureWeights = as.numeric(mixtureWeights) ) - validObject(obj) - obj } # A plain numeric matrix: a Matrix-package matrix is made dense, as every @@ -384,7 +382,7 @@ LdMatrix <- function( out <- tibble( SNP = snp %||% formatVariantId( - canonChrom(as.character(tbl$chrom)), + as.character(tbl$chrom), as.integer(tbl$pos), as.character(tbl$A2), as.character(tbl$A1) @@ -462,15 +460,13 @@ LdMatrix <- function( ) ids <- rownames(ref@correlation)[common] gr <- .ldmMixtureVariants(ref[common], components, aligned, w) - obj <- methods::new( + methods::new( "LdMatrix", gr, correlation = `dimnames<-`(R, list(ids, ids)), nSamples = .ldmMixtureN(map_int(components, nSamples), w), mixtureWeights = w ) - validObject(obj) - obj } # @noRd @@ -605,6 +601,18 @@ setMethod("extractROWS", "LdMatrix", function(x, i) { #' @export setMethod("ldMatrix", "LdMatrix", function(x) x@correlation) +#' @rdname ldMatrix +#' @importFrom S4Arrays as.matrix +#' @export +setMethod("as.matrix", "LdMatrix", function(x, ...) ldMatrix(x)) + +#' @rdname ldMatrix +#' @name coerce,LdMatrix,matrix-method +#' @aliases coerce,LdMatrix,matrix-method +#' @usage NULL +#' @exportMethod coerce +setAs("LdMatrix", "matrix", function(from) ldMatrix(from)) + #' @rdname nSamples #' @export setMethod("nSamples", "LdMatrix", function(x, ...) x@nSamples) @@ -615,10 +623,12 @@ setMethod("mixtureWeights", "LdMatrix", function(x) { if (length(x@mixtureWeights) == 0L) NULL else x@mixtureWeights }) +# The canonical chrom:pos:A2:A1 id every class renders; the labels the matrix +# was given stay in mcols(x)$SNP. #' @rdname variantIds #' @export setMethod("variantIds", "LdMatrix", function(x, ...) { - as.character(S4Vectors::mcols(x)$SNP) + .grVariantIds(methods::as(x, "GRanges")) }) #' @rdname af @@ -631,6 +641,8 @@ setMethod("af", "LdMatrix", function(x, ...) { #' @rdname LdMatrix-class #' @param object An \code{LdMatrix}. +#' @return \code{show} is called for its side effect and returns +#' \code{invisible(NULL)}. #' @export setMethod("show", "LdMatrix", function(object) { n <- if (is.na(object@nSamples)) "unknown" else object@nSamples diff --git a/R/LdScore.R b/R/LdScore.R index 6442a306..c0e2a171 100644 --- a/R/LdScore.R +++ b/R/LdScore.R @@ -64,7 +64,8 @@ setClass( #' ldsc's unbiased r^2, as ldsc's own score files do); further columns are #' annotation-stratified scores. #' @param ldScoreWeights Numeric regression weights, one per variant. -#' @param ldBlocks A \code{GRanges} of LD block intervals. +#' @param ldBlocks The LD block intervals: a \code{GRanges}, or the path +#' of a BED file, read as BED with a 0-based start. #' @param nSamples Integer, sample size of the LD reference panel. #' @param inSample Logical, whether the reference is the GWAS cohort. #' @param genome Character, genome build; recorded in \code{seqinfo()}. @@ -107,7 +108,7 @@ LdScore <- function( ) ) ) - obj <- methods::new( + methods::new( "LdScore", scored, ldBlocks = .asLdBlockRanges(ldBlocks), @@ -115,8 +116,6 @@ LdScore <- function( inSample = isTRUE(inSample), ldMatrixList = ldMatrixList ) - validObject(obj) - obj } #' @importFrom checkmate assertCount assertFlag @@ -148,8 +147,8 @@ LdScore <- function( #' standard error from a delete-one-block jackknife, so it requires at #' least two blocks and wants many more. #' @param ldBlocks With a genotype panel, the LD blocks to cut it into: a -#' \code{GRanges}, or a data frame with columns \code{chrom}, \code{start} -#' and \code{end}. Each block's LD is computed from the panel variants +#' \code{GRanges}, or the path of a BED file, read as BED with a 0-based +#' start. Each block's LD is computed from the panel variants #' inside it; variants outside every block are left out. Not used with #' \code{LdMatrix} blocks. #' @param nSamples Integer, the number of samples the reference's LD was @@ -176,8 +175,8 @@ LdScore <- function( #' panel <- readGenotypes(plink2Prefix = file.path(system.file("extdata", #' "ld_reference", "chr22", package = "pecotmr"), #' "protocol_example.LD.chr22")) -#' blocks <- data.frame(chrom = "chr22", start = c(10000000, 15000001), -#' end = c(15000000, 19000000)) +#' blocks <- GenomicRanges::GRanges("chr22", +#' IRanges::IRanges(c(10000000, 15000001), c(15000000, 19000000))) #' ldScore <- buildLdScore(panel, ldBlocks = blocks, genome = "hg38") #' ldScore #' head(S4Vectors::mcols(ldScore)$ldScores) @@ -380,6 +379,9 @@ setMethod("ldMatrixList", "LdScore", function(x) { # One block's LD matrix computed from the panel an LdScore reads it from. # @noRd .ldScorePanelMatrix <- function(block, ldReference) { - F <- .ldRefFactor(ldReference, block$rows) - list(R = crossprod(F) / (nrow(F) - 1), snpIdx = block$idx) + ldFactor <- .ldRefFactor(ldReference, block$rows) + list( + R = crossprod(ldFactor) / (nrow(ldFactor) - 1), + snpIdx = block$idx + ) } diff --git a/R/LdStatistic.R b/R/LdStatistic.R index bcd87248..1197cd66 100644 --- a/R/LdStatistic.R +++ b/R/LdStatistic.R @@ -228,12 +228,7 @@ setClass( i = "It says where each LD block starts and ends." )) } - # A panel's seqnames are chr-prefixed; a block table may not be. - blocks <- .asLdBlockRanges(ldBlocks) - spans <- GenomeInfoDb::renameSeqlevels( - blocks, - withChrPrefix(GenomeInfoDb::seqlevels(blocks)) - ) + spans <- .asLdBlockRanges(ldBlocks) gr <- .ldRefRanges(panel) hits <- GenomicRanges::findOverlaps(gr, spans) if (anyDuplicated(S4Vectors::queryHits(hits)) > 0L) { @@ -348,7 +343,7 @@ setClass( # silently get a range covering everything between them. # @noRd .h2RefBlockChrom <- function(block) { - chrom <- unique(withChrPrefix(as.character(seqnames(block$gr)))) + chrom <- unique(as.character(seqnames(block$gr))) if (length(chrom) != 1L) { abort(glue( "an LD block spans {length(chrom)} chromosomes ", diff --git a/R/MashPrior.R b/R/MashPrior.R index 878f45e5..d5798176 100644 --- a/R/MashPrior.R +++ b/R/MashPrior.R @@ -130,9 +130,7 @@ setClass( #' @export MashPrior <- function(fullFit = NULL, cvFits = NULL) { assertList(cvFits, null.ok = TRUE) - obj <- new("MashPrior", fullFit = fullFit, cvFits = cvFits) - validObject(obj) - obj + new("MashPrior", fullFit = fullFit, cvFits = cvFits) } #' @rdname fullFit diff --git a/R/MethodOptions.R b/R/MethodOptions.R index 95522d97..786feca7 100644 --- a/R/MethodOptions.R +++ b/R/MethodOptions.R @@ -322,7 +322,6 @@ setClass("MethodOptions", contains = "SimpleList") # is no foreign signature to check against. # @noRd #' @importFrom rlang is_named -#' @importFrom purrr map2_lgl #' @importFrom S4Vectors SimpleList metadata metadata<- .newMethodOptions <- function( callee, @@ -524,24 +523,17 @@ setClass("MethodOptions", contains = "SimpleList") # --- nested per-engine bundles --------------------------------------------- -# Every entry must have been built by a constructor its key accepts. -# Checked before building so the message is the user's, not purrr's "In -# index: 1. With name: foo." framing around it. The acceptable engines come -# from the key's own constructor rather than from the key: several keys may -# share one engine (lasso and enet are both glmnet). `engines` overrides -# that for a key whose paths run more than one -- TWAS's lasso fits with -# glmnet on individual data and with pecotmr's lassosum solver on summary -# statistics, and either constructor is a legitimate way to configure it. +# Every entry must have been built by its key's own constructor, or be a +# plain list, which declares no engine. Checked before building so the +# message is the user's, not purrr's "In index: 1. With name: foo." framing +# around it. The engine to match comes from the key's constructor rather +# than from the key: several keys may share one engine (lasso and enet are +# both glmnet). # @noRd -.nestedAssertEngines <- function(elements, ctors, engines, label) { +.nestedAssertEngines <- function(elements, ctors, label) { declared <- map_chr(elements, .nestedDeclaredEngine) - allowed <- map( - names(elements), - .nestedAllowedEngines, - ctors = ctors, - engines = engines - ) - mismatch <- which(!map2_lgl(declared, allowed, .nestedEngineMatches)) + expected <- map_chr(names(elements), .nestedExpectedEngine, ctors = ctors) + mismatch <- which(!is.na(declared) & declared != expected) if (length(mismatch) == 0L) { return(invisible(NULL)) } @@ -549,27 +541,10 @@ setClass("MethodOptions", contains = "SimpleList") abort(glue( "{label}: the `{names(elements)[i]}` entry was built with the ", "constructor for '{declared[[i]]}', but `{names(elements)[i]}` ", - "uses the ", - "{str_flatten(sprintf(\"'%s'\", allowed[[i]]), ' or ')} ", - "constructor. ", - "{if (length(allowed[[i]]) > 1L) 'Pass one of those' else ", - "'Pass that'}, or a plain list." + "uses the '{expected[[i]]}' constructor. Pass that, or a plain list." )) } -# A plain-list entry declares no engine, so nothing to match. -# @noRd -.nestedEngineMatches <- function(declared, allowed) { - is.na(declared) || is_in(declared, allowed) -} - -# The engines a key accepts: the caller's list for that key when given, -# otherwise the single one the key's own constructor produces. -# @noRd -.nestedAllowedEngines <- function(key, ctors, engines) { - engines[[key]] %||% .nestedExpectedEngine(key, ctors) -} - # The engine a key's own constructor produces, so an entry built by a # different engine's constructor can be told apart from one built by a # sibling key that shares the same engine. diff --git a/R/MethodParam.R b/R/MethodParam.R index d6dddff6..42d60062 100644 --- a/R/MethodParam.R +++ b/R/MethodParam.R @@ -70,8 +70,8 @@ setClassUnion("MethodOptions_OR_NULL", c("MethodOptions", "NULL")) #' does not attempt to mirror its semantics. #' @section List interface: #' A \code{MethodParam} reads like a list: \code{$} and \code{[[} fetch a -#' field, and \code{names()}, \code{length()} and \code{as.list()} describe -#' it. +#' field, \code{$<-} replaces one, and \code{names()}, \code{length()} and +#' \code{as.list()} describe it. #' #' Those last three report only the fields that are \strong{set}. A slot #' holding \code{NULL} is absent from all three, while \code{$} and @@ -179,6 +179,82 @@ setMethod("as.list", "MethodParam", function(x, ...) { set_names(map(set, slot, object = x), set) }) +#' @rdname MethodParam-class +#' @param value The setting's new value; \code{NULL} unsets a setting that +#' may be unset. +#' @return \code{$<-} returns the record rebuilt with that setting replaced. +#' The rebuild goes through the class's own constructor, so the value is +#' normalised and checked exactly as it is when the record is built, and a +#' value the constructor would refuse is refused here too. A setting that +#' cannot change once the record exists is refused, saying why. +#' @export +setReplaceMethod("$", "MethodParam", function(x, name, value) { + .paramReplace(x, name, value) +}) + +# The one replacement path, shared by `$<-` and the deprecated per-field +# setters. `$<-` takes its name literally, so a setter holding the field name +# in a variable cannot reach it through `$<-` itself. +# @noRd +.paramReplace <- function(x, name, value) { + .paramAssertField(x, name) + .paramAssertSettable(x, name) + .paramRebuild(x, name, value) +} + +# Settings `$<-` refuses, by class, and why. CredibleSetParam's L / Lgreedy +# seed each SuSiE-family fit's own arguments, so changing one needs a refit; +# a record that took the new value would look applied without being so. The +# other two are assembled by their constructors from several arguments, so +# there is no single value to put back. +# @noRd +.PARAM_FIXED_FIELDS <- list( + CredibleSetParam = c( + maxNumSingleEffects = str_c( + "it seeds each SuSiE-family fit's own arguments, so changing it ", + "needs a refit" + ), + maxNumSingleEffectsGreedy = str_c( + "it seeds each SuSiE-family fit's own arguments, so changing it ", + "needs a refit" + ) + ), + MashComponentParam = c( + components = str_c( + "MashComponentParam() assembles it from its canonical / pca / ", + "flash / flashNonneg arguments" + ) + ), + PvalMethodsParam = c( + methods = "PvalMethodsParam() assembles it from one argument per method" + ) +) + +# @noRd +.paramAssertSettable <- function(x, name) { + cls <- class(x)[[1L]] + fixed <- .PARAM_FIXED_FIELDS[[cls]] + if (!is_in(name, names(fixed))) { + return(invisible(NULL)) + } + abort(glue( + "`{name}` cannot be replaced on a {cls}: {fixed[[name]]}. Build a new ", + "{cls}() instead." + )) +} + +# The record rebuilt by its own constructor from every current setting plus +# the replaced one. Every settable class's constructor takes exactly its +# slots, so a replacement runs the constructor's normalisation and checks +# rather than a bare slot write that could store what construction refuses. +# @noRd +.paramRebuild <- function(x, name, value) { + cls <- class(x)[[1L]] + fields <- set_names(map(slotNames(x), slot, object = x), slotNames(x)) + fields[name] <- list(value) + exec(get(cls, mode = "function", envir = topenv()), !!!fields) +} + #' @rdname MethodParam-class #' @param object A \code{MethodParam} object. #' @return \code{show} is called for its side effect and returns @@ -1003,6 +1079,9 @@ setValidity("MethodsSelectionParam", function(object) { if (.isMethodParam(value)) { return(.paramNestedText(value)) } + if (methods::is(value, "BiocParallelParam")) { + return(.paramBpparamText(value)) + } if (is.list(value) && !is.null(names(value))) { return(str_flatten(names(value), ", ")) } @@ -1014,6 +1093,15 @@ setValidity("MethodsSelectionParam", function(object) { str_flatten(format(value), ", ") } +# A BiocParallelParam by its class and worker count; format() would print +# the reference object's every field. +# @noRd +#' @importFrom BiocParallel bpnworkers +.paramBpparamText <- function(value) { + n <- bpnworkers(value) + glue("{class(value)[[1L]]} ({n} worker{if (n == 1L) '' else 's'})") +} + # A nested Param by what it CONTAINS, not by its slot names. The # aggregators hold their per-method entries in one list slot, so reporting # slot names would say "components" where the reader wants "pca". diff --git a/R/MultiStudyQtlDataset.R b/R/MultiStudyQtlDataset.R index e9d27060..32ac4fa6 100644 --- a/R/MultiStudyQtlDataset.R +++ b/R/MultiStudyQtlDataset.R @@ -1,11 +1,12 @@ # ============================================================================= # MultiStudyQtlDataset S4 class # ----------------------------------------------------------------------------- -# Multi-study container that holds a named list of individual-level -# QtlDataset objects plus an optional QtlSumStats collection for -# summary-statistic-only studies. Used as the entry point for -# multi-study pipelines (fineMappingPipeline, twasWeightsPipeline) that -# orchestrate joint or per-study analyses across multiple cohorts. +# Multi-study container: a SimpleList of individual-level QtlDataset objects, +# keyed by study, plus an optional QtlSumStats collection for +# summary-statistic-only studies. Used as the entry point for multi-study +# pipelines (fineMappingPipeline, twasWeightsPipeline) that orchestrate joint +# or per-study analyses across multiple cohorts. Being a List, it subsets, +# indexes and maps like one: ms["s1"], ms[["s1"]], names(ms), lapply(ms, f). # ============================================================================= #' @include QtlDataset.R qtlSumStats.R @@ -21,6 +22,12 @@ setClassUnion("QtlSumStats_OR_NULL", c("QtlSumStats", "NULL")) #' \code{QtlSumStats} collection of summary-statistic-only studies. Used as #' the input to multi-study fine-mapping and colocboost-style analyses. #' +#' It is a \code{\link[S4Vectors]{SimpleList}} of the individual-level +#' studies, keyed by study name, so \code{length()}, \code{names()}, +#' \code{[[} and \code{[} address them as on any Bioconductor list; +#' \code{[} keeps the summary-statistic studies whole and still requires two +#' studies in total. +#' #' At least two studies must be present in total, counting \code{qtlDatasets} #' entries plus the studies in \code{sumStats}. #' @@ -29,17 +36,14 @@ setClassUnion("QtlSumStats_OR_NULL", c("QtlSumStats", "NULL")) #' validity). No cross-checking is performed against \code{sumStats} variant #' positions, since summary statistics are already computed and cannot be #' re-aligned at construction time. -#' @slot qtlDatasets A named list of \code{QtlDataset} objects, keyed by study -#' identifier. #' @slot sumStats An optional \code{QtlSumStats} carrying additional #' summary-statistic-only studies. \code{NULL} when absent. #' @export setClass( "MultiStudyQtlDataset", - representation( - qtlDatasets = "list", - sumStats = "QtlSumStats_OR_NULL" - ), + contains = "SimpleList", + representation(sumStats = "QtlSumStats_OR_NULL"), + prototype(elementType = "QtlDataset"), validity = function(object) .validateMultiStudyQtlDataset(object) ) @@ -48,9 +52,10 @@ setClass( # @noRd .validateMultiStudyQtlDataset <- function(object) { # Each stage only makes sense once the previous one holds: the study count - # reads slots the type checks just validated, and trait consistency reads - # across the studies the count check just confirmed. - slotErrors <- .msqdCheckDatasets(object@qtlDatasets) + # reads the list the first check just validated, and trait consistency + # reads across the studies the count check just confirmed. The element + # type is SimpleList's own check (elementType), which runs first. + slotErrors <- .msqdCheckDatasets(as.list(object)) if (length(slotErrors) > 0L) { return(slotErrors) } @@ -70,15 +75,22 @@ setClass( if (!isTRUE(res)) { return(str_c("'qtlDatasets' ", res)) } - .msqdCheckDatasetTypes(qtlDatasets) + NULL } +# SimpleList refuses an element of another class as well, but without naming +# it, so the constructor checks first. # @noRd -.msqdCheckDatasetTypes <- function(qtlDatasets) { - if (any(!map_lgl(qtlDatasets, .msqdIsQtlDataset))) { - return("every element of 'qtlDatasets' must be a QtlDataset") +.msqdAssertDatasetTypes <- function(qtlDatasets) { + bad <- names(qtlDatasets)[!map_lgl(qtlDatasets, .msqdIsQtlDataset)] + if (length(bad) == 0L) { + return(invisible(NULL)) } - NULL + abort(glue( + "every element of `qtlDatasets` must be a QtlDataset; ", + "{str_flatten(bad, ', ')} {if (length(bad) == 1L) 'is' else 'are'} ", + "not." + )) } # @noRd @@ -89,7 +101,7 @@ setClass( # At least 2 studies in total (individual-level + summary-statistic). # @noRd .msqdCheckStudyCount <- function(object) { - nQtl <- length(object@qtlDatasets) + nQtl <- length(object) nSumstats <- if (is.null(object@sumStats)) { 0L } else { @@ -109,12 +121,12 @@ setClass( # identical rowRanges. # @noRd .msqdCheckTraitConsistency <- function(object) { - if (length(object@qtlDatasets) < 2L) { + if (length(object) < 2L) { return(NULL) } - traitRanges <- map(object@qtlDatasets, .msqdTraitRanges) + traitRanges <- map(as.list(object), .msqdTraitRanges) pairs <- utils::combn(seq_along(traitRanges), 2L) - dsNames <- names(object@qtlDatasets) + dsNames <- names(object) list_c(compact(map( seq_len(ncol(pairs)), .msqdPairErrors, @@ -154,7 +166,7 @@ setClass( # One context's (trait, range) pairs in row order. # @noRd .msqdContextTraitRanges <- function(ctx, qd) { - se <- molecularTraits(qd, ctx) + se <- .qtlContextSe(qd, ctx) map( seq_along(rownames(se)), .msqdTraitRangePair, @@ -184,10 +196,10 @@ setClass( # TRUE when trait `tid`'s ranges match across the two datasets. # @noRd .msqdRangesEqual <- function(tid, a, b) { - isTRUE(all.equal( - canonChrom(GenomicRanges::seqnames(a[[tid]])), - canonChrom(GenomicRanges::seqnames(b[[tid]])) - )) && + identical( + as.character(GenomicRanges::seqnames(a[[tid]])), + as.character(GenomicRanges::seqnames(b[[tid]])) + ) && GenomicRanges::start(a[[tid]]) == GenomicRanges::start(b[[tid]]) && GenomicRanges::end(a[[tid]]) == GenomicRanges::end(b[[tid]]) } @@ -242,18 +254,59 @@ setClass( #' @export MultiStudyQtlDataset <- function(qtlDatasets, sumStats = NULL) { assertList(qtlDatasets, min.len = 1L, names = "unique") - obj <- new( + .msqdAssertDatasetTypes(qtlDatasets) + new( "MultiStudyQtlDataset", - qtlDatasets = qtlDatasets, + listData = qtlDatasets, sumStats = sumStats ) - validObject(obj) - obj } -#' @rdname qtlDatasets +# Selecting studies keeps the summary-statistic ones whole, and re-checks the +# result: the stock List subset does not run validity, and a selection below +# two studies in total is not a multi-study dataset. +setMethod("extractROWS", "MultiStudyQtlDataset", function(x, i) { + ans <- methods::callNextMethod() + validObject(ans) + ans +}) + +# Before it became a SimpleList the studies sat in a `qtlDatasets` slot, which +# an object saved then still carries as an attribute; either way they are +# rebuilt through the constructor, each one updated first. +#' @rdname updateObject-methods #' @export -setMethod("qtlDatasets", "MultiStudyQtlDataset", function(x) x@qtlDatasets) +setMethod( + "updateObject", + "MultiStudyQtlDataset", + function(object, ..., verbose = FALSE) { + if (isTRUE(verbose)) { + message("updateObject(object = 'MultiStudyQtlDataset')") + } + studies <- attr(object, "qtlDatasets", exact = TRUE) %||% + attr(object, "listData", exact = TRUE) + sumStats <- .msqdSavedSumStats(object) + MultiStudyQtlDataset( + qtlDatasets = map(studies, updateObject, ..., verbose = verbose), + sumStats = if (is.null(sumStats)) { + NULL + } else { + updateObject(sumStats, ..., verbose = verbose) + } + ) + } +) + +# The summary statistics an object saved under any earlier definition holds, +# NULL when it holds none. slot() rather than attr(): R stores a NULL slot as +# a placeholder symbol, which attr() hands back unconverted. +# @noRd +.msqdSavedSumStats <- function(object) { + if (is.null(attr(object, "sumStats", exact = TRUE))) { + return(NULL) + } + methods::slot(object, "sumStats") +} #' @rdname sumStats #' @export @@ -266,7 +319,7 @@ setMethod("sumStats", "MultiStudyQtlDataset", function(x) x@sumStats) #' @rdname studyName #' @export setMethod("studyName", "MultiStudyQtlDataset", function(x) { - fromQtl <- names(x@qtlDatasets) + fromQtl <- names(x) fromSs <- if (is.null(x@sumStats)) { character(0) } else { @@ -275,11 +328,10 @@ setMethod("studyName", "MultiStudyQtlDataset", function(x) { unique(c(fromQtl, fromSs)) }) - #' @rdname show-methods #' @export setMethod("show", "MultiStudyQtlDataset", function(object) { - nQtl <- length(object@qtlDatasets) + nQtl <- length(object) ssEntries <- if (is.null(object@sumStats)) { 0L } else { @@ -293,7 +345,7 @@ setMethod("show", "MultiStudyQtlDataset", function(object) { if (nQtl > 0L) { cat(glue( " Individual-level studies: ", - "{str_flatten(names(object@qtlDatasets), ', ')}\n", + "{str_flatten(names(object), ', ')}\n", .trim = FALSE )) } diff --git a/R/QtlDataset.R b/R/QtlDataset.R index 0f1a2a13..a2244251 100644 --- a/R/QtlDataset.R +++ b/R/QtlDataset.R @@ -3,10 +3,10 @@ # ----------------------------------------------------------------------------- # Single-study individual-level QTL container, built on MultiAssayExperiment: # one RangedSummarizedExperiment per QTL context, plus a `genotype` experiment -# whose assay reads lazily through a GenotypeHandle. Adds the handle itself and -# constructor-level QC knobs (mafCutoff, macCutoff, xvarCutoff, imissCutoff, -# keepVariants, keepIndel), which the genotypes / residualizedGenotypes -# accessors apply at extraction time. The entry point for individual-level +# whose assay reads lazily through a GenotypeHandle. It holds data only: the QC +# and residualization a run applies are the pipeline's settings +# (GenotypeFilterParam, ResidualizationParam), not stored here. The entry point +# for individual-level # fine-mapping (fineMappingPipeline), TWAS weight learning # (twasWeightsPipeline), and multi-study composition (MultiStudyQtlDataset). # ============================================================================= @@ -47,46 +47,12 @@ NULL #' @slot studyName Character (length 1). Study identifier; used in collection #' classes to tag downstream \code{QtlFineMappingResult} / \code{TwasWeights} #' entries. -#' The \code{genotype} experiment's assay reads through this handle; the -#' extraction accessors read it directly, so that QC can be applied per -#' block. -#' @slot scaleResiduals Logical (length 1). Whether residualization accessors -#' scale residuals to unit variance. -#' @slot mafCutoff Numeric (length 1). Minor allele frequency threshold; -#' variants with \code{MAF < mafCutoff} are dropped at extraction time inside -#' \code{genotypes()} / \code{residualizedGenotypes()}. Default 0 (no -#' filter). -#' @slot macCutoff Numeric (length 1). Minor allele count threshold; converted -#' to a MAF threshold using \code{max(mafCutoff, macCutoff / (2 * n))} where -#' \code{n} is the post-narrowing sample count of the extracted block. Default -#' 0 (no filter). -#' @slot xvarCutoff Numeric (length 1). Per-variant genotype variance threshold; -#' variants with column variance below this are dropped at extraction time. -#' Default 0 (no filter). -#' @slot imissCutoff Numeric (length 1). Per-sample genotype-missingness -#' threshold; samples with a missing-genotype rate above this are dropped at -#' extraction time. Default 0 (no filter). -#' @slot keepVariants Character vector of variant identifiers to retain prior to -#' per-block QC. Length 0 means no restriction. -#' @slot keepIndel Logical (length 1). When \code{FALSE}, indel variants -#' (alleles that are not single nucleotides) are dropped at extraction time. -#' Default \code{TRUE}. #' @importClassesFrom MultiAssayExperiment MultiAssayExperiment #' @export setClass( "QtlDataset", contains = "MultiAssayExperiment", - representation( - studyName = "character", - scaleResiduals = "logical", - mafCutoff = "numeric", - macCutoff = "numeric", - xvarCutoff = "numeric", - imissCutoff = "numeric", - keepVariants = "character", - keepIndel = "logical" - ), - prototype = prototype(keepIndel = TRUE), + representation(studyName = "character"), validity = function(object) .validateQtlDataset(object) ) @@ -105,7 +71,7 @@ setClass( out[nms] } -# Validity for QtlDataset: scalar/cutoff slots, the phenotypes list, and +# Validity for QtlDataset: the study name, the phenotypes list, and # cross-context trait-position consistency. Returns TRUE or an error vector. # @noRd .validateQtlDataset <- function(object) { @@ -117,11 +83,9 @@ setClass( if (length(errors) == 0) TRUE else errors } -# study / scaleResiduals / keepIndel scalars + the four non-negative cutoffs. +# The study name: one non-empty string. # @noRd -#' @importFrom checkmate makeAssertCollection assertString assertLogical -#' @importFrom checkmate assertFlag assertNumber -#' @importFrom purrr walk +#' @importFrom checkmate makeAssertCollection assertString .qtlValidateScalars <- function(object) { coll <- makeAssertCollection() assertString( @@ -130,35 +94,9 @@ setClass( .var.name = "studyName", add = coll ) - assertLogical( - object@scaleResiduals, - len = 1L, - .var.name = "scaleResiduals", - add = coll - ) - assertFlag(object@keepIndel, .var.name = "keepIndel", add = coll) - walk( - c("mafCutoff", "macCutoff", "xvarCutoff", "imissCutoff"), - .qtlValidateCutoff, - object = object, - coll = coll - ) coll$getMessages() } -# Each cutoff slot must be a single finite non-negative number. -# @noRd -#' @importFrom checkmate assertNumber -.qtlValidateCutoff <- function(nm, object, coll) { - assertNumber( - methods::slot(object, nm), - lower = 0, - finite = TRUE, - .var.name = nm, - add = coll - ) -} - # What is wrong with the context names, if anything. The checks are ordered: # a list with no usable names is not also reported as having duplicates. # @noRd @@ -253,13 +191,13 @@ setClass( as.character(c(missingGeno, noContexts)) } -# TRUE when two GRanges share canonical chrom + start + end. +# TRUE when two GRanges share chrom + start + end. # @noRd .qtlSameRange <- function(prev, this) { - isTRUE(all.equal( - canonChrom(GenomicRanges::seqnames(prev)), - canonChrom(GenomicRanges::seqnames(this)) - )) && + identical( + as.character(GenomicRanges::seqnames(prev)), + as.character(GenomicRanges::seqnames(this)) + ) && GenomicRanges::start(prev) == GenomicRanges::start(this) && GenomicRanges::end(prev) == GenomicRanges::end(this) } @@ -371,9 +309,9 @@ setClass( } # A panel that has already been narrowed is refused rather than taken as the -# study's genotypes: narrowing belongs to keepVariants / keepSamples, which -# the extraction path honours, and it is recorded there rather than in which -# panel happened to be passed. +# study's genotypes: the dataset is built from the whole panel and narrowed +# afterwards (x[i, j, ]), so what it holds is not decided by which panel +# happened to be passed. # @noRd .qtlCheckWholePanel <- function(genotypes) { if (!methods::is(genotypes, "RangedSummarizedExperiment")) { @@ -386,8 +324,8 @@ setClass( } abort(glue( "'genotypes' is a subset panel ({got[[1L]]} x {got[[2L]]} of ", - "{full[[1L]]} x {full[[2L]]}); pass the whole panel and narrow with ", - "'keepVariants' / 'keepSamples' instead." + "{full[[1L]]} x {full[[2L]]}); pass the whole panel and subset the ", + "QtlDataset afterwards, with x[i, j, ]." )) } @@ -408,32 +346,14 @@ setClass( #' @param genotypeCovariates Numeric matrix of genotype-derived covariates #' (e.g., ancestry PCs); rows are samples. Becomes the \code{colData} of the #' genotype experiment. -#' @param scaleResiduals Logical (length 1). Default \code{TRUE}. -#' @param genotypeFilterParam Which variants and samples to keep, built with -#' \code{\link{GenotypeFilterParam}}. A bare list is refused, since it -#' cannot be checked. Each field is recorded on the object and applied -#' lazily, at extraction time inside \code{genotypes()} / -#' \code{residualizedGenotypes()}: -#' \itemize{ -#' \item \code{mafCutoff} --- drop variants with -#' \code{MAF < mafCutoff}. Unset means 0 (no filter). -#' \item \code{macCutoff} --- a minor-allele-count threshold, converted -#' to a MAF threshold as \code{max(mafCutoff, macCutoff / (2 * n))} -#' with \code{n} the post-narrowing sample count of the extracted -#' block. Unset means 0. -#' \item \code{xvarCutoff} --- drop variants whose column variance is -#' below this. Unset means 0. -#' \item \code{imissCutoff} --- drop samples whose missing-genotype rate -#' exceeds this. Unset means 0. -#' \item \code{keepSamples} --- subset the dataset to these samples, -#' narrowing \code{colData} and \code{sampleMap} together so the -#' sample set has one home rather than two. Unset, or -#' \code{character(0)}, means no restriction. -#' \item \code{keepVariants} --- retain only these variants, before -#' per-block QC. Unset, or \code{character(0)}, means no restriction. -#' \item \code{keepIndel} --- when \code{FALSE}, drop variants whose -#' alleles are not single nucleotides. Unset means \code{TRUE}. -#' } +#' @details A \code{QtlDataset} holds data only. Which variants and samples +#' an analysis keeps, and whether residuals are scaled, are the pipeline's +#' settings (\code{\link{GenotypeFilterParam}} and +#' \code{\link{ResidualizationParam}} on \code{\link{fineMappingPipeline}}, +#' \code{\link{twasWeightsPipeline}} and \code{\link{colocboostPipeline}}), +#' applied per extracted block. To work with part of the data, subset the +#' dataset itself: \code{x[i, j, k]} narrows features, samples and +#' contexts. #' @return A \code{QtlDataset} object. #' @examples #' panel <- readGenotypes( @@ -458,42 +378,31 @@ QtlDataset <- function( studyName, genotypes, phenotypes, - genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0), - scaleResiduals = TRUE, - genotypeFilterParam = GenotypeFilterParam() + genotypeCovariates = matrix(numeric(0), nrow = 0, ncol = 0) ) { - .assertMethodParam( - genotypeFilterParam, - "GenotypeFilterParam" - ) - filt <- .qtlResolveFilter(genotypeFilterParam) handle <- .qtlValidateInputs(phenotypes, genotypes) - experiments <- c( - set_names( - list(.genotypeExperiment(genotypes, genotypeCovariates)), - .QTL_GENO_EXPERIMENT + # Every experiment's rowRanges in UCSC style, so the dataset's traits and + # variants meet every other range pecotmr holds exactly. + experiments <- map( + c( + set_names( + list(.genotypeExperiment(genotypes, genotypeCovariates)), + .QTL_GENO_EXPERIMENT + ), + as.list(phenotypes) ), - as.list(phenotypes) + .ucscExperiment ) mae <- MultiAssayExperiment::MultiAssayExperiment( experiments = experiments, colData = .qtlPrimaryColData(experiments), sampleMap = .qtlSampleMap(experiments) ) - obj <- methods::new( + methods::new( "QtlDataset", - .qtlRestrictSamples(mae, filt$keepSamples), - studyName = as.character(studyName), - scaleResiduals = isTRUE(scaleResiduals), - mafCutoff = as.numeric(filt$mafCutoff), - macCutoff = as.numeric(filt$macCutoff), - xvarCutoff = as.numeric(filt$xvarCutoff), - imissCutoff = as.numeric(filt$imissCutoff), - keepVariants = as.character(filt$keepVariants), - keepIndel = isTRUE(filt$keepIndel) + mae, + studyName = as.character(studyName) ) - validObject(obj) - obj } #' @describeIn QtlDataset-class Subset by feature, sample and experiment. @@ -746,10 +655,6 @@ setMethod("genotypeCovariates", "QtlDataset", function(x) { `rownames<-`(as.matrix(as.data.frame(cd)), rownames(cd)) } -#' @rdname scaleResiduals -#' @export -setMethod("scaleResiduals", "QtlDataset", function(x) x@scaleResiduals) - #' @rdname genotypeHandle #' @keywords internal setMethod("genotypeHandle", "QtlDataset", function(x) { @@ -762,37 +667,13 @@ setMethod("genotypeHandle", "QtlDataset", function(x) { }) # The genotype experiment's variants, one row per panel row: SNP (the -# panel's own ids), CHR (canonical), BP, A1, A2. Read off its rowRanges, so +# panel's own ids), CHR, BP, A1, A2. Read off its rowRanges, so # genotypes from any backend answer alike. # @noRd .qtlGenotypeVariants <- function(x) { .rangesSnpInfo(SummarizedExperiment::rowRanges(.qtlGenotypeSe(x))) } -#' @rdname qtlDatasetFilters -#' @export -setMethod("mafCutoff", "QtlDataset", function(x) x@mafCutoff) - -#' @rdname qtlDatasetFilters -#' @export -setMethod("macCutoff", "QtlDataset", function(x) x@macCutoff) - -#' @rdname qtlDatasetFilters -#' @export -setMethod("xvarCutoff", "QtlDataset", function(x) x@xvarCutoff) - -#' @rdname qtlDatasetFilters -#' @export -setMethod("imissCutoff", "QtlDataset", function(x) x@imissCutoff) - -#' @rdname qtlDatasetFilters -#' @export -setMethod("keepVariants", "QtlDataset", function(x) x@keepVariants) - -#' @rdname qtlDatasetFilters -#' @export -setMethod("keepIndel", "QtlDataset", function(x) x@keepIndel) - # --- Internal: resolve the variant-selection region for the genotype handle. # Returns a GRanges (one or more ranges). When `traitId` is supplied, expand # each trait's rowRange by `cisWindow` bp and take the union span (per the @@ -823,7 +704,7 @@ setMethod("keepIndel", "QtlDataset", function(x) x@keepIndel) # none of them. # @noRd .qtlTraitRangesInContext <- function(ctx, x, traitId) { - se <- molecularTraits(x, ctx) + se <- .qtlContextSe(x, ctx) hits <- .qtlPresentIndices(traitId, rownames(se)) if (length(hits) == 0L) { return(NULL) @@ -879,9 +760,8 @@ setMethod("keepIndel", "QtlDataset", function(x) x@keepIndel) # A literal `region` GRanges, each range optionally extended by cisWindow. # @noRd #' @importFrom checkmate assertNumber -#' @importFrom checkmate assertClass .qtlLiteralRegion <- function(region, cisWindow) { - assertClass(region, "GRanges") + region <- .assertRegionGRanges(region) if (length(region) == 0L) { abort("`region` must contain at least one range.") } @@ -900,8 +780,8 @@ setMethod("keepIndel", "QtlDataset", function(x) x@keepIndel) # Per-trait genomic position: each trait's OWN rowRanges span across contexts # (union min-start to max-end), WITHOUT the cisWindow expansion. One range per -# traitId (a 0-width chrUn sentinel for a trait absent from every context), for -# threading trait-position provenance onto QtlFineMappingResult / TwasWeights. +# traitId; a trait absent from every context is an error, as a lookup by an +# unknown name is for rowRanges(). # @noRd .qtlTraitPos <- function(x, traitIds) { # Extract chrom/start/end as plain vectors per trait (union span across @@ -909,6 +789,13 @@ setMethod("keepIndel", "QtlDataset", function(x) x@keepIndel) # GRanges with do.call(c, .) can trip S4 seqinfo reconciliation in some # GenomeInfoDb builds, so we avoid it entirely. spans <- map(traitIds, .qtlTraitSpan, x = x, contexts = contexts(x)) + absent <- traitIds[map_lgl(spans, is.null)] + if (length(absent) > 0L) { + abort(glue( + "traitPosition: trait(s) in no context of this QtlDataset: ", + "{str_flatten(absent, ', ')}." + )) + } starts <- map_int(spans, "start") # `set_names()` is vector-only, so name the GRanges through `names<-` # applied as a function -- still a copy, no binding rewritten. @@ -941,7 +828,7 @@ setMethod("keepIndel", "QtlDataset", function(x) x@keepIndel) traitId = tid )) if (length(ranges) == 0L) { - return(list(chr = "chrUn", start = 1L, end = 1L)) + return(NULL) } chrs <- map_chr(ranges, .qtlFirstSeqname) list( @@ -963,11 +850,11 @@ setMethod("keepIndel", "QtlDataset", function(x) x@keepIndel) #' @rdname traitPosition #' @export -setMethod("traitPosition", "QtlDataset", function(x, traitId = NULL) { - tids <- if (is.null(traitId)) { +setMethod("traitPosition", "QtlDataset", function(x, trait = NULL) { + tids <- if (is.null(trait)) { unique(list_c(map(.qtlPhenotypeList(x), rownames))) } else { - as.character(traitId) + as.character(trait) } .qtlTraitPos(x, tids) }) @@ -983,7 +870,7 @@ setMethod("traitPosition", "QtlDataset", function(x, traitId = NULL) { } siChr <- variants$CHR bp <- variants$BP - rChr <- canonChrom(GenomicRanges::seqnames(region)) + rChr <- as.character(GenomicRanges::seqnames(region)) rStart <- GenomicRanges::start(region) rEnd <- GenomicRanges::end(region) if (length(region) == 0L) { @@ -1006,19 +893,14 @@ setMethod("traitPosition", "QtlDataset", function(x, traitId = NULL) { which(siChr == rChr[i] & bp >= rStart[i] & bp <= rEnd[i]) } -# Internal: keepIndel slot read, tolerant of QtlDataset objects serialized -# before the slot existed (treat a missing slot as TRUE = keep indels). -#' @importFrom purrr possibly -.qtlKeepIndel <- function(x) { - isTRUE(possibly(keepIndel, otherwise = TRUE)(x)) -} - -# A GenotypeFilterParam() bundle with every field resolved. Unset fields -# (absent from the bundle) take this constructor's documented defaults -- -# which is what makes the same bundle usable as a specification here and as an -# override in .qtlApplyFilterOverrides, where unset means "leave the slot". +# A GenotypeFilterParam() bundle with every field resolved: an unset field +# (absent from the bundle) takes its default -- 0 for each cutoff, no +# restriction for each keep-list, TRUE for keepIndel. This is the form a +# pipeline threads to every extraction it makes; a dataset records no filter +# of its own, so the accessors extract with the all-default one. # @noRd -.qtlResolveFilter <- function(genotypeFilterParam) { +.qtlResolveFilter <- function(genotypeFilterParam = GenotypeFilterParam()) { + .assertMethodParam(genotypeFilterParam, "GenotypeFilterParam") list( mafCutoff = genotypeFilterParam$mafCutoff %||% 0, macCutoff = genotypeFilterParam$macCutoff %||% 0, @@ -1030,78 +912,25 @@ setMethod("traitPosition", "QtlDataset", function(x, traitId = NULL) { ) } -# Coerce an override, preserving "unset" as NULL. Hoisted rather than written -# inline three times, and not nested, per the package's no-nested-functions -# rule. -# @noRd -.qtlNumOverride <- function(x) { - if (is.null(x)) NULL else as.numeric(x) -} - -# @noRd -.qtlLglOverride <- function(x) { - if (is.null(x)) NULL else as.logical(x) -} - -# @noRd -.qtlChrOverride <- function(x) { - if (is.null(x)) NULL else as.character(x) -} - -# Internal: return a copy of a QtlDataset with the supplied filter cutoffs / -# keep-lists REPLACING the stored slot values (NULL = leave the stored value -# untouched). This lets a pipeline accept per-call filter overrides as ordinary -# arguments instead of forcing callers to mutate @slots directly (which bypasses -# the class's validity checks). Applied against a validated copy. -.qtlApplyFilterOverrides <- function(data, genotypeFilterParam) { - .assertMethodParam( - genotypeFilterParam, - "GenotypeFilterParam" - ) - # discard(is.null), not compact(): a keepVariants of character(0) is a - # real instruction ("restrict to nothing was not asked, keep all"), and - # compact() would drop it along with the unset fields. - overridden <- exec( - methods::initialize, - data, - !!!discard( - list( - mafCutoff = .qtlNumOverride(genotypeFilterParam$mafCutoff), - macCutoff = .qtlNumOverride(genotypeFilterParam$macCutoff), - xvarCutoff = .qtlNumOverride(genotypeFilterParam$xvarCutoff), - imissCutoff = .qtlNumOverride(genotypeFilterParam$imissCutoff), - keepIndel = .qtlLglOverride(genotypeFilterParam$keepIndel), - keepVariants = .qtlChrOverride(genotypeFilterParam$keepVariants) - ), - is.null - ) - ) - keepSamples <- genotypeFilterParam$keepSamples - restricted <- if (is.null(keepSamples)) { - overridden - } else { - .qtlRestrictSamples(overridden, keepSamples) - } - methods::validObject(restricted) - restricted -} - -# Drop samples whose missingness across the block exceeds the dataset's +# Drop samples whose missingness across the block exceeds the filter's # imissCutoff. A cutoff of 0 (or an empty block) keeps every sample. # @noRd -.qtlDropMissingSamples <- function(dosage, x) { - if (imissCutoff(x) <= 0 || nrow(dosage) == 0L || ncol(dosage) == 0L) { +.qtlDropMissingSamples <- function(dosage, filter) { + cutoff <- filter$imissCutoff + if (cutoff <= 0 || nrow(dosage) == 0L || ncol(dosage) == 0L) { return(dosage) } - dosage[rowMeans(is.na(dosage)) <= imissCutoff(x), , drop = FALSE] + dosage[rowMeans(is.na(dosage)) <= cutoff, , drop = FALSE] } -# Internal: extract the panel dosage block (samples x variants) for the -# requested region, narrow to the requested sample set, and apply lazy QC -# (per-sample imiss filter, then per-variant max(mafCutoff, -# macCutoff / (2 * n)) and xvarCutoff filters). Used by genotypes, -# residualizedGenotypes (via genotypes), and maf so all three -# share a single variant/sample selection result. +# Internal: extract the dosage block (samples x variants) for the variants +# in `window` (every variant when NULL), narrow to `samples`, and apply the +# resolved genotype `filter` (.qtlResolveFilter()): per-sample imiss, then +# per-variant max(mafCutoff, macCutoff / (2 * n)) and xvarCutoff. The +# accessors extract the whole dataset with the all-default filter; a +# pipeline passes the window, samples and filter its run settled on, so +# genotypes, allele frequencies and residualized genotypes share one +# selection. # # Returns a list: # geno : numeric matrix (kept samples x kept variants) @@ -1115,24 +944,25 @@ setMethod("traitPosition", "QtlDataset", function(x, traitId = NULL) { # is `pmin(af, 1 - af)`. .qtlExtractBlock <- function( x, - traitId = NULL, - region = NULL, - cisWindow = NULL, - samples = NULL + window = NULL, + samples = NULL, + filter = .qtlResolveFilter() ) { - gr <- .qtlResolveVariantRegion( - x, - traitId = traitId, - region = region, - cisWindow = cisWindow - ) - inRegion <- .qtlVariantIndices(x, gr) + # A pipeline threads its resolved filter to every extraction; a NULL one + # means a call site was missed, which must not pass for "no filter". + if (!is.list(filter) || is.null(filter$mafCutoff)) { + abort( + "No resolved genotype filter reached this extraction.", + .internal = TRUE + ) + } + inRegion <- .qtlVariantIndices(x, window) if (length(inRegion) == 0L) { return(.qtlEmptyBlockAllSamples(x)) } # Apply keepVariants + indel restrictions before materialization so we do # not extract dosage we would immediately drop. - snpIdx <- .qtlNarrowSnpIdx(x, inRegion) + snpIdx <- .qtlNarrowSnpIdx(x, inRegion, filter) if (length(snpIdx) == 0L) { return(.qtlEmptyBlock()) } @@ -1147,7 +977,10 @@ setMethod("traitPosition", "QtlDataset", function(x, traitId = NULL) { return(.qtlEmptyBlockNoSamples(dosage)) } kept <- dosage[keep, , drop = FALSE] - filtered <- .qtlVariantFilters(.qtlDropMissingSamples(kept, x), x) + filtered <- .qtlVariantFilters( + .qtlDropMissingSamples(kept, filter), + filter + ) imputed <- .qtlMeanImpute(filtered$dosage) list( geno = imputed, @@ -1208,16 +1041,16 @@ setMethod("traitPosition", "QtlDataset", function(x, traitId = NULL) { # Narrow the selected variant indices by keepVariants (matched by chrom/pos/ # allele) and, unless kept, by dropping indels. Done before materialization. # @noRd -.qtlNarrowSnpIdx <- function(x, snpIdx) { +.qtlNarrowSnpIdx <- function(x, snpIdx, filter) { si <- .qtlGenotypeVariants(x) - kept <- if (length(keepVariants(x)) == 0L) { + kept <- if (length(filter$keepVariants) == 0L) { snpIdx } else { snpAll <- si$SNP[snpIdx] - km <- matchVariants(snpAll, as.character(keepVariants(x))) + km <- matchVariants(snpAll, as.character(filter$keepVariants)) snpIdx[replace(logical(length(snpAll)), km$idxA, TRUE)] } - if (length(kept) == 0L || .qtlKeepIndel(x)) { + if (length(kept) == 0L || isTRUE(filter$keepIndel)) { return(kept) } # which() (not the mask) so an NA mask drops the variant rather than @@ -1249,7 +1082,7 @@ setMethod("traitPosition", "QtlDataset", function(x, traitId = NULL) { # gives directional `af`; `maf` folds to the minor allele). Returns # list(dosage, maf, af). # @noRd -.qtlVariantFilters <- function(dosage, x) { +.qtlVariantFilters <- function(dosage, filter) { # No zero-variant guard: the only caller returns early when snpIdx is # empty, and extraction preserves the column count (.restoreRequestedOrder # aborts on a mismatch). The body is 0-column safe regardless -- colSums @@ -1261,11 +1094,11 @@ setMethod("traitPosition", "QtlDataset", function(x, traitId = NULL) { afVec <- p mafVec <- pmin(p, 1 - p) effectiveMaf <- max( - mafCutoff(x), - if (nSamp > 0L) macCutoff(x) / (2 * nSamp) else 0 + filter$mafCutoff, + if (nSamp > 0L) filter$macCutoff / (2 * nSamp) else 0 ) byMaf <- !is.na(mafVec) & mafVec >= effectiveMaf - keepVarMask <- if (xvarCutoff(x) <= 0 || nSamp <= 1L) { + keepVarMask <- if (filter$xvarCutoff <= 0 || nSamp <= 1L) { byMaf } else { mu <- if_else(nObs > 0L, sumD / nObs, 0) @@ -1277,7 +1110,7 @@ setMethod("traitPosition", "QtlDataset", function(x, traitId = NULL) { 0 ) varVec <- colSums(centered * centered) / (nSamp - 1L) - byMaf & varVec >= xvarCutoff(x) + byMaf & varVec >= filter$xvarCutoff } list( dosage = dosage[, keepVarMask, drop = FALSE], @@ -1304,105 +1137,74 @@ setMethod("traitPosition", "QtlDataset", function(x, traitId = NULL) { #' @rdname genotypes #' @export -setMethod( - "genotypes", - "QtlDataset", - function( - x, - traitId = NULL, - region = NULL, - cisWindow = NULL, - samples = NULL - ) { - .qtlExtractBlock( - x, - traitId = traitId, - region = region, - cisWindow = cisWindow, - samples = samples - )$geno - } -) +setMethod("genotypes", "QtlDataset", function(x) { + # The whole dataset, unfiltered: narrow it first with x[i, j, ]. + .qtlExtractBlock(x)$geno +}) #' @rdname maf #' @export -setMethod( - "maf", - "QtlDataset", - function(x, region = NULL, cisWindow = NULL, samples = NULL) { - block <- .qtlExtractBlock( - x, - traitId = NULL, - region = region, - cisWindow = cisWindow, - samples = samples - ) - set_names(block$maf, block$variantIds) - } -) +setMethod("maf", "QtlDataset", function(x) { + block <- .qtlExtractBlock(x) + set_names(block$maf, block$variantIds) +}) #' @rdname af #' @export -setMethod( - "af", - "QtlDataset", - function( - x, - traitId = NULL, - region = NULL, - cisWindow = NULL, - samples = NULL - ) { - block <- .qtlExtractBlock( - x, - traitId = traitId, - region = region, - cisWindow = cisWindow, - samples = samples - ) - set_names(block$af, block$variantIds) - } -) +setMethod("af", "QtlDataset", function(x) { + block <- .qtlExtractBlock(x) + set_names(block$af, block$variantIds) +}) #' @rdname molecularTraits #' @export setMethod( "molecularTraits", "QtlDataset", - function( - x, - contexts, - traitId = NULL, - region = NULL, - naAction = c("keep", "drop", "impute"), - outlierAction = c("keep", "drop"), - outlierPvalThreshold = 1e-3, - outlierArgs = CovMcdOptions() - ) { - naAction <- arg_match(naAction) - outlierAction <- arg_match(outlierAction) - .assertMethodOptions(outlierArgs, "CovMcdOptions", "outlierArgs") - .qtlValidateContexts(x, contexts) - out <- .qtlPhenotypeList(x)[contexts] |> - .qtlFilterPhenotypes( - contexts, - traitId, - region, - naAction, - outlierAction, - outlierPvalThreshold, - outlierArgs - ) - if (length(contexts) == 1L) out[[1L]] else out + function(x, context, trait = NULL) { + .qtlMolecularTraits(x, context, trait) } ) +# molecularTraits() for the pipelines, which may also keep only the traits +# positioned inside an analysis `window` (a GRanges) and apply the run's +# resolved phenotype QC (.qtlResolvePhenotypeFilter()). The accessor passes +# neither, so it returns the data as stored. Always a list keyed by context. +# @noRd +.qtlMolecularTraits <- function( + x, + contexts, + traitId = NULL, + window = NULL, + phenotypeFilter = .qtlKeepAllPhenotypes() +) { + .qtlValidateContexts(x, contexts) + .qtlPhenotypeList(x)[contexts] |> + .qtlFilterPhenotypes( + contexts, + traitId, + window, + phenotypeFilter$naAction, + phenotypeFilter$outlierAction, + phenotypeFilter$outlierPvalThreshold, + phenotypeFilter$outlierArgs + ) +} + +# One context's phenotype SummarizedExperiment as stored, for the internal +# callers that hold a single context name and read its traits or ranges. +# @noRd +.qtlContextSe <- function(x, context) { + .qtlValidateContexts(x, context) + .qtlPhenotypeList(x)[[context]] +} + # `contexts` is required and must all be known phenotype contexts. # @noRd .qtlValidateContexts <- function(x, contexts) { if (missing(contexts) || is.null(contexts) || length(contexts) == 0L) { msg <- glue( - "`contexts` is required for molecularTraits(QtlDataset). Pass a ", + "`context` is required for molecularTraits(QtlDataset). Pass a ", "character vector of one or more context names; use ", "contexts(x) to list the available contexts." ) @@ -1432,14 +1234,14 @@ setMethod( set_names(filtered, contexts) } -# Apply the optional trait / region / NA / outlier filters to the per-context +# Apply the optional trait / window / NA / outlier filters to the per-context # phenotype SEs. # @noRd .qtlFilterPhenotypes <- function( out, contexts, traitId, - region, + window, naAction, outlierAction, outlierPvalThreshold, @@ -1450,10 +1252,17 @@ setMethod( } else { .qtlFilterTraits(out, contexts, traitId) } - inRegion <- if (is.null(region)) { + inRegion <- if (is.null(window)) { byTrait } else { - set_names(map(byTrait, .qtlSeInRegion, region = region), contexts) + set_names( + map( + byTrait, + .qtlSeInRegion, + region = .assertRegionGRanges(window, "`window`") + ), + contexts + ) } naHandled <- if (naAction == "keep") { inRegion @@ -1570,29 +1379,47 @@ CovMcdOptions <- function(...) { # robustbase's MCD when it is installed and converges, else the non-robust # colMeans/cov pair. Both fallbacks are announced -- a silently non-robust # estimate would make the outlier rule mean something different from what -# the caller asked for. +# the caller asked for. `singularReported` records that robustbase has +# already warned its MCD covariance is singular, so the caller does not say +# it a second time. # @noRd #' @importFrom rlang try_fetch .qtlOutlierCenterCov <- function(Y, outlierArgs = list()) { # Engine-call exception: robustbase::covMcd is a covariance estimator, # interchangeable with the colMeans/stats::cov fallback above -- a numeric # primitive for outlier detection while a QtlDataset is built. + fallback <- list( + center = colMeans(Y), + cov = stats::cov(Y), + singularReported = FALSE + ) if (!requireNamespace("robustbase", quietly = TRUE)) { msg <- glue( "outlier detection: install 'robustbase' for an MCD-based ", "estimator; falling back to non-robust colMeans/cov." ) inform(msg) - return(list(center = colMeans(Y), cov = stats::cov(Y))) + return(fallback) } mcd <- try_fetch( exec(robustbase::covMcd, Y, !!!as.list(outlierArgs)), - error = function(cnd) NULL + error = function(cnd) { + msg <- glue( + "outlier detection: robustbase's MCD estimator failed; ", + "falling back to non-robust colMeans/cov." + ) + inform(msg, parent = cnd) + NULL + } ) if (is.null(mcd)) { - return(list(center = colMeans(Y), cov = stats::cov(Y))) + return(fallback) } - list(center = mcd$center, cov = mcd$cov) + list( + center = mcd$center, + cov = mcd$cov, + singularReported = !is.null(mcd$singularity) + ) } # Significance: per-sample chi-squared(p) p-value with Bonferroni @@ -1624,11 +1451,15 @@ CovMcdOptions <- function(...) { invCov <- try_fetch( solve(covMat), error = function(cnd) { - msg <- glue( - "outlier detection: the trait covariance is singular; ", - "using a Moore-Penrose pseudo-inverse instead." - ) - inform(msg, parent = cnd) + # When robustbase has already warned that its covariance is + # singular, that warning is the one signal the caller gets. + if (!est$singularReported) { + msg <- glue( + "outlier detection: the trait covariance is singular; ", + "using a Moore-Penrose pseudo-inverse instead." + ) + inform(msg, parent = cnd) + } MASS::ginv(covMat) } ) @@ -1661,31 +1492,29 @@ CovMcdOptions <- function(...) { #' @rdname phenotypeCovariates #' @export -setMethod("phenotypeCovariates", "QtlDataset", function(x, contexts) { - if (missing(contexts) || is.null(contexts) || length(contexts) == 0L) { - abort("`contexts` is required.") +setMethod("phenotypeCovariates", "QtlDataset", function(x, context) { + if (missing(context) || is.null(context) || length(context) == 0L) { + abort("`context` is required.") } available <- contexts(x) - bad <- setdiff(contexts, available) + bad <- setdiff(context, available) if (length(bad) > 0L) { msg <- glue("Unknown context(s): {str_flatten(bad, ', ')}") abort(msg) } - set_names(map(contexts, .qtlContextColData, x = x), contexts) + set_names(map(context, .qtlContextColData, x = x), context) }) -# Whether to scale residual columns to unit variance: the per-call override -# when the bundle sets one, else the dataset's own slot. +# Whether to scale residual columns to unit variance: what the bundle sets, +# else TRUE -- the run's setting, since a dataset records none. A NULL bundle +# answers NULL for the field, so it resolves to TRUE as well. # # Unset (NULL) rather than FALSE means "not asked", the same three-state # convention `residualizePhenotype` / `residualizeGenotype` use -- a flat # formal defaulting to TRUE could not tell "FALSE" from "not given". # @noRd -.qtlScaleResiduals <- function(x, residualizationParam) { - if (is.null(residualizationParam)) { - return(scaleResiduals(x)) - } - residualizationParam$scaleResiduals %||% scaleResiduals(x) +.qtlScaleResiduals <- function(residualizationParam) { + residualizationParam$scaleResiduals %||% TRUE } # Internal: residualize a numeric matrix Y (n x k) against a covariate @@ -1696,6 +1525,11 @@ setMethod("phenotypeCovariates", "QtlDataset", function(x, contexts) { # column to unit standard deviation; constant-valued columns are left # unchanged. .qtlResidualizeQr <- function(Y, C, scaleResiduals = TRUE) { + # A trait filter that keeps none of a context's traits leaves nothing to + # residualize; lm.fit() cannot take a zero-column response. + if (ncol(Y) == 0L) { + return(Y) + } X <- if (is.null(C) || ncol(C) == 0L) { matrix( 1, @@ -1732,7 +1566,7 @@ setMethod("phenotypeCovariates", "QtlDataset", function(x, contexts) { # all available covariates; otherwise validate the requested names are present. # @noRd .qtlResolveOne <- function(ctx, requested, x) { - se <- molecularTraits(x, ctx) + se <- .qtlContextSe(x, ctx) avail <- colnames(SummarizedExperiment::colData(se)) if (is.null(requested)) { return(avail) @@ -1801,7 +1635,7 @@ setMethod("phenotypeCovariates", "QtlDataset", function(x, contexts) { if (length(badKeys) > 0L) { msg <- glue( "`phenotypeCovariates`: list key(s) not in ", - "`contexts`: {str_flatten(badKeys, ', ')}" + "`context`: {str_flatten(badKeys, ', ')}" ) abort(msg) } @@ -1809,8 +1643,8 @@ setMethod("phenotypeCovariates", "QtlDataset", function(x, contexts) { if (length(missingKeys) > 0L) { msg <- glue( "`phenotypeCovariates`: list does not cover all ", - "`contexts`. Per-context lists must have exactly the same context ", - "set as `contexts`. Missing keys: ", + "`context`. Per-context lists must have exactly the same context ", + "set as `context`. Missing keys: ", "{str_flatten(missingKeys, ', ')}" ) abort(msg) @@ -1912,7 +1746,7 @@ setMethod("phenotypeCovariates", "QtlDataset", function(x, contexts) { if (length(keep) == 0L) { return(NULL) } - se <- molecularTraits(x, ctx) + se <- .qtlContextSe(x, ctx) cd <- as.matrix(as.data.frame(SummarizedExperiment::colData(se))) block <- cd[, keep, drop = FALSE] `colnames<-`(block, str_c(ctx, ".", colnames(block))) @@ -2013,18 +1847,22 @@ setMethod("phenotypeCovariates", "QtlDataset", function(x, contexts) { list(G = G[common, , drop = FALSE], C = C[common, , drop = FALSE]) } -.qtlResidualizedGenotypesImpl <- function( +# residualizedGenotypes() for the pipelines: the genotypes of `window` and +# `samples` under the run's resolved genotype `filter`, residualized on the +# covariates of `contexts`. The accessor passes the whole dataset and the +# all-default filter. +# @noRd +.qtlResidualizedGenotypes <- function( x, contexts, - traitId = NULL, - region = NULL, - cisWindow = NULL, + window = NULL, samples = NULL, + filter = .qtlResolveFilter(), residualizationParam = ResidualizationParam() ) { if (missing(contexts) || is.null(contexts) || length(contexts) == 0L) { msg <- glue( - "`contexts` is required for ", + "`context` is required for ", "residualizedGenotypes(QtlDataset). ", "Use contexts(x) to list the available contexts. ", "Pass a single context for per-context mode or multiple ", @@ -2041,13 +1879,7 @@ setMethod("phenotypeCovariates", "QtlDataset", function(x, contexts) { msg <- glue("Unknown context(s): {str_flatten(bad, \', \')}") abort(msg) } - G <- genotypes( - x, - traitId = traitId, - region = region, - cisWindow = cisWindow, - samples = samples - ) + G <- .qtlExtractBlock(x, window, samples, filter)$geno if (ncol(G) == 0L) { return(G) } @@ -2056,7 +1888,7 @@ setMethod("phenotypeCovariates", "QtlDataset", function(x, contexts) { .qtlResidualizeQr( aligned$G, aligned$C, - scaleResiduals = .qtlScaleResiduals(x, residualizationParam) + scaleResiduals = .qtlScaleResiduals(residualizationParam) ) } @@ -2065,27 +1897,29 @@ setMethod("phenotypeCovariates", "QtlDataset", function(x, contexts) { setMethod( "residualizedGenotypes", "QtlDataset", - .qtlResidualizedGenotypesImpl + function(x, context, residualizationParam = ResidualizationParam()) { + .qtlResidualizedGenotypes( + x, + context, + residualizationParam = residualizationParam + ) + } ) -# NA-handled raw phenotypes per context (re-wrapped to a list so single- and -# multi-context callers see the same shape). +# NA-handled raw phenotypes, a list keyed by context. # @noRd -.qtlResidPhenoY <- function(x, contexts, traitId, region, naAction) { - fetched <- molecularTraits( +.qtlResidPhenoY <- function(x, contexts, traitId, window, naAction) { + # Missing values only: outliers are judged on the residualized values. + .qtlMolecularTraits( x, contexts = contexts, traitId = traitId, - region = region, - naAction = naAction + window = window, + phenotypeFilter = list_modify( + .qtlKeepAllPhenotypes(), + naAction = naAction + ) ) - # A single context returns the bare matrix rather than a named list. - Yraw <- if (length(contexts) == 1L) { - set_names(list(fetched), contexts) - } else { - fetched - } - Yraw } # Phenotype and covariate matrices restricted to the samples they share. @@ -2138,27 +1972,23 @@ setMethod( allRes[keep, , drop = FALSE] } -# residualizedPhenotypes worker: resolve covariate inclusion + selections, +# residualizedPhenotypes() worker: resolve covariate inclusion + selections, # NA-handle Y, build the covariate design, and per-context residualize + -# outlier-filter. `p` holds the setMethod args + precomputed missing() flags. +# outlier-filter, under the run's resolved phenotype QC. The pipelines may +# also keep only the traits inside an analysis `window`; the accessor passes +# no window and no QC. Always a list keyed by context. # @noRd -.qtlResidualizedPhenotypesImpl <- function( +.qtlResidualizedPhenotypes <- function( x, contexts, traitId = NULL, - region = NULL, - naAction = c("keep", "drop", "impute"), - outlierAction = c("keep", "drop"), - outlierPvalThreshold = 1e-3, - outlierArgs = CovMcdOptions(), + window = NULL, + phenotypeFilter = .qtlKeepAllPhenotypes(), residualizationParam = ResidualizationParam() ) { if (missing(contexts) || is.null(contexts) || length(contexts) == 0L) { - abort("`contexts` is required for residualizedPhenotypes().") + abort("`context` is required for residualizedPhenotypes().") } - naAction <- arg_match(naAction) - outlierAction <- arg_match(outlierAction) - .assertMethodOptions(outlierArgs, "CovMcdOptions", "outlierArgs") .assertMethodParam( residualizationParam, "ResidualizationParam" @@ -2173,18 +2003,18 @@ setMethod( x, contexts, traitId, - region, - naAction + window, + phenotypeFilter$naAction ) .qtlResidPerContext( contexts, Yraw = Yraw, C = C, x = x, - outlierAction = outlierAction, - outlierPvalThreshold = outlierPvalThreshold, - outlierArgs = outlierArgs, - scaleResiduals = .qtlScaleResiduals(x, residualizationParam) + outlierAction = phenotypeFilter$outlierAction, + outlierPvalThreshold = phenotypeFilter$outlierPvalThreshold, + outlierArgs = phenotypeFilter$outlierArgs, + scaleResiduals = .qtlScaleResiduals(residualizationParam) ) } @@ -2193,7 +2023,19 @@ setMethod( setMethod( "residualizedPhenotypes", "QtlDataset", - .qtlResidualizedPhenotypesImpl + function( + x, + context, + trait = NULL, + residualizationParam = ResidualizationParam() + ) { + .qtlResidualizedPhenotypes( + x, + context, + trait, + residualizationParam = residualizationParam + ) + } ) # What the phenotypes are regressed against: resolve the convenience vs @@ -2241,7 +2083,7 @@ setMethod( outlierArgs, scaleResiduals ) { - out <- set_names( + set_names( map( contexts, .qtlResidualizeContext, @@ -2255,7 +2097,6 @@ setMethod( ), contexts ) - if (length(contexts) == 1L) out[[1L]] else out } #' @rdname show-methods @@ -2287,7 +2128,6 @@ setMethod("show", "QtlDataset", function(object) { " Samples: {nrow(MultiAssayExperiment::colData(object))}\n", .trim = FALSE )) - cat(glue(" Scale residuals: {object@scaleResiduals}\n", .trim = FALSE)) }) # ---- map/apply helpers (lambda-free callbacks) --------------------------- @@ -2309,17 +2149,24 @@ setMethod("show", "QtlDataset", function(object) { se[present, , drop = FALSE] } -# One context's SE restricted to features overlapping `region`. +# One context's SE restricted to features overlapping `region`. A context with +# no trait on the window's chromosomes keeps none, decided before +# overlapsAny(), which would warn that the two share no seqlevel. # @noRd .qtlSeInRegion <- function(se, region) { rr <- SummarizedExperiment::rowRanges(se) + if ( + !any(is_in(as.character(seqnames(rr)), as.character(seqnames(region)))) + ) { + return(se[integer(0), , drop = FALSE]) + } se[IRanges::overlapsAny(rr, region), , drop = FALSE] } # One context's covariate matrix (colData of its phenotype SE). # @noRd .qtlContextColData <- function(ctx, x) { - se <- molecularTraits(x, ctx) + se <- .qtlContextSe(x, ctx) cd <- SummarizedExperiment::colData(se) as.matrix(as.data.frame(cd)) } @@ -2340,7 +2187,7 @@ setMethod("show", "QtlDataset", function(object) { outlierAction, outlierPvalThreshold, outlierArgs = list(), - scaleResiduals = scaleResiduals(x) + scaleResiduals = TRUE ) { .qtlResidualizeContextPheno( Yraw[[ctx]], @@ -2414,12 +2261,10 @@ setClass( #' covariates. \code{NULL} (default) means unset, read as \code{TRUE}. #' @param scaleResiduals Logical. Scale each residual column to unit #' variance, which is what puts a fitted effect on the standardized -#' genotype scale. \code{NULL} (default) means unset, and the accessors -#' fall back to the dataset's own \code{\link{scaleResiduals}} slot -#' (itself \code{TRUE} by default) --- so this is the per-call override of -#' a per-object default, and the only knob the pipelines need: it reaches -#' \code{\link{residualizedGenotypes}} already, which is the one point -#' every individual-level fit draws its genotypes through. +#' genotype scale. \code{NULL} (default) means unset, read as +#' \code{TRUE}. It is the only scale knob the pipelines need: it reaches +#' \code{\link{residualizedGenotypes}}, the one point every +#' individual-level fit draws its genotypes through. #' @param covariateNaAction How missing covariate values are handled when the #' design is assembled: \code{"impute"} or \code{"drop"}. \code{NULL} #' (default) leaves the accessor's own default in place. @@ -2450,6 +2295,36 @@ ResidualizationParam <- function( ) } +# Slots a QtlDataset held before its run settings moved to the pipelines' +# Params (GenotypeFilterParam, ResidualizationParam). An object saved then +# still carries them as attributes, which updateObject() drops. +# @noRd +.QTL_RETIRED_SLOTS <- c( + "scaleResiduals", + "mafCutoff", + "macCutoff", + "xvarCutoff", + "imissCutoff", + "keepVariants", + "keepIndel" +) + +#' @rdname updateObject-methods +#' @export +setMethod("updateObject", "QtlDataset", function(object, ..., verbose = FALSE) { + if (isTRUE(verbose)) { + message("updateObject(object = 'QtlDataset')") + } + trimmed <- reduce(.QTL_RETIRED_SLOTS, .qtlDropAttribute, .init = object) + methods::callNextMethod(trimmed, ..., verbose = verbose) +}) + +# @noRd +.qtlDropAttribute <- function(object, nm) { + attr(object, nm) <- NULL + object +} + #' @rdname GenotypeFilterParam #' @aliases GenotypeFilterParam-class #' @exportClass GenotypeFilterParam @@ -2469,29 +2344,25 @@ setClass( #' @title Genotype Filtering Options #' @description Which variants and samples survive when a genotype matrix is -#' assembled, as one checked bundle. Used by \code{\link{QtlDataset}}, the -#' manifest loaders, and the pipelines that build a dataset. -#' @section Unset versus set: -#' Every field defaults to \code{NULL}, meaning \strong{not set}, and an -#' unset field is absent from the result rather than carried as \code{NULL}. -#' That is what lets one bundle serve two roles: -#' \itemize{ -#' \item to \code{\link{QtlDataset}} it is a \emph{specification}, and -#' an unset field takes that constructor's own default --- \code{0} for -#' each cutoff, \code{character(0)} for each \code{keep}, \code{TRUE} -#' for \code{keepIndel}. -#' \item to a pipeline it is an \emph{override}, and an unset field -#' leaves the dataset's construct-time value alone. -#' } -#' So \code{GenotypeFilterParam(mafCutoff = 0)} and -#' \code{GenotypeFilterParam()} differ: the first pins the cutoff at zero, -#' the second defers. \code{\link{PanelFilterParam}} needs no such -#' distinction and keeps ordinary defaults. +#' assembled, as one checked bundle: the genotype QC of a run of +#' \code{\link{fineMappingPipeline}}, \code{\link{twasWeightsPipeline}} +#' or \code{\link{colocboostPipeline}} on a \code{\link{QtlDataset}}. +#' A \code{QtlDataset} records no filter of its own; \code{keepSamples} +#' narrows it once at the start of the run, and the other fields apply to +#' each extracted block, against that block's samples. +#' @section Unset fields: +#' Every field defaults to \code{NULL}, meaning \strong{not set}: an unset +#' field is absent from the result rather than carried as \code{NULL}, and +#' takes its default when the run resolves the bundle --- \code{0} for +#' each cutoff, no restriction for each \code{keep}, \code{TRUE} for +#' \code{keepIndel}. So \code{GenotypeFilterParam()} filters nothing. #' @param mafCutoff Minor-allele-frequency floor. #' @param macCutoff Minor-allele-count floor; the stricter of this and #' \code{mafCutoff} applies. #' @param xvarCutoff Genotype-variance floor. -#' @param imissCutoff Per-variant missingness ceiling. +#' @param imissCutoff Per-sample missingness ceiling: a sample missing more +#' than this fraction of an extracted block's genotypes is dropped from +#' it. #' @param keepSamples Sample ids to restrict to; \code{character(0)} keeps #' all samples. #' @param keepVariants Variant ids to restrict to; \code{character(0)} keeps @@ -2523,6 +2394,182 @@ GenotypeFilterParam <- function( ) } +# Each cutoff a single finite non-negative number and keepIndel a flag, +# checked where the filter is built, so a bad value is reported against the +# argument that set it rather than surfacing inside an extraction. An unset +# field has nothing to check. +setValidity("GenotypeFilterParam", function(object) { + coll <- makeAssertCollection() + walk( + c("mafCutoff", "macCutoff", "xvarCutoff", "imissCutoff"), + .gfpCheckCutoff, + object = object, + coll = coll + ) + if (!is.null(object@keepIndel)) { + assertFlag(object@keepIndel, .var.name = "keepIndel", add = coll) + } + problems <- coll$getMessages() + if (length(problems) == 0L) TRUE else problems +}) + +# @noRd +.gfpCheckCutoff <- function(nm, object, coll) { + value <- methods::slot(object, nm) + if (is.null(value)) { + return(invisible(NULL)) + } + assertNumber(value, lower = 0, finite = TRUE, .var.name = nm, add = coll) +} + +#' @rdname PhenotypeFilterParam +#' @aliases PhenotypeFilterParam-class +#' @exportClass PhenotypeFilterParam +setClass( + "PhenotypeFilterParam", + contains = "MethodParam", + slots = c( + naAction = "character_OR_NULL", + outlierAction = "character_OR_NULL", + outlierPvalThreshold = "numeric_OR_NULL", + outlierArgs = "MethodOptions_OR_NULL" + ) +) + +#' @title Phenotype Quality-Control Options +#' @description How a run of \code{\link{fineMappingPipeline}}, +#' \code{\link{twasWeightsPipeline}} or \code{\link{colocboostPipeline}} on +#' a \code{\link{QtlDataset}} treats the phenotypes it reads: missing +#' values, and multivariate outlier samples. The phenotype counterpart of +#' \code{\link{GenotypeFilterParam}}. A \code{QtlDataset}'s own accessors +#' (\code{\link{molecularTraits}}, \code{\link{residualizedPhenotypes}}) +#' apply none of it and return the data as stored. +#' @section Unset fields: +#' Every field defaults to \code{NULL}, meaning \strong{not set}, and takes +#' its default when the run resolves the bundle. \code{naAction} resolves +#' to the pipeline's own policy: fine-mapping and TWAS fits cannot take a +#' missing phenotype, so they drop the affected samples (and refuse +#' \code{"keep"}), while colocboost receives the phenotypes as they are. +#' Outliers are kept unless \code{outlierAction = "drop"}. +#' @param naAction How missing phenotype values are handled: \code{"drop"} +#' the samples with any missing value among the selected traits, +#' \code{"impute"} each trait's mean, or \code{"keep"} them as they are. +#' @param outlierAction \code{"keep"} or \code{"drop"} samples flagged as +#' multivariate outliers by a robust (MCD) Mahalanobis distance, computed +#' on the residualized phenotypes. +#' @param outlierPvalThreshold Two-sided p-value below which a sample is an +#' outlier. Default \code{1e-3} when unset. +#' @param outlierArgs A \code{\link{CovMcdOptions}} record of extra arguments +#' for \code{robustbase::covMcd()}, the outlier detector. +#' @return A \code{PhenotypeFilterParam} object, a \code{\link{MethodParam}}. +#' @seealso \code{\link{GenotypeFilterParam}} +#' @examples +#' PhenotypeFilterParam(naAction = "impute", outlierAction = "drop") +#' @importFrom checkmate assertChoice +#' @export +PhenotypeFilterParam <- function( + naAction = NULL, + outlierAction = NULL, + outlierPvalThreshold = NULL, + outlierArgs = NULL +) { + new( + "PhenotypeFilterParam", + naAction = naAction, + outlierAction = outlierAction, + outlierPvalThreshold = outlierPvalThreshold, + outlierArgs = outlierArgs + ) +} + +# Each set field one of its allowed values, checked where the bundle is +# built, so a bad value is reported against the argument that set it. An +# unset field has nothing to check. +setValidity("PhenotypeFilterParam", function(object) { + coll <- makeAssertCollection() + if (!is.null(object@naAction)) { + assertChoice( + object@naAction, + c("drop", "impute", "keep"), + .var.name = "naAction", + add = coll + ) + } + if (!is.null(object@outlierAction)) { + assertChoice( + object@outlierAction, + c("keep", "drop"), + .var.name = "outlierAction", + add = coll + ) + } + if (!is.null(object@outlierPvalThreshold)) { + assertNumber( + object@outlierPvalThreshold, + lower = 0, + upper = 1, + .var.name = "outlierPvalThreshold", + add = coll + ) + } + # Any MethodOptions fits the slot; only a covMcd record means anything to + # the outlier detector, which would otherwise fail on foreign arguments. + if (!is.null(object@outlierArgs)) { + engine <- metadata(object@outlierArgs)$engine + if (!identical(engine, "covMcd")) { + coll$push(glue( + "`outlierArgs` must be built with CovMcdOptions() (got a ", + "record for {engine %||% 'no engine'})." + )) + } + } + problems <- coll$getMessages() + if (length(problems) == 0L) TRUE else problems +}) + +# The run's phenotype QC with every unset field at its default, as a plain +# list the extraction reads. `naDefault` is the pipeline's NA policy and +# `naAllowed` what its fits can take; a choice outside it is refused here, +# naming the pipeline, rather than failing inside a fit. +# @noRd +.qtlResolvePhenotypeFilter <- function( + phenotypeFilterParam, + naDefault, + naAllowed, + caller +) { + .assertMethodParam(phenotypeFilterParam, "PhenotypeFilterParam") + naAction <- phenotypeFilterParam$naAction %||% naDefault + if (!is_in(naAction, naAllowed)) { + abort(glue( + "{caller}: naAction = \"{naAction}\" is not available here; its ", + "fits cannot take a missing phenotype. Use ", + "{str_flatten(str_c('\"', naAllowed, '\"'), ' or ')}." + )) + } + outlierArgs <- phenotypeFilterParam$outlierArgs %||% CovMcdOptions() + .assertMethodOptions(outlierArgs, "CovMcdOptions", "outlierArgs") + list( + naAction = naAction, + outlierAction = phenotypeFilterParam$outlierAction %||% "keep", + outlierPvalThreshold = phenotypeFilterParam$outlierPvalThreshold %||% + 1e-3, + outlierArgs = outlierArgs + ) +} + +# What an accessor applies: nothing. Missing values and outliers are kept, so +# molecularTraits() and residualizedPhenotypes() return the data as stored. +# @noRd +.qtlKeepAllPhenotypes <- function() { + list( + naAction = "keep", + outlierAction = "keep", + outlierPvalThreshold = 1e-3, + outlierArgs = CovMcdOptions() + ) +} + # ============================================================================= # Variant / sample filtering bundles # ----------------------------------------------------------------------------- @@ -2542,10 +2589,9 @@ GenotypeFilterParam <- function( # accept `removeIndels` where nothing reads it -- the failure mode these # constructors exist to prevent. # -# GenotypeFilterParam defaults every field to NULL ("not set") because its -# fields are a SPECIFICATION to QtlDataset and an OVERRIDE to the pipelines; -# absence is what distinguishes "pin this value" from "leave it alone". The -# other two have one meaning each and keep ordinary defaults. +# GenotypeFilterParam defaults every field to NULL ("not set"), resolved to +# its default by .qtlResolveFilter() when a run threads it to its +# extractions; the other two keep ordinary defaults. # # SumstatsCleaningParam sits with them because it runs on the same pass over # the same table, but it is coercion and normalisation (coerceNumeric, diff --git a/R/QtlFineMappingResult.R b/R/QtlFineMappingResult.R index 4910ef1d..482f2a08 100644 --- a/R/QtlFineMappingResult.R +++ b/R/QtlFineMappingResult.R @@ -1,9 +1,10 @@ # ============================================================================= # QtlFineMappingResult S4 class # ----------------------------------------------------------------------------- -# DFrame-subclass collection keyed by the identity tuple (study, context, -# trait, method). Each row holds a FineMappingRow payload. Class-level -# slots: +# RangedTupleList collection keyed by the identity tuple (study, context, +# trait, method). Each element is one fit's variants, with their topLoci +# values as its mcols; the fit and its cross-validation are columns of the +# collection's own mcols. Class-level slots: # * ldReference the LD references RSS-derived fits used, each stored # once; the ldReference mcols column names each row's (NA # for an individual-level fit). @@ -17,14 +18,16 @@ NULL #' @title QTL Fine-Mapping Result Collection #' @description S4 collection of fine-mapping fits for one or more QTL -#' studies on a single LD block. Keyed by the identity tuple -#' \code{(study, context, trait, method)}; each entry is a -#' \code{FineMappingRow}. +#' studies, one row per \code{(study, context, trait, method)} fit. Each +#' element is a fit's variants: a \code{GRanges} on one chromosome whose +#' \code{mcols} hold the per-variant values \code{\link{topLoci}} reads. #' -#' Required columns: \code{study}, \code{context}, \code{trait}, -#' \code{method}, \code{entry}. The 4-tuple is unique. The caller is -#' expected to construct one \code{QtlFineMappingResult} per LD block (no -#' in-class block indexing). +#' Required \code{mcols()} columns: the identity tuple \code{study}, +#' \code{context}, \code{trait} and \code{method}, which is unique, and +#' each row's stored fit \code{susieFit} and cross-validation result +#' \code{cvResult}. The constructor also records \code{fitVariants}, the +#' variants each fit was made with. There is no LD-block axis: a trait's fit +#' is one row wherever its window falls. #' #' Optional columns \code{jointStudies}, \code{jointContexts}, #' \code{jointTraits} appear when the collection contains rows produced by a @@ -62,7 +65,8 @@ setClass( coll$getMessages() } -# Entry-column + region/traitPos + joint-column + tuple-uniqueness contract. +# Payload-column + region/traitPos + joint-column + tuple-uniqueness +# contract. # @noRd .qfmrCheckEntries <- function(object) { jointCols <- intersect( @@ -114,9 +118,7 @@ setClass( # @noRd .qfmrCheckTupleUniqueness <- function(object, jointCols) { keyCols <- c("study", "context", "trait", "method", jointCols) - # Extract key columns directly rather than via `object[, keyCols]`: column- - # subsetting preserves the class while dropping the required `entry` column, - # and older S4Vectors revalidates that intermediate, spuriously failing. + # Read column by column: `[` takes no column index on a collection. keyTbl <- as_tibble(set_names( map(keyCols, .qfmrColOf, object = object), keyCols @@ -149,16 +151,16 @@ setClass( return(invisible(NULL)) } abort(glue( - "`study`, `context`, `trait`, `method`, and `entry` must all ", + "`studyName`, `context`, `trait`, `method`, and `entry` must all ", "have the same length." )) } #' @title Create a QtlFineMappingResult Collection -#' @description Construct a \code{QtlFineMappingResult} DFrame-subclass -#' collection from per-tuple vectors and a list of \code{FineMappingRow} -#' payloads (one per tuple). The optional \code{ldReference} records the LD +#' @description Construct a \code{QtlFineMappingResult} collection from +#' per-tuple vectors and a list of \code{FineMappingRow} payloads (one per +#' tuple). The optional \code{ldReference} records the LD #' reference each RSS-derived fit used; leave it \code{NULL} (the default) #' for individual-level fits. #' @param studyName Character vector of study identifiers (per tuple). Use the @@ -204,11 +206,14 @@ setClass( #' forward as provenance; not part of the identity key. \code{NULL} #' (default) omits the column, and \code{\link{genomicRegion}} then #' derives the window from the span of the variants present. +#' @param metadata A list of free-form metadata about the collection, +#' as \code{metadata()} holds on any Bioconductor vector. Default +#' \code{list()}. #' @return A \code{QtlFineMappingResult} object. #' @examples #' tl <- data.frame(variant_id = paste0("chr1:", 100 * 1:3, ":A:G"), #' pip = c(0.9, 0.5, 0.1), cs = c(1L, 1L, NA)) -#' fe <- fineMappingRow( +#' fe <- FineMappingRow( #' variantIds = tl$variant_id, susieFit = list(), topLoci = tl) #' QtlFineMappingResult(studyName = "s1", context = "brain", trait = "g1", #' method = "susie", entry = list(fe)) @@ -229,7 +234,8 @@ QtlFineMappingResult <- function( dataType = NULL, dataSource = NULL, weightStandardized = NULL, - ldReference = NULL + ldReference = NULL, + metadata = list() ) { .qfmrAssertArgs( studyName, @@ -241,10 +247,7 @@ QtlFineMappingResult <- function( jointContexts, jointTraits ) - n <- length(studyName) - .qfmrCheckTupleLengths(studyName, context, trait, method, entry) - payloads <- map(entry, .asFmRowPayload) - .checkRowPayloads(payloads, "FineMappingRow", "fine-mapping") + payloads <- .qfmrPayloads(entry) cols <- .qfmrMetadataCols( studyName, context, @@ -258,13 +261,43 @@ QtlFineMappingResult <- function( region, dataType, dataSource, - weightStandardized, - n + weightStandardized + ) + .withMetadata( + .rtlNewValidated("QtlFineMappingResult", payloads, cols, ldReference), + metadata ) - .rtlNewValidated("QtlFineMappingResult", payloads, cols, ldReference) } -# Every argument's type contract, checked before anything is built. +# The entries as fine-mapping row payloads, each on one chromosome. +# @noRd +.qfmrPayloads <- function(entry) { + payloads <- map(entry, .asFmRowPayload) + .checkRowPayloads(payloads, "FineMappingRow", "fine-mapping") + .qfmrRefuseMultiChromosome(payloads) + payloads +} + +# A QTL fit is one row per (study, context, trait, method), on one chromosome, +# so an entry whose variants span several -- a trans fit -- has no row to go +# in: split per chromosome, it would repeat its tuple and fail as a +# uniqueness violation. Said here, before the split, instead. +# @noRd +.qfmrRefuseMultiChromosome <- function(payloads) { + bad <- .multiChromosomeEntries(payloads) + if (length(bad) == 0L) { + return(invisible(NULL)) + } + abort(glue( + "QtlFineMappingResult: `entry` element(s) ", + "{str_flatten(utils::head(bad, 5L), ', ')} span more than one ", + "chromosome. A row is one (study, context, trait, method) fit on one ", + "chromosome, so a fit across chromosomes has no row to go in." + )) +} + +# Every argument's type and length contract, checked before anything is +# built. # @noRd .qfmrAssertArgs <- function( studyName, @@ -290,6 +323,7 @@ QtlFineMappingResult <- function( assertCharacter(jointStudies, null.ok = TRUE) assertCharacter(jointContexts, null.ok = TRUE) assertCharacter(jointTraits, null.ok = TRUE) + .qfmrCheckTupleLengths(studyName, context, trait, method, entry) } # The collection's outer mcols: the identity tuple, each entry's fit / cv @@ -308,16 +342,17 @@ QtlFineMappingResult <- function( region, dataType, dataSource, - weightStandardized, - n + weightStandardized ) { + n <- length(studyName) baseCols <- list( study = as.character(studyName), context = as.character(context), trait = as.character(trait), method = as.character(method), susieFit = S4Vectors::SimpleList(map(payloads, susieFit)), - cvResult = S4Vectors::SimpleList(map(payloads, cvResult)) + cvResult = S4Vectors::SimpleList(map(payloads, cvResult)), + fitVariants = IRanges::CharacterList(map(payloads, .fmRowFitVariants)) ) withJoint <- .qfmrAppendJointCols( baseCols, @@ -385,11 +420,33 @@ QtlFineMappingResult <- function( setMethod( "fineMappingResult", "QtlFineMappingResult", - function(x, studyName = NULL, context = NULL, trait = NULL, method = NULL) { + function( + x, + studyName = NULL, + context = NULL, + trait = NULL, + method = NULL, + blockId = NULL + ) { + .qfmrRefuseBlockId(blockId, "fineMappingResult(QtlFineMappingResult)") x[.qfmrSelectRowIndex(x, studyName, context, trait, method)] } ) +# A QTL fit is one row, named by (study, context, trait, method), so there is +# no block for `blockId` to pick; one is refused rather than ignored. NA +# counts as unset, as it does for the GWAS-side refusal of context / trait. +# @noRd +.qfmrRefuseBlockId <- function(blockId, caller) { + if (is.null(blockId) || (length(blockId) == 1L && is.na(blockId))) { + return(invisible(NULL)) + } + abort(glue( + "{caller}: `blockId` names an LD block of a GWAS fit. A QTL fit is ", + "one row; select it with `studyName`, `context`, `trait` and `method`." + )) +} + # Derived collection-level accessors (delegate to entry-level methods). #' @rdname pip @@ -402,23 +459,10 @@ setMethod( studyName = NULL, context = NULL, trait = NULL, - method = NULL, - returnList = FALSE + method = NULL ) { - pip <- .fmrRowPip( - .fmrRowParts( - x, - .qfmrSelectRowIndex(x, studyName, context, trait, method) - ) - ) - if (isTRUE(returnList)) { - nm <- glue( - "{as.character(x$study)[1L]}|{as.character(x$context)[1L]}|", - "{as.character(x$trait)[1L]}|{as.character(x$method)[1L]}" - ) - return(set_names(list(pip), nm)) - } - pip + idx <- .qfmrSelectRowIndex(x, studyName, context, trait, method) + .fmrRowPip(.fmrRowParts(x, idx)) } ) @@ -434,17 +478,17 @@ setMethod( context = NULL, trait = NULL, method = NULL, - region = NULL + blockId = NULL ) { # The shared FineMappingResultBase accessors pass the whole selector - # set, and only GwasFineMappingResult is region-indexed. Refusing a - # non-NULL `region` is the point of naming it: it used to vanish into - # `...` and silently return the study/context/trait/method match. - if (!is.null(region)) { + # set, and only GwasFineMappingResult is block-indexed. Refusing a + # non-NULL `blockId` is the point of naming it: a selector absorbed + # by `...` would silently return the study/context/trait/method match. + if (!is.null(blockId)) { abort(glue( - "QtlFineMappingResult is not region-indexed: select with ", - "study / context / trait / method. `region` applies to ", - "GwasFineMappingResult only." + "QtlFineMappingResult has no LD blocks: select with ", + "study / context / trait / method. `blockId` ", + "applies to GwasFineMappingResult only." )) } .fmrRowParts( @@ -466,10 +510,11 @@ setMethod( trait = NULL, method = NULL ) { - cvResult(.fmrRowParts( + parts <- .fmrRowParts( x, .qfmrSelectRowIndex(x, studyName, context, trait, method) - )) + ) + cvResult(.fitCoverageChecked(parts, "cvResult()")) } ) diff --git a/R/RangedTupleList.R b/R/RangedTupleList.R index bba1e95a..37d7104e 100644 --- a/R/RangedTupleList.R +++ b/R/RangedTupleList.R @@ -15,7 +15,7 @@ # `[[` is left alone on purpose: on a GRangesList it addresses elements, so # overloading it for columns would collide. Use `mcols(x)[i, j]` for a cell. # -# Slots hold COLLECTION-LEVEL scalars only (ldReference, genome, qcInfo). +# Slots hold COLLECTION-LEVEL scalars only (ldReference, genome, qcOptions). # Anything with one value per element belongs in mcols -- a per-element slot # silently desyncs on subsetting, because `x[i]` narrows the elements and the # mcols but has no idea the slot is parallel to them. @@ -31,14 +31,23 @@ NULL #' \code{nrow()} counts elements, \code{ncol()} counts metadata columns and #' \code{colnames()} names them, so the collections read exactly as the #' \code{DFrame}-shaped ones they replace. \code{$} and \code{$<-} -#' read and write \code{mcols} columns. \code{[} selects elements and +#' read and write \code{mcols} columns. Storing metadata, whether by +#' \code{$<-}, \code{mcols<-} or its older spellings \code{values<-} and +#' \code{elementMetadata<-}, refuses an identity column (\code{study}, +#' \code{context}, \code{trait}, \code{method}, their \code{gwas} +#' counterparts and \code{blockId}) that is not character; \code{NA} values +#' are allowed. \code{[} selects elements and #' \strong{rejects} a second argument, because the stock method would #' silently discard it. \code{endoapply()} maps over the elements and -#' rebuilds the object with its collection-level slots intact. +#' rebuilds the object with its collection-level slots intact; +#' \code{sort()}, \code{unique()} and \code{trim()} work on each element +#' the same way, so they too return the collection's own class rather than +#' a bare \code{GRangesList}. #' @param x,X A \code{RangedTupleList} collection. #' @param name An \code{mcols} column name. #' @param do.NULL,prefix Unused; present for generic compatibility. -#' @param value Replacement value for that column. +#' @param value For \code{$<-}, the replacement column; for +#' \code{elementMetadata<-}, the replacement metadata table. #' @param i Element selector. #' @param j Not supported; supplying it is an error. #' @param drop Passed through to the inherited method. @@ -46,11 +55,15 @@ NULL #' @param FUN A function applied to each element, returning a \code{GRanges}. #' @param objects Further collections to append, as \code{c()} and #' \code{append()} pass them. -#' @param use.names,ignore.mcols,check Unused; present for generic -#' compatibility. +#' @param use.names For \code{trim()}, passed to each element's +#' \code{trim()}; otherwise unused, present for generic compatibility. +#' @param ignore.mcols,check Unused; present for generic compatibility. +#' @param decreasing Passed to each element's \code{sort()}. +#' @param incomparables Passed to each element's \code{unique()}. #' @return \code{nrow()} and \code{ncol()} integers; \code{colnames()} a -#' character vector; \code{$} a metadata column; \code{$<-}, \code{[} and -#' \code{endoapply()} a collection of the same class. +#' character vector; \code{$} a metadata column; \code{$<-}, +#' \code{elementMetadata<-}, \code{[}, \code{endoapply()}, \code{sort()}, +#' \code{unique()} and \code{trim()} a collection of the same class. #' @examples #' data(qtlSumStatsMulticontextExample) #' mc <- qtlSumStatsMulticontextExample @@ -79,6 +92,20 @@ NULL #' elements and \code{mcols} together, but leaves slots untouched, so a #' per-element slot silently ends up the wrong length and positionally wrong. #' +#' @section Sequence names and genome build: Every range pecotmr holds is on +#' UCSC sequence names (\code{chr1}, \code{chrX}, \code{chrM}), the style +#' \code{seqlevelsStyle(x) <- "UCSC"} gives. Ranges read from a file, +#' placed by variant id, passed to a constructor or given as a range +#' argument are renamed on the way in (\code{"1"} and \code{"chr1"} both +#' become \code{chr1}), so ranges from different inputs compare as they +#' are. A query handed straight to an inherited Bioconductor method, such +#' as \code{subsetByOverlaps()}, is not renamed: give it in UCSC style. +#' A pipeline's result carries the genome build its inputs name in +#' \code{seqinfo()}, as do the ranged views of it (\code{topLoci()}, +#' \code{colocVariants()}, ...); inputs naming different builds are +#' refused. When no input names one, \code{genome()} is \code{NA} until it +#' is set with \code{genome(x) <- "hg38"}. +#' #' @section Invariant: One seqname and one strand per element. \code{range()} #' splits on both, so a mixed element would return two ranges and break the #' 1:1 element-to-span mapping the rest of the package relies on. Variants @@ -87,9 +114,70 @@ NULL setClass("RangedTupleList", contains = c("VIRTUAL", "CompressedGRangesList")) methods::setValidity("RangedTupleList", function(object) { - .rtlCheckSingleSpan(object) + span <- .rtlCheckSingleSpan(object) + problems <- c( + if (!isTRUE(span)) span, + .rtlIdentityProblems(mcols(object, use.names = FALSE)) + ) + if (length(problems) == 0L) TRUE else problems }) +# The identity columns of the metadata `md` name a row, so each is character. +# NA stays allowed: a GWAS side has no context or trait, and a row off the +# LD-block axis has no blockId. +# @noRd +.rtlIdentityProblems <- function(md) { + cols <- intersect( + c( + "study", + "context", + "trait", + "method", + "gwasStudy", + "gwasContext", + "gwasTrait", + "gwasMethod", + "blockId" + ), + colnames(md) + ) + list_c(map(cols, .rtlIdentityProblem, md = md), ptype = character()) +} + +# @noRd +.rtlIdentityProblem <- function(cn, md) { + v <- md[[cn]] + if (is.character(v)) { + return(character(0)) + } + as.character(glue( + "the `{cn}` column must be character (got {class(v)[[1L]]})." + )) +} + +#' @rdname genomicRegion +#' @examples +#' data(qtlFineMappingExample) +#' genomicRegion(qtlFineMappingExample) +#' data(gwasSumStatsS4Example) +#' genomicRegion(gwasSumStatsS4Example) +#' @export +setMethod("genomicRegion", "RangedTupleList", function(x) { + .getRegionColumn(x) +}) + +# `obj` carrying the caller's `metadata`: a free-form list, as metadata() +# is on any Bioconductor vector. +# @noRd +#' @importFrom checkmate assertList +.withMetadata <- function(obj, metadata) { + assertList(metadata, .var.name = "metadata") + if (length(metadata) == 0L) { + return(obj) + } + S4Vectors::`metadata<-`(obj, value = metadata) +} + # Each element must occupy exactly one (seqname, strand) span. range() already # splits on both, so an element that yields more than one range has violated # the invariant -- no need to inspect seqnames and strand separately. @@ -152,6 +240,76 @@ methods::setValidity("RangedTupleList", function(object) { ) } +# ----------------------------------------------------------------------------- +# Element names +# ----------------------------------------------------------------------------- + +# The identity columns an element's name is read from, in reading order. A +# name is the present columns' values joined by "|", missing parts skipped, so +# it reads as the row's key: "Q1|brain|ENSG1|susie". +# @noRd +.RTL_NAME_COLUMNS <- c( + "study", + "context", + "trait", + "method", + "gwasStudy", + "gwasContext", + "gwasTrait", + "gwasMethod", + "analysis", + "cosId", + "blockId", + "qtlCs", + "gwasCs", + "jointStudies", + "jointContexts", + "jointTraits" +) + +# Element names from the identity columns, as Bioconductor keys a List's +# elements. Rows sharing an identity -- one tuple split across chromosomes -- +# are told apart by their span, the key the uniqueness checks already use. +# NULL when the collection carries no identity columns. +# @noRd +.rtlElementNames <- function(grl) { + md <- mcols(grl, use.names = FALSE) + cols <- intersect(.RTL_NAME_COLUMNS, colnames(md)) + if (length(cols) == 0L || length(grl) == 0L) { + return(NULL) + } + parts <- exec(cbind, !!!map(cols, .rtlNameColumn, md = md)) + keys <- apply(parts, 1L, .rtlJoinNameParts) + shared <- is_in(keys, keys[duplicated(keys)]) + if (!any(shared)) { + return(keys) + } + spans <- .rtlRangeKeys(grl) + spans <- if_else(is.na(spans), str_c("row", seq_along(keys)), spans) + if_else(shared, str_c(keys, spans, sep = "|"), keys) +} + +# @noRd +.rtlNameColumn <- function(nm, md) { + as.character(md[[nm]]) +} + +# @noRd +.rtlJoinNameParts <- function(parts) { + str_flatten(parts[!is.na(parts) & nzchar(parts)], "|") +} + +# `grl` with its element names set from its identity columns, left as it is +# when it carries none. +# @noRd +.rtlNamed <- function(grl) { + nms <- .rtlElementNames(grl) + if (is.null(nms)) { + return(grl) + } + `names<-`(grl, nms) +} + # Rebuild `x` from a new list of GRanges elements, carrying every # collection-level slot over and narrowing mcols by `keep`. # @@ -165,7 +323,7 @@ methods::setValidity("RangedTupleList", function(object) { # during initialize(), and a subclass's validity method reads its identity # columns and slots. Building the object bare and filling it in afterwards # trips that check on the way past. - bare <- GenomicRanges::GRangesList(elements) + bare <- .rtlBindElements(elements) # seqinfo is collection-level state, exactly like the slots below: it # carries the genome build. A rebuild from bare elements starts with the # seqlevels those elements happen to span -- none at all when everything @@ -178,6 +336,13 @@ methods::setValidity("RangedTupleList", function(object) { } else { S4Vectors::`mcols<-`(withSeqinfo, value = md[keep, , drop = FALSE]) } + # The rebuilt elements keep the names they had -- the caller may have set + # their own -- and an unnamed collection is named off its identity. + grl <- if (is.null(names(x))) { + .rtlNamed(grl) + } else { + `names<-`(grl, names(x)[keep]) + } ownSlots <- .rtlOwnSlots(x) slotArgs <- set_names(map(ownSlots, .rtlGetSlot, x = x), ownSlots) exec(methods::new, class(x), grl, !!!slotArgs) @@ -270,8 +435,28 @@ setMethod("$", "RangedTupleList", function(x, name) { #' @rdname RangedTupleList-methods #' @export setMethod("$<-", "RangedTupleList", function(x, name, value) { + derived <- is.null(names(x)) || identical(names(x), .rtlElementNames(x)) md <- `[[<-`(mcols(x, use.names = FALSE), name, value = value) - S4Vectors::`mcols<-`(x, value = md) + out <- S4Vectors::`mcols<-`(x, value = md) + # Names read off the identity follow an edit to it; names the caller set + # are the caller's to keep. + if (derived) .rtlNamed(out) else out +}) + +# mcols<- and values<- both store their table through this generic, so one +# method checks all three spellings. The inherited method stores the table +# without running validity, which would keep an identity column of the wrong +# type. +#' @rdname RangedTupleList-methods +#' @importFrom S4Vectors elementMetadata<- +#' @export +setMethod("elementMetadata<-", "RangedTupleList", function(x, ..., value) { + out <- methods::callNextMethod() + problems <- .rtlIdentityProblems(mcols(out, use.names = FALSE)) + if (length(problems) > 0L) { + abort(problems) + } + out }) #' @rdname RangedTupleList-methods @@ -372,30 +557,100 @@ setMethod("endoapply", "RangedTupleList", function(X, FUN, ...) { .rtlRebuild(X, elements, seq_along(X)) }) +# The inherited GRangesList sort() / unique() / trim() work per element too, +# but rebuild the result as a bare CompressedGRangesList, dropping the class +# and every collection-level slot. Routed through endoapply() they keep both. +#' @rdname RangedTupleList-methods +#' @importFrom BiocGenerics sort +#' @export +setMethod("sort", "RangedTupleList", function(x, decreasing = FALSE, ...) { + endoapply(x, sort, decreasing = decreasing, ...) +}) + +#' @rdname RangedTupleList-methods +#' @importFrom BiocGenerics unique +#' @export +setMethod( + "unique", + "RangedTupleList", + function(x, incomparables = FALSE, ...) { + endoapply(x, unique, incomparables = incomparables, ...) + } +) + +#' @rdname RangedTupleList-methods +#' @importFrom IRanges trim +#' @export +setMethod("trim", "RangedTupleList", function(x, use.names = TRUE, ...) { + endoapply(x, trim, use.names = use.names, ...) +}) + # A stable per-element key for the element's own genomic span, used where an # identity tuple needs a positional component. Derived from range() rather than # from a stored label so it cannot drift out of step with the variants, and so -# it stays correct after subsetRegion() narrows an element. +# it stays correct after an element is narrowed. The keys are values, so they +# do not carry the collection's element names. An empty element has no span +# and keys NA. # @noRd .rtlRangeKeys <- function(x) { if (length(x) == 0L) { return(character(0)) } + spans <- .rtlFirstSpans(x) + keys <- rep(NA_character_, length(x)) + keys[spans$has] <- .rtlSpanKey(spans$first) + keys +} + +# Each element's span -- its first range under range(), which every element +# of a collection has exactly one of (.rtlCheckSingleSpan()) -- in element +# order, and which elements have one. One range() over the whole list: one +# per element made building the keys cost a millisecond a row. +# @noRd +.rtlFirstSpans <- function(x) { spans <- range(x) - map_chr(as.list(spans), .rtlOneRangeKey) + n <- lengths(spans) + has <- n > 0L + flat <- unlist(spans, use.names = FALSE) + list(first = flat[(cumsum(n) - n + 1L)[has]], has = has) } +# The key of the first range of `g`, a span: callers pass range() of a +# GRanges that has variants (an empty GWAS entry is skipped before it is +# keyed). # @noRd .rtlOneRangeKey <- function(g) { - if (length(g) == 0L) { - return(NA_character_) - } - str_c( - as.character(seqnames(g))[[1L]], - start(g)[[1L]], - end(g)[[1L]], - sep = "_" - ) + .rtlSpanKey(g[1L]) +} + +# "chrom_start_end" for each range of `gr`: the one formatter every span key +# goes through, so a key minted for one range and the keys of a collection +# agree by construction. +# @noRd +.rtlSpanKey <- function(gr) { + str_c(as.character(seqnames(gr)), start(gr), end(gr), sep = "_") +} + +# The seqname each element of a GRangesList sits on, NA for an empty one, as +# .rtlElementSeqname() reads one element -- read off the joined elements +# rather than element by element. +# @noRd +.rtlElementSeqnames <- function(x) { + n <- lengths(x) + has <- n > 0L + flat <- unlist(x, use.names = FALSE) + out <- rep(NA_character_, length(x)) + out[has] <- as.character(seqnames(flat))[(cumsum(n) - n + 1L)[has]] + out +} + +# Whether the elements' variant metadata has column `cn`. A collection's +# elements share one variant metadata table, so all of them have it or none +# does. +# @noRd +.rtlHasVariantColumn <- function(x, cn) { + md <- mcols(unlist(x, use.names = FALSE), use.names = FALSE) + is_in(cn, colnames(md)) } # ----------------------------------------------------------------------------- @@ -403,17 +658,31 @@ setMethod("endoapply", "RangedTupleList", function(X, FUN, ...) { # ----------------------------------------------------------------------------- #' @title Update an Object Saved by an Earlier pecotmr -#' @description Bring a collection saved by an earlier version of pecotmr up -#' to date. Collections now keep their LD references per row: each distinct -#' reference once in the \code{ldReference} slot, and an \code{ldReference} -#' column naming the one every row uses (in \code{outcomeInfo} for a -#' \code{ColocBoostResult}). An object saved when it held a single reference -#' for all its rows is converted by keying every row to that reference (for -#' a \code{ColocBoostResult}, every summary-statistic outcome), and one that -#' held none by marking every row LD-free. An up-to-date object is returned -#' unchanged. -#' @param object A collection: summary statistics, fine-mapping results, TWAS -#' weights, or a colocalization result. +#' @description Bring an object saved by an earlier version of pecotmr up to +#' date. An up-to-date object is returned unchanged. +#' +#' \itemize{ +#' \item Collections keep their LD references per row: each distinct +#' reference once in the \code{ldReference} slot, and an +#' \code{ldReference} column naming the one every row uses (in +#' \code{outcomeInfo} for a \code{ColocBoostResult}). An object saved +#' when it held a single reference for all its rows is converted by +#' keying every row to that reference (for a \code{ColocBoostResult}, +#' every summary-statistic outcome), and one that held none by marking +#' every row LD-free. +#' \item Collections name their elements by their identity tuple; one +#' saved without names gets them. +#' \item A \code{QtlDataset} no longer stores run settings (genotype +#' QC cutoffs, \code{scaleResiduals}); one saved with them has them +#' dropped, as the pipelines' \code{\link{GenotypeFilterParam}} and +#' \code{\link{ResidualizationParam}} now carry them. +#' \item A \code{MultiStudyQtlDataset} is now a list of its studies; one +#' saved when it held them in a slot is rebuilt as one, its studies +#' updated too. +#' } +#' @param object A collection (summary statistics, fine-mapping results, TWAS +#' weights, a colocalization result), a \code{QtlDataset} or a +#' \code{MultiStudyQtlDataset}. #' @param ... Passed on to the inherited method. #' @param verbose Report the update. #' @return \code{object} in the current representation. @@ -436,26 +705,13 @@ setMethod( message("updateObject(object = '", class(object)[[1L]], "')") } methods::callNextMethod( - .updateRowLdRefs(object), + .rtlNamed(.updateRowLdRefs(object)), ..., verbose = verbose ) } ) -# ----------------------------------------------------------------------------- -# subsetRegion -# ----------------------------------------------------------------------------- - -#' @rdname subsetRegion -#' @export -setMethod("subsetRegion", "RangedTupleList", function(x, region) { - win <- .asGRegion(region) - elements <- map(as.list(x), .rtlRestrictOne, win = win) - keep <- lengths(elements) > 0L - .rtlRebuild(x, elements[keep], keep) -}) - # ----------------------------------------------------------------------------- # Construction helper: enforce one seqname per element # ----------------------------------------------------------------------------- @@ -471,26 +727,205 @@ setMethod("subsetRegion", "RangedTupleList", function(x, region) { split <- .rtlSplitBySeqname(map(payloads, variants)) md <- exec(S4Vectors::DataFrame, !!!c(cols, list(check.names = FALSE))) S4Vectors::`mcols<-`( - GenomicRanges::GRangesList(split$entry), + .rtlBindElements(split$entry), value = md[split$fromIdx, , drop = FALSE] ) } -# Build and validate a RangedTupleList subclass from its payloads and metadata -# columns -- the shared tail of the TwasWeights and QtlFineMappingResult -# constructors. `ldReference` is one reference for every payload or a list -# with one per payload; each distinct one is stored once, and every row names -# its own in the `ldReference` column. +# Build a RangedTupleList subclass from its payloads and metadata columns -- +# the shared tail of the TwasWeights and QtlFineMappingResult constructors. +# new() validates it, once. `ldReference` is one reference for every payload +# or a list with one per payload; each distinct one is stored once, and every +# row names its own in the `ldReference` column. # @noRd .rtlNewValidated <- function(Class, payloads, cols, ldReference) { dict <- .ldRefDict(.ldRefPerTuple(ldReference, length(payloads))) - obj <- new( + new( Class, - .rtlGrlWithMetadata(payloads, c(cols, list(ldReference = dict$keys))), + .rtlNamed(.rtlGrlWithMetadata( + payloads, + c(cols, list(ldReference = dict$keys)) + )), ldReference = dict$refs ) - validObject(obj) - obj +} + +# ----------------------------------------------------------------------------- +# Joining elements into a list +# ----------------------------------------------------------------------------- + +# GenomicRanges::GRangesList(elements), built faster. GRangesList() joins +# the elements' variant metadata through S4Vectors, which reads every column +# of every element by S4 dispatch, about 0.25 ms a cell: 3 s for a 1,000-row +# collection of fine-mapping fits. When every element is a plain GRanges +# whose metadata holds the same plain vector columns, in the same order and +# of the same types -- what the collection constructors pass -- they are +# joined from their vectors instead, giving the identical object. Anything +# else takes GRangesList(). Like GRangesList(), which builds its result inside +# suppressWarnings(), the join reports no warnings: merging the elements' +# seqinfo warns about every two on different chromosomes. +# @noRd +.rtlBindElements <- function(elements) { + flat <- suppressWarnings(.rtlJoinPlainElements(elements)) + if (is.null(flat)) { + return(GenomicRanges::GRangesList(elements)) + } + IRanges::relist( + flat, + IRanges::PartitioningByEnd( + cumsum(lengths(elements)), + names = names(elements) + ) + ) +} + +# The elements of collections `parts`, in order, as one GRangesList: what +# GRangesList() makes of their elements, keeping their names. Each part is +# joined whole -- its elements are already one GRanges underneath -- rather +# than taken apart with as.list() and put back together, which cost about +# 0.6 ms an element. c() joins the parts' variant metadata as GRangesList() +# would, filling a column one part lacks with NA, and its warnings are +# silenced as GRangesList() silences them (.rtlBindElements()). +# @noRd +.rtlJoinParts <- function(parts) { + flats <- unname(map(parts, unlist, use.names = FALSE)) + flat <- suppressWarnings(exec(c, !!!flats)) + ends <- cumsum(list_c(map(parts, .rtlElementLengths), ptype = integer())) + IRanges::relist( + flat, + IRanges::PartitioningByEnd(ends, names = .rtlJoinedNames(parts)) + ) +} + +# @noRd +.rtlElementLengths <- function(x) { + unname(lengths(x)) +} + +# The elements joined into one GRanges as c() joins them, or NULL when one of +# them falls outside the plain case .rtlBindElements() builds. +# @noRd +.rtlJoinPlainElements <- function(elements) { + elements <- unname(as.list(elements)) + if ( + length(elements) == 0L || + !all(map_lgl(elements, .rtlIsPlainGRanges)) + ) { + return(NULL) + } + columns <- map(elements, .rtlMcolList) + if (!.rtlSameVectorColumns(columns)) { + return(NULL) + } + flat <- GenomicRanges::GRanges( + seqnames = list_c( + map(elements, .rtlSeqnameValues), + ptype = character() + ), + ranges = IRanges::IRanges( + start = list_c(map(elements, start), ptype = integer()), + end = list_c(map(elements, end), ptype = integer()), + names = .rtlJoinedNames(elements) + ), + strand = list_c(map(elements, .rtlStrandValues), ptype = character()), + seqinfo = .rtlMergedSeqinfo(elements) + ) + .rtlWithJoinedMcols(flat, columns) +} + +# A GRanges itself, not a subclass, with no metadata() of its own, which c() +# would carry over from the first element. +# @noRd +.rtlIsPlainGRanges <- function(g) { + methods::is(g, "GRanges") && + identical(class(g)[[1L]], "GRanges") && + length(S4Vectors::metadata(g)) == 0L +} + +# One element's variant metadata as a plain list of its columns. +# @noRd +.rtlMcolList <- function(g) { + as.list(mcols(g, use.names = FALSE)) +} + +# TRUE when every element's metadata holds the first one's plain vector +# columns: the same names, in the same order, of the same types. +# @noRd +.rtlSameVectorColumns <- function(columns) { + first <- columns[[1L]] + all(map_lgl( + columns, + .rtlColumnsMatch, + names = names(first) %||% character(0), + types = map_chr(first, typeof) + )) +} + +# @noRd +.rtlColumnsMatch <- function(cols, names, types) { + identical(names(cols) %||% character(0), names) && + identical(map_chr(cols, typeof), types) && + all(map_lgl(cols, .rtlIsPlainVector)) +} + +# An atomic vector with no attributes beyond its names -- no dimensions or +# class -- so joining it is plain concatenation, names included. +# @noRd +.rtlIsPlainVector <- function(v) { + is.atomic(v) && all(is_in(names(attributes(v)), "names")) +} + +# @noRd +.rtlSeqnameValues <- function(g) { + as.character(seqnames(g)) +} + +# @noRd +.rtlStrandValues <- function(g) { + as.character(GenomicRanges::strand(g)) +} + +# The elements' variant names joined, "" for an element without any; NULL +# when none has any, as c() leaves them. +# @noRd +.rtlJoinedNames <- function(elements) { + nms <- map(elements, names) + if (all(map_lgl(nms, is.null))) { + return(NULL) + } + list_c(map2(nms, elements, .rtlNamesOrBlank), ptype = character()) +} + +# @noRd +.rtlNamesOrBlank <- function(nm, g) { + nm %||% rep("", length(g)) +} + +# The elements' seqinfo merged as c() merges it, each distinct one once, in +# the order they appear. +# @noRd +.rtlMergedSeqinfo <- function(elements) { + infos <- unique(map(elements, GenomeInfoDb::seqinfo)) + reduce(infos, S4Vectors::merge) +} + +# `flat` carrying the elements' metadata columns, each joined once. +# @noRd +.rtlWithJoinedMcols <- function(flat, columns) { + cn <- names(columns[[1L]]) %||% character(0) + if (length(cn) == 0L) { + return(flat) + } + joined <- set_names(map(cn, .rtlJoinColumn, columns = columns), cn) + S4Vectors::`mcols<-`( + flat, + value = S4Vectors::DataFrame(joined, check.names = FALSE) + ) +} + +# @noRd +.rtlJoinColumn <- function(cn, columns) { + list_c(map(columns, cn)) } # Split any multi-seqname element into one element per seqname, and report the @@ -548,17 +983,18 @@ setMethod("subsetRegion", "RangedTupleList", function(x, region) { g[chroms == level] } -# Split each element by an LD-block manifest instead of by seqname, returning -# the same (entry, fromIdx) shape plus the block key each piece belongs to. +# Split each element across a set of windows (a GWAS `region`, typically LD +# blocks) instead of by seqname, returning the same (entry, fromIdx) shape +# plus the key and the interval of the window each piece belongs to. # # A genome-wide GWAS split by seqname gives one element per chromosome, which # is too coarse for cTWAS: its EM needs per-block context (§4.7). `blocks` is a -# GRanges of LD blocks whose names supply the keys. +# GRanges of windows whose names supply the keys. # -# A variant matching no block is dropped rather than pooled into a catch-all: -# a variant outside every LD block has no block-local LD to be fine-mapped -# against, so carrying it would put variants in a block whose LD does not -# describe them. The count is reported so the loss is never silent. +# A variant matching no window is dropped rather than pooled into a +# catch-all: the windows are what the caller asked to analyse, and a variant +# outside every LD block has no block-local LD to be fine-mapped against. The +# count is reported so the loss is never silent. # @noRd .rtlSplitByBlocks <- function(entry, blocks) { entry <- as.list(entry) @@ -566,7 +1002,8 @@ setMethod("subsetRegion", "RangedTupleList", function(x, region) { return(list( entry = list(), fromIdx = integer(0), - blockId = character(0) + blockId = character(0), + blockRange = GenomicRanges::GRanges() )) } notRanges <- !map_lgl(entry, methods::is, "GRanges") @@ -582,12 +1019,12 @@ setMethod("subsetRegion", "RangedTupleList", function(x, region) { dropped <- sum(lengths(entry)) - sum(map_int(pieces, .rtlPieceSize)) if (dropped > 0L) { msg <- glue( - "{dropped} variant(s) overlap no LD block and were dropped; ", - "a variant outside every block has no block-local LD to be ", - "fine-mapped against." + "{dropped} variant(s) lie outside every `region` window and ", + "were dropped." ) warn(msg) } + keys <- unname(list_c(map(pieces, names), ptype = character())) list( # unname(): the flattened names were an artifact of base unlist()'s # `outer.inner` mangling and were never coherent -- a multi-seqname @@ -596,29 +1033,30 @@ setMethod("subsetRegion", "RangedTupleList", function(x, region) { # already had to unname() derived values to keep them out of mcols. entry = unname(list_flatten(pieces)), fromIdx = rep(seq_along(entry), lengths(pieces)), - blockId = unname(list_c(map(pieces, names))) + blockId = keys, + blockRange = unname(blocks[keys]) ) } -# The manifest must name its blocks: the names become `blockId`, which is what +# Every window needs a name: the names become `blockId`, which is what # downstream code keys regions by. # @noRd .rtlValidateBlocks <- function(blocks) { if (!methods::is(blocks, "GRanges")) { msg <- glue( - "`ldBlocks` must be a GRanges of LD blocks ", + "`region` must be a GRanges of windows ", "(got {class(blocks)[[1L]]})." ) abort(msg) } if (length(blocks) == 0L) { - abort("`ldBlocks` is empty; it must describe at least one LD block.") + abort("`region` is empty; it must describe at least one window.") } keys <- .rtlBlockKeys(blocks) if (anyDuplicated(keys) > 0L) { dup <- unique(keys[duplicated(keys)]) msg <- glue( - "`ldBlocks` keys must be unique; repeated: ", + "`region` window names must be unique; repeated: ", "{str_flatten(head(dup, 5L), ', ')}." ) abort(msg) @@ -653,7 +1091,11 @@ setMethod("subsetRegion", "RangedTupleList", function(x, region) { # One element -> a named list of per-block GRanges, in manifest order. # @noRd .rtlSplitOneByBlocks <- function(g, blocks) { - hits <- IRanges::findOverlaps(g, blocks, select = "first") + hits <- IRanges::findOverlaps( + .locusRanges(g), + .locusRanges(blocks), + select = "first" + ) if (!any(!is.na(hits))) { return(list()) } @@ -675,24 +1117,6 @@ setMethod("subsetRegion", "RangedTupleList", function(x, region) { g[!is.na(hits) & hits == i] } -# Keep only the variants of one element that overlap the window. -# -# The seqname is checked first because an element on another chromosome cannot -# overlap by definition, and going straight to overlapsAny() would emit -# GenomicRanges' "no sequence levels in common" warning for every such element -# on every call -- pure noise for a collection spanning several chromosomes. -# @noRd -.rtlRestrictOne <- function(g, win) { - onWindowChrom <- is_in( - as.character(seqnames(g)), - as.character(seqnames(win)) - ) - if (!any(onWindowChrom)) { - return(g[0L]) - } - g[onWindowChrom & IRanges::overlapsAny(g, win)] -} - # ============================================================================= # Combining collections @@ -765,12 +1189,15 @@ setMethod( #' range, so there is no row to broadcast them onto. Use the accessors #' (\code{\link{susieFit}}, \code{\link{cvResult}}) for those. #' +#' \code{as(x, "GRanges")} is the same conversion. +#' #' @param x A \code{RangedTupleList}. #' @return A \code{GRanges}. #' @examples #' data(qtlFineMappingExample) #' flat <- flattenTupleRanges(qtlFineMappingExample) #' head(names(S4Vectors::mcols(flat))) +#' identical(as(qtlFineMappingExample, "GRanges"), flat) #' @export flattenTupleRanges <- function(x) { if (!methods::is(x, "RangedTupleList")) { @@ -802,6 +1229,16 @@ flattenTupleRanges <- function(x) { ) } +#' @rdname flattenTupleRanges +#' @name coerce,RangedTupleList,GRanges-method +#' @aliases coerce,RangedTupleList,GRanges-method +#' @usage NULL +#' @importFrom methods coerce +#' @exportMethod coerce +setAs("RangedTupleList", "GRanges", function(from) { + flattenTupleRanges(from) +}) + # @noRd .rtlBroadcastColumn <- function(col, reps) { col[reps] @@ -817,7 +1254,8 @@ flattenTupleRanges <- function(x) { #' Re-nest a flattened GRanges into a tuple collection #' #' The inverse of \code{\link{flattenTupleRanges}}: ranges are grouped by the -#' identity tuple they carry and returned to \code{template}'s elements, so the +#' identity tuple they carry -- and, for a tuple split across chromosomes, by +#' chromosome -- and returned to \code{template}'s elements, so the #' collection's class, its per-element payloads and its collection-level slots #' all survive a plyranges round trip. #' @@ -846,8 +1284,17 @@ nestTupleRanges <- function(flat, template) { msg <- glue("`flat` must be a GRanges (got {class(flat)[[1L]]}).") abort(msg) } - keyCols <- .rtlTupleKeyCols(template) - dotted <- map_chr(keyCols, .rtlDotName) + keys <- .rtlNestKeys(flat, template, .rtlTupleKeyCols(template)) + elements <- map(keys$wanted, .rtlPickByKey, flat = flat, have = keys$have) + .rtlRebuild(template, elements, seq_len(length(template))) +} + +# Element and range keys for re-nesting. The identity tuple alone keys an +# element unless several elements share it -- one tuple split across +# chromosomes -- and then the one seqname each of those spans is added on both +# sides. An empty element spans none, so its key is NA and it stays empty. +# @noRd +.rtlNestKeys <- function(flat, template, keyCols) { wanted <- .rtlTupleKeys( mcols(template, use.names = FALSE), keyCols, @@ -855,11 +1302,30 @@ nestTupleRanges <- function(flat, template) { ) have <- .rtlTupleKeys( mcols(flat, use.names = FALSE), - dotted, + map_chr(keyCols, .rtlDotName), n = length(flat) ) - elements <- map(wanted, .rtlPickByKey, flat = flat, have = have) - .rtlRebuild(template, elements, seq_len(length(template))) + shared <- unique(wanted[duplicated(wanted)]) + if (length(shared) == 0L) { + return(list(wanted = wanted, have = have)) + } + list( + wanted = .rtlKeyWithSeqname( + wanted, + is_in(wanted, shared), + map_chr(as.list(template), .rtlElementSeqname) + ), + have = .rtlKeyWithSeqname( + have, + is_in(have, shared), + as.character(seqnames(flat)) + ) + ) +} + +# @noRd +.rtlKeyWithSeqname <- function(keys, add, seqs) { + if_else(add, str_c(keys, seqs, sep = "\r"), keys) } # The identity columns to group by: the atomic mcols the flattener broadcasts. @@ -894,7 +1360,17 @@ nestTupleRanges <- function(flat, template) { # @noRd .rtlPickByKey <- function(key, flat, have) { - flat[have == key] + flat[which(have == key)] +} + +# The one seqname an element sits on. NA for an empty element, which carries +# no coordinate to name. +# @noRd +.rtlElementSeqname <- function(g) { + if (length(g) == 0L) { + return(NA_character_) + } + as.character(seqnames(g))[[1L]] } diff --git a/R/SldscData.R b/R/SldscData.R index bfa440f6..e3ef467e 100644 --- a/R/SldscData.R +++ b/R/SldscData.R @@ -158,25 +158,34 @@ SldscData <- function(annotData, frqData = NULL, traits = list()) { if (is.null(frqData)) { frqData <- tibble() } - obj <- new( + new( "SldscData", annotData = as_tibble(annotData), frqData = as_tibble(frqData), traits = traits ) - validObject(obj) - obj } # ---- accessors ---- #' @rdname annotData #' @export -setMethod("annotData", "SldscData", function(x) x@annotData) +setMethod("annotData", "SldscData", function(x) { + S4Vectors::DataFrame(x@annotData, check.names = FALSE) +}) #' @rdname frqData #' @export -setMethod("frqData", "SldscData", function(x) x@frqData) +setMethod("frqData", "SldscData", function(x) { + S4Vectors::DataFrame(x@frqData, check.names = FALSE) +}) + +# The stored tables as the estimators read them, with dplyr. +# @noRd +.sdAnnot <- function(x) x@annotData + +# @noRd +.sdFrq <- function(x) x@frqData #' @rdname traitNames #' @export @@ -193,28 +202,43 @@ setMethod("annotCols", "SldscData", function(x) { setMethod( "sldscResults", "SldscData", - function(x, trait = NULL, mode = c("single", "joint"), idx = NULL) { + function(x, trait = NULL) { if (is.null(trait)) { return(x@traits) } - mode <- arg_match(mode) - runs <- x@traits[[trait]] - if (is.null(runs)) { - return(NULL) - } - if (mode == "joint") { - return(runs$joint) - } - if (is.null(idx)) { - return(runs$single) - } - if (idx > length(runs$single)) { - return(NULL) + unknown <- setdiff(trait, names(x@traits)) + if (length(unknown) > 0L) { + abort(glue( + "sldscResults: no trait {str_flatten(unknown, ', ')} in this ", + "SldscData. It has: {str_flatten(names(x@traits), ', ')}." + )) } - runs$single[[idx]] + x@traits[trait] } ) +# One trait's run, for the pipelines: its joint run, its single runs, or one +# single run by position -- NULL when the trait, the run kind or that index +# is absent, which those callers turn into their own message. +# @noRd +.sldscRun <- function(x, trait, mode = c("single", "joint"), idx = NULL) { + mode <- arg_match(mode) + runs <- x@traits[[trait]] + if (is.null(runs)) { + return(NULL) + } + if (mode == "joint") { + return(runs$joint) + } + if (is.null(idx)) { + return(runs$single) + } + if (idx > length(runs$single)) { + return(NULL) + } + runs$single[[idx]] +} + #' @rdname SldscData setMethod("show", "SldscData", function(object) { cat("SldscData\n") diff --git a/R/causalInferencePipeline.R b/R/causalInferencePipeline.R index 96875103..464e2b6b 100644 --- a/R/causalInferencePipeline.R +++ b/R/causalInferencePipeline.R @@ -53,9 +53,14 @@ NULL #' } #' #' @param gwasSumStats A \code{\link{GwasSumStats}} object. Must be QC'd -#' (\code{length(qcInfo(x)) > 0L}). A study may span many rows (one per +#' (\code{length(qcOptions(x)) > 0L}). A study may span many rows (one per #' chromosome or LD block); each QTL tuple is scored once per study, over the -#' statistics of the rows its window overlaps. +#' statistics of the rows its window overlaps. A tuple's variants outside +#' every loaded block of a study it overlaps are an error where the blocks' +#' ranges were given (\code{regionGiven}, see +#' \code{\linkS4class{GwasSumStats}}), since they lie in a block that was not +#' loaded, and a warning for more than one in a row past a range computed +#' from the GWAS variants. #' @param twasWeights Optional \code{\link{TwasWeights}} carrying per-(study, #' context, trait, method) weights. When supplied, drives the TWAS-Z #' computation. @@ -73,7 +78,9 @@ NULL #' it keeps the highest-\code{metric} method among those clearing both #' gates that also produced a finite TWAS Z. Otherwise every method is #' carried through. Ports the legacy \code{twas_pipeline} -#' \code{pick_best_model} / \code{update_twas_method}. +#' \code{pick_best_model} / \code{update_twas_method}. The metrics describe +#' each fit on all of its variants, so selection warns about a row narrowed +#' since its fit (condition class \code{pecotmrFitCoverage}). #' @param mrParam How Mendelian randomization is run, built with #' \code{\link{MrParam}}: \code{method} (\code{"ivwPerVariant"}, the #' default, or \code{"csAware"}), the PIP threshold that method reads @@ -88,7 +95,9 @@ NULL #' to the GWAS by (chrom, pos) with ref/alt swaps recognized and the exposure #' effect / weight sign-flipped accordingly; when FALSE, match on exact #' alleles only, so a ref/alt swap is treated as a distinct variant. -#' @return A \code{GRanges} as described above. +#' @return A \code{GRanges} as described above, its \code{seqinfo()} naming +#' the genome build the inputs name (inputs naming different builds are +#' refused). #' @examples #' data(qtlDatasetExample) #' data(gwasSumStatsS4Example) @@ -111,7 +120,11 @@ causalInferencePipeline <- function( "WeightSelectionParam" ) .assertMethodParam(mrParam, "MrParam") - .cipRun( + build <- .inputsBuild( + list(gwasSumStats, twasWeights, fineMappingResult), + "causalInferencePipeline" + ) + res <- .cipRun( gwasSumStats = gwasSumStats, twasWeights = twasWeights, fineMappingResult = fineMappingResult, @@ -120,6 +133,7 @@ causalInferencePipeline <- function( alleleFlip = alleleFlip, mrParam = mrParam ) + .withGenome(res, build) } # Orchestrate the causal-inference pipeline: validate, resolve the QTL work @@ -143,12 +157,17 @@ causalInferencePipeline <- function( weightSelectionParam = weightSelectionParam ) qtlRows <- sel$qtlRows - outRows <- list_flatten(map( + tuples <- compact(map( seq_len(nrow(qtlRows)), - .cipScoreQtlTuple, + .cipTupleInputs, qtlRows = qtlRows, twasWeights = twasWeights, - fineMappingResult = fineMappingResult, + fineMappingResult = fineMappingResult + )) + .cipCheckBlockReach(tuples, gwasSumStats) + outRows <- list_flatten(map( + tuples, + .cipScoreQtlTuple, gwasSumStats = gwasSumStats, gwasIndex = .rowSpans(gwasSumStats), alleleFlip = alleleFlip, @@ -167,10 +186,10 @@ causalInferencePipeline <- function( #' @importFrom checkmate assertClass checkClass .cipValidateInputs <- function(gwasSumStats, twasWeights, fineMappingResult) { assertClass(gwasSumStats, "GwasSumStats") - if (length(qcInfo(gwasSumStats)) == 0L) { + if (length(qcOptions(gwasSumStats)) == 0L) { msg <- glue( "causalInferencePipeline: gwasSumStats has no QC record ", - "(qcInfo() is empty). Call summaryStatsQc() first." + "(qcOptions() is empty). Call summaryStatsQc() first." ) abort(msg) } @@ -224,21 +243,14 @@ causalInferencePipeline <- function( # other rows are not read and may. # @noRd .cipRowsLdRef <- function(gwasSumStats, rows, gStudy) { - keys <- unique(.ldRefKeys(gwasSumStats)[rows]) - if (length(keys) > 1L) { - abort(c( - glue( - "causalInferencePipeline: the rows of GWAS study '{gStudy}' ", - "a QTL tuple overlaps use {length(keys)} different LD ", - "references." - ), - i = str_c( - "Their statistics are scored together against one LD matrix; ", - "give them one LD reference." - ) - )) - } - .rowLdRef(gwasSumStats, rows[[1L]]) + .rowsSharedLdRef( + gwasSumStats, + rows, + glue( + "causalInferencePipeline: the rows of GWAS study '{gStudy}' ", + "a QTL tuple overlaps" + ) + ) } # Build the (qtlStudy, context, trait, method) work list + the per-row @@ -296,6 +308,8 @@ causalInferencePipeline <- function( selectionActive = FALSE )) } + # The metrics describe each fit on all of its variants. + .fitCoverageCheckedRows(twasWeights, "causalInferencePipeline()") metricTab <- .cipMethodMetrics( qtlRows, twasWeights, @@ -321,23 +335,12 @@ causalInferencePipeline <- function( list(qtlRows = qtlRows, rsqLookup = rsqLookup, selectionActive = TRUE) } -# Score one QTL tuple against every GWAS study it overlaps -> a list of -# result records (empty when the tuple has no usable weights, or overlaps no -# GWAS row). Each study is scored once, over just the rows the tuple's window -# overlaps: a study split by chromosome or LD block has many rows, and -# pairing the tuple with every one of them scored it once per row. -# `gwasIndex` is .rowSpans(gwasSumStats), built once for the run. +# One QTL tuple's inputs: its identity, weights and fine-mapping entry, and +# the variants it reads the GWAS at. NULL when the tuple has no usable +# weights. The variants are its weight variants plus its fine-mapping ones, +# which MR reads too. # @noRd -.cipScoreQtlTuple <- function( - qi, - qtlRows, - twasWeights, - fineMappingResult, - gwasSumStats, - gwasIndex, - alleleFlip, - mrParam -) { +.cipTupleInputs <- function(qi, qtlRows, twasWeights, fineMappingResult) { tuple <- list( qStudy = qtlRows$qtlStudy[[qi]], qContext = qtlRows$context[[qi]], @@ -354,7 +357,7 @@ causalInferencePipeline <- function( useFmr = qtlRows$useFmrForWeights[[qi]] ) if (is.null(weightsInfo)) { - return(list()) + return(NULL) } fmrEntry <- .cipResolveFmrEntry( fineMappingResult, @@ -363,15 +366,69 @@ causalInferencePipeline <- function( tuple$qTrait, tuple$qMethod ) - window <- .cipTupleWindow(weightsInfo, fmrEntry) + fmrIds <- if (!is.null(fmrEntry)) { + .grVariantIds(unlist(fmrEntry, use.names = FALSE)) + } + list( + tuple = tuple, + weightsInfo = weightsInfo, + fmrEntry = fmrEntry, + variants = .variantIdsToGRanges( + unique(c(weightsInfo$variantIds, fmrIds)), + what = "causalInferencePipeline variant id" + ) + ) +} + +# Each tuple's variants against the LD blocks of the GWAS studies they +# overlap (.checkGwasBlockReach()). +# @noRd +.cipCheckBlockReach <- function(tuples, gwasSumStats) { + .checkGwasBlockReach( + set_names(map(tuples, "variants"), map_chr(tuples, .cipTupleLabel)), + gwasSumStats, + "causalInferencePipeline", + "QTL tuples" + ) +} + +# @noRd +.cipTupleLabel <- function(input) { + t <- input$tuple + .fmrTupleLabel( + "QTL", + list( + study = t$qStudy, + context = t$qContext, + trait = t$qTrait, + method = t$qMethod + ) + ) +} + +# Score one QTL tuple against every GWAS study it overlaps -> a list of +# result records (empty when it overlaps no GWAS row). Each study is scored +# once, over just the rows the tuple's window -- the span of its variants -- +# overlaps: a study split by chromosome or LD block has many rows, and +# pairing the tuple with every one of them scored it once per row. +# `gwasIndex` is .rowSpans(gwasSumStats), built once for the run. +# @noRd +.cipScoreQtlTuple <- function( + input, + gwasSumStats, + gwasIndex, + alleleFlip, + mrParam +) { + window <- range(input$variants) rows <- unique(gwasIndex$rows[.overlapsOnShared(gwasIndex$spans, window)]) studies <- as.character(gwasSumStats$study)[rows] compact(imap( split(rows, factor(studies, levels = unique(studies))), .cipScoreGwasPair, - tuple = tuple, - weightsInfo = weightsInfo, - fmrEntry = fmrEntry, + tuple = input$tuple, + weightsInfo = input$weightsInfo, + fmrEntry = input$fmrEntry, gwasSumStats = gwasSumStats, window = window, alleleFlip = alleleFlip, @@ -379,19 +436,6 @@ causalInferencePipeline <- function( )) } -# The window a QTL tuple's GWAS statistics are read over: the span of its -# weight variants, widened to its fine-mapping variants, which MR reads too. -# @noRd -.cipTupleWindow <- function(weightsInfo, fmrEntry) { - fmrIds <- if (!is.null(fmrEntry)) { - .grVariantIds(unlist(fmrEntry, use.names = FALSE)) - } - range(.variantIdsToGRanges( - unique(c(weightsInfo$variantIds, fmrIds)), - what = "causalInferencePipeline variant id" - )) -} - # The tuple's single-row collection from `fineMappingResult` (NULL when it # lacks the tuple). # @noRd @@ -614,6 +658,9 @@ causalInferencePipeline <- function( # with a named $metrics vector (corr, rsq, adj_rsq, pval, RMSE, MAE); a bare # metrics vector / data frame is tolerated too. `which` is a vector of candidate # metric names; the first present is used. Returns NA when no usable metric. +# Read from the row, not through cvResult(x, ...): .cipCvSelection() has +# already warned once about narrowed rows, which the accessor would repeat +# for every row and metric. # @noRd #' @importFrom rlang try_fetch .cipCvMetric <- function( @@ -626,11 +673,7 @@ causalInferencePipeline <- function( ) { perf <- try_fetch( cvResult( - twasWeights, - studyName = studyName, - context = context, - trait = trait, - method = method + .twrSelectRowParts(twasWeights, studyName, context, trait, method) ), error = function(cnd) NULL ) @@ -1393,9 +1436,8 @@ causalInferencePipeline <- function( # Convert the assembled result data.frame to a GRanges with mcols. .cipDfToGranges <- function(df) { - chr <- withChrPrefix(df$chrom) gr <- GenomicRanges::GRanges( - seqnames = chr, + seqnames = df$chrom, ranges = IRanges::IRanges( start = as.integer(df$startPos), end = as.integer(df$endPos) diff --git a/R/colocPipeline.R b/R/colocPipeline.R index c958639a..9bd3073e 100644 --- a/R/colocPipeline.R +++ b/R/colocPipeline.R @@ -203,8 +203,9 @@ setClass( #' @return \code{GwasFineMappingParam} returns a #' \code{GwasFineMappingParam} object, a \code{\link{MethodParam}}. #' Each accessor returns that setting's value --- for the three nested -#' bundles, the \code{MethodParam} itself --- and each replacement form -#' returns a modified copy. +#' bundles, the \code{MethodParam} itself. Change a setting with +#' \code{x$ <- value} (the field for \code{fineMappingMethods()} +#' is \code{methods}), which returns a modified copy. #' @examples #' GwasFineMappingParam( #' credibleSetParam = CredibleSetParam(coverage = 0.9) @@ -282,6 +283,35 @@ GwasFineMappingParam <- function( #' inline fine-mapping. #' } #' +#' @section A region over several LD blocks: Each first-side region is +#' colocalized with ONE fit per second-side study and method, however many +#' of a GWAS study's LD blocks it reaches -- scoring it against each block +#' separately would split one region into as many colocalizations as it +#' has blocks, each truncating the region's effects to one block's +#' variants. +#' \itemize{ +#' \item A \code{GwasSumStats} is fine-mapped once per set of rows a +#' region reaches, their statistics stitched together on their one +#' LD reference (rows on different references are refused). A +#' region inside one block reads that block's fit. +#' \item A \code{GwasFineMappingResult} was fine-mapped block by block. +#' Assuming no LD between blocks, the blocks a region reaches +#' collapse into one fit: every block's effects, each confined to +#' its own block (a Bayes factor of zero elsewhere), numbered on +#' from the blocks before it in row order. +#' } +#' The fit's \code{blockId} is then the stretch the blocks' ranges cover, +#' as \code{"chrom_start_end"} (see \code{region} in +#' \code{\linkS4class{GwasSumStats}}). +#' +#' A region's variants that lie outside every loaded block of a GWAS +#' study it overlaps are left out of that fit, a sign that a block it +#' reaches was not loaded. Where those blocks' ranges were given +#' (\code{regionGiven}), the variants lie in a block that was not loaded, +#' and that is an error. Where the ranges are the span of the GWAS +#' variants, the variants may only be ones the GWAS lacks, so more than one +#' in a row past a block is a warning. +#' #' @section LD reference compatibility check: Rows can sit on different LD #' references, so the check is per pair of rows coloc scores against each #' other -- a QTL row and a GWAS row whose regions overlap. Where the QTL @@ -334,13 +364,15 @@ GwasFineMappingParam <- function( #' two different things. #' @param returnGwasFineMapping Logical. When \code{TRUE}, attach the #' fine-mapping result computed from \code{gwasInput} on the returned object -#' as attribute \code{"gwasFineMapping"}. Default \code{FALSE}. +#' as attribute \code{"gwasFineMapping"}: for a \code{GwasSumStats}, one fit +#' per set of rows a first-side region reaches. Default \code{FALSE}. #' @param enrichment Optional data.frame of per-pair enrichment factors with #' columns \code{gwasStudy}, \code{qtlStudy}, \code{qtlContext}, #' \code{enrichment}, and optionally \code{gwasContext} / \code{gwasTrait} -#' (which the join uses when present, and which -#' \code{\link{qtlEnrichmentPipeline}} emits for a QTL outcome side). Output -#' of \code{\link{qtlEnrichmentPipeline}}. When non-\code{NULL} the pair is +#' / \code{gwasMethod} / \code{qtlMethod} (which the join uses when +#' present; \code{\link{qtlEnrichmentPipeline}} emits all four, the context +#' and trait set for a QTL outcome side). Output of +#' \code{\link{qtlEnrichmentPipeline}}. When non-\code{NULL} the pair is #' scored by enloc rather than coloc: the priors come from that table's #' \code{colocP1} / \code{colocP2} / \code{colocP12} columns, and the #' report gains \code{RCP} and \code{LCP}. Pairs without a matching @@ -354,7 +386,9 @@ GwasFineMappingParam <- function( #' missing variants in the GWAS \code{SumStats} and the QTL fine-mapping #' input has additional variants; (2) the GWAS fine-mapping result contains #' variants not present in the QTL fine-mapping result. Pass \code{FALSE} to -#' use the FMRs as supplied. +#' use the FMRs as supplied; each fit is then scored whole, so a row +#' narrowed since its fit warns (condition class +#' \code{pecotmrFitCoverage}). #' #' How much of each effect's posterior survived that restriction is reported #' per result row as \code{qtlRetainedMass} / \code{gwasRetainedMass}; a low @@ -371,7 +405,7 @@ GwasFineMappingParam <- function( #' prior probabilities are set through \code{priors} instead, since the #' enrichment adjustment reads them too. #' @return A \code{\linkS4class{ColocResult}}: one element per tested -#' (first-side credible set, second-side credible set, block) pair, holding +#' (first-side credible set, second-side credible set) pair, holding #' that pair's aligned variants with their \code{SNP.PP.H4}. Pair-level #' metadata carries the identity columns (\code{study}, \code{context}, #' \code{trait}, \code{method}, \code{gwasStudy}, \code{gwasContext}, @@ -390,9 +424,10 @@ GwasFineMappingParam <- function( #' is what readers of enloc output expect to find. #' #' Project it with \code{\link{colocPairs}} (the flat table this -#' pipeline used to return, also available as \code{as.data.frame}), -#' \code{\link{colocVariants}}, \code{\link{colocCredibleSets}} or -#' \code{\link{colocGenes}}. +#' pipeline used to return), \code{\link{colocVariants}}, +#' \code{\link{colocCredibleSets}} or \code{\link{colocGenes}}. Its +#' \code{seqinfo()} names the genome build the two sides name; sides +#' naming different builds are refused. #' @examples #' data(qtlFineMappingLbfExample) #' data(gwasFineMappingLbfExample) @@ -442,7 +477,7 @@ colocPipeline <- function( returnGwasFineMapping = returnGwasFineMapping ) if (length(gwasLbfByPair) == 0L) { - return(exec(.colocEarlyReturn, !!!shape)) + return(.withGenome(exec(.colocEarlyReturn, !!!shape), prepared$build)) } results <- .colocScoreAll( prepared, @@ -452,7 +487,7 @@ colocPipeline <- function( priors = priors, alleleFlip = alleleFlip ) - exec(.colocFinalize, results, !!!shape) + .withGenome(exec(.colocFinalize, results, !!!shape), prepared$build) } # Score every QTL tuple against the pre-extracted GWAS LBF matrices. @@ -465,11 +500,16 @@ colocPipeline <- function( priors, alleleFlip ) { + qtlKeys <- if (!is.null(prepared$pairing)) { + .colocRowKeys(prepared$qtlFineMappingResult) + } list_flatten(map( seq_len(nrow(prepared$qtlFineMappingResult)), .colocScoreQtlTuple, qtlFineMappingResult = prepared$qtlFineMappingResult, gwasLbfByPair = gwasLbfByPair, + pairing = prepared$pairing, + qtlKeys = qtlKeys, colocLbfFilterParam = colocLbfFilterParam, useEnrichment = prepared$useEnrichment, enrichment = enrichment, @@ -495,6 +535,11 @@ colocPipeline <- function( colocLbfFilterParam, priorsMissing ) { + # The genome build the two sides share, checked before any work. + build <- .inputsBuild( + list(qtlFineMappingResult, gwasInput), + "colocPipeline" + ) .colocAssertGroups(priors, colocLbfFilterParam, methodArgs) .colocRefusePriorsWithEnrichment(priors, enrichment, priorsMissing) useEnrichment <- !is.null(enrichment) @@ -504,18 +549,25 @@ colocPipeline <- function( enrichment = enrichment, useEnrichment = useEnrichment ) - rawGwasFmr <- .colocResolveGwasFmr(gwasInput, gwasFineMappingParam) - .colocRequireMatchingLdRefs(qtlFineMappingResult, rawGwasFmr) + .colocCheckBlockReach(qtlFineMappingResult, gwasInput) + resolved <- .colocResolveGwasFmr( + gwasInput, + gwasFineMappingParam, + qtlFineMappingResult + ) + .colocRequireMatchingLdRefs(qtlFineMappingResult, resolved$fmr) adjusted <- .colocMaybeAdjustPips( adjustPips = adjustPips, qtlFineMappingResult = qtlFineMappingResult, - gwasFmr = rawGwasFmr + gwasFmr = resolved$fmr ) list( ColocOptions = .colocEngineArgs(methodArgs, priors), useEnrichment = useEnrichment, qtlFineMappingResult = adjusted$qtlFineMappingResult, - gwasFmr = adjusted$gwasFmr + gwasFmr = adjusted$gwasFmr, + pairing = resolved$pairing, + build = build ) } @@ -582,7 +634,15 @@ colocPipeline <- function( # @noRd .colocValidateEnrichmentKeys <- function(enrichment) { idCols <- intersect( - c("gwasStudy", "gwasContext", "gwasTrait", "qtlStudy", "qtlContext"), + c( + "gwasStudy", + "gwasContext", + "gwasTrait", + "gwasMethod", + "qtlStudy", + "qtlContext", + "qtlMethod" + ), colnames(enrichment) ) ids <- select(as_tibble(enrichment), all_of(idCols)) @@ -597,26 +657,117 @@ colocPipeline <- function( } # Resolve the second side to a fine-mapping collection (fine-map QC'd sumstats -# when summary statistics are passed, whichever flavour they are). +# when summary statistics are passed, whichever flavour they are), with the +# pairing that says which of its fits each first-side row is scored against +# -- NULL when that is decided by shared variants. +# +# A GWAS study split into LD blocks is fine-mapped once per set of blocks a +# first-side region reaches, those blocks' statistics stitched together: +# scoring a region against each block's own fit would split one region into +# as many colocalizations as it has blocks. A region inside one block reads +# that block's fit. # @noRd -.colocResolveGwasFmr <- function(gwasInput, gwasFineMappingParam) { +.colocResolveGwasFmr <- function( + gwasInput, + gwasFineMappingParam, + qtlFineMappingResult +) { if (methods::is(gwasInput, "FineMappingResultBase")) { # Already fine-mapped: nothing in the bundle applies, so a setting # given here would be dropped rather than honoured. .colocAssertGwasFmrUnset(gwasFineMappingParam, class(gwasInput)[[1L]]) - return(gwasInput) + return(list(fmr = gwasInput, pairing = NULL)) } .assertMethodParam( gwasFineMappingParam, "GwasFineMappingParam" ) - if (length(qcInfo(gwasInput)) == 0L) { + if (length(qcOptions(gwasInput)) == 0L) { msg <- glue( "colocPipeline: gwasInput ({class(gwasInput)[[1L]]}) has no QC ", "record. Call summaryStatsQc() first." ) abort(msg) } + if (!methods::is(gwasInput, "GwasSumStats")) { + return(list( + fmr = .colocFineMapGwas(gwasInput, gwasFineMappingParam), + pairing = NULL + )) + } + sets <- .colocQtlRowSets(gwasInput, qtlFineMappingResult) + list( + fmr = .colocFineMapUnions(gwasInput, sets, gwasFineMappingParam), + pairing = tibble( + qtlKey = .colocRowKeys(qtlFineMappingResult)[sets$qtlRow], + key = str_c(sets$study, sets$blockId, sep = "\r") + ) + ) +} + +# Each first-side row's variants against the LD blocks of the GWAS studies it +# overlaps (.checkGwasBlockReach()). Only a GWAS second side has blocks. +# @noRd +.colocCheckBlockReach <- function(qtlFineMappingResult, gwasInput) { + if ( + !methods::is(gwasInput, "GwasSumStats") && + !methods::is(gwasInput, "GwasFineMappingResult") + ) { + return(invisible(NULL)) + } + side <- .fmrSideName(qtlFineMappingResult) + labels <- map_chr( + seq_len(nrow(qtlFineMappingResult)), + .colocUnitLabel, + fmr = qtlFineMappingResult, + side = side + ) + .checkGwasBlockReach( + set_names(as.list(qtlFineMappingResult), labels), + gwasInput, + "colocPipeline", + "regions of `qtlFineMappingResult`" + ) +} + +# @noRd +.colocUnitLabel <- function(ri, fmr, side) { + .fmrTupleLabel( + side, + .colocTupleIdentity(fmr, ri), + block = .fmrIdentityAt(fmr, "blockId", ri) + ) +} + +# A first-side row's identity: its tuple, its block and the one chromosome it +# sits on. The pairing keys rows by this rather than by index, since the PIP +# reconciliation that follows drops rows sharing no variant with the other +# side, and an index would then point at the wrong row. +# @noRd +.colocRowKeys <- function(fmr) { + cols <- intersect( + c( + "study", + "context", + "trait", + "method", + "blockId", + "jointStudies", + "jointContexts", + "jointTraits" + ), + .rtlTupleKeyCols(fmr) + ) + str_c( + .rtlTupleKeys(mcols(fmr, use.names = FALSE), cols, n = nrow(fmr)), + map_chr(as.list(fmr), .rtlElementSeqname), + sep = "\r" + ) +} + +# Fine-map summary statistics with the bundle's settings. +# @noRd +.colocFineMapGwas <- function(gwasInput, gwasFineMappingParam) { # The bundle's terminal: fineMappingPipeline takes these as its own # arguments, so it is unrolled once, here. withSusieInf <- gwasFineMappingParam$initializeWithSusieInf %||% TRUE @@ -633,6 +784,155 @@ colocPipeline <- function( ) } +# For each first-side row, the rows of each GWAS study its span reaches: one +# row per (first-side row, study), with the block id the fit of those rows +# goes by. Empty rows have no span and are never reached. +# @noRd +.colocQtlRowSets <- function(gws, qtlFineMappingResult) { + q <- .rowSpans(qtlFineMappingResult) + sets <- list_rbind(map( + seq_along(q$rows), + .colocRowSetsOf, + q = q, + index = .rowSpans(gws), + gws = gws, + regions = .rowRegions(gws) + )) + if (is.null(sets) || nrow(sets) == 0L) { + return(tibble( + qtlRow = integer(0), + study = character(0), + rows = list(), + blockId = character(0) + )) + } + sets +} + +# @noRd +.colocRowSetsOf <- function(k, q, index, gws, regions) { + hits <- sort(unique( + index$rows[.overlapsOnShared(index$spans, q$spans[k])] + )) + if (length(hits) == 0L) { + return(NULL) + } + studies <- as.character(gws$study)[hits] + byStudy <- unname(split(hits, factor(studies, levels = unique(studies)))) + tibble( + qtlRow = rep(q$rows[[k]], length(byStudy)), + study = unique(studies), + rows = byStudy, + blockId = map_chr( + byStudy, + .colocUnionBlockId, + gws = gws, + regions = regions + ) + ) +} + +# The block id a set of a study's rows is fine-mapped under. fineMappingPipeline +# carries it over as it is, which is what lets each first-side row find its +# own fit again afterwards. +# @noRd +.colocUnionBlockId <- function(rows, gws, regions) { + .colocMergedBlockId( + as.character(gws$blockId)[rows], + regions$region[rows] + ) +} + +# Fine-map each distinct set of rows once, however many first-side rows reach +# it. +# @noRd +.colocFineMapUnions <- function(gws, sets, gwasFineMappingParam) { + unions <- slice( + sets, + which(!duplicated(str_c(sets$study, sets$blockId, sep = "\r"))) + ) + if (nrow(unions) == 0L) { + return(GwasFineMappingResult( + studyName = character(0), + method = character(0), + entry = list() + )) + } + .colocFineMapGwas(.colocUnionSumStats(gws, unions), gwasFineMappingParam) +} + +# One row per set: its rows' statistics stitched together, on their one LD +# reference, under the set's block id. Study-level values are read off the +# set's first row, which every row of a study shares. +# @noRd +.colocUnionSumStats <- function(gws, unions) { + first <- map_int(unions$rows, 1L) + md <- mcols(gws) + stitched <- GwasSumStats( + studyName = unions$study, + entry = map(unions$rows, .ssStitchElements, x = gws), + genome = discard(unique(GenomeInfoDb::genome(gws)), is.na)[[1L]], + ldReference = map2( + unions$rows, + unions$study, + .colocUnionLdRef, + gws = gws + ), + varY = as.numeric(md$varY)[first], + nCase = .colocStudyValue(md, "nCase", first), + nControl = .colocStudyValue(md, "nControl", first), + nSample = .colocStudyValue(md, "nSample", first), + qcOptions = qcOptions(gws), + blockId = unions$blockId + ) + .withRegionColumns( + stitched, + .colocUnionRegions(unions$rows, .rowRegions(gws)) + ) +} + +# Each set's block range: the stretch its rows' ranges cover, given only when +# every one of them was. +# @noRd +.colocUnionRegions <- function(sets, regions) { + list( + region = unname(unlist(.rtlBindElements( + map(sets, .colocSetRange, regions = regions) + ))), + regionGiven = map_lgl(sets, .colocSetGiven, regions = regions) + ) +} + +# @noRd +.colocSetRange <- function(rows, regions) { + range(regions$region[rows]) +} + +# @noRd +.colocSetGiven <- function(rows, regions) { + all(regions$regionGiven[rows]) +} + +# @noRd +.colocStudyValue <- function(md, nm, rows) { + if (!is_in(nm, colnames(md))) { + return(NULL) + } + as.numeric(md[[nm]])[rows] +} + +# @noRd +.colocUnionLdRef <- function(rows, study, gws) { + .rowsSharedLdRef( + gws, + rows, + glue( + "colocPipeline: the rows of GWAS study '{study}' a QTL region ", + "reaches" + ) + ) +} + # `gwasFineMappingParam` configures the fine-mapping run colocPipeline does on # a raw GWAS input. A caller who has already fine-mapped the GWAS has no such # run, so a non-default bundle is an instruction that cannot be carried out. @@ -672,6 +972,10 @@ colocPipeline <- function( # intersectVariants() gives, and it replaces the older hand-rolled pass which # adjusted each side to the UNION of the other's variants -- a union is not an # intersection, so the two sides could still end up on different sets. +# +# The adjustment restricts each fit to the shared variants, which its row +# then holds exactly. Only a fit scored as supplied can describe variants its +# row no longer holds, and that warns. # @noRd .colocMaybeAdjustPips <- function( adjustPips, @@ -682,10 +986,11 @@ colocPipeline <- function( qtlFineMappingResult = qtlFineMappingResult, gwasFmr = gwasFmr ) - if (!isTRUE(adjustPips)) { + if (nrow(qtlFineMappingResult) == 0L || nrow(gwasFmr) == 0L) { return(unchanged) } - if (nrow(qtlFineMappingResult) == 0L || nrow(gwasFmr) == 0L) { + if (!isTRUE(adjustPips)) { + .fitCoverageCheckedAll(unchanged, "colocPipeline()") return(unchanged) } both <- intersectVariants(qtlFineMappingResult, gwasFmr) @@ -705,12 +1010,14 @@ colocPipeline <- function( .colocAttachGwasFm(out, returnGwasFineMapping, gwasInput, gwasFmr) } -# Score one QTL tuple against every pre-extracted GWAS pair -> summary rows. +# Score one QTL tuple against each second-side fit it reaches -> summary rows. # @noRd .colocScoreQtlTuple <- function( qi, qtlFineMappingResult, gwasLbfByPair, + pairing, + qtlKeys, colocLbfFilterParam, useEnrichment, enrichment, @@ -733,7 +1040,13 @@ colocPipeline <- function( effect = qLbfInfo$effect ) compact(map( - gwasLbfByPair, + .colocGwasRecordsFor( + qtlKeys[[qi]], + colnames(qLbfInfo$lbf), + gwasLbfByPair, + pairing, + alleleFlip + ), .colocScorePairAt, qLbfInfo = qLbfInfo, q = scored, @@ -927,12 +1240,15 @@ colocPipeline <- function( list(summary = summary, results = .colocEnlocResults(scored, aligned)) } -# One (QTL effect, GWAS effect) pair, which is enloc's signal cluster. +# One (QTL effect, GWAS effect) pair, which is enloc's signal cluster. The +# LBF matrices hold SuSiE's natural-log Bayes factors and enloc reads log10 +# ones, so they are converted here; read as log10 unconverted, every cluster's +# PIPs came out sharper than SuSiE's own alpha. # @noRd .colocEnlocOneEffectPair <- function(i, j, aligned, priors) { .enlocScoreEffectPair( - qtlLog10Bf = aligned$qtl[i, ], - gwasLog10Bf = aligned$gwas[j, ], + qtlLog10Bf = aligned$qtl[i, ] / log(10), + gwasLog10Bf = aligned$gwas[j, ] / log(10), priors = priors ) } @@ -1181,7 +1497,10 @@ colocPipeline <- function( # The fit's own effect indices, which -- unlike coloc's idx1 / idx2 -- # are stable across calls and blocks, so they are what identifies a # credible set in the result. - effect = keep + effect = keep, + # How many effects the fit has before filtering, which is what a + # collapse of several blocks numbers the next block's effects after. + nEffects = nrow(allRows) ) } @@ -1275,13 +1594,15 @@ colocPipeline <- function( as.numeric(mass) } -# The entry's variant ids, when the matrix does not already name its columns. +# The ids the fit was made with, when the matrix does not already name its +# columns: the columns are the fit's variables, which a row narrowed since no +# longer holds all of. # @noRd .colocLbfNamesFrom <- function(lbfMatrix, parts) { if (!is.null(colnames(lbfMatrix)) && !any(is.na(colnames(lbfMatrix)))) { return(lbfMatrix) } - vids <- .fmrPartsVariantIds(parts) + vids <- .partsFitIds(parts) if (length(vids) != ncol(lbfMatrix)) { return(lbfMatrix) } @@ -1314,11 +1635,28 @@ colocPipeline <- function( .colocGwasLbfAt, gwasFmr = gwasFmr, blockIds = .colocGwasBlockIds(gwasFmr), + regions = .rowRegions(gwasFmr)$region, + fits = .colocGwasFitKeys(gwasFmr), side = .fmrSideName(gwasFmr), colocLbfFilterParam = colocLbfFilterParam )) } +# Which fit each second-side row belongs to. A GWAS fit is every LD block of +# one (study, method), and those rows are what a QTL region's blocks are +# collapsed from; a QTL row is a fit of its own. +# @noRd +.colocGwasFitKeys <- function(gwasFmr) { + if (!methods::is(gwasFmr, "GwasFineMappingResult")) { + return(as.character(seq_len(nrow(gwasFmr)))) + } + str_c( + .fmrIdentityColumn(gwasFmr, "study"), + .fmrIdentityColumn(gwasFmr, "method"), + sep = "\r" + ) +} + # One second-side row's LBF matrix plus its identity, or NULL when the row has # no usable LBF. # @noRd @@ -1326,6 +1664,8 @@ colocPipeline <- function( ri, gwasFmr, blockIds, + regions, + fits, side, colocLbfFilterParam ) { @@ -1346,13 +1686,133 @@ colocPipeline <- function( lbf = info$lbf, retainedMass = info$retainedMass, effect = info$effect, + nEffects = info$nEffects, blockId = blockId, + fit = fits[[ri]], + region = regions[ri], label = label, + side = side, + ldKey = .ldRefKeys(gwasFmr)[[ri]], ldReference = .rowLdRef(gwasFmr, ri) ) ) } +# The second-side fits one QTL tuple is scored against: one record per fit, +# however many LD blocks it spans. With a `pairing` -- the GWAS fine-mapped +# here, once per set of rows a QTL region reaches -- that is the tuple's own +# fits. Otherwise it is every fit sharing variants with the tuple, its +# overlapped blocks collapsed into one. +# @noRd +.colocGwasRecordsFor <- function( + qKey, + qIds, + gwasLbfByPair, + pairing, + alleleFlip +) { + if (!is.null(pairing)) { + return(keep( + gwasLbfByPair, + .colocRecordKeyIn, + keys = pairing$key[pairing$qtlKey == qKey] + )) + } + hits <- keep( + gwasLbfByPair, + .colocSharesVariants, + qIds = qIds, + alleleFlip = alleleFlip + ) + fits <- map_chr(hits, "fit") + unname(map( + split(hits, factor(fits, levels = unique(fits))), + .colocCollapseBlocks + )) +} + +# @noRd +.colocRecordKeyIn <- function(rec, keys) { + is_in(str_c(rec$study, rec$blockId, sep = "\r"), keys) +} + +# @noRd +.colocSharesVariants <- function(rec, qIds, alleleFlip) { + m <- matchVariants(qIds, colnames(rec$lbf), allowFlip = alleleFlip) + length(m$idxA) > 0L +} + +# The LD blocks of one GWAS fit a QTL region reaches, collapsed into the one +# fit they make when there is no LD between blocks. The RSS likelihood then +# factorizes over blocks, so an effect fitted in one block carries no evidence +# about another's variants: the collapsed fit holds every block's effects, +# each confined to its own block -- an LBF of -Inf, a Bayes factor of zero, +# elsewhere -- and numbered on from the blocks before it, in row order. A fit +# the region reaches in one block is that block's record as it is. +# @noRd +.colocCollapseBlocks <- function(recs) { + if (length(recs) == 1L) { + return(recs[[1L]]) + } + ids <- unique(list_c(map(recs, .colocLbfIds))) + offsets <- cumsum(c(0L, map_int(recs, "nEffects")))[seq_along(recs)] + blockId <- .colocMergedBlockId( + map_chr(recs, "blockId"), + unlist(.rtlBindElements(map(recs, "region"))) + ) + list_assign( + recs[[1L]], + lbf = exec(rbind, !!!map(recs, .colocPadLbf, ids = ids)), + retainedMass = list_c(map(recs, "retainedMass")), + effect = list_c(map2(recs, offsets, .colocShiftEffects)), + nEffects = sum(map_int(recs, "nEffects")), + blockId = blockId, + label = .fmrTupleLabel( + recs[[1L]]$side, + recs[[1L]][c("study", "context", "trait", "method")], + block = blockId + ), + ldReference = .colocMergedLdRef(recs) + ) +} + +# @noRd +.colocLbfIds <- function(rec) { + colnames(rec$lbf) +} + +# One block's LBF rows over the collapsed fit's variants: -Inf off the block. +# @noRd +.colocPadLbf <- function(rec, ids) { + out <- matrix(-Inf, nrow(rec$lbf), length(ids), dimnames = list(NULL, ids)) + out[, colnames(rec$lbf)] <- rec$lbf + out +} + +# @noRd +.colocShiftEffects <- function(rec, offset) { + rec$effect + offset +} + +# The blocks' shared LD reference, or none when they sit on different ones. +# @noRd +.colocMergedLdRef <- function(recs) { + if (n_distinct(map_chr(recs, "ldKey")) > 1L) { + return(NULL) + } + recs[[1L]]$ldReference +} + +# The block id of a fit over several LD blocks: the stretch their windows +# cover, as "chrom_start_end". A single block keeps its own. +# @noRd +.colocMergedBlockId <- function(blockIds, regions) { + if (length(blockIds) == 1L) { + return(blockIds[[1L]]) + } + .rtlOneRangeKey(range(regions)) +} + # The LD block each GWAS fine-mapping row was computed on. The element's own # range is the identity; an explicit `blockId` (which keys the external block # manifest, and so carries the true block BOUNDARIES rather than the span of @@ -1477,8 +1937,10 @@ colocPipeline <- function( gwasStudy = gInfo$study, gwasContext = gInfo$context, gwasTrait = gInfo$trait, + gwasMethod = gInfo$method, qtlStudy = q$study, - qtlContext = q$context + qtlContext = q$context, + qtlMethod = q$method ) wanted[is_in(names(wanted), colnames(enrichment))] } @@ -1577,94 +2039,36 @@ colocPipeline <- function( } # --- GwasFineMappingParam accessors ---------------------------------------- -# The nested getters return the Param itself, so a caller edits it with its -# own replacement methods and hands it back: -# cs <- credibleSetParam(g); csCoverage(cs) <- 0.9; credibleSetParam(g) <- cs +# The nested getters return the Param itself, so a caller edits it with `$<-` +# and hands it back: +# cs <- g$credibleSetParam; cs$coverage <- 0.9; g$credibleSetParam <- cs #' @rdname GwasFineMappingParam setMethod("fineMappingMethods", "GwasFineMappingParam", function(x) { x@methods }) -#' @rdname GwasFineMappingParam -setReplaceMethod( - "fineMappingMethods", - "GwasFineMappingParam", - function(x, value) { - x@methods <- value - validObject(x) - x - } -) - #' @rdname GwasFineMappingParam setMethod("credibleSetParam", "GwasFineMappingParam", function(x) { x@credibleSetParam }) -#' @rdname GwasFineMappingParam -setReplaceMethod( - "credibleSetParam", - "GwasFineMappingParam", - function(x, value) { - x@credibleSetParam <- value - validObject(x) - x - } -) - #' @rdname GwasFineMappingParam setMethod("susieRssParam", "GwasFineMappingParam", function(x) x@susieRssParam) -#' @rdname GwasFineMappingParam -setReplaceMethod("susieRssParam", "GwasFineMappingParam", function(x, value) { - x@susieRssParam <- value - validObject(x) - x -}) - #' @rdname GwasFineMappingParam setMethod("panelFilterParam", "GwasFineMappingParam", function(x) { x@panelFilterParam }) -#' @rdname GwasFineMappingParam -setReplaceMethod( - "panelFilterParam", - "GwasFineMappingParam", - function(x, value) { - x@panelFilterParam <- value - validObject(x) - x - } -) - #' @rdname GwasFineMappingParam setMethod("initializeWithSusieInf", "GwasFineMappingParam", function(x) { x@initializeWithSusieInf }) -#' @rdname GwasFineMappingParam -setReplaceMethod( - "initializeWithSusieInf", - "GwasFineMappingParam", - function(x, value) { - x@initializeWithSusieInf <- value - validObject(x) - x - } -) - #' @rdname GwasFineMappingParam setMethod("fitRetention", "GwasFineMappingParam", function(x) x@fitRetention) -#' @rdname GwasFineMappingParam -setReplaceMethod("fitRetention", "GwasFineMappingParam", function(x, value) { - x@fitRetention <- value - validObject(x) - x -}) - #' @title Arguments For coloc's Bayes-Factor Scorer #' @description Options forwarded to \code{coloc::coloc.bf_bf}. The prior #' probabilities are \emph{not} settable here --- pecotmr derives them from @@ -1705,14 +2109,24 @@ ColocOptions <- function(overlap.min = NULL, trim_by_posterior = NULL, ...) { # Run coloc.bf_bf for an aligned pair, warning + NULL on failure. # @noRd #' @importFrom rlang try_fetch +# An LBF matrix with coloc's "null" column: log BF 0, the null against itself. +# Without one, coloc.bf_bf takes the LAST variant for the null and subtracts +# its LBF from the others, which is NaN when that LBF is -Inf -- as it is for +# an effect of a collapsed block fit that sits in another block. With one +# nothing is shifted, so a single block's scores are unchanged. +# @noRd +.colocWithNull <- function(lbf) { + cbind(lbf, null = 0) +} + .colocRunPair <- function(aligned, p12Used, q, gInfo, p1, p2, ColocOptions) { # Engine-call exception: coloc's whole interface is two blocks -- this and # ColocOptions -- so a colocWrapper.R would hold ~50 lines against this # file's 1600. The engine boundary is stated here instead of split out. callArgs <- c( list( - aligned$qtl, - aligned$gwas, + .colocWithNull(aligned$qtl), + .colocWithNull(aligned$gwas), p1 = p1, p2 = p2, p12 = p12Used diff --git a/R/colocboostPipeline.R b/R/colocboostPipeline.R index b6dcf963..9f6229a3 100644 --- a/R/colocboostPipeline.R +++ b/R/colocboostPipeline.R @@ -10,7 +10,7 @@ #' \item \code{QtlSumStats} -- summary-statistic-only QTL data with an #' LD reference per row (\code{ldReference}). Must already have #' been passed through \code{\link{summaryStatsQc}} (the -#' pipeline rejects inputs whose \code{qcInfo()} is empty). +#' pipeline rejects inputs whose \code{qcOptions()} is empty). #' Every analysis variant is available on this input, including #' \code{xqtlColoc}, which colocalizes the QTL studies against #' each other with no GWAS involved. @@ -27,11 +27,10 @@ #' @section QC contract: #' \itemize{ #' \item Individual-level QC (MAF / MAC / X-variance / per-sample -#' missingness, sample / variant restrictions) lives on the -#' \code{QtlDataset} constructor and is applied lazily inside -#' \code{genotypes()} / \code{residualizedGenotypes()}. -#' The pipeline does \emph{not} run a separate -#' individual-level QC pass. +#' missingness, sample / variant restrictions) is +#' \code{genotypeFilterParam}, applied to each block of genotypes +#' the pipeline extracts. A \code{QtlDataset} records no filter +#' of its own. #' \item \code{panelFilterParam} acts at ANALYSIS time on the sumstat #' sides, measured against the \strong{LD reference panel}: a #' variant whose panel genotypes fall below its cutoffs is dropped @@ -46,7 +45,7 @@ #' imputation, etc.) lives in #' \code{\link{summaryStatsQc}}. The pipeline rejects any #' \code{QtlSumStats} or \code{GwasSumStats} where -#' \code{length(qcInfo(x)) == 0L}. +#' \code{length(qcOptions(x)) == 0L}. #' } #' #' @section Analysis variants: @@ -56,11 +55,13 @@ #' \code{gwasSumStats}. Works for either data form -- the #' individual-level contexts, the summary-level QTL studies, or #' both together when a \code{MultiStudyQtlDataset} carries a -#' mixture. This is the only variant that honors -#' \code{focalTrait}. -#' \item \code{jointGwas} (default \code{FALSE}): run a non-focal -#' colocboost model that combines all QTL contexts/studies -#' with the supplied \code{gwasSumStats} studies. +#' mixture. Focal only on a QTL outcome named by +#' \code{focalOutcome}. +#' \item \code{jointGwas} (default \code{FALSE}): run one colocboost +#' model that combines all QTL contexts/studies with the +#' supplied \code{gwasSumStats} studies. By default it is focal on +#' the GWAS when \code{gwasSumStats} holds a single study, and +#' non-focal when it holds several; \code{focalOutcome} chooses. #' \item \code{separateGwas} (default \code{FALSE}): run one focal #' colocboost model per GWAS study, where the GWAS is the #' focal outcome. @@ -69,36 +70,63 @@ #' @param qtlData One of \code{QtlDataset}, \code{QtlSumStats}, or #' \code{MultiStudyQtlDataset}. #' @param gwasSumStats Optional \code{GwasSumStats} with the GWAS studies to -#' colocalize against. \code{NULL} to skip GWAS colocalization. Its -#' \code{ldReference} need not be the QTL side's: every row's summary -#' statistics are matched against that row's own reference. When some rows' -#' references are genotype panels and others' are \code{LdMatrix} objects, -#' the runs that combine them pass colocboost the panels' LD as matrices, -#' since colocboost takes LD matrices or reference genotypes but not both. -#' @param contexts Optional character vector of context names to restrict the -#' individual-level / QtlSumStats QTL analysis to. When \code{NULL} (default), -#' every context present is used. -#' @param traitId Optional character vector of trait identifiers to restrict the -#' analysis to. When supplied with an individual-level \code{QtlDataset} -#' input, \code{cisWindow} is required (passed to -#' \code{residualizedGenotypes} / \code{molecularTraits} for the -#' variant-window selection). +#' colocalize against. \code{NULL} to skip GWAS colocalization. Each study +#' is one outcome: the union of its rows that the QTL data overlap, so a +#' study split by chromosome or LD block contributes just the one or two +#' rows the QTL region reaches, and a study none of whose rows it reaches is +#' left out. QTL variants outside every loaded block of a study the QTL data +#' overlap are an error where the blocks' ranges were given +#' (\code{regionGiven}, see \code{\linkS4class{GwasSumStats}}), since they +#' lie in a block that was not loaded, and a warning for more than one in a +#' row past a range computed from the GWAS variants. Those rows must share +#' one LD reference, but it need not be the +#' QTL side's: every outcome's summary statistics are matched against their +#' own reference. When some references are genotype panels and others are +#' \code{LdMatrix} objects, the runs that combine them pass colocboost the +#' panels' LD as matrices, since colocboost takes LD matrices or reference +#' genotypes but not both. +#' @param contexts Optional character vector of context names to restrict +#' the individual-level / QtlSumStats QTL analysis to. When \code{NULL} +#' (default), every context present is used. A MultiStudyQtlDataset applies +#' it to every study: a context no study has is an error, and one only some +#' studies lack is skipped for those, with a warning. +#' @param traitId Optional character vector of trait identifiers to restrict +#' the analysis to. When supplied with an individual-level +#' \code{QtlDataset} input, \code{cisWindow} is required: each trait's +#' position \eqn{\pm} \code{cisWindow} is the variant window. In a +#' MultiStudyQtlDataset a study carrying none of them sits out; the run is +#' refused only when no study or summary-statistics row carries one. #' @param region Optional single-range \code{GRanges} describing the analysis -#' window. Mutually exclusive with \code{traitId} (see the \code{QtlDataset} -#' accessors). Individual-level input only: summary statistics carry no -#' genotypes to window, so the \code{QtlSumStats} method does not take it -#' --- matching \code{\link{fineMappingPipeline}} and -#' \code{\link{twasWeightsPipeline}}. -#' @param cisWindow Optional cis window in basepairs; required with -#' \code{traitId}, optional with \code{region}. Individual-level input -#' only, as for \code{region}. +#' window. Mutually exclusive with \code{traitId}. Individual-level input +#' only: a summary-statistics tuple +#' keeps the window it was built with (its \code{region}), so the +#' \code{QtlSumStats} method does not take one --- matching +#' \code{\link{fineMappingPipeline}} and \code{\link{twasWeightsPipeline}}. +#' @param cisWindow Optional cis window in basepairs. Individual-level +#' input: required with \code{traitId}, optional with \code{region}. +#' QtlSumStats input: each selected tuple is analysed over its +#' \code{traitPos} \eqn{\pm} \code{cisWindow}, within its \code{region}; +#' every selected tuple needs a \code{traitPos}. A MultiStudyQtlDataset +#' applies it to both kinds of study it holds. #' @param samples Optional character vector of sample IDs to restrict the #' analysis to; \code{NULL} (default) uses all samples. -#' @param focalTrait Optional trait name; when supplied and present in the -#' assembled outcome list, the colocboost xQTL-only run uses it as the focal -#' outcome. Only \code{xqtlColoc} reads it: \code{jointGwas} is -#' non-focal by construction and \code{separateGwas} always makes the -#' GWAS study focal. +#' @param focalOutcome The outcome a run treats as focal (colocboost's +#' \code{focal_outcome_idx}). One of: +#' \itemize{ +#' \item \code{NULL} (default): the GWAS study, in the \code{jointGwas} +#' run, when \code{gwasSumStats} holds exactly one. With several +#' there is no one study to choose, so no run is focal. +#' \item A GWAS study name, as a plain string: that study is focal in +#' the \code{jointGwas} run. It must be a study of +#' \code{gwasSumStats}. +#' \item A named character vector with any of \code{study}, +#' \code{context} and \code{trait} that identifies exactly one QTL +#' outcome, e.g. \code{c(context = "brain", trait = "ENSG1")}: that +#' outcome is focal in every run holding it, the \code{xqtlColoc} +#' run and the \code{jointGwas} run. +#' \item \code{NA}: no run is focal. +#' } +#' The \code{separateGwas} runs are always focal on their own GWAS study. #' @param xqtlColoc,jointGwas,separateGwas Logical flags selecting which #' colocboost variants to run. #' @param signalScreenParam Individual-level pre-filter (ports the legacy @@ -124,15 +152,27 @@ #' summary-statistic sides against the LD reference panel, built with #' \code{\link{PanelFilterParam}}: a variant whose panel genotypes fall #' below its cutoffs is dropped before the LD matrix is built. The defaults -#' filter nothing. See the Details section for how these relate to the -#' individual-level cutoffs recorded on a \code{QtlDataset}. +#' filter nothing. Individual-level genotypes are filtered by +#' \code{genotypeFilterParam} instead. +#' @param genotypeFilterParam Which individual-level variants and samples to +#' keep, built with \code{\link{GenotypeFilterParam}}: its +#' \code{keepSamples} narrows the dataset once, and its MAF, MAC, +#' variance, missingness, \code{keepVariants} and \code{keepIndel} +#' settings apply to each extracted block, as in +#' \code{\link{fineMappingPipeline}}. The default filters nothing. +#' \code{QtlDataset} and \code{MultiStudyQtlDataset} input only. +#' @param phenotypeFilterParam The run's phenotype QC, built with +#' \code{\link{PhenotypeFilterParam}}. colocboost takes missing phenotype +#' values as they are, so unset keeps them; \code{"drop"} or +#' \code{"impute"} applies that instead, and \code{outlierAction = +#' "drop"} removes outlier samples. \code{QtlDataset} and +#' \code{MultiStudyQtlDataset} input only. #' @param residualizationParam Covariate residualization settings for #' individual-level input, built with \code{\link{ResidualizationParam}}. #' Reaches both \code{\link{residualizedGenotypes}} and #' \code{\link{residualizedPhenotypes}}, so it governs what is regressed #' out of each side and --- through \code{scaleResiduals} --- whether the -#' columns are scaled to unit variance. Previously absent, which left this -#' pipeline on the dataset's own settings with no per-call say, unlike +#' columns are scaled to unit variance, as in #' \code{\link{fineMappingPipeline}} and #' \code{\link{twasWeightsPipeline}}. \strong{Ignored} on #' \code{QtlSumStats} input, which has nothing to residualize. @@ -157,14 +197,15 @@ #' \code{separate_gwas} runs. Outcome-specific (uncolocalized) sets are #' included with \code{isColocalized = FALSE}. #' -#' Project it with \code{\link{colocPairs}} (also available as -#' \code{as.data.frame}), \code{\link{colocVariants}} or -#' \code{\link{colocBoostOutcomes}}; timings are on +#' Project it with \code{\link{colocPairs}}, \code{\link{colocVariants}} +#' or \code{\link{colocBoostOutcomes}}; timings are on #' \code{\link{computingTime}} and the region-wide marginal #' probabilities on \code{\link{regionVcp}}. \code{\link{ldReference}} #' returns the LD references the summary statistics were matched against, #' each stored once, and the \code{ldReference} column of -#' \code{colocBoostOutcomes()} names the one each outcome used. +#' \code{colocBoostOutcomes()} names the one each outcome used. Its +#' \code{seqinfo()} names the genome build the inputs name; inputs naming +#' different builds are refused. #' @name colocboostPipeline #' @importFrom methods is setGeneric setMethod #' @importFrom S4Vectors mcols @@ -216,6 +257,176 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { )) } +# focalOutcome's shape: NULL, NA, one GWAS study name, or a named character +# vector of `study` / `context` / `trait` naming one QTL outcome. Whether it +# names a real outcome is settled once the outcomes are built +# (.cbResolveFocal()). +# @noRd +.cbAssertFocalOutcome <- function(focalOutcome) { + if (is.null(focalOutcome) || .cbFocalIsNa(focalOutcome)) { + return(invisible(NULL)) + } + if (.cbFocalShapeOk(focalOutcome)) { + return(invisible(NULL)) + } + abort(c( + str_c( + "colocboostPipeline: `focalOutcome` must be NULL, NA, one GWAS ", + "study name, or a named character vector of `study`, `context` ", + "and/or `trait` naming one QTL outcome." + ), + i = str_c( + "e.g. focalOutcome = \"MyGWAS\", or ", + "focalOutcome = c(context = \"brain\", trait = \"ENSG1\")." + ) + )) +} + +# @noRd +.cbFocalIsNa <- function(x) { + is.atomic(x) && length(x) == 1L && is.null(names(x)) && is.na(x) +} + +# One unnamed string, or a named character vector whose names are distinct +# fields of a QTL outcome. +# @noRd +.cbFocalShapeOk <- function(x) { + if (!is.character(x) || length(x) == 0L || anyNA(x)) { + return(FALSE) + } + nm <- names(x) + if (is.null(nm)) { + return(length(x) == 1L) + } + !anyDuplicated(nm) && all(is_in(nm, c("study", "context", "trait"))) +} + +# The outcome each run is focal on (NULL for none), from `focalOutcome`. +# `qtlInfo` lists the QTL outcomes (.cbQtlOutcomeInfo()) and `gwasKeys` maps +# each GWAS study that reached the runs to its outcome name (.cbGwasKeys()). +# A GWAS study can be focal only where it is an outcome, the joint run; a QTL +# outcome is focal in both runs that hold it. +# @noRd +.cbResolveFocal <- function(focalOutcome, gwasSumStats, qtlInfo, gwasKeys) { + if (.cbFocalIsNa(focalOutcome)) { + return(list(xqtl = NULL, joint = NULL)) + } + studies <- unique(as.character(gwasSumStats$study)) + if (is.null(focalOutcome)) { + return(list(xqtl = NULL, joint = .cbDefaultFocal(studies, gwasKeys))) + } + if (is.null(names(focalOutcome))) { + return(list( + xqtl = NULL, + joint = .cbFocalGwasKey(focalOutcome, studies, gwasKeys) + )) + } + name <- .cbFocalQtlName(focalOutcome, qtlInfo) + list(xqtl = name, joint = name) +} + +# The default focal outcome: the GWAS, when gwasSumStats holds one study and +# it reached the runs. Several studies leave no one study to choose. +# @noRd +.cbDefaultFocal <- function(studies, gwasKeys) { + if (length(studies) != 1L || !is_in(studies, names(gwasKeys))) { + return(NULL) + } + unname(gwasKeys[[studies]]) +} + +# The outcome name of GWAS study `study`, which must be a study of +# gwasSumStats and must have reached the runs. +# @noRd +.cbFocalGwasKey <- function(study, studies, gwasKeys) { + if (!is_in(study, studies)) { + known <- if (length(studies) == 0L) { + "no gwasSumStats was given" + } else { + str_c("its studies are ", str_flatten(studies, ", ")) + } + abort(c( + glue( + "colocboostPipeline: focalOutcome '{study}' names no GWAS ", + "study ({known})." + ), + i = str_c( + "Name a QTL outcome by a named vector, e.g. ", + "c(context = \"brain\", trait = \"ENSG1\")." + ) + )) + } + if (!is_in(study, names(gwasKeys))) { + abort(glue( + "colocboostPipeline: focalOutcome names GWAS study '{study}', ", + "but none of its rows overlap the QTL data, so it is not an ", + "outcome of the joint run." + )) + } + unname(gwasKeys[[study]]) +} + +# The one QTL outcome a focalOutcome vector identifies. +# @noRd +.cbFocalQtlName <- function(focal, qtlInfo) { + hit <- reduce( + names(focal), + .cbFocalField, + focal = focal, + qtlInfo = qtlInfo, + .init = rep(TRUE, nrow(qtlInfo)) + ) + if (sum(hit) == 1L) { + return(qtlInfo$name[hit]) + } + .cbAbortFocalQtl(focal, qtlInfo, hit) +} + +# @noRd +.cbFocalField <- function(hit, field, focal, qtlInfo) { + hit & is_in(qtlInfo[[field]], focal[[field]]) +} + +# A focalOutcome vector that names no QTL outcome, or several. +# @noRd +.cbAbortFocalQtl <- function(focal, qtlInfo, hit) { + asked <- str_flatten(str_c(names(focal), " = '", focal, "'"), ", ") + if (any(hit)) { + abort(c( + glue( + "colocboostPipeline: focalOutcome ({asked}) matches ", + "{sum(hit)} QTL outcomes: ", + "{.cbDescribeOutcomes(filter(qtlInfo, hit))}." + ), + i = "Add `study`, `context` or `trait` until it names one." + )) + } + abort(c( + glue( + "colocboostPipeline: focalOutcome ({asked}) matches no QTL ", + "outcome." + ), + i = glue("The QTL outcomes are: {.cbDescribeOutcomes(qtlInfo)}.") + )) +} + +# "study / context / trait" for up to ten outcomes, "-" for a part one lacks. +# @noRd +.cbDescribeOutcomes <- function(info) { + if (nrow(info) == 0L) { + return("none") + } + shown <- slice(info, seq_len(min(10L, nrow(info)))) + listed <- str_c( + coalesce(shown$study, "-"), + coalesce(shown$context, "-"), + coalesce(shown$trait, "-"), + sep = " / " + ) + more <- if (nrow(info) > 10L) str_c(", and ", nrow(info) - 10L, " more") + str_c(str_flatten(listed, "; "), more %||% "") +} + # The data slots the pipeline builds from its inputs. They are real # colocboost formals, so the union check would accept them -- but the # pipeline supplies them, so a value given here would be overwritten. @@ -264,16 +475,16 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { } # Reject SumStats objects that have not been passed through -# summaryStatsQc(). Both QtlSumStats and GwasSumStats expose qcInfo(); +# summaryStatsQc(). Both QtlSumStats and GwasSumStats expose qcOptions(); # an empty list (the constructor default) signals "no QC run". .cbRequireSumStatsQc <- function(x, what) { if (is.null(x)) { return(invisible(NULL)) } - if (length(qcInfo(x)) == 0L) { + if (length(qcOptions(x)) == 0L) { msg <- glue( "{what} must be passed through summaryStatsQc() before ", - "reaching colocboostPipeline (qcInfo() returned an empty ", + "reaching colocboostPipeline (qcOptions() returned an empty ", "list). Call summaryStatsQc(x, ...) and pass the result." ) abort(msg) @@ -316,11 +527,15 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { cisWindow = NULL, samples = NULL, pipCutoffToSkip = 0, - residualizationParam = ResidualizationParam() + residualizationParam = ResidualizationParam(), + genotypeFilter, + phenotypeFilter = .qtlKeepAllPhenotypes() ) { contexts <- .cbResolveBundleContexts(qd, contexts) p <- list( qd = qd, + genotypeFilter = genotypeFilter, + phenotypeFilter = phenotypeFilter, traitId = traitId, region = region, cisWindow = cisWindow, @@ -375,6 +590,71 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { contexts } +# A `trait` no selected context carries is refused, as fineMappingPipeline and +# twasWeightsPipeline refuse it, rather than every context being skipped into +# an empty result. +# @noRd +.cbAssertTraitsSelected <- function(qd, contexts, traitId) { + ctxs <- .cbResolveBundleContexts(qd, contexts) + carried <- map_lgl(ctxs, .cbContextCarries, qd = qd, traitId = traitId) + if (length(traitId) > 0L && !any(carried)) { + abort("colocboostPipeline(QtlDataset): no traits selected.") + } + invisible(NULL) +} + +# The QtlSumStats form: a contexts / trait selection that matches no row. +# @noRd +.cbAssertQssRowsSelected <- function(ss, contexts, traitId) { + if (nrow(ss) > 0L && !any(.cbQtlRowsSelected(ss, contexts, traitId))) { + abort(glue( + "colocboostPipeline(QtlSumStats): no entries matched the ", + "supplied contexts / traitId filters." + )) + } + invisible(NULL) +} + +# The multi-study form: refused only when no embedded dataset's contexts and +# no sumstat row carry a requested trait. A study that lacks it sits out, as +# it does in fineMappingPipeline and twasWeightsPipeline. +# @noRd +.cbMsAssertTraitsSelected <- function(msqd, contexts, traitId) { + if (length(traitId) == 0L) { + return(invisible(NULL)) + } + inData <- map_lgl( + as.list(msqd), + .cbDatasetCarries, + contexts = contexts, + traitId = traitId + ) + ss <- sumStats(msqd) + inSumStats <- !is.null(ss) && + nrow(ss) > 0L && + any(.cbQtlRowsSelected(ss, contexts, traitId)) + if (!any(inData) && !inSumStats) { + abort("colocboostPipeline(MultiStudyQtlDataset): no traits selected.") + } + invisible(NULL) +} + +# Whether any of a dataset's selected contexts carries a requested trait; +# contexts it lacks are left out (a study need not carry every context). +# @noRd +.cbDatasetCarries <- function(qd, contexts, traitId) { + ctxs <- intersect(contexts %||% contexts(qd), contexts(qd)) + any(map_lgl(ctxs, .cbContextCarries, qd = qd, traitId = traitId)) +} + +# Whether one context carries any requested trait (every context does when no +# trait was requested). +# @noRd +.cbContextCarries <- function(ctx, qd, traitId) { + length(traitId) == 0L || + any(is_in(traitId, rownames(.qtlContextSe(qd, context = ctx)))) +} + # Residualized (X, Y) for one context (sample-aligned + signal-screened), or # NULL when the context should be skipped. # @noRd @@ -384,7 +664,8 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { ctx, p$traitId, p$region, - p$residualizationParam + p$residualizationParam, + p$phenotypeFilter ) if (is.null(rawY) || ncol(rawY) == 0L) { return(NULL) @@ -396,11 +677,19 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { p$region, p$cisWindow, p$samples, - p$residualizationParam + p$residualizationParam, + p$genotypeFilter ) if (is.null(rawX) || ncol(rawX) == 0L) { return(NULL) } + .cbAlignContextXY(ctx, rawX, rawY, p$pipCutoffToSkip) +} + +# One context's X and Y on the samples they share, Y signal-screened; NULL, +# with a message, when they share none. +# @noRd +.cbAlignContextXY <- function(ctx, rawX, rawY, pipCutoffToSkip) { # Canonicalize variant colnames (chr-prefix + separator, allele order # preserved; rsIDs passed through) so colocboost's name-based matching # aligns them with the sumstat / LD ids and across studies. A genuine @@ -417,18 +706,25 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { return(NULL) } X <- named[common, , drop = FALSE] - Y <- .cbApplyScreen( - X, - rawY[common, , drop = FALSE], - ctx, - p$pipCutoffToSkip - ) + Y <- .cbApplyScreen(X, rawY[common, , drop = FALSE], ctx, pipCutoffToSkip) if (is.null(Y)) { return(NULL) } list(ctx = ctx, X = X, Y = Y) } +# colocboost's phenotype QC: colocboost takes missing phenotypes as they are, +# so an unset naAction keeps them, and every choice is available. +# @noRd +.cbResolvePhenotypeFilter <- function(phenotypeFilterParam) { + .qtlResolvePhenotypeFilter( + phenotypeFilterParam, + naDefault = "keep", + naAllowed = c("keep", "drop", "impute"), + caller = "colocboostPipeline" + ) +} + # Residualized phenotypes for one context (message + NULL on failure). # @noRd .cbResidualizedY <- function( @@ -436,16 +732,18 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { ctx, traitId, region, - residualizationParam = ResidualizationParam() + residualizationParam = ResidualizationParam(), + phenotypeFilter = .qtlKeepAllPhenotypes() ) { try_fetch( - residualizedPhenotypes( + .qtlResidualizedPhenotypes( qd, contexts = ctx, traitId = traitId, - region = region, + window = region, + phenotypeFilter = phenotypeFilter, residualizationParam = residualizationParam - ), + )[[ctx]], error = function(cnd) { msg <- glue( "colocboostPipeline: skipping context '{ctx}' ", @@ -466,16 +764,16 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { region, cisWindow, samples, - residualizationParam = ResidualizationParam() + residualizationParam = ResidualizationParam(), + genotypeFilter ) { try_fetch( - residualizedGenotypes( + .qtlResidualizedGenotypes( qd, contexts = ctx, - traitId = traitId, - region = region, - cisWindow = cisWindow, + window = .qtlResolveVariantRegion(qd, traitId, region, cisWindow), samples = samples, + filter = genotypeFilter, residualizationParam = residualizationParam ), error = function(cnd) { @@ -744,17 +1042,34 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { } # Build the colocboost sumstat / LD bundle from a QtlSumStats and an -# optional contexts / traitId filter. Returns a list keyed by sumstat -# study label, where each entry has (sumstat, LD). +# optional contexts / traitId filter, with `cisWindow` laid on the tuples it +# keeps. Returns a list keyed by sumstat study label, where each entry has +# (sumstat, LD). .cbQtlSumStatsBundle <- function( ss, contexts = NULL, traitId = NULL, - cutoffs = NULL + cutoffs = NULL, + cisWindow = NULL ) { if (is.null(ss) || nrow(ss) == 0L) { return(list()) } + rows <- which(.cbQtlRowsSelected(ss, contexts, traitId)) + if (length(rows) == 0L) { + return(list()) + } + ss <- .qssApplyCisWindow(ss, cisWindow, "colocboostPipeline", rows) + compact(set_names( + map(rows, .cbQtlEntryPair, ss = ss, cutoffs = cutoffs), + map_chr(rows, .cbQtlEntryLabel, ss = ss) + )) +} + +# The rows of `ss` colocboost's selection keeps: `contexts` and `traitId` are +# plain vectors here, and an empty one keeps everything. +# @noRd +.cbQtlRowsSelected <- function(ss, contexts, traitId) { byContext <- if (!is.null(contexts) && length(contexts) > 0L) { is_in(as.character(ss$context), contexts) } else { @@ -765,16 +1080,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { } else { TRUE } - keepRow <- byContext & byTrait - if (!any(keepRow)) { - return(list()) - } - rows <- which(keepRow) - - compact(set_names( - map(rows, .cbQtlEntryPair, ss = ss, cutoffs = cutoffs), - map_chr(rows, .cbQtlEntryLabel, ss = ss) - )) + byContext & byTrait } # @noRd @@ -788,21 +1094,32 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { } # One QTL entry's (sumstat, LD) pair, against the entry's own LD reference, -# or NULL when it has no panel overlap. +# or NULL when it has no panel overlap. It carries the tuple it came from, +# which a focalOutcome vector is matched against, and the tuple's span, which +# decides the GWAS rows a study contributes (.cbQtlWindow()). # @noRd .cbQtlEntryPair <- function(i, ss, cutoffs) { - .cbSumstatPair( - df = as.data.frame( + tuple <- list( + study = as.character(ss$study)[[i]], + context = as.character(ss$context)[[i]], + trait = as.character(ss$trait)[[i]] + ) + pair <- .cbSumstatPair( + df = .sumStatsDf( ss, - studyName = as.character(ss$study)[[i]], - context = as.character(ss$context)[[i]], - trait = as.character(ss$trait)[[i]], + studyName = tuple$study, + context = tuple$context, + trait = tuple$trait, require = "Z" ), ldReference = .rowLdRef(ss, i), varY = .cbTupleValue(ss, "varY", i), cutoffs = cutoffs ) + if (is.null(pair)) { + return(NULL) + } + list_assign(pair, !!!tuple, span = range(ss[[i]])) } # A tuple column's value for row `i`, or NA when the collection lacks it. @@ -816,34 +1133,76 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { S4Vectors::mcols(collection, use.names = FALSE)[[column]][[i]] } -# Same as .cbQtlSumStatsBundle for a GwasSumStats collection, keyed by -# study label. -.cbGwasSumStatsBundle <- function(gws, cutoffs = NULL) { +# Same as .cbQtlSumStatsBundle for a GwasSumStats collection: one pair per +# STUDY, keyed by study name. A study split by chromosome or LD block owns +# several rows, but it is one trait, so it reaches colocboost as one outcome +# -- the union of the rows that overlap `window`, where the QTL data sit +# (.cbQtlWindow()); its other rows are not read. `window = NULL` takes every +# row. +.cbGwasSumStatsBundle <- function(gws, window = NULL, cutoffs = NULL) { if (is.null(gws) || nrow(gws) == 0L) { return(list()) } - compact(set_names( - map(seq_len(nrow(gws)), .cbGwasEntryPair, gws = gws, cutoffs = cutoffs), - as.character(gws$study) + index <- .rowSpans(gws) + hit <- if (is.null(window)) { + rep(TRUE, length(index$rows)) + } else { + .overlapsOnShared(index$spans, window) + } + rows <- unique(index$rows[hit]) + studies <- as.character(gws$study) + .cbInformGwasLeftOut(setdiff(unique(studies), studies[rows])) + compact(imap( + split(rows, factor(studies[rows], levels = unique(studies[rows]))), + .cbGwasStudyPair, + gws = gws, + cutoffs = cutoffs )) } -# One GWAS entry's (sumstat, LD) pair, against the entry's own LD reference, -# or NULL when it has no panel overlap. # @noRd -.cbGwasEntryPair <- function(i, gws, cutoffs) { - .cbSumstatPair( - df = as.data.frame( +.cbInformGwasLeftOut <- function(studies) { + if (length(studies) == 0L) { + return(invisible(NULL)) + } + inform(glue( + "colocboostPipeline: leaving out GWAS ", + "{str_flatten(studies, ', ')}: no row overlaps the QTL data." + )) +} + +# One GWAS study's (sumstat, LD) pair over `rows`, its rows the QTL data +# overlap, stitched into one outcome; NULL when it has no panel overlap. The +# rows' statistics are read against one LD matrix, so they must share an LD +# reference. The study-level columns (varY, nCase, nControl) repeat on every +# row, so the first row's stand for the study. +# @noRd +.cbGwasStudyPair <- function(rows, study, gws, cutoffs) { + pair <- .cbSumstatPair( + df = .entryToSumstatDf( + .ssStitchElements(gws, rows), + require = "Z", + derive = "none", + keepChrPrefix = TRUE, + label = glue("GwasSumStats[{study}]") + ), + ldReference = .rowsSharedLdRef( gws, - studyName = as.character(gws$study)[[i]], - require = "Z" + rows, + glue( + "colocboostPipeline: the rows of GWAS study '{study}' the ", + "QTL data overlap" + ) ), - ldReference = .rowLdRef(gws, i), - varY = .cbTupleValue(gws, "varY", i), - nCase = .cbTupleValue(gws, "nCase", i), - nControl = .cbTupleValue(gws, "nControl", i), + varY = .cbTupleValue(gws, "varY", rows[[1L]]), + nCase = .cbTupleValue(gws, "nCase", rows[[1L]]), + nControl = .cbTupleValue(gws, "nControl", rows[[1L]]), cutoffs = cutoffs ) + if (is.null(pair)) { + return(NULL) + } + list_assign(pair, study = study) } # Combine sumstat bundles into the (sumstat-list, LD-list, dict) shape @@ -943,14 +1302,14 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { # A requested analysis with nothing to run on would otherwise be a silent # no-op: the caller gets an empty ColocBoostResult whose computingTime() -# entries are all NULL, with no indication of why. Say so. +# has no row for it, with no indication of why. Say so. # @noRd .cbWarnNoData <- function(flag, needed) { msg <- glue( "colocboostPipeline: {flag} = TRUE was requested, but there is no ", "{needed} to run it on. Skipping it -- the returned ", "ColocBoostResult will hold no confidence sets from this analysis ", - "and its computingTime() entry will be NULL." + "and its computingTime() will have no row for it." ) warn(msg) } @@ -959,9 +1318,9 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { # NULL) plus a sumstat bundle (possibly empty) and runs the colocboost # variants `run` (from .cbResolveRuns) switched on. `qtlSumstatBundle` is the # QTL-side subset of `sumstatBundle` (see .cbDriver); only the xQTL-only run -# uses it, so that a GWAS study never becomes an xQTL-only outcome. The -# result is keyed by the result slot each run fills; compact() drops what did -# not run. +# uses it, so that a GWAS study never becomes an xQTL-only outcome. `focal` +# names each run's focal outcome (.cbResolveFocal()). The result is keyed by +# the result slot each run fills; compact() drops what did not run. # @noRd .cbDispatchRuns <- function( individualBundle, @@ -969,7 +1328,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { qtlSumstatBundle, run, hasInd, - focalTrait, + focal, methodArgs, gwasRunBundles = list() ) { @@ -979,7 +1338,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { individualBundle, qtlSumstatBundle, hasInd, - focalTrait, + focal$xqtl, methodArgs ) }, @@ -989,7 +1348,8 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { sumstatBundle, hasInd, methodArgs, - gwasNames = names(gwasRunBundles) + gwasNames = names(gwasRunBundles), + focal = focal$joint ) }, separate_gwas = if (run$separate) { @@ -1085,6 +1445,8 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { # Run the requested colocboost analyses over the prepared bundles and fold # them into a ColocBoostResult (an empty one when no QTL input remains). +# `focal` names each run's focal outcome; `resultInfo` carries the outcome +# table and LD references the result records (.cbPrepareInputs()). # @noRd .cbRunVariants <- function( individualBundle, @@ -1092,9 +1454,9 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { xqtlColoc, jointGwas, separateGwas, - focalTrait, + focal, methodArgs, - ldRefs = list(refs = list(), keys = character(0)), + resultInfo = list(outcomeInfo = .cbEmptyOutcomeInfo(), ldRefs = list()), qtlSumstatBundle = NULL, gwasRunBundles = list() ) { @@ -1124,15 +1486,14 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { qtlSumstatBundle, run, hasInd, - focalTrait, + focal, methodArgs, gwasRunBundles = gwasRunBundles ) - results <- .cbMergeRuns(.cbEmptyResult(), runs) .cbToResultObject( - results, - .cbOutcomeInfo(individualBundle, sumstatBundle, hasInd, ldRefs$keys), - ldRefs$refs + .cbMergeRuns(.cbEmptyResult(), runs), + resultInfo$outcomeInfo, + resultInfo$ldRefs ) } @@ -1243,18 +1604,14 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { individualBundle, sumstatBundle, hasInd, - focalTrait, + focal, methodArgs ) { traits <- c( if (hasInd) individualBundle$outcomeNames else character(), names(sumstatBundle$sumstat) ) - focalIdx <- if (!is.null(focalTrait) && is_in(focalTrait, traits)) { - which(traits == focalTrait) - } else { - NULL - } + focalIdx <- .cbFocalIdx(focal, traits) nCtx <- if (hasInd) length(individualBundle$Y) else 0L nSs <- length(sumstatBundle$sumstat) .cbAnnounceXqtl(nCtx, nSs) @@ -1292,29 +1649,22 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { # # Outcome names reach colocboost as bare labels; this is what lets a # ColocBoostResult answer "which contexts colocalized" instead of handing the -# caller a string to parse. Sumstat outcomes are keyed by study name and carry -# no context or trait of their own, which is recorded as NA rather than -# invented. `ldKeys` names, per sumstat outcome, the result's LD-reference -# entry it was matched against (.cbResultLdRefs()). +# caller a string to parse. `ldKeys` names, per sumstat outcome, the result's +# LD-reference entry it was matched against (.cbResultLdRefs()), and +# `sumstatInfo` (.cbPairsInfo()) the tuple each sumstat outcome came from. # @noRd .cbOutcomeInfo <- function( individualBundle, sumstatBundle, hasInd, - ldKeys = character(0) + ldKeys = character(0), + sumstatInfo = NULL ) { ssNames <- names(sumstatBundle$sumstat) parts <- compact(list( if (isTRUE(hasInd)) individualBundle$outcomeInfo, if (length(ssNames) > 0L) { - tibble( - name = ssNames, - context = NA_character_, - trait = NA_character_, - study = ssNames, - dataForm = "sumstats", - ldReference = unname(ldKeys[ssNames]) - ) + .cbSumstatOutcomeInfo(ssNames, ldKeys, sumstatInfo) } )) if (length(parts) == 0L) { @@ -1323,6 +1673,37 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { bind_rows(parts) } +# The summary-statistic outcomes' rows. A QTL tuple records its study, +# context and trait; a GWAS study has no context or trait of its own, which +# is recorded as NA rather than invented. Without `sumstatInfo` each outcome +# stands as its own study. +# @noRd +#' @importFrom dplyr coalesce +.cbSumstatOutcomeInfo <- function(ssNames, ldKeys, sumstatInfo) { + info <- sumstatInfo %||% .cbPairsInfo(set_names(list(), character(0))) + hit <- match(ssNames, info$name) + tibble( + name = ssNames, + context = info$context[hit], + trait = info$trait[hit], + study = coalesce(info$study[hit], ssNames), + dataForm = "sumstats", + ldReference = unname(ldKeys[ssNames]) + ) +} + +# The (name, study, context, trait) of each summary-statistic pair, as the +# pair records them: a QTL tuple's three, a GWAS study's study alone. +# @noRd +.cbPairsInfo <- function(pairs) { + tibble( + name = names(pairs) %||% character(0), + study = map_chr(unname(pairs), "study", .default = NA_character_), + context = map_chr(unname(pairs), "context", .default = NA_character_), + trait = map_chr(unname(pairs), "trait", .default = NA_character_) + ) +} + # @noRd .cbEmptyOutcomeInfo <- function() { tibble( @@ -1335,32 +1716,30 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { ) } -# Joint (non-focal) QTL + GWAS run -> list(result, time). +# Joint QTL + GWAS run -> list(result, time). Focal on `focal`, an outcome +# name, when one was resolved (.cbResolveFocal()); non-focal otherwise. # @noRd .cbRunJointGwas <- function( individualBundle, sumstatBundle, hasInd, methodArgs, - gwasNames = character() + gwasNames = character(), + focal = NULL ) { ssNames <- names(sumstatBundle$sumstat) traits <- c( if (hasInd) individualBundle$outcomeNames else character(), ssNames ) + focalIdx <- .cbFocalIdx(focal, traits) ldArgs <- .cbBuildLdArgs(sumstatBundle$LD, sumstatBundle$ldArg) # The merged bundle holds QTL sumstats as well as GWAS, so split the # labels rather than calling every sumstat a GWAS: a context is any # outcome that is not one of the GWAS studies, whether it arrived as # individual-level data or as summary statistics. nGwas <- length(intersect(ssNames, gwasNames)) - nContexts <- length(traits) - nGwas - msg <- glue( - "====== Performing non-focal GWAS-xQTL ColocBoost on ", - "{nContexts} contexts and {nGwas} GWAS. =====" - ) - inform(msg) + inform(.cbJointMessage(length(traits) - nGwas, nGwas, traits[focalIdx])) args <- c( list( X = if (hasInd) individualBundle$X else NULL, @@ -1369,7 +1748,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { dict_YX = if (hasInd) individualBundle$dict_YX else NULL, dict_sumstatLD = sumstatBundle$dict_sumstatLD, outcome_names = traits, - focal_outcome_idx = NULL, + focal_outcome_idx = focalIdx, output_level = 2 ), ldArgs, @@ -1382,6 +1761,31 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { list(result = run$result, time = run$time) } +# The joint run's announcement; `focal` is the focal outcome's name, or empty +# for a non-focal run. +# @noRd +.cbJointMessage <- function(nContexts, nGwas, focal) { + if (length(focal) == 0L) { + return(glue( + "====== Performing non-focal GWAS-xQTL ColocBoost on ", + "{nContexts} contexts and {nGwas} GWAS. =====" + )) + } + glue( + "====== Performing focal GWAS-xQTL ColocBoost on {nContexts} ", + "contexts and {nGwas} GWAS, focal on {focal}. =====" + ) +} + +# The position of outcome `focal` among `traits`, the form colocboost's +# focal_outcome_idx takes; NULL when there is no focal outcome or the run +# does not hold it. +# @noRd +.cbFocalIdx <- function(focal, traits) { + idx <- if (is.null(focal)) NA_integer_ else match(focal, traits) + if (is.na(idx)) NULL else idx +} + # Separate (focal) per-GWAS runs -> list(result, time) with per-study timing. # @noRd .cbRunSeparateGwas <- function( @@ -1614,7 +2018,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { xqtlColoc, jointGwas, separateGwas, - focalTrait, + focalOutcome, methodArgs, alleleFlip = TRUE, cutoffs = NULL @@ -1623,31 +2027,158 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { inform("colocboostPipeline: no analysis flag is TRUE; nothing to do.") return(.cbEmptyResultObject()) } - combinedPairs <- .cbAppendGwasPairs( + inputs <- .cbPrepareInputs( + individualBundle, qtlPairs, gwasSumStats, - cutoffs = cutoffs - ) - harmonized <- .cbMaybeHarmonize( - individualBundle, - combinedPairs, - alleleFlip + focalOutcome, + alleleFlip, + cutoffs ) - sumstatBundle <- .cbMergeSumstatBundles(harmonized$pairs) - qtlKeys <- intersect(names(harmonized$pairs), names(qtlPairs)) - qtlSumstatBundle <- .cbMergeSumstatBundles(harmonized$pairs[qtlKeys]) - gwasRunBundles <- .cbGwasRunBundles(harmonized$pairs, qtlKeys) .cbRunVariants( - harmonized$individualBundle, - sumstatBundle, + inputs$individualBundle, + inputs$sumstatBundle, xqtlColoc, jointGwas, separateGwas, - focalTrait, + inputs$focal, methodArgs, - ldRefs = .cbResultLdRefs(harmonized$pairs), - qtlSumstatBundle = qtlSumstatBundle, - gwasRunBundles = gwasRunBundles + resultInfo = inputs$resultInfo, + qtlSumstatBundle = inputs$qtlSumstatBundle, + gwasRunBundles = inputs$gwasRunBundles + ) +} + +# Everything the runs read, from the QTL side and gwasSumStats: each +# outcome's (sumstat, LD) pair -- a GWAS study once, over its rows the QTL +# data overlap -- allele-harmonized when asked; the bundles each run takes; +# the outcome each run is focal on; and the outcome table and LD references +# the result records. The tuples and keys are read before harmonization, +# which keeps every pair's name. +# @noRd +.cbPrepareInputs <- function( + individualBundle, + qtlPairs, + gwasSumStats, + focalOutcome, + alleleFlip, + cutoffs +) { + pairs <- .cbAppendGwasPairs( + qtlPairs, + gwasSumStats, + window = .cbQtlWindow(individualBundle, qtlPairs), + cutoffs = cutoffs, + qtlVariants = .cbQtlVariants(individualBundle, qtlPairs) + ) + harmonized <- .cbMaybeHarmonize(individualBundle, pairs, alleleFlip) + sumstatBundle <- .cbMergeSumstatBundles(harmonized$pairs) + qtlKeys <- intersect(names(harmonized$pairs), names(qtlPairs)) + ldRefs <- .cbResultLdRefs(harmonized$pairs) + list( + individualBundle = harmonized$individualBundle, + sumstatBundle = sumstatBundle, + qtlSumstatBundle = .cbMergeSumstatBundles(harmonized$pairs[qtlKeys]), + gwasRunBundles = .cbGwasRunBundles(harmonized$pairs, qtlKeys), + focal = .cbResolveFocal( + focalOutcome, + gwasSumStats, + .cbQtlOutcomeInfo(individualBundle, qtlPairs), + .cbGwasKeys(pairs, names(qtlPairs)) + ), + resultInfo = list( + outcomeInfo = .cbOutcomeInfo( + harmonized$individualBundle, + sumstatBundle, + !is.null(harmonized$individualBundle), + ldRefs$keys, + .cbPairsInfo(pairs) + ), + ldRefs = ldRefs$refs + ) + ) +} + +# Where the QTL data sit, one span per chromosome: the GWAS rows a study +# contributes are those overlapping it. Individual-level +# variants are placed by their ids, which the panel normalizes to chrom:pos +# form (an id that does not parse, such as an rsID, places nothing), and +# summary-level ones by their tuple's range. NULL when nothing is placed, +# which leaves every GWAS row in. +# @noRd +.cbQtlWindow <- function(individualBundle, qtlPairs) { + ids <- unique(list_c( + map(individualBundle$X, colnames), + ptype = character() + )) + parsed <- parseVariantId(ids) + ok <- !is.na(parsed$chrom) & !is.na(parsed$pos) + placed <- exec( + c, + GenomicRanges::GRanges( + parsed$chrom[ok], + IRanges::IRanges(parsed$pos[ok], width = 1L) + ), + !!!unname(map(compact(map(qtlPairs, "span")), .locusRanges)) + ) + if (length(placed) == 0L) { + return(NULL) + } + range(placed) +} + +# The QTL variants a run reads, placed by their ids, each position once: the +# individual-level ones and those each summary-statistic pair kept. NULL when +# none places (an rsID places nothing). +# @noRd +.cbQtlVariants <- function(individualBundle, qtlPairs) { + ids <- unique(c( + list_c(map(individualBundle$X, colnames), ptype = character()), + list_c(map(unname(qtlPairs), "variantIds"), ptype = character()) + )) + parsed <- parseVariantId(ids) + ok <- !is.na(parsed$chrom) & !is.na(parsed$pos) + if (!any(ok)) { + return(NULL) + } + unique(GenomicRanges::GRanges( + parsed$chrom[ok], + IRanges::IRanges(parsed$pos[ok], width = 1L) + )) +} + +# colocboost reads every QTL outcome together, so the QTL data are one +# region, checked against the LD blocks of the GWAS studies they overlap +# (.checkGwasBlockReach()). +# @noRd +.cbCheckBlockReach <- function(qtlVariants, gwasSumStats) { + if (is.null(qtlVariants)) { + return(invisible(NULL)) + } + .checkGwasBlockReach( + list(`the QTL data` = qtlVariants), + gwasSumStats, + "colocboostPipeline", + "the QTL data" + ) +} + +# Each GWAS study that reached the runs, mapped to its outcome name. +# @noRd +.cbGwasKeys <- function(pairs, qtlNames) { + gwas <- pairs[setdiff(names(pairs), qtlNames)] + set_names(names(gwas), map_chr(unname(gwas), "study")) +} + +# The QTL outcomes a focalOutcome vector is matched against: the +# individual-level ones with the (study, context, trait) they were built +# from, then each QTL summary-statistic tuple. +# @noRd +.cbQtlOutcomeInfo <- function(individualBundle, qtlPairs) { + ind <- individualBundle$outcomeInfo %||% .cbEmptyOutcomeInfo() + bind_rows( + select(ind, all_of(c("name", "study", "context", "trait"))), + .cbPairsInfo(qtlPairs) ) } @@ -1676,17 +2207,29 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { ) } -# Append the GWAS sumstat pairs to the QTL pairs, QC-gating gwasSumStats and -# make.unique-ing colliding labels. (Sequential key resolution -- kept as a -# loop.) The GWAS side's LD comes from its own reference, which need not be -# the QTL side's: each pair carries the LD it was matched against. +# Append the GWAS sumstat pairs -- one per study, over its rows that overlap +# `window` (.cbGwasSumStatsBundle()) -- to the QTL pairs, QC-gating +# gwasSumStats and make.unique-ing colliding labels. The GWAS side's LD comes +# from its own reference, which need not be the QTL side's: each pair carries +# the LD it was matched against. # @noRd -.cbAppendGwasPairs <- function(qtlPairs, gwasSumStats, cutoffs = NULL) { +.cbAppendGwasPairs <- function( + qtlPairs, + gwasSumStats, + window = NULL, + cutoffs = NULL, + qtlVariants = NULL +) { if (is.null(gwasSumStats)) { return(qtlPairs) } .cbRequireSumStatsQc(gwasSumStats, "gwasSumStats") - gwasPairs <- .cbGwasSumStatsBundle(gwasSumStats, cutoffs = cutoffs) + .cbCheckBlockReach(qtlVariants, gwasSumStats) + gwasPairs <- .cbGwasSumStatsBundle( + gwasSumStats, + window = window, + cutoffs = cutoffs + ) if (length(gwasPairs) == 0L) { return(qtlPairs) } @@ -1716,7 +2259,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { traitId, region, cisWindow, - focalTrait, + focalOutcome, xqtlColoc, jointGwas, separateGwas, @@ -1725,18 +2268,23 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { signalScreenParam, alleleFlip, methodArgs, + genotypeFilterParam, + phenotypeFilterParam, residualizationParam ) { screenSpec <- .screenResolve(signalScreenParam) + genotypeFilter <- .qtlResolveFilter(genotypeFilterParam) indBundle <- .cbIndividualBundle( - qtlData, + .qtlRestrictSamples(qtlData, genotypeFilter$keepSamples), contexts = contexts, traitId = traitId, region = region, cisWindow = cisWindow, samples = samples, pipCutoffToSkip = screenSpec, - residualizationParam = residualizationParam + residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter, + phenotypeFilter = .cbResolvePhenotypeFilter(phenotypeFilterParam) ) .cbDriver( indBundle, @@ -1745,7 +2293,7 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { xqtlColoc, jointGwas, separateGwas, - focalTrait, + focalOutcome, methodArgs, alleleFlip = alleleFlip, # The QTL side is individual-level here, but the GWAS side may still @@ -1755,6 +2303,13 @@ setGeneric("colocboostPipeline", function(qtlData, gwasSumStats = NULL, ...) { } +# The genome build colocboostPipeline()'s inputs share; NA when none names +# one, an error when two disagree. +# @noRd +.cbBuild <- function(...) { + .inputsBuild(list(...), "colocboostPipeline") +} + #' @rdname colocboostPipeline #' @export setMethod( @@ -1767,7 +2322,7 @@ setMethod( traitId = NULL, region = NULL, cisWindow = NULL, - focalTrait = NULL, + focalOutcome = NULL, xqtlColoc = TRUE, jointGwas = FALSE, separateGwas = FALSE, @@ -1775,23 +2330,24 @@ setMethod( panelFilterParam = PanelFilterParam(), signalScreenParam = SignalScreenParam(), alleleFlip = TRUE, + genotypeFilterParam = GenotypeFilterParam(), + phenotypeFilterParam = PhenotypeFilterParam(), residualizationParam = ResidualizationParam(), - # `list()`, not ColocboostOptions(): the formal shadows the - # constructor, so a constructor-call default is a recursive - # reference. An empty list is the "no options" spelling - # .assertMethodOptions already accepts; anything else must be built. methodArgs = ColocboostOptions() ) { .assertMethodOptions(methodArgs, "ColocboostOptions", "methodArgs") .cbAssertAnyRun(xqtlColoc, jointGwas, separateGwas) - .cbQtlDatasetDrive( + .cbAssertFocalOutcome(focalOutcome) + .cbAssertTraitsSelected(qtlData, contexts, traitId) + build <- .cbBuild(qtlData, gwasSumStats, region) + res <- .cbQtlDatasetDrive( qtlData = qtlData, gwasSumStats = gwasSumStats, contexts = contexts, traitId = traitId, region = region, cisWindow = cisWindow, - focalTrait = focalTrait, + focalOutcome = focalOutcome, xqtlColoc = xqtlColoc, jointGwas = jointGwas, separateGwas = separateGwas, @@ -1800,8 +2356,11 @@ setMethod( signalScreenParam = signalScreenParam, alleleFlip = alleleFlip, methodArgs = methodArgs, + genotypeFilterParam = genotypeFilterParam, + phenotypeFilterParam = phenotypeFilterParam, residualizationParam = residualizationParam ) + .withGenome(res, build) } ) @@ -1815,7 +2374,8 @@ setMethod( gwasSumStats = NULL, contexts = NULL, traitId = NULL, - focalTrait = NULL, + cisWindow = NULL, + focalOutcome = NULL, xqtlColoc = TRUE, jointGwas = FALSE, separateGwas = FALSE, @@ -1825,26 +2385,31 @@ setMethod( ) { .assertMethodOptions(methodArgs, "ColocboostOptions", "methodArgs") .cbAssertAnyRun(xqtlColoc, jointGwas, separateGwas) + .cbAssertFocalOutcome(focalOutcome) .cbRequireSumStatsQc(qtlData, "qtlData") + .cbAssertQssRowsSelected(qtlData, contexts, traitId) + build <- .cbBuild(qtlData, gwasSumStats) cutoffs <- .panelCutoffs(panelFilterParam) qtlPairs <- .cbQtlSumStatsBundle( qtlData, contexts = contexts, traitId = traitId, - cutoffs = cutoffs + cutoffs = cutoffs, + cisWindow = cisWindow ) - .cbDriver( + res <- .cbDriver( individualBundle = NULL, qtlPairs = qtlPairs, gwasSumStats = gwasSumStats, xqtlColoc = xqtlColoc, jointGwas = jointGwas, separateGwas = separateGwas, - focalTrait = focalTrait, + focalOutcome = focalOutcome, methodArgs = methodArgs, alleleFlip = alleleFlip, cutoffs = cutoffs ) + .withGenome(res, build) } ) @@ -1860,7 +2425,7 @@ setMethod( traitId = NULL, region = NULL, cisWindow = NULL, - focalTrait = NULL, + focalOutcome = NULL, xqtlColoc = TRUE, jointGwas = FALSE, separateGwas = FALSE, @@ -1868,23 +2433,27 @@ setMethod( panelFilterParam = PanelFilterParam(), signalScreenParam = SignalScreenParam(), alleleFlip = TRUE, + genotypeFilterParam = GenotypeFilterParam(), + phenotypeFilterParam = PhenotypeFilterParam(), residualizationParam = ResidualizationParam(), - # `list()`, not ColocboostOptions(): the formal shadows the - # constructor, so a constructor-call default is a recursive - # reference. An empty list is the "no options" spelling - # .assertMethodOptions already accepts; anything else must be built. methodArgs = ColocboostOptions() ) { .assertMethodOptions(methodArgs, "ColocboostOptions", "methodArgs") .cbAssertAnyRun(xqtlColoc, jointGwas, separateGwas) - .cbPipelineMultiStudy( + .cbAssertFocalOutcome(focalOutcome) + # As in fineMappingPipeline: a context no study has is refused, and + # one only some lack is skipped for those, with a warning. + parseContexts(contexts, qtlData) + .cbMsAssertTraitsSelected(qtlData, contexts, traitId) + build <- .cbBuild(qtlData, gwasSumStats, region) + res <- .cbPipelineMultiStudy( qtlData = qtlData, gwasSumStats = gwasSumStats, contexts = contexts, traitId = traitId, region = region, cisWindow = cisWindow, - focalTrait = focalTrait, + focalOutcome = focalOutcome, xqtlColoc = xqtlColoc, jointGwas = jointGwas, separateGwas = separateGwas, @@ -1893,8 +2462,11 @@ setMethod( signalScreenParam = signalScreenParam, alleleFlip = alleleFlip, methodArgs = methodArgs, + genotypeFilterParam = genotypeFilterParam, + phenotypeFilterParam = phenotypeFilterParam, residualizationParam = residualizationParam ) + .withGenome(res, build) } ) @@ -1908,7 +2480,7 @@ setMethod( traitId, region, cisWindow, - focalTrait, + focalOutcome, xqtlColoc, jointGwas, separateGwas, @@ -1917,42 +2489,81 @@ setMethod( signalScreenParam, alleleFlip, methodArgs, + genotypeFilterParam, + phenotypeFilterParam, residualizationParam ) { - screenSpec <- .screenResolve(signalScreenParam) - indBundle <- .cbMultiStudyIndBundle( - qtlData = qtlData, + cutoffs <- .panelCutoffs(panelFilterParam) + qtlSide <- .cbMultiStudyQtlSide( + qtlData, contexts = contexts, traitId = traitId, region = region, cisWindow = cisWindow, samples = samples, - screenSpec = screenSpec, - residualizationParam = residualizationParam - ) - cutoffs <- .panelCutoffs(panelFilterParam) - ss <- .cbMultiStudySumstats( - qtlData, - contexts, - traitId, + screenSpec = .screenResolve(signalScreenParam), + residualizationParam = residualizationParam, + genotypeFilter = .qtlResolveFilter(genotypeFilterParam), + phenotypeFilter = .cbResolvePhenotypeFilter(phenotypeFilterParam), cutoffs = cutoffs ) .cbDriver( - indBundle, - ss$qtlPairs, + qtlSide$indBundle, + qtlSide$qtlPairs, gwasSumStats, xqtlColoc, jointGwas, separateGwas, - focalTrait, + focalOutcome, methodArgs, alleleFlip = alleleFlip, cutoffs = cutoffs ) } +# The QTL side of a MultiStudyQtlDataset run: the individual-level bundle +# across its studies, and the summary-statistic pairs alongside them. +# @noRd +.cbMultiStudyQtlSide <- function( + qtlData, + contexts, + traitId, + region, + cisWindow, + samples, + screenSpec, + residualizationParam, + genotypeFilter, + phenotypeFilter, + cutoffs +) { + list( + indBundle = .cbMultiStudyIndBundle( + qtlData = qtlData, + contexts = contexts, + traitId = traitId, + region = region, + cisWindow = cisWindow, + samples = samples, + screenSpec = screenSpec, + residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter, + phenotypeFilter = phenotypeFilter + ), + qtlPairs = .cbMultiStudySumstats( + qtlData, + contexts, + traitId, + cisWindow, + cutoffs = cutoffs + )$qtlPairs + ) +} + # One study's bundle with its names study-prefixed, or NULL when it has -# nothing to contribute. +# nothing to contribute. A `contexts` vector applies to every study: each +# runs on the ones it has, and a study with none of them sits out (the entry +# point has warned about it). # @noRd .cbStudyBundle <- function( studyName, @@ -1963,17 +2574,26 @@ setMethod( cisWindow, samples, screenSpec, - residualizationParam = ResidualizationParam() + residualizationParam = ResidualizationParam(), + genotypeFilter, + phenotypeFilter = .qtlKeepAllPhenotypes() ) { + qd <- qtlDatasets[[studyName]] + share <- if (is.null(contexts)) NULL else intersect(contexts, contexts(qd)) + if (!is.null(share) && length(share) == 0L) { + return(NULL) + } sub <- .cbIndividualBundle( - qtlDatasets[[studyName]], - contexts = contexts, + .qtlRestrictSamples(qd, genotypeFilter$keepSamples), + contexts = share, traitId = traitId, region = region, cisWindow = cisWindow, samples = samples, pipCutoffToSkip = screenSpec, - residualizationParam = residualizationParam + residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter, + phenotypeFilter = phenotypeFilter ) if (is.null(sub)) { return(NULL) @@ -2013,9 +2633,11 @@ setMethod( cisWindow, samples, screenSpec, - residualizationParam = ResidualizationParam() + residualizationParam = ResidualizationParam(), + genotypeFilter, + phenotypeFilter = .qtlKeepAllPhenotypes() ) { - qtlDatasets <- qtlDatasets(qtlData) + qtlDatasets <- as.list(qtlData) subs <- compact(map( names(qtlDatasets), .cbStudyBundle, @@ -2026,11 +2648,21 @@ setMethod( cisWindow = cisWindow, samples = samples, screenSpec = screenSpec, - residualizationParam = residualizationParam + residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter, + phenotypeFilter = phenotypeFilter )) if (length(subs) == 0L) { return(NULL) } + .cbCombineStudyBundles(subs) +} + +# The per-study bundles as one: X, Y and the outcomes concatenated, and each +# study's dict shifted past the entries the studies before it contributed. +# NULL when no study contributes any X. +# @noRd +.cbCombineStudyBundles <- function(subs) { xOffsets <- .cbOffsets(map_int(subs, .cbFieldLength, field = "X")) yOffsets <- .cbOffsets(map_int(subs, .cbFieldLength, field = "Y")) combinedX <- .cbConcat(map(subs, "X")) @@ -2085,13 +2717,15 @@ setMethod( ) } -# Sumstat side of a MultiStudyQtlDataset: bundle any embedded QtlSumStats. +# Sumstat side of a MultiStudyQtlDataset: bundle any embedded QtlSumStats, +# with `cisWindow` laid on the tuples selected as a QtlSumStats run lays it. # Returns list(qtlPairs); each pair carries its own row's LD reference. # @noRd .cbMultiStudySumstats <- function( qtlData, contexts, traitId, + cisWindow, cutoffs = NULL ) { embeddedSs <- sumStats(qtlData) @@ -2104,7 +2738,8 @@ setMethod( embeddedSs, contexts = contexts, traitId = traitId, - cutoffs = cutoffs + cutoffs = cutoffs, + cisWindow = cisWindow ) ) } diff --git a/R/cpp11.R b/R/cpp11.R index 141781de..25978b9a 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -16,14 +16,6 @@ dentistIterativeImputeFactor <- function(factorR, nSample, zScoreR, pValueThresh .Call(`_pecotmr_dentistIterativeImputeFactor`, factorR, nSample, zScoreR, pValueThreshold, propSVD, gcControl, nIter, gPvalueThreshold, numThreads, correctChenEtAlBug, verbose, seed) } -lassosumRssCpp <- function(zR, LD, shrink, lambdaR, thr, maxiter) { - .Call(`_pecotmr_lassosumRssCpp`, zR, LD, shrink, lambdaR, thr, maxiter) -} - -lassosumRssFactorCpp <- function(zR, factorR, shrink, lambdaR, thr, maxiter) { - .Call(`_pecotmr_lassosumRssFactorCpp`, zR, factorR, shrink, lambdaR, thr, maxiter) -} - ldThresholdComponents <- function(standardized, threshold, stripe) { .Call(`_pecotmr_ldThresholdComponents`, standardized, threshold, stripe) } diff --git a/R/crossValidation.R b/R/crossValidation.R index b3d5f356..8d8c4834 100644 --- a/R/crossValidation.R +++ b/R/crossValidation.R @@ -135,9 +135,9 @@ NULL # predicts held-out samples (Xtest[, common] %*% W[common, ]), aggregates the # out-of-fold predictions into full-Y matrices, scores them with .cvMetricRow, # and keys the output via .cvOutputKey(). `maxNumVariants` (optional) randomly -# subsamples variants up front to bound compute; `numThreads` parallelises the -# fold loop (-1 = all cores, 0/1 = serial). -#' @importFrom BiocParallel bplapply multicoreWorkers MulticoreParam +# subsamples variants up front to bound compute; `BPPARAM` runs the folds +# (SerialParam() one at a time). +#' @importFrom BiocParallel SerialParam #' @importFrom stats sd lm cor #' @importFrom dplyr n_distinct #' @noRd @@ -148,7 +148,7 @@ NULL samplePartitions = NULL, fitFold, fitFoldCtx = NULL, - numThreads = 1, + BPPARAM = SerialParam(), maxNumVariants = NULL, variantsToKeep = NULL, fitRetention = c("none", "slim", "full"), @@ -168,7 +168,6 @@ NULL ) foldIds <- sort(unique(samplePartition$Fold)) st <- proc.time() - numCores <- .cvNumCores(numThreads) cvState <- list( X = X, Y = Y, @@ -180,7 +179,7 @@ NULL verbose = verbose, rngSeed = seed ) - foldResults <- .cvRunFolds(foldIds, cvState, numCores) + foldResults <- .cvRunFolds(foldIds, cvState, BPPARAM) agg <- .cvAggregate(foldResults, Y, verbose) list( samplePartition = samplePartition, @@ -347,29 +346,101 @@ NULL samplePartitions } -# multicoreWorkers() rather than bpworkers(MulticoreParam()): the two answer -# the same number, but constructing a MulticoreParam costs ~0.6s (almost all -# of it garbage collection) and this runs on every fit. +# ---- BiocParallel ------------------------------------------------------------ + +# Refuse a `BPPARAM` that is not a BiocParallelParam. # @noRd -.cvNumCores <- function(numThreads) { - avail <- multicoreWorkers() - min(if (numThreads == -1) avail else numThreads, avail) +.assertBpparam <- function(BPPARAM, what = "BPPARAM") { + if (methods::is(BPPARAM, "BiocParallelParam")) { + return(invisible(BPPARAM)) + } + abort(glue( + "`{what}` must be a BiocParallelParam, such as SerialParam() or ", + "MulticoreParam(workers = 4) (got {class(BPPARAM)[[1L]]})." + )) } -# MulticoreParam for CV / weight-fitting parallelism. A NULL seed keeps the -# historical default RNGseed = 1L (reproducible); a caller-supplied seed -# overrides it so the parallel L'Ecuyer streams are reproducible under it. This -# is the one place a user seed reaches BiocParallel workers, which set.seed() -# in the main process cannot. +# bplapply() on a copy of the caller's BPPARAM seeded by .seededBpparam(). A +# worker's error comes back as BiocParallel's report on every element; the +# first one is raised again with its own message, as a serial map would have +# raised it. The extra arguments reach `.f` through bplapply(), whose own +# formals include X and FUN, so pass an argument of either name by position. # @noRd -.bpSeedParam <- function(numCores, seed = NULL) { - MulticoreParam(workers = numCores, RNGseed = as.integer(seed %||% 1L)) +#' @importFrom BiocParallel bplapply +.bpMap <- function(.x, .f, ..., BPPARAM, seed = NULL) { + try_fetch( + bplapply(.x, .f, ..., BPPARAM = .seededBpparam(BPPARAM, seed)), + bplist_error = .bpRaiseFirstError + ) +} + +# @noRd +.bpRaiseFirstError <- function(cnd) { + failed <- keep(attr(cnd, "result"), .isRemoteError) + if (length(failed) == 0L) { + cnd_signal(cnd) + } + abort(conditionMessage(failed[[1L]])) +} + +# @noRd +.isRemoteError <- function(x) { + methods::is(x, "remote_error") +} + +# The caller's BPPARAM, copied and given the RNG seed its workers draw from: +# `seed` when one is given, else the param's own RNGseed, else one draw from +# the session RNG, so a set.seed() before the call still governs the run. A +# copy is seeded because a BiocParallelParam is a reference object: seeding +# it in place would change the caller's own. Each element then draws from its +# own stream, so the numbers do not depend on the backend or worker count. +# @noRd +#' @importFrom BiocParallel bpRNGseed bpRNGseed<- +.seededBpparam <- function(BPPARAM, seed = NULL) { + copy <- BPPARAM$copy() + bpRNGseed(copy) <- as.integer( + seed %||% bpRNGseed(BPPARAM) %||% .sessionSeedDraw() + ) + copy +} + +# One integer from the session RNG. +# @noRd +.sessionSeedDraw <- function() { + sample.int(.Machine$integer.max, 1L) +} + +# The threads an engine with its own parallelism (OpenMP, a C++ thread pool, +# mclapply) may use under BPPARAM: its worker count when the workers are +# processes on this machine (SerialParam, MulticoreParam), else 1. A +# SnowParam's or BatchtoolsParam's workers can be other machines or +# scheduler jobs, so their count is no budget for threads here. Said once a +# session per backend, as a windowed engine asks once per window. +# @noRd +#' @importFrom BiocParallel bpnworkers +.bpLocalThreads <- function(BPPARAM, caller) { + if ( + methods::is(BPPARAM, "SerialParam") || + methods::is(BPPARAM, "MulticoreParam") + ) { + return(as.integer(bpnworkers(BPPARAM))) + } + backend <- class(BPPARAM)[[1L]] + inform( + glue( + "{caller}: the workers of a {backend} need not run on this ", + "machine, so a threaded engine runs on 1 thread." + ), + .frequency = "once", + .frequency_id = str_c("pecotmr-bpLocalThreads-", backend) + ) + 1L } # Seed the main-process RNG when a seed is supplied. This covers only the serial -# draws (fold partitioning, variant sub-sampling, single-threaded fitting); -# BiocParallel workers seed their own L'Ecuyer streams via .bpSeedParam. A NULL -# seed leaves the session RNG untouched so an outer set.seed() still governs it. +# draws (fold partitioning, variant sub-sampling); BiocParallel workers draw +# from the streams .seededBpparam() seeds. A NULL seed leaves the session RNG +# untouched so an outer set.seed() still governs it. # # Scoped to the CALLER's frame rather than set.seed()'s permanent mutation, so # a seeded call does not leave the user's session RNG changed after it returns. @@ -381,18 +452,16 @@ NULL } } -# Run each fold (parallel via BiocParallel when >= 2 cores). +# Run each fold on BPPARAM's workers. # @noRd -.cvRunFolds <- function(foldIds, cvState, numCores) { - if (numCores >= 2) { - return(bplapply( - foldIds, - .cvRunFold, - cv = cvState, - BPPARAM = .bpSeedParam(numCores, cvState$rngSeed) - )) - } - map(foldIds, .cvRunFold, cv = cvState) +.cvRunFolds <- function(foldIds, cvState, BPPARAM) { + .bpMap( + foldIds, + .cvRunFold, + cv = cvState, + BPPARAM = BPPARAM, + seed = cvState$rngSeed + ) } # Aggregate per-fold predictions + performance across methods. Returns @@ -519,13 +588,14 @@ NULL #' @rdname CrossValidationParam #' @aliases CrossValidationParam-class +#' @importClassesFrom BiocParallel BiocParallelParam #' @exportClass CrossValidationParam setClass( "CrossValidationParam", contains = "MethodParam", slots = c( folds = "numeric", - numThreads = "numeric", + BPPARAM = "BiocParallelParam", samplePartition = "list_OR_NULL", maxVariants = "numeric_OR_NULL", weightMethods = "list_OR_NULL", @@ -560,7 +630,7 @@ setValidity("CrossValidationParam", function(object) { #' @description How cross-validation runs, shared by #' \code{\link{fineMappingPipeline}} and \code{\link{twasWeightsPipeline}}. #' -#' \code{folds}, \code{numThreads}, \code{samplePartition} and +#' \code{folds}, \code{BPPARAM}, \code{samplePartition} and #' \code{fitFullData} mean the same thing in both. \code{maxVariants} and #' \code{weightMethods} are honoured by \code{\link{twasWeightsPipeline}} #' only and are \strong{ignored} by \code{\link{fineMappingPipeline}}, so @@ -569,9 +639,12 @@ setValidity("CrossValidationParam", function(object) { #' \code{1} skips cross-validation. The same value in both pipelines --- #' \code{twasWeightsPipeline} used to default to \code{5}, which made an #' unspecified setting mean two different things. -#' @param numThreads Integer. Parallel workers for the per-fold refits. -#' \code{1} (default) is serial; \code{-1} uses all cores. Only consulted -#' when \code{folds > 1}. +#' @param BPPARAM A \code{BiocParallelParam} the per-fold refits run on; +#' \code{SerialParam()} (default) runs them one at a time. Its workers draw +#' from random-number streams seeded by the pipeline's \code{seed}, else by +#' the param's own \code{RNGseed}, else by one draw from the session RNG, +#' so a run gives the same numbers however many workers it has. Only +#' consulted when \code{folds > 1}. #' @param samplePartition Optional pre-defined partition \code{data.frame} #' with columns \code{Sample} and \code{Fold}. When supplied, every method #' reuses this exact partition instead of generating a fresh one. @@ -593,12 +666,12 @@ setValidity("CrossValidationParam", function(object) { #' downstream. #' @return A \code{CrossValidationParam} object, a \code{\link{MethodParam}}. #' @examples -#' CrossValidationParam(folds = 10, numThreads = 4) +#' CrossValidationParam(folds = 10, BPPARAM = BiocParallel::SerialParam()) #' CrossValidationParam(folds = 5, fitFullData = FALSE) #' @export CrossValidationParam <- function( folds = 0, - numThreads = 1, + BPPARAM = SerialParam(), samplePartition = NULL, maxVariants = NULL, weightMethods = NULL, @@ -607,7 +680,7 @@ CrossValidationParam <- function( new( "CrossValidationParam", folds = folds, - numThreads = numThreads, + BPPARAM = .assertBpparam(BPPARAM), samplePartition = samplePartition, maxVariants = maxVariants, weightMethods = weightMethods, @@ -621,7 +694,7 @@ CrossValidationParam <- function( .cvResolve <- function(crossValidationParam) { list( folds = crossValidationParam$folds %||% 0, - numThreads = crossValidationParam$numThreads %||% 1, + BPPARAM = crossValidationParam$BPPARAM %||% SerialParam(), samplePartition = crossValidationParam$samplePartition, # -1 is twasWeightsCv()'s "no cap" sentinel. fineMappingPipeline # resolves these two as well but never reads them. @@ -661,13 +734,16 @@ CrossValidationParam <- function( # A field counts as "set" when it differs from the constructor's own default, # so passing CrossValidationParam() unchanged is not mistaken for a request. -# fitFullData = TRUE is that field's default. +# fitFullData = TRUE and BPPARAM = SerialParam() are those fields' defaults. # @noRd .cvFieldIsSet <- function(x) { - if (is.null(x) || isTRUE(x)) { + if (is.null(x) || isTRUE(x) || methods::is(x, "SerialParam")) { return(FALSE) } - # numThreads = 1 and folds = 0 are the no-op defaults. + if (methods::is(x, "BiocParallelParam")) { + return(TRUE) + } + # folds = 0 (or 1) is the no-op default. !(length(x) == 1L && !is.na(x) && is.numeric(x) && (x == 0 || x == 1)) } diff --git a/R/ctwasPipeline.R b/R/ctwasPipeline.R index f8fcceb4..528f5eb9 100644 --- a/R/ctwasPipeline.R +++ b/R/ctwasPipeline.R @@ -187,7 +187,7 @@ BoundaryMergeParam <- function( #' @section LD block convention: \code{gwasSumStats} is ONE #' \code{\link{GwasSumStats}} whose elements are LD blocks, keyed by its #' \code{blockId} column -- build it with -#' \code{loadGwasSumStatsFromManifest(..., ldBlocks = )}. Per-block +#' \code{loadGwasSumStatsFromManifest(..., region = )}. Per-block #' \code{region_info}, \code{LD_map}, and \code{snp_map} entries are built #' automatically from the LD reference and concatenated before the call to #' \code{ctwas::ctwas_sumstats}. A single-block input is rejected: cTWAS's EM @@ -215,8 +215,8 @@ BoundaryMergeParam <- function( #' #' @param gwasSumStats A \code{\link{GwasSumStats}} whose elements are LD #' blocks (at least two), keyed by its \code{blockId} column, with -#' \code{qcInfo()} non-empty. Build it with -#' \code{loadGwasSumStatsFromManifest(..., ldBlocks = )} and pass it +#' \code{qcOptions()} non-empty. Build it with +#' \code{loadGwasSumStatsFromManifest(..., region = )} and pass it #' through \code{\link{summaryStatsQc}}. #' @param twasWeights The per-gene weight source. Either (a) a FLAT #' \code{\link{TwasWeights}} / \code{QtlFineMappingResult} (or a homogeneous @@ -229,28 +229,41 @@ BoundaryMergeParam <- function( #' where only a few of many LD blocks carry gene weights). A gene whose cis #' span straddles a block boundary is homed by its single anchor; the #' cross-block signal is cTWAS's boundary-gene concern -#' (\code{\link{mergeCtwasBoundaryRegions}}), not placement. +#' (\code{\link{mergeCtwasBoundaryRegions}}), not placement. A +#' \code{TwasWeights} row of the run's method that carries a SuSiE fit and +#' was narrowed since that fit warns (condition class +#' \code{pecotmrFitCoverage}): the fit no longer lines up with the row's +#' variants, so its weights are not renormalized over the variants kept. #' @param twasZ Optional \code{GRanges} of TWAS Z-scores (output of #' \code{\link{causalInferencePipeline}}). When supplied, the per-(trait, #' context) Z is used as the \code{z_gene} input to \code{ctwas_sumstats} so #' it is not recomputed. -#' @param fineMappingResult Optional \code{QtlFineMappingResult} or -#' \code{GwasFineMappingResult} carrying the per-variant PIP and credible-set -#' membership data used by the CS / PIP rescue filters (\code{csMinCor} and -#' \code{minPipCutoff}). When \code{NULL} (default) the smart filters are -#' no-ops; only the magnitude filter (\code{twasWeightCutoff}) and the -#' per-gene cap (\code{maxNumVariants}, ordered by \code{|weight|}) apply. -#' @param method Optional character (length 1). Picks which TWAS method's -#' weights to feed into ctwas for each (study, context, trait) gene. When -#' \code{NULL} (default): use \code{"ensemble"} if that method is present -#' across the weight sources; otherwise use the sole method when only one is -#' present; otherwise run \strong{every} method as an independent cTWAS run -#' (one \code{CtwasResult} row-set per method). Passing the name explicitly -#' (e.g. \code{"mrash"}) restricts the run to that single method. +#' @param fineMappingResult Optional \code{QtlFineMappingResult}: the genes' +#' own fine-mapping, whose per-variant PIP and credible-set membership the +#' CS / PIP rescue filters (\code{csMinCor} and \code{minPipCutoff}) read. +#' Each gene is looked up by its weights' \code{(study, context, trait)} in +#' the fits of \code{fineMappingMethod}; a gene with no fit there gets no +#' rescue. When \code{NULL} (default) the smart filters are no-ops; only the +#' magnitude filter (\code{twasWeightCutoff}) and the per-gene cap +#' (\code{maxNumVariants}, ordered by \code{|weight|}) apply. +#' @param fineMappingMethod Character (length 1): the method of +#' \code{fineMappingResult} whose fits the rescues read, e.g. +#' \code{"susie"}. Required with a \code{fineMappingResult}, since the +#' weights' own method -- an \code{"ensemble"} or \code{"lasso"} weight -- +#' names no fine-mapping fit. Default \code{NULL}. +#' @param method Character (length 1): which TWAS method's weights to feed +#' into ctwas for each (study, context, trait) gene, one method per run. +#' \code{NULL} (default) uses the pre-combined \code{"ensemble"} weights of +#' \code{TwasWeights}. Weights with no ensemble, and fine-mapping results as +#' the weight source, have no default: name the method (e.g. +#' \code{"mrash"}, or a fine-mapping method such as \code{"susie"}). #' @param maxNumSingleEffects Integer. Max number of single effects in cTWAS #' fine-mapping. Default \code{5}. Pass-through to #' \code{ctwas::ctwas_sumstats}. -#' @param numThreads Number of cores. Default \code{1}. +#' @param BPPARAM A \code{BiocParallelParam} whose workers number the cores +#' ctwas's own \code{ncore} parallelism uses when they run on this machine +#' (\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +#' core. Default \code{SerialParam()}. #' @param ctwasPriorParam The EM stage that estimates cTWAS's group priors, #' built with \code{\link{CtwasPriorParam}}: \code{thin}, #' \code{niterPrefit}, \code{niter}, \code{varStructure} and @@ -268,22 +281,25 @@ BoundaryMergeParam <- function( #' \code{FALSE}), \code{pipThreshold}, \code{filterCs} and #' \code{maxSnp}. #' @param keepSnps Logical (length 1). When \code{TRUE}, retain the -#' context-agnostic SNP background of each run as one extra \code{CtwasResult} -#' row (\code{study = context = "SNP"}, mirroring cTWAS's own \code{"SNP"} -#' group) so the full ctwas output is reconstructable from +#' context-agnostic SNP background of each run as extra \code{CtwasResult} +#' rows, one per region (\code{study = context = "SNP"}, mirroring cTWAS's +#' own \code{"SNP"} group) so the full ctwas output is reconstructable from #' \code{\link{ctwasPosteriors}} / \code{susieAlpha}. Default \code{FALSE} -- #' the SNP rows are the null background and are dropped from the structured #' gene-level result. #' @param methodArgs Additional arguments forwarded to ctwas, built #' with \code{\link{CtwasOptions}}. Names are checked against what #' the ctwas steps accept between them. -#' @return A \code{\link{CtwasResult}} collection: one row per \code{(gwasStudy, -#' study, context, method)}. A single-context run is one row per method; a -#' multi-context (joint) run emits per-context rows sharing the same -#' \code{jointContexts} set and the jointly-estimated group priors. Each row's -#' \code{\link{CtwasResultEntry}} payload carries that context's per-gene -#' fine-mapping posteriors (\code{finemap}), the run's \code{param}, and its -#' \code{regionInfo}. For the raw \code{ctwas::finemap_regions} list (e.g. to +#' @return A \code{\link{CtwasResult}} collection: one row per +#' \code{(gwasStudy, study, context, method)} run and cTWAS region. A +#' single-context run gives each method its own rows; a multi-context +#' (joint) run emits per-context rows sharing the same \code{jointContexts} +#' set and the jointly-estimated group priors. Each row holds that region's +#' per-gene fine-mapping posteriors as ranges, with the region's per-effect +#' susie alpha table (\code{susieAlpha}), its \code{regionInfo} and the +#' run's \code{groupPriors} in \code{mcols()}. Its \code{seqinfo()} names +#' the genome build the inputs name; inputs naming different builds are +#' refused. For the raw \code{ctwas::finemap_regions} list (e.g. to #' feed \code{\link{mergeCtwasBoundaryRegions}}), call the granular #' \code{\link{assembleCtwasInputs}} \eqn{\to} #' \code{\link{estCtwasGroupPriors}} \eqn{\to} @@ -301,12 +317,11 @@ BoundaryMergeParam <- function( #' IRanges::IRanges(c(10000000, 15000001), c(15000000, 19000000)), #' blockId = c("chr22_1", "chr22_2")) #' gss <- loadGwasSumStatsFromManifest(manifest = mani, genome = "hg38", -#' ldReference = ldStem, region = "chr22:10000000-19000000", -#' ldBlocks = blocks) +#' ldReference = ldStem, which = blocks) #' gwasByRegion <- summaryStatsQc(gss, #' panelFilterParam = PanelFilterParam(mafCutoff = 0.0025)) #' ctwasPipeline(gwasSumStats = gwasByRegion, -#' twasWeights = list(ctwasWeightsExample), +#' twasWeights = list(ctwasWeightsExample), method = "susie", #' ctwasPriorParam = CtwasPriorParam(thin = 1, niterPrefit = 3, niter = 10, #' fallbackToPrefit = TRUE), #' methodArgs = CtwasOptions( @@ -321,9 +336,10 @@ ctwasPipeline <- function( twasWeights, twasZ = NULL, fineMappingResult = NULL, + fineMappingMethod = NULL, method = NULL, maxNumSingleEffects = 5L, - numThreads = 1L, + BPPARAM = SerialParam(), ctwasPriorParam = CtwasPriorParam(), variantPruningParam = VariantPruningParam(), boundaryMergeParam = BoundaryMergeParam(), @@ -336,34 +352,44 @@ ctwasPipeline <- function( boundaryMergeParam, methodArgs ) + .assertBpparam(BPPARAM) .ctwasRequireNamedLists(gwasSumStats, twasWeights) - methods <- .ctwasResolveMethods(twasWeights, method) - gwasStudy <- .ctwasGwasStudy(gwasSumStats) - rows <- list_flatten(map( - methods, - .ctwasRunMethod, + build <- .inputsBuild( + list(gwasSumStats, twasWeights, twasZ, fineMappingResult), + "ctwasPipeline" + ) + method <- .ctwasResolveMethod(twasWeights, method) + .ctwasCheckFitCoverage(twasWeights, method, "ctwasPipeline()") + rows <- .ctwasRunMethod( + method, gwasSumStats = gwasSumStats, twasWeights = twasWeights, twasZ = twasZ, fineMappingResult = fineMappingResult, + fineMappingMethod = fineMappingMethod, variantPruningParam = variantPruningParam, ctwasPriorParam = ctwasPriorParam, - numThreads = numThreads, + BPPARAM = BPPARAM, maxNumSingleEffects = maxNumSingleEffects, boundaryMergeParam = boundaryMergeParam, - gwasStudy = gwasStudy, + gwasStudy = .ctwasGwasStudy(gwasSumStats), keepSnps = keepSnps, methodArgs = methodArgs - )) - if (length(rows) == 0L) { - msg <- glue( - "ctwasPipeline: no genes were modeled (the weight sources ", - "produced no usable gene weights for method(s): ", - "{str_flatten(methods, ', ')})." - ) - abort(msg) + ) + .ctwasRequireRows(rows, method) + .withGenome(.ctwasRowsToResult(rows), build) +} + +# A run that modeled no gene has no result to return. +# @noRd +.ctwasRequireRows <- function(rows, method) { + if (length(rows) > 0L) { + return(invisible(NULL)) } - .ctwasRowsToResult(rows) + abort(glue( + "ctwasPipeline: no genes were modeled (the weight sources ", + "produced no usable gene weights for method '{method}')." + )) } # The cTWAS run proper: estimate the group priors, screen regions against @@ -376,24 +402,24 @@ ctwasPipeline <- function( ctwasPriorParam, boundaryMergeParam, maxNumSingleEffects, - numThreads, + BPPARAM, methodArgs ) { est <- estCtwasGroupPriors( inputs, ctwasPriorParam = ctwasPriorParam, - numThreads = numThreads, + BPPARAM = BPPARAM, methodArgs = methodArgs ) screened <- screenCtwasRegions( est, - numThreads = numThreads, + BPPARAM = BPPARAM, methodArgs = methodArgs ) finemap <- finemapCtwasRegions( screened, maxNumSingleEffects = maxNumSingleEffects, - numThreads = numThreads, + BPPARAM = BPPARAM, methodArgs = methodArgs ) if (!isTRUE(boundaryMergeParam$enabled)) { @@ -403,14 +429,13 @@ ctwasPipeline <- function( finemap, boundaryMergeParam = boundaryMergeParam, maxNumSingleEffects = maxNumSingleEffects, - numThreads = numThreads, + BPPARAM = BPPARAM, methodArgs = methodArgs ) } # One cTWAS run for method `m`: assemble inputs -> estimate params -> screen -> -# fine-map (optionally boundary-merge) -> per-context row-specs. `cfg` bundles -# the ctwasPipeline arguments (incl. the `CtwasOptions` option list). +# fine-map (optionally boundary-merge) -> per-context row-specs. # @noRd .ctwasRunMethod <- function( m, @@ -418,29 +443,32 @@ ctwasPipeline <- function( twasWeights, twasZ, fineMappingResult, + fineMappingMethod, variantPruningParam, ctwasPriorParam, - numThreads, + BPPARAM, maxNumSingleEffects, boundaryMergeParam, gwasStudy, keepSnps, methodArgs ) { - inputs <- assembleCtwasInputs( + # ctwasPipeline() has already warned about the rows whose fits this reads. + inputs <- .muffleFitCoverage(assembleCtwasInputs( gwasSumStats = gwasSumStats, twasWeights = twasWeights, twasZ = twasZ, fineMappingResult = fineMappingResult, + fineMappingMethod = fineMappingMethod, method = m, variantPruningParam = variantPruningParam - ) + )) merged <- .ctwasRunStages( inputs, ctwasPriorParam = ctwasPriorParam, boundaryMergeParam = boundaryMergeParam, maxNumSingleEffects = maxNumSingleEffects, - numThreads = numThreads, + BPPARAM = BPPARAM, methodArgs = methodArgs ) .ctwasRunToRows( @@ -458,7 +486,7 @@ ctwasPipeline <- function( posteriors, boundaryMergeParam, maxNumSingleEffects, - numThreads, + BPPARAM, methodArgs ) { # The bundle's terminal; mergeCtwasBoundaryRegions() takes scalars. @@ -474,7 +502,7 @@ ctwasPipeline <- function( filterCs = mergeFilterCs, maxSNP = mergeMaxSNP, maxNumSingleEffects = maxNumSingleEffects, - numThreads = numThreads, + BPPARAM = BPPARAM, methodArgs = methodArgs ) } @@ -510,18 +538,18 @@ ctwasPipeline <- function( #' IRanges::IRanges(c(10000000, 15000001), c(15000000, 19000000)), #' blockId = c("chr22_1", "chr22_2")) #' gss <- loadGwasSumStatsFromManifest(manifest = mani, genome = "hg38", -#' ldReference = ldStem, region = "chr22:10000000-19000000", -#' ldBlocks = blocks) +#' ldReference = ldStem, which = blocks) #' gwasByRegion <- summaryStatsQc(gss, #' panelFilterParam = PanelFilterParam(mafCutoff = 0.0025)) #' assembleCtwasInputs(gwasSumStats = gwasByRegion, -#' twasWeights = list(ctwasWeightsExample)) +#' twasWeights = list(ctwasWeightsExample), method = "susie") #' @export assembleCtwasInputs <- function( gwasSumStats, twasWeights, twasZ = NULL, fineMappingResult = NULL, + fineMappingMethod = NULL, method = NULL, variantPruningParam = VariantPruningParam() ) { @@ -529,43 +557,52 @@ assembleCtwasInputs <- function( variantPruningParam, "VariantPruningParam" ) - # The bundle's terminal: .ctwasBuildWeights and below take scalars. - twasWeightCutoff <- variantPruningParam$weightCutoff - csMinCor <- variantPruningParam$csMinCor - minPipCutoff <- variantPruningParam$pipRescue - maxNumVariants <- variantPruningParam$maxVariants .ctwasValidateGwasList(gwasSumStats) globalPanelInfo <- .ctwasGlobalPanelInfo(gwasSumStats) gwasSumStats <- .ctwasGwasByBlock(gwasSumStats) twasWeights <- .ctwasResolveAndValidateWeights(twasWeights, gwasSumStats) .ctwasValidateOptional(twasZ, fineMappingResult) + fineMappingResult <- .ctwasRescueSource( + fineMappingResult, + fineMappingMethod + ) regionIds <- names(gwasSumStats) resolvedMethod <- .ctwasResolveMethod(twasWeights, method) + .ctwasCheckFitCoverage( + twasWeights, + resolvedMethod, + "assembleCtwasInputs()" + ) fp <- .ctwasFirstPass( regionIds, gwasSumStats, twasWeights, globalPanelInfo ) - globalGwasSnpIds <- unique(list_c(map(fp$zSnpPieces, "id"))) - cutoffs <- list( - twasWeightCutoff = twasWeightCutoff, - csMinCor = csMinCor, - minPipCutoff = minPipCutoff, - maxNumVariants = maxNumVariants - ) weightsList <- .ctwasSecondPass( regionIds, twasWeights, resolvedMethod, fp, fineMappingResult, - cutoffs, - globalGwasSnpIds + .ctwasPruningCutoffs(variantPruningParam), + unique(list_c(map(fp$zSnpPieces, "id"))) ) .ctwasAssembleResult(regionIds, fp, weightsList, twasZ, resolvedMethod) } +# The bundle's terminal: .ctwasBuildWeights and below take scalars, under the +# names they have always had there. +# @noRd +.ctwasPruningCutoffs <- function(variantPruningParam) { + list( + twasWeightCutoff = variantPruningParam$weightCutoff, + csMinCor = variantPruningParam$csMinCor, + minPipCutoff = variantPruningParam$pipRescue, + maxNumVariants = variantPruningParam$maxVariants + ) +} + # Validate the gwasSumStats input: ctwas available, a QC'd GwasSumStats whose # elements are per-LD-block (>= 2 of them). # @@ -581,7 +618,7 @@ assembleCtwasInputs <- function( msg <- glue( "`gwasSumStats` must be a GwasSumStats whose elements are LD ", "blocks (got {class(gwasSumStats)[[1L]]}). Build one with ", - "`loadGwasSumStatsFromManifest(..., ldBlocks = )`." + "`loadGwasSumStatsFromManifest(..., region = )`." ) abort(msg) } @@ -606,7 +643,7 @@ assembleCtwasInputs <- function( # The collection must be QC'd, and its block keys must be usable as region ids. # @noRd .ctwasValidateGwasEntries <- function(gwasSumStats) { - if (length(qcInfo(gwasSumStats)) == 0L) { + if (length(qcOptions(gwasSumStats)) == 0L) { msg <- glue( "assembleCtwasInputs: `gwasSumStats` has no QC record. ", "Call summaryStatsQc() first." @@ -718,18 +755,55 @@ assembleCtwasInputs <- function( ) abort(msg) } + # The rescues keep a gene's weight variants by that gene's own fine-mapping, + # which is a QTL fit: the weights come from a TwasWeights or a + # QtlFineMappingResult, and a GWAS result is keyed by a study and method + # that no gene shares. if ( !is.null(fineMappingResult) && - !methods::is(fineMappingResult, "FineMappingResultBase") + !methods::is(fineMappingResult, "QtlFineMappingResult") ) { msg <- glue( - "`fineMappingResult` must be a FineMappingResultBase ", - "(QtlFineMappingResult or GwasFineMappingResult) or NULL." + "`fineMappingResult` must be a QtlFineMappingResult -- the genes' ", + "own fine-mapping -- or NULL." ) abort(msg) } } +# The fine-mapping the rescues read: `fineMappingResult` narrowed to the one +# method `fineMappingMethod` names. The weights' own method cannot pick it -- +# an "ensemble", "lasso" or "mrash" weight has no fine-mapping fit of that +# name -- so the method is named separately, and is required with a result. +# @noRd +.ctwasRescueSource <- function(fineMappingResult, fineMappingMethod) { + assertString(fineMappingMethod, null.ok = TRUE) + if (is.null(fineMappingResult)) { + if (!is.null(fineMappingMethod)) { + abort(glue( + "`fineMappingMethod` names a method of `fineMappingResult`, ", + "which was not given." + )) + } + return(NULL) + } + available <- unique(as.character(fineMappingResult$method)) + if (is.null(fineMappingMethod)) { + abort(glue( + "`fineMappingResult` is given, so `fineMappingMethod` must name ", + "the method of it whose PIPs and credible sets the rescues read ", + "(available: {str_flatten(available, ', ')})." + )) + } + if (!is_in(fineMappingMethod, available)) { + abort(glue( + "`fineMappingMethod` '{fineMappingMethod}' is not a method of ", + "`fineMappingResult` (available: {str_flatten(available, ', ')})." + )) + } + fineMappingResult[fineMappingResult$method == fineMappingMethod] +} + # The ctwas-shaped snpInfo for the whole collection's panel, captured BEFORE # .ctwasGwasByBlock() narrows each block's sketch to its own variants. A # gene's cis SPAN has to cover every block it reaches or @@ -986,7 +1060,10 @@ assembleCtwasInputs <- function( #' \code{fallbackToPrefit} -- when \code{TRUE}, an accurate EM that fails #' on a degenerate input is recovered by re-running only the prefit step #' and returning those (typically finite) priors. -#' @param numThreads Number of cores. +#' @param BPPARAM A \code{BiocParallelParam} whose workers number the cores +#' ctwas's own \code{ncore} parallelism uses when they run on this machine +#' (\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +#' core. Default \code{SerialParam()}. #' @param methodArgs Additional arguments forwarded to ctwas, built #' with \code{\link{CtwasOptions}}. Names are checked against what #' the ctwas steps accept between them. @@ -1007,27 +1084,28 @@ assembleCtwasInputs <- function( estCtwasGroupPriors <- function( inputs, ctwasPriorParam = CtwasPriorParam(), - numThreads = 1L, + BPPARAM = SerialParam(), methodArgs = CtwasOptions() ) { .assertMethodParam(ctwasPriorParam, "CtwasPriorParam") .assertMethodOptions(methodArgs, "CtwasOptions", "methodArgs") + .assertBpparam(BPPARAM) if (!requireNamespace("ctwas", quietly = TRUE)) { abort("Package 'ctwas' is required for estCtwasGroupPriors.") } - numThreads <- as.integer(numThreads) + threads <- .bpLocalThreads(BPPARAM, "estCtwasGroupPriors") inputs <- .ctwasResolveLdPaths(inputs) - zGene <- .ctwasEnsureZGene(inputs, numThreads, methodArgs$geneZ) + zGene <- .ctwasEnsureZGene(inputs, threads, methodArgs$geneZ) regionData <- .ctwasAssembleRegionData( inputs, zGene, ctwasPriorParam$thin, - numThreads, + threads, methodArgs$regionData ) boundaryGenes <- .ctwasBoundaryGenes( inputs, - numThreads, + threads, methodArgs$boundaryGenes ) paramRes <- .ctwasEstParamOrFallback( @@ -1035,7 +1113,7 @@ estCtwasGroupPriors <- function( ctwasPriorParam$niterPrefit, ctwasPriorParam$niter, ctwasPriorParam$varStructure, - numThreads, + threads, ctwasPriorParam$thin, ctwasPriorParam$fallbackToPrefit, methodArgs$estParam @@ -1062,7 +1140,7 @@ estCtwasGroupPriors <- function( niterPrefit, niter, groupPriorVarStructure, - numThreads, + threads, thin, fallbackToPrefit, extra @@ -1075,7 +1153,7 @@ estCtwasGroupPriors <- function( niterPrefit, niter, groupPriorVarStructure, - numThreads, + threads, extra )) } @@ -1085,7 +1163,7 @@ estCtwasGroupPriors <- function( niterPrefit, niter, groupPriorVarStructure, - numThreads, + threads, extra ), error = function(cnd) { @@ -1099,7 +1177,7 @@ estCtwasGroupPriors <- function( niter = as.integer(niter), groupPriorVarStructure = groupPriorVarStructure, thin = thin, - numThreads = numThreads, + threads = threads, extra = extra ) } @@ -1117,7 +1195,10 @@ estCtwasGroupPriors <- function( #' #' @param screenResult A list returned by \code{\link{screenCtwasRegions}}. #' @param maxNumSingleEffects Pass-through. -#' @param numThreads Number of cores. +#' @param BPPARAM A \code{BiocParallelParam} whose workers number the cores +#' ctwas's own \code{ncore} parallelism uses when they run on this machine +#' (\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +#' core. Default \code{SerialParam()}. #' @param methodArgs Additional arguments forwarded to ctwas, built #' with \code{\link{CtwasOptions}}. Names are checked against what #' the ctwas steps accept between them. @@ -1136,12 +1217,11 @@ estCtwasGroupPriors <- function( #' IRanges::IRanges(c(10000000, 15000001), c(15000000, 19000000)), #' blockId = c("chr22_1", "chr22_2")) #' gss <- loadGwasSumStatsFromManifest(manifest = mani, genome = "hg38", -#' ldReference = ldStem, region = "chr22:10000000-19000000", -#' ldBlocks = blocks) +#' ldReference = ldStem, which = blocks) #' gwasByRegion <- summaryStatsQc(gss, #' panelFilterParam = PanelFilterParam(mafCutoff = 0.0025)) #' inp <- assembleCtwasInputs(gwasSumStats = gwasByRegion, -#' twasWeights = list(ctwasWeightsExample)) +#' twasWeights = list(ctwasWeightsExample), method = "susie") #' est <- estCtwasGroupPriors(inp, #' ctwasPriorParam = CtwasPriorParam(thin = 1, niterPrefit = 3, niter = 10, #' fallbackToPrefit = TRUE), @@ -1157,18 +1237,20 @@ estCtwasGroupPriors <- function( finemapCtwasRegions <- function( screenResult, maxNumSingleEffects = 5L, - numThreads = 1L, + BPPARAM = SerialParam(), methodArgs = CtwasOptions() ) { .assertMethodOptions(methodArgs, "CtwasOptions", "methodArgs") + .assertBpparam(BPPARAM) if (!requireNamespace("ctwas", quietly = TRUE)) { abort("Package 'ctwas' is required for finemapCtwasRegions.") } + threads <- .bpLocalThreads(BPPARAM, "finemapCtwasRegions") screenResult <- .ctwasResolveLdPaths(screenResult) fmRes <- .ctwasFinemapOrEmpty( screenResult, maxNumSingleEffects, - numThreads, + threads, methodArgs ) # Repair cTWAS's molecular_id mislabel (first-"|" split of our composite @@ -1222,7 +1304,10 @@ finemapCtwasRegions <- function( #' \code{Inf}. #' @param maxNumSingleEffects Integer. Max number of single effects for the #' merged-region re-fine-mapping (LD path only). Default \code{5}. -#' @param numThreads Number of cores. Default \code{1}. +#' @param BPPARAM A \code{BiocParallelParam} whose workers number the cores +#' ctwas's own \code{ncore} parallelism uses when they run on this machine +#' (\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +#' core. Default \code{SerialParam()}. #' @param methodArgs Additional arguments forwarded to ctwas, built #' with \code{\link{CtwasOptions}}. Names are checked against what #' the ctwas steps accept between them. @@ -1242,13 +1327,15 @@ mergeCtwasBoundaryRegions <- function( filterCs = FALSE, maxSNP = Inf, maxNumSingleEffects = 5L, - numThreads = 1L, + BPPARAM = SerialParam(), methodArgs = CtwasOptions() ) { .assertMethodOptions(methodArgs, "CtwasOptions", "methodArgs") + .assertBpparam(BPPARAM) if (!requireNamespace("ctwas", quietly = TRUE)) { abort("Package 'ctwas' is required for mergeCtwasBoundaryRegions.") } + threads <- .bpLocalThreads(BPPARAM, "mergeCtwasBoundaryRegions") finemapResult <- .ctwasResolveLdPaths(finemapResult) fmRes <- finemapResult$finemap_res if (is.null(fmRes) || nrow(fmRes) == 0L) { @@ -1264,7 +1351,7 @@ mergeCtwasBoundaryRegions <- function( pipThresh, filterCs, maxSNP, - numThreads + threads ) fa <- .ctwasMergeDispatch(finemapResult, common, maxNumSingleEffects) # Flatten the record before merging: c() on a list and a MethodOptions (a @@ -1284,7 +1371,7 @@ mergeCtwasBoundaryRegions <- function( pipThresh, filterCs, maxSNP, - numThreads + threads ) { list( region_info = finemapResult$region_info, @@ -1300,7 +1387,7 @@ mergeCtwasBoundaryRegions <- function( pip_thresh = pipThresh, filter_cs = filterCs, maxSNP = maxSNP, - ncore = as.integer(numThreads) + ncore = threads ) } @@ -1363,7 +1450,7 @@ mergeCtwasBoundaryRegions <- function( niter, groupPriorVarStructure, thin, - numThreads, + threads, extra = list() ) { fitEm <- utils::getFromNamespace("fit_EM", "ctwas") @@ -1372,7 +1459,7 @@ mergeCtwasBoundaryRegions <- function( region_data = fitRegionData, niter = as.integer(niter), group_prior_var_structure = groupPriorVarStructure, - ncore = as.integer(numThreads) + ncore = threads ) prefit <- .ctwasInvoke(fitEm, fitArgs, extra) adj <- .ctwasApplyThin(prefit$group_prior, prefit$group_size, thin) @@ -1454,42 +1541,106 @@ mergeCtwasBoundaryRegions <- function( ) } -# Resolve which TWAS method's weights to feed into ctwas given a -# TwasWeights collection that may carry multiple methods per -# (study, context, trait). Rules: -# - Caller-supplied method (non-NULL, non-empty) wins, provided that -# method exists in the TwasWeights's `method` column. -# - Otherwise prefer "ensemble" when present. -# - Otherwise return the sole method when only one is present. -# - Otherwise: error. +# Which TWAS method's weights a cTWAS run feeds into ctwas -- one per run, as +# weights are homogeneous within a run. `twasWeights` is a flat weight source +# or a list of them. A caller-supplied `method` is used once checked present. +# Without one, TwasWeights default to their pre-combined "ensemble" weights. +# Anything else has no default: TwasWeights without an ensemble leave several +# methods to choose between, and a fine-mapping result's weights come from +# one of its fine-mapping methods. # @noRd -.ctwasResolveMethod <- function(twasWeightsList, method = NULL) { - available <- unique(list_c(map(twasWeightsList, .ctwasMethodChr))) +.ctwasResolveMethod <- function(twasWeights, method = NULL) { + sources <- .ctwasWeightSources(twasWeights) + available <- unique(.ctwasConcatChr(map(sources, .ctwasMethodsOf))) if (length(available) == 0L) { - abort("ctwasPipeline: TwasWeights collections have no method entries.") + abort("ctwasPipeline: the weight sources carry no method entries.") } if (!is.null(method) && str_length(method) > 0L) { if (!is_in(method, available)) { msg <- glue( - "ctwasPipeline: method '{method}' not present in TwasWeights ", - "(available: {str_flatten(available, ', ')})." + "ctwasPipeline: method '{method}' not present in the weight ", + "sources (available: {str_flatten(available, ', ')})." ) abort(msg) } return(method) } - if (is_in("ensemble", available)) { + allTwas <- all(map_lgl(sources, methods::is, "TwasWeights")) + if (allTwas && is_in("ensemble", available)) { return("ensemble") } - if (length(available) == 1L) { - return(available[[1L]]) + abort(glue( + "ctwasPipeline: pass `method` to choose the weights. ", + "{.ctwasNoDefaultMethod(allTwas)} ", + "(available: {str_flatten(available, ', ')})." + )) +} + +# Why the weight sources have no default method, for the error above. +# @noRd +.ctwasNoDefaultMethod <- function(allTwas) { + if (allTwas) { + return("These TwasWeights carry no 'ensemble' weights to default to") + } + str_c( + "A fine-mapping result's weights come from one of its fine-mapping ", + "methods" + ) +} + +# The weight sources a `twasWeights` argument holds: itself when it is one +# flat source, else the non-NULL elements of its list. +# @noRd +.ctwasWeightSources <- function(twasWeights) { + if ( + methods::is(twasWeights, "TwasWeights") || + methods::is(twasWeights, "QtlFineMappingResult") + ) { + return(list(twasWeights)) } - msg <- glue( - "ctwasPipeline: TwasWeights carries multiple methods ", - "({str_flatten(available, ', ')}) with no 'ensemble' entry. ", - "Supply a `method` argument to pick one (e.g. method = \"mrash\")." + compact(as.list(twasWeights)) +} + +# Warn once about the narrowed rows whose fits a run with `method` reads: the +# TwasWeights rows of that method carrying a SuSiE fit, which renormalizes a +# weight whose variants shrank. A narrowed row's fit no longer lines up with +# its variants, so its weights go in without that step. Other weights are +# used as the row holds them, and a fine-mapping weight source supplies its +# topLoci effects, not its fit. +# @noRd +.ctwasCheckFitCoverage <- function(twasWeights, method, caller) { + sources <- keep( + .ctwasWeightSources(twasWeights), + methods::is, + "TwasWeights" ) - abort(msg) + .fitCoverageCheckedAll( + map(sources, .ctwasSusieFitRows, method = method), + caller + ) +} + +# The rows of TwasWeights `tw` fitted by `method` whose stored fit is a SuSiE +# fit, or NULL when it has none. +# @noRd +.ctwasSusieFitRows <- function(tw, method) { + fits <- mcols(tw, use.names = FALSE)$fits + susie <- map_lgl(seq_along(tw), .ctwasRowHasSusieFit, fits = fits) + rows <- which(as.character(tw$method) == method & susie) + if (length(rows) == 0L) NULL else tw[rows] +} + +# @noRd +.ctwasRowHasSusieFit <- function(i, fits) { + .ctwasIsSusieFit(fits[[i]]) +} + +# @noRd +.ctwasConcatChr <- function(pieces) { + if (length(pieces) == 0L) { + return(character(0)) + } + as.character(list_c(pieces)) } # Fail fast on the two cTWAS inputs. `gwasSumStats` defines the LD-block grid: @@ -1503,7 +1654,7 @@ mergeCtwasBoundaryRegions <- function( msg <- glue( "`gwasSumStats` must be a GwasSumStats whose elements are LD ", "blocks (got {class(gwasSumStats)[[1L]]}). Build one with ", - "`loadGwasSumStatsFromManifest(..., ldBlocks = )`." + "`loadGwasSumStatsFromManifest(..., region = )`." ) abort(msg) } @@ -1521,13 +1672,6 @@ mergeCtwasBoundaryRegions <- function( } } -# Strip a leading "chr" and case so region_id-derived seqnames ("chr22") and -# phenotype rowRanges seqnames ("22" / "chr22") compare equal for placement. -# @noRd -.ctwasChrKey <- function(x) { - str_remove(str_to_lower(as.character(x)), "^chr") -} - # TRUE when `tw` is ALREADY a per-region named list (the pre-bucketed contract): # a NAMED plain list (not an S4 collection) of weight collections. Its keys are # validated against the block grid downstream (the `extra_tw_keys` check). A @@ -1577,65 +1721,25 @@ mergeCtwasBoundaryRegions <- function( abort(msg) } -# One block id parsed into chrom/start/end, or the unplaced sentinel when it -# does not parse as a range. -# @noRd -.ctwasBlockCoords <- function(id) { - g <- try_fetch( - asGranges(str_replace( - as.character(id), - "_([0-9]+)_([0-9]+)$", - ":\\1-\\2" - )), - error = function(cnd) NULL - ) - if (is.null(g) || length(g) < 1L) { - return(list(chrom = "chrUn", start = 1L, end = 0L)) - } - list( - chrom = as.character(GenomicRanges::seqnames(g))[[1L]], - start = GenomicRanges::start(g)[[1L]], - end = GenomicRanges::end(g)[[1L]] - ) -} - -# Parse cTWAS block-manifest keys ("chr1_1000_2000" / "chr1:1000-2000") into a -# per-key GRanges. -# -# This is cTWAS's OWN `region_id` concept, not pecotmr's: cTWAS keys its -# region_info, snp_map and per-region data by these strings, so the package has -# to be able to read them even though pecotmr's own collections now key on the -# element range instead (section 4.4). A key that carries no coordinates -# becomes a 0-width chrUn sentinel, which matches no anchor and so yields the -# documented "NA when the anchor falls in no block". -# @noRd -.ctwasBlockGrFromIds <- function(ids) { - coords <- map(ids, .ctwasBlockCoords) - GenomicRanges::GRanges( - map_chr(coords, "chrom"), - IRanges::IRanges( - start = map_int(coords, "start"), - end = map_int(coords, "end") - ) - ) -} - # Place each gene (row) of a flat weight source into its home LD block. The # anchor is start(region) -- matching cTWAS's own `assign_region_data` rule, # which homes a gene by its p0 (single point) into the block where -# p0 in [start, stop). Returns a region_id per row (NA when the anchor falls in -# no block). A gene whose cis SPAN straddles a boundary is still homed by its -# single anchor here; the cross-block signal is cTWAS's boundary-gene concern -# (get_boundary_genes / postprocess_region_merging), not placement. +# p0 in [start, stop), each block's [start, stop) being the one its +# region_info carries (.ctwasBuildSingleRegionInfo()). Returns a region_id per +# row (NA when the anchor falls in no block). A gene whose cis SPAN straddles +# a boundary is still homed by its single anchor here; the cross-block signal +# is cTWAS's boundary-gene concern (get_boundary_genes / +# postprocess_region_merging), not placement. # @noRd .ctwasPlaceByAnchor <- function(region, gwasSumStats) { ids <- names(gwasSumStats) blockGr <- .ctwasBlockWindows(gwasSumStats, ids) - aChr <- .ctwasChrKey(as.character(GenomicRanges::seqnames(region))) + aChr <- as.character(GenomicRanges::seqnames(region)) aPos <- GenomicRanges::start(region) - bChr <- .ctwasChrKey(as.character(GenomicRanges::seqnames(blockGr))) + bChr <- as.character(GenomicRanges::seqnames(blockGr)) bS <- GenomicRanges::start(blockGr) - bE <- GenomicRanges::end(blockGr) + # The half-open stop region_info hands cTWAS: one past the window's end. + bE <- GenomicRanges::end(blockGr) + 1L map_chr( seq_along(aPos), .ctwasBlockIdForVariant, @@ -1648,44 +1752,44 @@ mergeCtwasBoundaryRegions <- function( ) } -# The window of each LD block, taken from that block's own GWAS variants. -# -# These used to be parsed out of the region-id strings, which forced ids to -# encode coordinates ("chr1_100_200"). Each block is now an element of a -# GwasSumStats and carries its range directly, so an opaque id ("blockA") -# places just as well. A block with no variants yields an empty window and -# hosts no gene, which is the right answer: there is no GWAS signal there for -# a gene to be tested against. +# The window of each LD block (.ctwasBlockWindow()), one per block. Built from +# its parts rather than by c(): each window knows only its own chromosome, +# and combining blocks on different chromosomes would warn that their +# seqlevels share nothing. # @noRd .ctwasBlockWindows <- function(gwasSumStats, ids) { - spans <- map(gwasSumStats, .ctwasBlockSpan) - empty <- map_lgl(spans, .ctwasSpanIsEmpty) - if (all(empty)) { - # Nothing to place against; fall back to whatever the ids encode so a - # coordinate-keyed caller still behaves as before. - return(.ctwasBlockGrFromIds(ids)) - } - # unname(): c() on a NAMED list of GRanges builds a list rather than - # concatenating, and the result then fails seqnames() further down. - exec(c, !!!unname(spans)) + windows <- unname(map2(gwasSumStats, ids, .ctwasBlockWindow)) + GenomicRanges::GRanges( + map_chr(windows, .ctwasWindowSeqname), + IRanges::IRanges( + start = map_int(windows, GenomicRanges::start), + end = map_int(windows, GenomicRanges::end) + ) + ) } # @noRd -.ctwasBlockSpan <- function(gss) { - # S4 dispatch, not list flattening: `gss` is a GwasSumStats collection and - # unlist() returns the GRanges that range() below needs. - variants <- unlist(gss, use.names = FALSE) - if (length(variants) == 0L) { - return(GenomicRanges::GRanges()) - } - # A stored element spans exactly one seqname, so ignoring strand leaves a - # single range -- the block's window. - range(variants, ignore.strand = TRUE) +.ctwasWindowSeqname <- function(w) { + as.character(GenomicRanges::seqnames(w)) } +# The window of LD block `gss` (that block's GwasSumStats rows): its stored +# `region` -- the LD block it was split by, or the span of its variants as +# built -- not the span of the variants it holds now, so a gene or a SNP +# between two blocks' variants still lands in a block. A block id is only a +# name, so it gives no window. An error when the rows lie on several +# chromosomes. # @noRd -.ctwasSpanIsEmpty <- function(g) { - length(g) == 0L +.ctwasBlockWindow <- function(gss, regionId) { + window <- range(.rowRegions(gss)$region, ignore.strand = TRUE) + if (length(window) != 1L) { + chrs <- as.character(GenomicRanges::seqnames(window)) + abort(glue( + "ctwasPipeline: GwasSumStats block '{regionId}' spans multiple ", + "chromosomes ({str_flatten(chrs, ', ')})." + )) + } + window } # The genes homed into region `rid`, every row on that region's LD sketch, or @@ -1746,8 +1850,8 @@ mergeCtwasBoundaryRegions <- function( if (length(out) == 0L) { msg <- glue( "assembleCtwasInputs: no gene placed into any LD block. ", - "Check that the weight `region`s and the gwasSumStats region_id ", - "keys share a coordinate system (e.g. 'chr22_1_1000000')." + "Check that the genes' trait positions fall inside the GWAS ", + "blocks' windows (their `region`), on the same genome build." ) abort(msg) } @@ -1771,45 +1875,6 @@ mergeCtwasBoundaryRegions <- function( if (is.null(tw)) NULL else as.character(tw$method) } -# Resolve the LIST of TWAS methods a `ctwasPipeline` run should iterate over -# (one independent cTWAS run per method -- weights are homogeneous within a -# run). - explicit `method`: exactly that one (validated present). - NULL + an -# "ensemble" method present: just "ensemble" (the pre-combined weight, the -# historical default). - NULL + a single method present: that one. - NULL + -# MULTIPLE methods, no "ensemble": ALL of them (the singular -# `.ctwasResolveMethod` errors here; the pipeline instead fans out). -# @noRd -.ctwasResolveMethods <- function(twasWeightsList, method = NULL) { - available <- unique( - if ( - methods::is(twasWeightsList, "TwasWeights") || - methods::is(twasWeightsList, "QtlFineMappingResult") - ) { - # a flat weight source - .ctwasMethodsOf(twasWeightsList) - } else { - list_c(compact(map(twasWeightsList, .ctwasMethodsOf))) - } - ) # a list of them - if (length(available) == 0L) { - abort("ctwasPipeline: weight sources carry no method entries.") - } - if (!is.null(method) && str_length(method) > 0L) { - if (!is_in(method, available)) { - msg <- glue( - "ctwasPipeline: method '{method}' not present in the weight ", - "sources (available: {str_flatten(available, ', ')})." - ) - abort(msg) - } - return(method) - } - if (is_in("ensemble", available)) { - return("ensemble") - } - available # single -> length-1 (one run); multiple -> iterate over all -} - # The single GWAS (disease) study a cTWAS run models. cTWAS solves one disease # per run (the z_snp carries a single z per SNP), so the input blocks must all # reference the same GWAS study. @@ -1999,7 +2064,8 @@ mergeCtwasBoundaryRegions <- function( # A finemap / susieAlpha table as a GRanges, its original columns preserved as # mcols. Returns the table unchanged when no row can be placed, so a payload -# that genuinely has no coordinates is not silently fabricated onto chr1. +# that genuinely has no coordinates is not silently fabricated onto chr1; when +# only some rows can be, the rest are left out of the ranges, and named. # @noRd .ctwasRangePayload <- function(df, geneCoords) { if (is.null(df) || nrow(df) == 0L) { @@ -2011,6 +2077,7 @@ mergeCtwasBoundaryRegions <- function( if (!any(placed)) { return(df) } + .ctwasWarnUnplaced(ids[!placed]) gr <- GenomicRanges::GRanges( map_chr(coord, .ctwasCoordField, field = "chrom"), IRanges::IRanges( @@ -2032,6 +2099,23 @@ mergeCtwasBoundaryRegions <- function( )[placed] } +# Rows with neither a gene coordinate nor a chrom:pos id cannot be ranged. +# @noRd +.ctwasWarnUnplaced <- function(ids) { + if (length(ids) == 0L) { + return(invisible(NULL)) + } + shown <- unique(ids) + warn(c( + glue( + "cTWAS: {length(ids)} result row(s) could not be placed on the ", + "genome and are left out of the ranged results: they have no ", + "gene coordinate and their id is not a chrom:pos variant id." + ), + set_names(utils::head(shown, 5L), rep("*", min(5L, length(shown)))) + )) +} + # @noRd .ctwasRowCoord <- function(i, ids, gc) { id <- ids[[i]] @@ -2043,7 +2127,7 @@ mergeCtwasBoundaryRegions <- function( return(NULL) } list( - chrom = withChrPrefix(as.character(parsed$chrom[[1L]])), + chrom = parsed$chrom[[1L]], start = as.integer(parsed$pos[[1L]]), end = as.integer(parsed$pos[[1L]]) ) @@ -2072,9 +2156,10 @@ mergeCtwasBoundaryRegions <- function( ) } -# region_info as a GRanges. pecotmr builds this table itself with `chr` and a -# variant-derived [start, stop], so the ranges are already there -- this only -# gives them their proper type. +# region_info as a GRanges. pecotmr builds this table itself, each block's +# window as cTWAS's half-open [start, stop), so the range ends one base before +# `stop` -- the window again (a merged region, the span of the windows it +# merged). # @noRd .ctwasRangeRegionInfo <- function(ri) { if (is.null(ri) || nrow(ri) == 0L) { @@ -2088,7 +2173,7 @@ mergeCtwasBoundaryRegions <- function( withChrPrefix(as.character(ri$chrom)), IRanges::IRanges( start = as.integer(ri$start), - end = as.integer(ri$stop) + end = as.integer(ri$stop) - 1L ) ) S4Vectors::`mcols<-`( @@ -2406,72 +2491,39 @@ asCtwasResult <- function(finemapResult, keepSnps = FALSE) { .ctwasHarmonizeZToPanel(bind_rows(pieces), panelIds) } -# @noRd -.ctwasEntryPositions <- function(i, gss) { - gr <- gss[[i]] - list( - pos = as.integer(GenomicRanges::start(gr)), - chrs = as.character(GenomicRanges::seqnames(gr)) - ) -} - -# @noRd -.ctwasConcatInt <- function(pieces) { - if (length(pieces) == 0L) { - return(integer(0)) - } - list_c(pieces) -} - -# @noRd -.ctwasConcatChr <- function(pieces) { - if (length(pieces) == 0L) { - return(character(0)) - } - list_c(pieces) -} - -# The single-row region_info for block `regionId`: its chromosome and the -# [start, stop] span of the GWAS variants it holds. An empty block, or one +# The single-row region_info for block `regionId`: its chromosome and its +# window (.ctwasBlockWindow()), which cTWAS reads as the half-open +# [start, stop) -- so `stop` is one past the window's last base, and every +# variant of the block is assigned to it. A block with no variants, or one # spanning several chromosomes, is an error. # @noRd .ctwasBuildSingleRegionInfo <- function(regionId, gss) { - # Derive the block's [start, stop] from the GWAS variants actually in this - # block (the GwasSumStats entry GRanges) -- NOT the LD sketch. When many + # The window is the block's own -- NOT the LD sketch's span. When many # blocks share one whole-chromosome LD payload (the common one-file-per-chr # layout), snpInfo(ldReference) spans the entire chromosome, so every region # would collapse to the same whole-chromosome [start, stop] and every SNP # would be assigned to every region (inflating SNP group_size N-fold and # diluting the gene prior to ~0). - entries <- map(seq_len(nrow(gss)), .ctwasEntryPositions, gss = gss) - pos <- .ctwasConcatInt(map(entries, "pos")) - chrs <- .ctwasConcatChr(map(entries, "chrs")) - # Emptiness is checked FIRST: `pos` and `chrs` are filled from the same - # GRanges in the same loop, so an empty block has zero chromosomes too, - # and the chromosome check below would report it as "spans multiple - # chromosomes ()" -- which is both wrong and unactionable. - if (length(pos) == 0L) { + # + # Emptiness is checked FIRST: a block with no variants has nothing for + # cTWAS to fit, and the window of one empty from the start is only a + # placeholder. + if (sum(lengths(gss)) == 0L) { msg <- glue( "ctwasPipeline: GwasSumStats block '{regionId}' has no variants ", - "to define region bounds." - ) - abort(msg) - } - chr <- unique(as.integer( - str_remove(chrs, regex("^chr", ignore_case = TRUE)) - )) - if (length(chr) != 1L) { - msg <- glue( - "ctwasPipeline: GwasSumStats block '{regionId}' spans multiple ", - "chromosomes ({str_flatten(chr, ', ')})." + "for cTWAS to fit." ) abort(msg) } + window <- .ctwasBlockWindow(gss, regionId) tibble( region_id = regionId, - chrom = chr, - start = min(pos), - stop = max(pos) + chrom = as.integer(str_remove( + as.character(GenomicRanges::seqnames(window)), + regex("^chr", ignore_case = TRUE) + )), + start = GenomicRanges::start(window), + stop = GenomicRanges::end(window) + 1L ) } @@ -2496,7 +2548,7 @@ asCtwasResult <- function(finemapResult, keepSnps = FALSE) { # (df[, "pos"] -> vector for region-bound min/max); a tibble column is a # 1-col list and errors min(). data.frame( - chrom = as.integer(.ldRefChrom(gwasLd)), + chrom = as.integer(canonChrom(.ldRefChrom(gwasLd))), id = .ldRefMatchIds(gwasLd), pos = as.integer(GenomicRanges::start(gr)), alt = as.character(mc$A1), @@ -2574,7 +2626,7 @@ asCtwasResult <- function(finemapResult, keepSnps = FALSE) { return(NULL) } targetDf <- tibble( - chrom = as.integer(parsed$chrom), + chrom = parsed$chrom, pos = as.integer(parsed$pos), A2 = as.character(parsed$A2), A1 = as.character(parsed$A1), @@ -2949,7 +3001,7 @@ asCtwasResult <- function(finemapResult, keepSnps = FALSE) { .ctwasGenePrepared <- function(i, twasWeights, ctx) { # Polymorphic: the weight source may be a TwasWeights or a # fine-mapping result, so the payload comes from the class-aware bridge. - parts <- .rowParts(twasWeights, i) + parts <- .collectionEntry(twasWeights, i) aligned <- .ctwasAlignGeneWeights(parts, ctx$refVariants, ctx$panelSnps) if (is.null(aligned)) { return(NULL) @@ -2960,8 +3012,7 @@ asCtwasResult <- function(finemapResult, keepSnps = FALSE) { ctx$fineMappingResult, meta$study, meta$context, - meta$trait, - meta$method + meta$trait ) kept <- .ctwasFilterVariants( vids = aligned$vids, @@ -3118,46 +3169,32 @@ asCtwasResult <- function(finemapResult, keepSnps = FALSE) { is_in(vids, as.character(regionSnps)) } -# Look up the per-(study, context, trait, method) PIP vector and the -# 95% credible-set membership / purity for one gene from the supplied -# fine-mapping result. Returns NULL when none was passed -# or no matching tuple exists. Output is a list with: +# Look up one gene's PIP vector and 95% credible-set membership / purity in +# the rescues' fine-mapping result, which .ctwasRescueSource() narrowed to the +# one method they read, so the gene's (study, context, trait) picks its fit. +# Returns NULL when no result was passed or the gene has no fit in it. Output +# is a list with: # pip : named numeric vector keyed by variant_id # csMembers : list of character vectors (one per CS at 95% coverage) # csPurity : numeric vector aligned with csMembers # @noRd -.ctwasGetFinemapAux <- function( - fmr, - studyName, - context, - trait, - method -) { +.ctwasGetFinemapAux <- function(fmr, studyName, context, trait) { if (is.null(fmr)) { return(NULL) } - cols <- .tupleColumnNames(fmr) - selectors <- c( - list(study = studyName, method = method), - compact(list( - context = if (is_in("context", cols)) context, - trait = if (is_in("trait", cols)) trait - )) - ) - # `fineMappingResult` here is the accessor generic, not the `fmr` - # argument -- the two must not be conflated. - entry <- try_fetch( - exec(fineMappingResult, fmr, !!!selectors), - error = function(cnd) NULL + idx <- .matchTupleRows( + fmr, + list(study = studyName, context = context, trait = trait) ) - if (is.null(entry)) { + if (length(idx) == 0L) { return(NULL) } - tl <- topLoci(entry, raw = TRUE) + # The stored table verbatim: every variant, no posterior projection. + tl <- .fmrPartsTopLoci(.fmrRowParts(fmr, idx[[1L]])) if (nrow(tl) == 0L) { return(NULL) } - # `pip` is part of the topLoci schema -- fineMappingRow() requires it on + # `pip` is part of the topLoci schema -- FineMappingRow() requires it on # any non-empty table, and the zero-row case returned above -- so there is # no pip-less frame to guard against here. pip <- set_names(as.numeric(tl$pip), as.character(tl$variant_id)) @@ -3666,12 +3703,6 @@ asCtwasResult <- function(finemapResult, keepSnps = FALSE) { as.character(g$study) } -# The weight method of one assembled TwasWeights record (character). -# @noRd -.ctwasMethodChr <- function(tw) { - as.character(tw$method) -} - # The block id whose window contains anchor variant `i`, or NA when unplaced. # @noRd .ctwasBlockIdForVariant <- function(i, aPos, aChr, bChr, bS, bE, ids) { diff --git a/R/ctwasWrapper.R b/R/ctwasWrapper.R index 79015153..7f89c196 100644 --- a/R/ctwasWrapper.R +++ b/R/ctwasWrapper.R @@ -43,7 +43,7 @@ # ctwas_sumstats). Routed through .ctwasInvoke so `methodArgs` reaches it -- # this was the one ctwas step CtwasOptions() could not configure. # @noRd -.ctwasEnsureZGene <- function(inputs, numThreads, extra = list()) { +.ctwasEnsureZGene <- function(inputs, threads, extra = list()) { if (!is.null(inputs$z_gene)) { return(inputs$z_gene) } @@ -52,7 +52,7 @@ list( z_snp = inputs$z_snp, weights = inputs$weights, - ncore = numThreads + ncore = threads ), extra = extra ) @@ -61,7 +61,7 @@ # assemble_region_data -> the per-region list (keyed by region_id). It does NOT # echo z_gene or return boundary genes; both are recovered separately. # @noRd -.ctwasAssembleRegionData <- function(inputs, zGene, thin, numThreads, extra) { +.ctwasAssembleRegionData <- function(inputs, zGene, thin, threads, extra) { .ctwasInvoke( ctwas::assemble_region_data, list( @@ -71,7 +71,7 @@ weights = inputs$weights, snp_map = inputs$snp_map, thin = thin, - ncore = numThreads + ncore = threads ), extra = extra ) @@ -80,7 +80,7 @@ # Boundary genes (computed internally by assemble_region_data for adjustment but # never returned) recovered via ctwas::get_boundary_genes; NULL for one region. # @noRd -.ctwasBoundaryGenes <- function(inputs, numThreads, extra) { +.ctwasBoundaryGenes <- function(inputs, threads, extra) { if (nrow(inputs$region_info) <= 1L) { return(NULL) } @@ -89,7 +89,7 @@ list( region_info = inputs$region_info, weights = inputs$weights, - ncore = numThreads + ncore = threads ), extra = extra ) @@ -105,7 +105,7 @@ niterPrefit, niter, groupPriorVarStructure, - numThreads, + threads, extra ) { .ctwasInvoke( @@ -115,7 +115,7 @@ niter_prefit = as.integer(niterPrefit), niter = as.integer(niter), group_prior_var_structure = groupPriorVarStructure, - ncore = numThreads + ncore = threads ), extra = extra ) @@ -131,7 +131,10 @@ #' values). #' #' @param estResult A list returned by \code{\link{estCtwasGroupPriors}}. -#' @param numThreads Number of cores. +#' @param BPPARAM A \code{BiocParallelParam} whose workers number the cores +#' ctwas's own \code{ncore} parallelism uses when they run on this machine +#' (\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +#' core. Default \code{SerialParam()}. #' @param methodArgs Additional arguments forwarded to ctwas, built #' with \code{\link{CtwasOptions}}. Names are checked against what #' the ctwas steps accept between them. @@ -144,10 +147,12 @@ #' @export screenCtwasRegions <- function( estResult, - numThreads = 1L, + BPPARAM = SerialParam(), methodArgs = CtwasOptions() ) { + .assertBpparam(BPPARAM) .assertMethodOptions(methodArgs, "CtwasOptions", "methodArgs") + threads <- .bpLocalThreads(BPPARAM, "screenCtwasRegions") if (!requireNamespace("ctwas", quietly = TRUE)) { abort("Package 'ctwas' is required for screenCtwasRegions.") } @@ -164,7 +169,7 @@ screenCtwasRegions <- function( region_data = estResult$region_data, snp_map = estResult$snp_map, z_snp = estResult$z_snp, - ncore = as.integer(numThreads) + ncore = threads ), extra = methodArgs$expand ) @@ -177,7 +182,7 @@ screenCtwasRegions <- function( region_data = regionDataForScreen, group_prior = estResult$param$group_prior, group_prior_var = estResult$param$group_prior_var, - ncore = as.integer(numThreads) + ncore = threads ), extra = methodArgs$screen ) @@ -197,7 +202,7 @@ screenCtwasRegions <- function( .ctwasFinemapOrEmpty <- function( screenResult, maxNumSingleEffects, - numThreads, + threads, methodArgs ) { rd <- screenResult$screened_region_data @@ -216,7 +221,7 @@ screenCtwasRegions <- function( LD_format = "custom", LD_loader_fun = screenResult$LD_loader_fun, snpinfo_loader_fun = screenResult$snpinfo_loader_fun, - ncore = as.integer(numThreads) + ncore = threads ), extra = methodArgs$finemap ) @@ -271,13 +276,13 @@ screenCtwasRegions <- function( # What the pipeline itself supplies at each step's call site -- taken from the # base `list()` handed to .ctwasInvoke(), which is exactly the set that gets -# deduped away. `ncore` is the pipeline's `numThreads` everywhere. +# deduped away. `ncore` comes from the pipeline's `BPPARAM` everywhere. # @noRd .ctwasOwnedGeneZ <- function() { c( z_snp = "supplied from the data by the pipeline", weights = "supplied from the data by the pipeline", - ncore = "the pipeline's own `numThreads`" + ncore = "the pipeline's own `BPPARAM`" ) } @@ -324,7 +329,7 @@ CtwasRegionDataOptions <- function(...) { weights = "supplied from the data by the pipeline", snp_map = "supplied from the data by the pipeline", thin = "CtwasPriorParam(thin =)", - ncore = "the pipeline's own `numThreads`" + ncore = "the pipeline's own `BPPARAM`" ), "CtwasRegionDataOptions", "ctwasRegionData", @@ -354,7 +359,7 @@ CtwasEstParamOptions <- function(...) { niter_prefit = "CtwasPriorParam(niterPrefit =)", niter = "CtwasPriorParam(niter =)", group_prior_var_structure = "CtwasPriorParam(varStructure =)", - ncore = "the pipeline's own `numThreads`" + ncore = "the pipeline's own `BPPARAM`" ), "CtwasEstParamOptions", "ctwasEstParam", @@ -377,7 +382,7 @@ CtwasScreenOptions <- function(...) { region_data = "supplied from the data by the pipeline", group_prior = "estimated by the EM step", group_prior_var = "estimated by the EM step", - ncore = "the pipeline's own `numThreads`" + ncore = "the pipeline's own `BPPARAM`" ), "CtwasScreenOptions", "ctwasScreen", @@ -401,7 +406,7 @@ CtwasExpandOptions <- function(...) { region_data = "supplied from the data by the pipeline", snp_map = "supplied from the data by the pipeline", z_snp = "supplied from the data by the pipeline", - ncore = "the pipeline's own `numThreads`" + ncore = "the pipeline's own `BPPARAM`" ), "CtwasExpandOptions", "ctwasExpand", @@ -430,7 +435,7 @@ CtwasFinemapOptions <- function(...) { LD_format = "fixed by the pipeline's LD loaders", LD_loader_fun = "fixed by the pipeline's LD loaders", snpinfo_loader_fun = "fixed by the pipeline's LD loaders", - ncore = "the pipeline's own `numThreads`" + ncore = "the pipeline's own `BPPARAM`" ), "CtwasFinemapOptions", "ctwasFinemap", @@ -477,7 +482,7 @@ CtwasMergeOptions <- function(...) { LD_format = "fixed by the pipeline's LD loaders", LD_loader_fun = "fixed by the pipeline's LD loaders", snpinfo_loader_fun = "fixed by the pipeline's LD loaders", - ncore = "the pipeline's own `numThreads`" + ncore = "the pipeline's own `BPPARAM`" ), "CtwasMergeOptions", "ctwasMerge", @@ -505,7 +510,7 @@ CtwasBoundaryGenesOptions <- function(...) { c( region_info = "supplied from the data by the pipeline", weights = "supplied from the data by the pipeline", - ncore = "the pipeline's own `numThreads`" + ncore = "the pipeline's own `BPPARAM`" ), "CtwasBoundaryGenesOptions", "ctwasBoundaryGenes", diff --git a/R/fineMappingPipeline.R b/R/fineMappingPipeline.R index debf0635..cf792b0b 100644 --- a/R/fineMappingPipeline.R +++ b/R/fineMappingPipeline.R @@ -63,7 +63,7 @@ #' #' @section QC contract: All \code{QtlSumStats} and \code{GwasSumStats} inputs #' must have been QC'd via \code{\link{summaryStatsQc}}; the pipeline errors -#' on inputs where \code{length(qcInfo(x)) == 0L}. \code{summaryStatsQc} +#' on inputs where \code{length(qcOptions(x)) == 0L}. \code{summaryStatsQc} #' also drops variants absent from the \code{ldReference}, so by the time #' per-entry processing runs every variant is guaranteed to be present in the #' LD panel and a local LD matrix can be built with @@ -103,16 +103,21 @@ #' the method column on the returned collection #' carries the bare token (\code{"susie"}, #' \code{"susieInf"}, \code{"mvsusie"}, ...) only. QC -#' provenance is recorded on the sumstats' \code{qcInfo}. +#' provenance is recorded on the sumstats: \code{qcOptions()} and, +#' per row, \code{qcInfo()}. #' \item An entry that \code{summaryStatsQc(pipCutoffToSkip = ...)} screened -#' out (recorded as \code{qcInfo$entryAudit[[i]]$pipScreenSkipped}, and -#' emptied to 0 variants) is \strong{skipped}, not fit: it produces no -#' row and a message with the screen reason. An all-screened collection -#' yields a valid empty result rather than an error. +#' out (recorded in its row's \code{pipScreenSkipped} column of +#' \code{qcInfo()}, and emptied to 0 variants) is \strong{skipped}, +#' not fit: it produces no row and a message with the screen reason. +#' An all-screened collection yields a valid empty result rather than +#' an error. #' } #' #' @param data A \code{QtlDataset}, \code{MultiStudyQtlDataset}, -#' \code{QtlSumStats}, or \code{GwasSumStats}. +#' \code{QtlSumStats}, or \code{GwasSumStats}. Each row of a +#' \code{GwasSumStats} is fine-mapped as one region, so it should be an LD +#' block (load one block, or split the study with a \code{region}); a row +#' spanning more than 20 Mb, as a whole chromosome does, draws a warning. #' @param methods Method specification. Accepts either: #' \itemize{ #' \item A character vector of method tokens, e.g. @@ -131,9 +136,9 @@ #' by the pipeline (e.g. you can override \code{model_init} #' even when fitting from a susieInf chain). #' } -#' @param contexts Optional context selection; \code{NULL} (the default) uses -#' every context. A character vector applies to every study: a context no -#' study has is an error, and one only some studies lack is skipped for +#' @param contexts Optional context selection; \code{NULL} (the default) +#' uses every context. A character vector applies to every study: a context +#' no study has is an error, and one only some studies lack is skipped for #' those, with a warning. A list keyed by study name picks each study's #' contexts separately (\code{list(A = "liver")}); studies it does not name #' keep all of theirs. @@ -145,14 +150,19 @@ #' (\code{list(A = list(brain = "ENSG1"))}). Studies and contexts the list #' does not name keep all of their traits. A joint fit spanning a study's #' contexts uses every trait selected in any of them, minus the (context, -#' trait) pairs a per-context entry leaves out. +#' trait) pairs a per-context entry leaves out. In a MultiStudyQtlDataset +#' a study left with no trait selected sits out; the run is refused only +#' when no study or summary-statistics row has one. #' @param region Optional variant window for QtlDataset trait selection: a -#' \code{GRanges}, a \code{"chr:start-end"} string, or a one-row data.frame -#' with \code{chrom}/\code{start}/\code{end}. Mutually exclusive with -#' \code{traitId}. +#' \code{GRanges}. Mutually exclusive with \code{traitId}. #' @param cisWindow For QtlDataset: cis-window (bp) around each trait's genomic #' position when extracting variants. Required when \code{traitId} is -#' supplied. Mutually exclusive with \code{region}. +#' supplied. Mutually exclusive with \code{region}. For QtlSumStats: +#' optional; each selected tuple is analysed over its \code{traitPos} +#' \eqn{\pm} \code{cisWindow}, within its \code{region}, which is then +#' the window its result records. Every selected tuple needs a +#' \code{traitPos}. A MultiStudyQtlDataset applies it to each of its +#' studies, individual-level or summary-statistics, as above. #' @param jointRegions For QtlDataset with a multi-range \code{region}: #' \code{FALSE} (default) fits each range independently and merges the #' per-range results into one entry per (study, context, trait, method) -- the @@ -188,7 +198,7 @@ #' present are not refit. #' @param crossValidationParam Cross-validation settings, built with #' \code{\link{CrossValidationParam}}: \code{folds} (default \code{0}, no -#' CV), \code{numThreads} for the per-fold refits, and \code{samplePartition} +#' CV), \code{BPPARAM} for the per-fold refits, and \code{samplePartition} #' to reuse a fixed partition across methods. When \code{folds > 1} each #' method is refit on every fold's training samples and used to predict the #' held-out ones; the partition, the out-of-fold predictions and the metrics @@ -271,12 +281,14 @@ #' RAISS will impute. Use it when the panel cannot support the LD estimate a #' rare variant would need. #' -#' @param genotypeFilterParam Per-call overrides of the \code{QtlDataset}'s own -#' filters, built with \code{\link{GenotypeFilterParam}}. A field left unset -#' keeps the dataset's construct-time value, so -#' \code{GenotypeFilterParam(mafCutoff = 0)} pins the cutoff at zero while -#' \code{GenotypeFilterParam()} changes nothing. Applies to the -#' \code{QtlDataset} method only. +#' @param genotypeFilterParam Which variants and samples the run keeps, built +#' with \code{\link{GenotypeFilterParam}}: its \code{keepSamples} narrows +#' the dataset once, and its MAF, MAC, variance, missingness, +#' \code{keepVariants} and \code{keepIndel} settings apply to each +#' extracted block, against that block's samples. A field left unset +#' filters nothing. A \code{QtlDataset} records no filter of its own, so +#' this is the only one. \code{QtlDataset} and +#' \code{MultiStudyQtlDataset} input only. #' @param panelFilterParam LD-reference-panel filters for the summary-statistics #' and GWAS methods, built with \code{\link{PanelFilterParam}}. See #' \emph{Panel filters on the RSS path} above. @@ -288,8 +300,12 @@ #' @param dataDrivenPriorWeightsCutoff Numeric or \code{NULL}. Cutoff below #' which data-driven prior weights are zeroed; \code{NULL} disables the #' cutoff. -#' @param naAction Character. How to handle missing values in the extracted -#' phenotype/genotype data. +#' @param phenotypeFilterParam The run's phenotype QC, built with +#' \code{\link{PhenotypeFilterParam}}: how missing phenotype values are +#' handled (unset drops the affected samples; \code{"impute"} fills each +#' trait's mean; a fit cannot take \code{"keep"}) and whether outlier +#' samples are dropped. Every fit of the run, joint ones included, reads +#' its phenotypes under it. #' @param verbose Verbosity (0 silent, 1 default). Default \code{1}. #' @param residualizationParam Covariate residualization settings, built with #' \code{\link{ResidualizationParam}}: \code{phenotypeCovariates} and @@ -349,21 +365,21 @@ #' } #' @param dataType Optional assay / modality label for the phenotype the fit #' was run on (\code{"bulk_rnaseq"}, \code{"methylation"}), recorded as a -#' per-row provenance column and published by \code{\link{exportToBed}} / -#' \code{\link{exportToVcf}}. \code{NULL} (default) omits the column. It -#' cannot be derived --- the input carries the values, not what they measure. +#' per-row provenance column and published by \code{\link{writeBed}} / +#' \code{\link{writeGwasVcf}}. \code{NULL} (default) omits +#' the column. It cannot be derived --- the input carries the values, not +#' what they measure. #' @param ... Reserved for future per-method arguments. #' #' @section The genotype scale: #' Individual-level genotypes reach every fit centred and scaled to unit #' variance, so a posterior effect --- which is the prediction weight --- is #' on the standardized scale, and the published -#' \code{weight_standardized} records it. That scaling belongs to the -#' \code{QtlDataset} accessors, not to this pipeline: it is -#' \code{\link{residualizedGenotypes}} that applies it, governed by -#' \code{ResidualizationParam(scaleResiduals = )} per call with the -#' dataset's own \code{\link{scaleResiduals}} slot as the default. One -#' mechanism, one place, shared with \code{\link{twasWeightsPipeline}} and +#' \code{weight_standardized} records it. The residualization that applies +#' it (\code{\link{residualizedGenotypes}}) is governed by +#' \code{ResidualizationParam(scaleResiduals = )}, which defaults to +#' \code{TRUE}. One mechanism, one place, shared with +#' \code{\link{twasWeightsPipeline}} and #' \code{\link{colocboostPipeline}}. An RSS fit needs nothing done: its #' likelihood is written in standardized units already. #' @@ -381,7 +397,8 @@ #' Each row records the LD reference its fit used: none for #' individual-level (QtlDataset / all-individual-level #' MultiStudyQtlDataset) fits, the reference of the input row it was fitted -#' from for RSS-derived fits. +#' from for RSS-derived fits. Its \code{seqinfo()} names the genome build +#' the inputs name; inputs naming different builds are refused. #' @examples #' data(qtlDatasetExample) #' fineMappingPipeline(qtlDatasetExample, methods = "susie", cisWindow = 1e6) @@ -760,11 +777,11 @@ setGeneric("fineMappingPipeline", function(data, ...) { # Reject SumStats inputs that have not been QC'd via summaryStatsQc. # @noRd .fmAssertQcd <- function(sumstats) { - if (length(qcInfo(sumstats)) == 0L) { + if (length(qcOptions(sumstats)) == 0L) { cls <- class(sumstats)[[1L]] msg <- glue( "fineMappingPipeline: the supplied {cls} has no QC record ", - "(qcInfo is empty). Call summaryStatsQc() first and pass the ", + "(qcOptions() is empty). Call summaryStatsQc() first and pass the ", "QC-applied result." ) abort(msg) @@ -878,12 +895,12 @@ setGeneric("fineMappingPipeline", function(data, ...) { return(NULL) } # Several rows share (study, method) when the study was split into blocks; - # the block key picks the one this lookup wants. - idx <- if (length(matched) == 1L) { - matched - } else { - matched[.rtlRangeKeys(fineMappingResult)[matched] == blockId] - } + # the block key picks the one this lookup wants. It is compared even when + # only one row matches: a cache holding one block of the study is no fit + # for any other block. + idx <- matched[which( + .rtlRangeKeys(fineMappingResult)[matched] == blockId + )] if (length(idx) == 0L) { return(NULL) } @@ -916,7 +933,7 @@ setGeneric("fineMappingPipeline", function(data, ...) { # DERIVED, never declared: it records what the accessors actually did. # `residualizedGenotypes()` scales each genotype column to unit variance # unless told otherwise -- `ResidualizationParam(scaleResiduals = FALSE)` - # per call, or the dataset's own `scaleResiduals` slot -- and an RSS fit's + # -- and an RSS fit's # likelihood is written in standardized units to begin with. mcols(x)$standardized <- rep(as.logical(standardized), length.out = n) x @@ -977,6 +994,7 @@ setGeneric("fineMappingPipeline", function(data, ...) { } per <- .anchorVector( cfg$data, + rep(studyName(cfg$data), length(traits)), rep(ctx, length(traits)), traits, "region", @@ -985,20 +1003,28 @@ setGeneric("fineMappingPipeline", function(data, ...) { range(per)[1L] } -# The per-row ANALYSIS WINDOW for a set of (context, trait) rows: the explicit -# `region` when the caller named one, else each trait's own cis window -# (traitPos +/- cisWindow) -- which is the interval the cis path actually -# slices X over, so a per-gene fit records its window just as a region-mode -# fit does. NULL when nothing resolves, so the builder omits the column and -# genomicRegion() falls back to the derived span. +# The per-row ANALYSIS WINDOW for a set of (study, context, trait) rows: the +# explicit `region` when the caller named one, else each trait's own cis +# window (traitPos +/- cisWindow) -- which is the interval the cis path +# actually slices X over, so a per-gene fit records its window just as a +# region-mode fit does. NULL when nothing resolves, so the builder omits the +# column and genomicRegion() falls back to the derived span. # @noRd -.fmRowWindows <- function(data, contexts, traits, region, cisWindow, n) { +.fmRowWindows <- function( + data, + studies, + contexts, + traits, + region, + cisWindow, + n +) { explicit <- .analysisWindowForRows(region, n) if (!is.null(explicit)) { return(explicit) } try_fetch( - .anchorVector(data, contexts, traits, "region", cisWindow), + .anchorVector(data, studies, contexts, traits, "region", cisWindow), error = function(cnd) NULL ) } @@ -1012,7 +1038,7 @@ setGeneric("fineMappingPipeline", function(data, ...) { methods, entries, blockIds = NULL, - region = NULL, + regions = NULL, ldReference = NULL, allowEmpty = FALSE ) { @@ -1023,14 +1049,17 @@ setGeneric("fineMappingPipeline", function(data, ...) { ) abort(msg) } - GwasFineMappingResult( + out <- GwasFineMappingResult( studyName = studies, method = methods, blockId = blockIds, entry = entries, - region = region, + region = regions$region, ldReference = ldReference ) + # The constructor counts every range it is handed as given; the run knows + # which of them its input was given and which it computed. + if (is.null(regions)) out else .withRegionColumns(out, regions) } # One QTL-side result row as an immutable record (study/context/trait/method @@ -1047,12 +1076,20 @@ setGeneric("fineMappingPipeline", function(data, ...) { ) } -# One GWAS-side result row as an immutable record (study/method/blockId + the -# FineMappingRow). blockId is provenance for the external block manifest; -# row identity comes from (study, method) plus the element's own range. +# One GWAS-side result row as an immutable record (study/method + the block +# the input row covers + the FineMappingRow). The block's id, range and +# whether that range was given are provenance; row identity comes from +# (study, method) plus the element's own range. # @noRd -.fmGwasRow <- function(studyName, method, blockId, entry) { - list(study = studyName, method = method, blockId = blockId, entry = entry) +.fmGwasRow <- function(studyName, method, block, entry) { + list( + study = studyName, + method = method, + blockId = block$id, + region = block$region, + regionGiven = block$given, + entry = entry + ) } # Effect-allele frequency vector aligned to `variantIds` from an entry's @@ -1069,32 +1106,29 @@ setGeneric("fineMappingPipeline", function(data, ...) { set_names(as.numeric(mc$AF), as.character(mc$SNP))[variantIds] } -# The block key for GWAS entry `i`: the one the caller SUPPLIED when the -# GwasSumStats carries it, else derived from the entry's variant span. -# -# GwasSumStats() always materializes a `blockId` column (from the entry names, -# a blockId metadata column, else coordinates), but it lives in the -# COLLECTION's mcols -- .collectionEntry() hands back the element alone, so -# deriving from that element silently discarded a supplied key and replaced a -# true block boundary (chr22_49355984_50799822) with the narrower span of the -# variants that survived QC (chr22_49363017_50598205). +# The block GWAS entry `i` covers: its name, its analysis window and whether +# that window was given. The window is the row's own `region` -- the one it +# was given, else the span of its variants as first built, before QC -- so a +# fit records the stretch its input stood for, not the narrower span of the +# variants that survived QC. # -# A supplied key is one that carries COORDINATES. GwasSumStats() always -# materializes a blockId, but with no `ldBlocks` manifest and no explicit -# `blockId` it falls back to the bare seqname ("chr22") -- which is the -# "nothing was specified" case, and is less informative than the span. Only a -# coordinate-bearing key (from a manifest or an explicit vector) overrides. -# @noRd -.fmGwasBlockId <- function(data, i, gr) { - supplied <- try_fetch( - as.character(.tupleColumn(data, "blockId")[[i]]), - error = function(cnd) NULL +# The name is the row's `blockId`, carried over as it is. It lives in the +# COLLECTION's mcols -- .collectionEntry() hands back the element alone -- so +# it is read off `data`. A row with none, in a collection saved before the +# column existed, is named by its span. +# @noRd +.fmGwasBlock <- function(data, i, gr, regions) { + list( + id = .fmGwasBlockName(.tupleColumn(data, "blockId")[i], gr), + region = regions$region[i], + given = regions$regionGiven[[i]] ) - if ( - length(supplied) == 1L && - !is.na(supplied) && - !is.null(.fmBlockIdRange(supplied)) - ) { +} + +# @noRd +.fmGwasBlockName <- function(supplied, gr) { + supplied <- as.character(supplied) + if (length(supplied) == 1L && !is.na(supplied)) { return(supplied) } .fmGwasRangeKey(gr) @@ -1125,71 +1159,35 @@ setGeneric("fineMappingPipeline", function(data, ...) { } } -# The window an RSS fit covered. -# -# A GWAS block's BOUNDARY is the one positional fact not recoverable from the -# variants -- adjacent blocks leave gaps, so the realized span is narrower than -# the block (a chr22_49355984_50799822 block whose variants span -# 49363017-50598205). The boundary survives only in `blockId`, so parse it when -# it carries coordinates. Failing that the fit's own variants define the -# window: a QtlSumStats entry has no separately-requested window at all. -# @noRd -.fmBlockIdRange <- function(blockId) { - if (is.null(blockId) || length(blockId) != 1L || is.na(blockId)) { - return(NULL) - } - # .asGRegion() owns both spellings ("chr1:100-200" and "chr1_100_200") - # and keeps the seqname verbatim, so the window matches the variants' - # chromosome naming. It aborts on anything that is not coordinates -- - # the "this blockId is an opaque label" case. - try_fetch(.asGRegion(as.character(blockId)), error = function(cnd) NULL) -} - -# Per-row windows for a GWAS collection, from each row's blockId -- which -# always spells coordinates (.fmGwasBlockId()): the block boundary when one -# was supplied, else the entry's own span. NULL when there are no rows, so the -# column is omitted. +# Per-row block ranges for a GWAS result, and whether each was given: the +# block's range when the input row was given one, else the span of the +# entry fitted (.fmGwasBlock()). NULL when there are no rows, so the column is +# omitted. # @noRd -.fmGwasRowWindows <- function(rows) { +.fmGwasRowRegions <- function(rows) { if (length(rows) == 0L) { return(NULL) } - exec(c, !!!map(map_chr(rows, "blockId"), .fmBlockIdRange)) -} - -# @noRd -.fmRssFitWindow <- function(entry, variantIds, blockId = NULL) { - fromBlock <- .fmBlockIdRange(blockId) - if (!is.null(fromBlock)) { - return(fromBlock) - } - # isS4 guard, not just try_fetch: base::range(NULL) WARNS rather than - # erroring, so an unguarded call leaks "no non-missing arguments" noise. - rg <- if (isS4(entry)) { - try_fetch(range(entry), error = function(cnd) NULL) - } else { - NULL - } - if (methods::is(rg, "GRanges") && length(rg) > 0L) { - return(rg[1L]) - } - try_fetch(.csVariantRegion(variantIds), error = function(cnd) NULL) + list( + region = unname(unlist(.rtlBindElements(map(rows, "region")))), + regionGiven = map_lgl(rows, "regionGiven") + ) } # Fit the still-to-run RSS tokens for one GWAS region and return one row-record # per fitted token. # @noRd -.fmGwasFitRows <- function(gr, zn, st, blockId, toRun, cfg) { +.fmGwasFitRows <- function(gr, zn, st, block, toRun, cfg) { ents <- .fmFitRssBlockP( set_names(zn$z, zn$variantIds), zn, toRun, - glue("GWAS (study='{st}', region='{blockId}')"), + glue("GWAS (study='{st}', region='{block$id}')"), .fmAfByVar(gr, zn$variantIds), cfg, - region = .fmRssFitWindow(gr, zn$variantIds, blockId) + region = block$region ) - map(names(ents), .fmGwasRowFor, st = st, blockId = blockId, ents = ents) + map(names(ents), .fmGwasRowFor, st = st, block = block, ents = ents) } # All result rows for one GwasSumStats entry: cache hits + freshly-fitted @@ -1218,10 +1216,10 @@ setGeneric("fineMappingPipeline", function(data, ...) { cutoffs = .panelCutoffs(cfg$panelFilterParam) ) # Two different things that used to be one: the key the resume cache - # matches on is always the entry's derived range, while the key stored as - # provenance is the manifest block boundary when one was supplied. + # matches on is always the entry's derived range, while the block stored + # as provenance is the one the caller gave when they gave one. rangeKey <- .fmGwasRangeKey(gr) - blockId <- .fmGwasBlockId(cfg$data, i, gr) + block <- .fmGwasBlock(cfg$data, i, gr, cfg$gwasRegions) lookups <- map( tokens, .fmGwasLookup, @@ -1233,11 +1231,11 @@ setGeneric("fineMappingPipeline", function(data, ...) { keep(lookups, .fmHasCached), .fmGwasRowFromLookup, st = st, - blockId = blockId + block = block ) toRun <- map_chr(keep(lookups, .fmNotCached), "tk") computed <- if (length(toRun) > 0L) { - .fmGwasFitRows(gr, zn, st, blockId, toRun, cfg) + .fmGwasFitRows(gr, zn, st, block, toRun, cfg) } list( rows = .recordsWithLdRef(c(cachedRows, computed), cfg$ldReference), @@ -1257,7 +1255,6 @@ setGeneric("fineMappingPipeline", function(data, ...) { ) } - # The fine-mapping settings shared by every summary-statistics path: the # QtlSumStats joint phase and the RSS / GWAS row builders all act on these. # Named once here so the records built from it cannot disagree about the same @@ -1373,7 +1370,7 @@ setGeneric("fineMappingPipeline", function(data, ...) { glue("(study='{st}', context='{ctx}', trait='{tr}')"), .fmAfByVar(entry, zn$variantIds), cfg, - region = .fmRssFitWindow(entry, zn$variantIds) + region = .rowRegionAt(cfg$data, i) ) map(names(ents), .fmQtlRowFor, st = st, ctx = ctx, tr = tr, ents = ents) } @@ -1477,75 +1474,56 @@ combineFineMappingResults <- function(..., ldReference = NULL) { .combineTupleCollections(parts, ldReference, "combineFineMappingResults") } - -# The selector arguments are named rather than carried in `...`: an omitted -# one must still fall through to the extractor's own default, so NULL entries -# are dropped instead of forwarded. discard(is.null), not compact(): compact() -# would also drop a legitimately zero-length `contexts` / `samples`. +# Residualized phenotypes for the fits, under the run's resolved phenotype QC +# (.qtlResolvePhenotypeFilter()); NULL applies none, as the accessor does. One +# context gives its matrix, several a list keyed by context. +# @noRd .fmResidPheno <- function( x, residualizationParam, contexts = NULL, traitId = NULL, - naAction = NULL + phenotypeFilter = NULL ) { - sel <- discard( - list(contexts = contexts, traitId = traitId, naAction = naAction), - is.null - ) - exec( - residualizedPhenotypes, - !!!c( - list( - x = x, - residualizationParam = residualizationParam %||% - ResidualizationParam() - ), - sel - ) + out <- .qtlResidualizedPhenotypes( + x, + contexts, + traitId, + phenotypeFilter = phenotypeFilter %||% .qtlKeepAllPhenotypes(), + residualizationParam = residualizationParam %||% ResidualizationParam() ) + if (length(contexts) == 1L) out[[1L]] else out } +# The residualized genotypes of one analysis window -- the cis window of +# `traitId` +/- `cisWindow`, or an explicit `region` -- over `samples`, under +# the run's resolved `genotypeFilter`. No default for the filter: a call site +# that forgot it must fail rather than extract unfiltered. +# @noRd .fmResidGeno <- function( x, residualizationParam, + genotypeFilter, contexts = NULL, traitId = NULL, region = NULL, cisWindow = NULL, samples = NULL ) { - sel <- discard( - list( - contexts = contexts, - traitId = traitId, - region = region, - cisWindow = cisWindow, - samples = samples - ), - is.null - ) - # No scaling step here: `residualizedGenotypes()` already returns columns - # scaled to unit variance, governed by - # `ResidualizationParam(scaleResiduals=)` with the dataset's own slot as - # the default. Adding a second one here would have been a parallel - # mechanism for something the accessor layer owns -- and would have - # covered only the callers that happen to come through this function, - # not `colocboostPipeline`, which calls the accessor directly. - exec( - residualizedGenotypes, - !!!c( - list( - x = x, - residualizationParam = residualizationParam %||% - ResidualizationParam() - ), - sel - ) + # No scaling step here: the residualizer already returns columns scaled + # to unit variance, governed by `ResidualizationParam(scaleResiduals=)`. + # A second one here would be a parallel mechanism for something the + # residualizer owns. + .qtlResidualizedGenotypes( + x, + contexts, + window = .qtlResolveVariantRegion(x, traitId, region, cisWindow), + samples = samples, + filter = genotypeFilter, + residualizationParam = residualizationParam %||% ResidualizationParam() ) } - # Directional effect-allele (A1) frequency for the variants in a fitted # genotype block `X` (samples x variants, post-residualization and post # sample-intersection). Re-extracts the allele frequency from the dataset @@ -1560,6 +1538,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { .fmAfForX <- function( data, X, + genotypeFilter, traitId = NULL, region = NULL, cisWindow = NULL @@ -1570,23 +1549,33 @@ combineFineMappingResults <- function(..., ldReference = NULL) { if (!is(data, "QtlDataset")) { return(NULL) } - afAll <- try_fetch( - if (is.null(region)) { - af( - data, - traitId = traitId, - cisWindow = cisWindow, - samples = rownames(X) - ) - } else { - af(data, region = region, samples = rownames(X)) - }, + block <- try_fetch( + .qtlExtractBlock( + data, + window = .fmAfWindow(data, traitId, region, cisWindow), + samples = rownames(X), + filter = genotypeFilter + ), error = function(cnd) NULL ) - if (is.null(afAll) || length(afAll) == 0L) { + if (is.null(block) || length(block$af) == 0L) { return(NULL) } - unname(afAll[colnames(X)]) + unname(set_names(block$af, block$variantIds)[colnames(X)]) +} + +# The window .fmAfForX() re-extracts: the explicit `region` when given (the +# trait is then only what the block was fit for), else the trait's cis window. +# @noRd +.fmAfWindow <- function(data, traitId, region, cisWindow) { + if (is.null(region)) { + return(.qtlResolveVariantRegion( + data, + traitId = traitId, + cisWindow = cisWindow + )) + } + .qtlResolveVariantRegion(data, region = region) } .fmPostprocessOne <- function( @@ -1665,22 +1654,18 @@ combineFineMappingResults <- function(..., ldReference = NULL) { # --- Multi-region (jointRegions) helpers ------------------------------------ # Resolve the per-trait X windows from a (region, jointRegions) pair. The cis -# path (region NULL) is a single trait-derived block; an explicit `region` is -# taken literally as one joint block (jointRegions=TRUE -> concatenated -# genotypes) or one block per range (jointRegions=FALSE -> independent fits -# merged downstream). Shared by the QtlDataset / MultiStudyQtlDataset -# fineMapping & twas methods. +# path (region NULL) is a single trait-derived block; an explicit `region`, a +# GRanges, is taken literally as one joint block (jointRegions=TRUE -> +# concatenated genotypes) or one block per range (jointRegions=FALSE -> +# independent fits merged downstream). Shared by the QtlDataset / +# MultiStudyQtlDataset fineMapping & twas methods. #' @keywords internal .makeXRegions <- function(region, jointRegions) { - # Accept a "chr:start-end" string / one-row data.frame as well as a GRanges - # (a GRanges passes through unchanged), so pipeline callers need not - # pre-parse. - if (!is.null(region)) { - region <- .asGRegion(region) - } if (is.null(region)) { - list(NULL) - } else if (isTRUE(jointRegions)) { + return(list(NULL)) + } + region <- .assertRegionGRanges(region) + if (isTRUE(jointRegions)) { list(region) } else { map(seq_along(region), .fmNthRegion, region = region) @@ -1705,17 +1690,26 @@ combineFineMappingResults <- function(..., ldReference = NULL) { invisible(NULL) } +# Fine-mapping's phenotype QC: a fit cannot take a missing phenotype, so an +# unset naAction drops the affected samples and "keep" is refused. +# @noRd +.fmResolvePhenotypeFilter <- function(phenotypeFilterParam) { + .qtlResolvePhenotypeFilter( + phenotypeFilterParam, + naDefault = "drop", + naAllowed = c("drop", "impute"), + caller = "fineMappingPipeline" + ) +} + # The MultiStudyQtlDataset inputs both pipelines resolve the same way: the -# region + cisWindow guard, the naAction choice and the joint-region spec. The -# per-call filter overrides are left to the components, which apply them to -# their own data. +# region + cisWindow guard and the joint-region spec. The genotype and +# phenotype filter bundles are left to the components, which resolve them +# against their own data. # @noRd -.msResolveInputs <- function(naAction, region, cisWindow, jointRegions, label) { +.msResolveInputs <- function(region, cisWindow, jointRegions, label) { .rejectRegionWithCisWindow(region, cisWindow, label) - list( - naAction = arg_match(naAction, c("drop", "impute")), - xRegions = .makeXRegions(region, jointRegions) - ) + list(xRegions = .makeXRegions(region, jointRegions)) } # Rows of a TwasWeights whose method is mr.mash and whose identity matches @@ -1985,7 +1979,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { str_c("region", seq_along(entries)) ) cvResult <- if (all(map_lgl(cvList, is.null))) NULL else cvList - fineMappingRow( + FineMappingRow( variantIds = variantIds, susieFit = susieFit, topLoci = topLoci, @@ -2130,11 +2124,10 @@ combineFineMappingResults <- function(..., ldReference = NULL) { # Whether entry `i` of a QC'd SumStats was deliberately screened out (and why), # so fineMappingPipeline can skip it gracefully instead of erroring on a # 0-variant entry. `summaryStatsQc(pipCutoffToSkip = ...)` empties a no-signal -# region and records qcInfo$entryAudit[[i]]$pipScreenSkipped (+ -# pipScreenReason); +# region and records pipScreenSkipped (+ pipScreenReason) in row i's QC audit; # an entry may also be empty for other reasons. Returns list(skipped, reason). .fmEntrySkipInfo <- function(data, i) { - ea <- try_fetch(qcInfo(data)$entryAudit[[i]], error = function(cnd) NULL) + ea <- .rowQcAudit(data, i) screened <- isTRUE(ea$pipScreenSkipped) entry <- .collectionEntry(data, i) empty <- is.null(entry) || length(entry) == 0L @@ -2383,7 +2376,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { verbose = 1, mvPrior = NULL, mvPriorCv = NULL, - numThreads = 1, + BPPARAM = SerialParam(), seed = NULL ) { if (length(tokens) == 0L) { @@ -2409,7 +2402,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { samplePartitions = samplePartition, fitFold = .fmFitFold, fitFoldCtx = cvFitCtx, - numThreads = numThreads, + BPPARAM = BPPARAM, verbose = verbose, seed = seed, # Retained so twasWeightsCv can cross-validate a SuSiE-family method: @@ -2479,7 +2472,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { if (is.null(entry) || is.null(cvResult)) { return(entry) } - fineMappingRow( + FineMappingRow( variantIds = .fmrPartsVariantIds(entry), susieFit = .fmrPartsSusieFit(entry), topLoci = .fmrPartsTopLoci(entry), @@ -2487,7 +2480,6 @@ combineFineMappingResults <- function(..., ldReference = NULL) { ) } - # ============================================================================= # Residualized genotype for one X window: the trait-derived cis block when # `rg` is NULL, else the explicit region. Shared by the univariate and PCA @@ -2500,7 +2492,8 @@ combineFineMappingResults <- function(..., ldReference = NULL) { samples, data, cisWindow, - residualizationParam + residualizationParam, + genotypeFilter ) { if (is.null(rg)) { .fmResidGeno( @@ -2509,7 +2502,8 @@ combineFineMappingResults <- function(..., ldReference = NULL) { traitId = traitId, cisWindow = cisWindow, samples = samples, - residualizationParam = residualizationParam + residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter ) } else { .fmResidGeno( @@ -2517,7 +2511,8 @@ combineFineMappingResults <- function(..., ldReference = NULL) { contexts = ctx, region = rg, samples = samples, - residualizationParam = residualizationParam + residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter ) } } @@ -2531,7 +2526,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { compact(map( tokens, .fmMergeTokenRow, - study = studyName, + studyName = studyName, ctx = ctx, trait = trait, blockEntries = blockEntries @@ -2540,7 +2535,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { # .fmFitXBlock with the many per-run knobs supplied from the config bundle `p`; # callers pass only the block-specific arguments (design, response, tokens, -# addSusieInf, context label, trait/PC label, allele frequencies). +# initializeWithSusieInf, context label, trait/PC label, allele frequencies). # @noRd .fmFitXBlockP <- function( X, @@ -2563,7 +2558,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { ctx, label, cvFolds = cfg$crossValidationParam$folds, - cvThreads = cfg$crossValidationParam$numThreads, + cvBpparam = cfg$crossValidationParam$BPPARAM, samplePartition = cfg$crossValidationParam$samplePartition, af = afVec, credibleSetParam = cfg$credibleSetParam, @@ -2586,7 +2581,8 @@ combineFineMappingResults <- function(..., ldReference = NULL) { rownames(Y), data = cfg$data, cisWindow = cfg$cisWindow, - residualizationParam = cfg$residualizationParam + residualizationParam = cfg$residualizationParam, + genotypeFilter = cfg$genotypeFilter ) xy <- .fmAlignXY(allX, Y, ctx, tid) X <- xy$X @@ -2603,6 +2599,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { afVec <- .fmAfForX( cfg$data, X, + genotypeFilter = cfg$genotypeFilter, traitId = tid, region = rg, cisWindow = cfg$cisWindow @@ -2645,14 +2642,14 @@ combineFineMappingResults <- function(..., ldReference = NULL) { cfg$univTokens, .fmUnivLookup, fineMappingResult = cfg$fineMappingResult, - study = cfg$study, + studyName = cfg$study, ctx = ctx, tid = tid ) cachedRows <- map( keep(lookups, .fmHasCached), .fmUnivCachedRow, - study = cfg$study, + studyName = cfg$study, ctx = ctx, tid = tid ) @@ -2664,7 +2661,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { cfg$data, contexts = ctx, traitId = tid, - naAction = cfg$naAction, + phenotypeFilter = cfg$phenotypeFilter, residualizationParam = cfg$residualizationParam ) blockEntries <- map( @@ -2692,7 +2689,8 @@ combineFineMappingResults <- function(..., ldReference = NULL) { samples, data = cfg$data, cisWindow = cfg$cisWindow, - residualizationParam = cfg$residualizationParam + residualizationParam = cfg$residualizationParam, + genotypeFilter = cfg$genotypeFilter ) common <- intersect(rownames(X), names(pcY)) if (length(common) < 2L) { @@ -2705,6 +2703,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { afVec <- .fmAfForX( cfg$data, Xb, + genotypeFilter = cfg$genotypeFilter, traitId = traits, region = rg, cisWindow = cfg$cisWindow @@ -2766,7 +2765,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { cfg$data, contexts = ctx, traitId = traits, - naAction = cfg$naAction, + phenotypeFilter = cfg$phenotypeFilter, residualizationParam = cfg$residualizationParam ) scores <- .fmTopPcScores(Yctx, cfg$nPCs) @@ -2798,11 +2797,14 @@ combineFineMappingResults <- function(..., ldReference = NULL) { # dispatch, and that a MultiStudyQtlDataset run hands each individual-level # component's joint dispatch. One builder, so a setting added for one path # reaches the others: the per-study joint dispatch used to assemble its own -# record and lost six settings that way. `data` is the dataset after its -# per-call filter overrides; `screen` is the resolved signal screen. +# record and lost six settings that way. `data` is the dataset narrowed to +# the filter's samples, `genotypeFilter` the run's resolved genotype filter +# (.qtlResolveFilter()), `screen` the resolved signal screen. # @noRd .fmIndividualJointCfg <- function( data, + genotypeFilter, + phenotypeFilter, contexts, traitId, cisWindow, @@ -2821,6 +2823,8 @@ combineFineMappingResults <- function(..., ldReference = NULL) { cvCfg <- .cvResolve(crossValidationParam) list( data = data, + genotypeFilter = genotypeFilter, + phenotypeFilter = phenotypeFilter, contexts = contexts, traitId = traitId, cisWindow = cisWindow, @@ -2838,10 +2842,9 @@ combineFineMappingResults <- function(..., ldReference = NULL) { ) } - -# Resolve the signal screen, apply per-call filter overrides to a validated -# copy of the dataset, and derive the X windows. Rejects the region + cisWindow -# combination. Returns `p` extended with data / screen / xRegions. +# Resolve the signal screen and the run's genotype filter, narrow the dataset +# to the filter's samples, and derive the X windows. Rejects the region + +# cisWindow combination. Returns data / screen / xRegions / genotypeFilter. # @noRd .fmQdsResolveInputs <- function( data, @@ -2852,7 +2855,8 @@ combineFineMappingResults <- function(..., ldReference = NULL) { jointRegions ) { screen <- .fmResolveScreen(signalScreenParam) - data <- .qtlApplyFilterOverrides(data, genotypeFilterParam) + genotypeFilter <- .qtlResolveFilter(genotypeFilterParam) + data <- .qtlRestrictSamples(data, genotypeFilter$keepSamples) .rejectRegionWithCisWindow( region, cisWindow, @@ -2861,7 +2865,8 @@ combineFineMappingResults <- function(..., ldReference = NULL) { list( data = data, screen = screen, - xRegions = .makeXRegions(region, jointRegions) + xRegions = .makeXRegions(region, jointRegions), + genotypeFilter = genotypeFilter ) } @@ -2947,30 +2952,6 @@ combineFineMappingResults <- function(..., ldReference = NULL) { list(tokens = remaining, methodArgs = methodArgs[remaining]) } -# Trait ids available in one context: the ones `traitId` selects there, else -# those overlapping the requested region (mirrors twasWeightsPipeline). A -# `traitId` that leaves this context out keeps all of its traits -- region -# picks traits only when no traitId is given at all. -# @noRd -.fmQdsTraitsForContext <- function(ctx, data, traitId, region) { - se <- molecularTraits(data, contexts = ctx) - allIds <- rownames(se) - ids <- if (!is.null(traitId)) { - intersect( - allIds, - .selectedTraits(traitId, studyName(data), ctx) %||% allIds - ) - } else if (!is.null(region)) { - allIds[IRanges::overlapsAny( - SummarizedExperiment::rowRanges(se), - region - )] - } else { - allIds - } - ids -} - # Resolve the study, the contexts to use, and the per-context trait lists. # `contexts` / `traitId` arrive parsed (parseContexts() / parseTraitIds()), # which is where requested contexts were checked. Returns `p` extended with @@ -2981,8 +2962,8 @@ combineFineMappingResults <- function(..., ldReference = NULL) { perCtxTraits <- set_names( map( useCtx, - .fmQdsTraitsForContext, - data = data, + .contextSelectedTraits, + qd = data, traitId = traitId, region = region ), @@ -3042,7 +3023,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { initializeWithSusieInf, methodArgs, nPCs, - naAction, + phenotypeFilter, perCtxTraits, studyName, univTokens, @@ -3055,7 +3036,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { initializeWithSusieInf = initializeWithSusieInf, methodArgs = methodArgs, nPCs = nPCs, - naAction = naAction, + phenotypeFilter = phenotypeFilter, perCtxTraits = perCtxTraits, study = studyName, univTokens = univTokens, @@ -3119,21 +3100,23 @@ combineFineMappingResults <- function(..., ldReference = NULL) { region = NULL, cisWindow = NULL ) { + rowStudy <- map_chr(rows, "study") rowContext <- map_chr(rows, "context") rowTrait <- map_chr(rows, "trait") perTupleResult <- if (length(rows) > 0L) { .fmBuildQtlResult( - map_chr(rows, "study"), + rowStudy, rowContext, rowTrait, map_chr(rows, "method"), map(rows, "entry"), traitPos = try_fetch( - .anchorVector(data, rowContext, rowTrait, "traitPos"), + .anchorVector(data, rowStudy, rowContext, rowTrait, "traitPos"), error = function(cnd) NULL ), region = .fmRowWindows( data, + rowStudy, rowContext, rowTrait, region, @@ -3177,7 +3160,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { jointResult, initializeWithSusieInf, nPCs, - naAction, + phenotypeFilter, usePCA ) { ctxInfo <- .fmQdsResolveContexts( @@ -3192,7 +3175,7 @@ combineFineMappingResults <- function(..., ldReference = NULL) { initializeWithSusieInf = initializeWithSusieInf, methodArgs = methodArgs, nPCs = nPCs, - naAction = naAction, + phenotypeFilter = phenotypeFilter, perCtxTraits = ctxInfo$perCtxTraits, studyName = ctxInfo$study, univTokens = split$univTokens, @@ -3222,8 +3205,8 @@ combineFineMappingResults <- function(..., ldReference = NULL) { # inside .fmFitXBlock / .fmFitRssBlock (which recompute # .fmResolveSusieChain), so no chain config is threaded here. # -# `genotypeFilterParam` is a per-call override; NULL uses the QtlDataset's -# construct-time slot value (applied lazily at extraction). The +# `genotypeFilterParam` is the run's genotype filter: its keepSamples narrows +# the dataset once, the rest applies per extracted block. The # CrossValidationParam bundle is the user-facing form; below it the cfg # plumbing (and the joint engine that reads it) keeps plain scalars. # `cfg` (.fmIndividualJointCfg()) holds the settings the joint phase and the @@ -3250,13 +3233,17 @@ combineFineMappingResults <- function(..., ldReference = NULL) { seed = NULL, mrmashPrior = NULL, dataDrivenPriorWeightsCutoff = 1e-10, - naAction = c("drop", "impute"), + phenotypeFilterParam = PhenotypeFilterParam(), verbose = 1, fitRetention = c("slim", "full"), dataType = NULL ) { fitRetention <- arg_match(fitRetention) - naAction <- arg_match(naAction, c("drop", "impute")) + phenotypeFilter <- .fmResolvePhenotypeFilter(phenotypeFilterParam) + build <- .inputsBuild( + list(data, region, fineMappingResult), + "fineMappingPipeline" + ) contexts <- parseContexts(contexts, data) traitId <- parseTraitIds(traitId, data) if (!is.null(seed)) { @@ -3272,6 +3259,8 @@ combineFineMappingResults <- function(..., ldReference = NULL) { ) cfg <- .fmIndividualJointCfg( data = resolved$data, + genotypeFilter = resolved$genotypeFilter, + phenotypeFilter = phenotypeFilter, contexts = contexts, traitId = traitId, cisWindow = cisWindow, @@ -3307,15 +3296,18 @@ combineFineMappingResults <- function(..., ldReference = NULL) { jointResult = rt$result, initializeWithSusieInf = initializeWithSusieInf, nPCs = nPCs, - naAction = naAction, + phenotypeFilter = phenotypeFilter, usePCA = usePCA ) } - .fmRecordProvenance( - out, - dataType, - "individual", - .qtlScaleResiduals(cfg$data, residualizationParam) + .withGenome( + .fmRecordProvenance( + out, + dataType, + "individual", + .qtlScaleResiduals(residualizationParam) + ), + build ) } @@ -3333,19 +3325,6 @@ setMethod( # MultiStudyQtlDataset method # ============================================================================= -# Whether a MultiStudyQtlDataset's JOINT rows are on the standardized scale. -# The per-call override settles it when given; otherwise the embedded studies' -# own slots do, and a collection whose studies disagree gets NA rather than a -# guess. -# @noRd -.fmMsScaleResiduals <- function(data, residualizationParam) { - if (!is.null(residualizationParam$scaleResiduals)) { - return(residualizationParam$scaleResiduals) - } - perStudy <- unique(map_lgl(qtlDatasets(data), scaleResiduals)) - if (length(perStudy) == 1L) perStudy else NA -} - # The `data_source` a MultiStudyQtlDataset run can state for its JOINT rows. # A collection always holds individual-level studies (its validity requires # one), and a joint fit spans the studies the specification selected, so when @@ -3366,24 +3345,24 @@ setMethod( return(NULL) } # `cfg` carries the parsed selection for every study; this study gets its - # own share, and a study with none of its contexts selected sits out. - s <- studyName(qd) - contexts <- .selectedContexts(cfg$contexts, s) - if (!is.null(contexts) && length(contexts) == 0L) { + # own share, and a study left with no trait selected in its selected + # contexts -- none of its contexts, none of the traits -- sits out. + if (!.studyHasSelectedTraits(qd, cfg$contexts, cfg$traitId, cfg$region)) { return(NULL) } + s <- studyName(qd) # Every setting is named. `cfg` also carries panelFilterParam and - # susieRssParam, - # which belong to the summary-statistics path: a study's own genotypes - # are filtered by genotypeFilterParam, so those two are deliberately not - # forwarded here. A name this entry point does not accept would be an - # "unused argument" error, so the only way this can go wrong is by - # OMITTING a setting -- which test_fineMappingPipeline.R pins. + # susieRssParam, which belong to the summary-statistics path: a study's + # own genotypes are filtered by genotypeFilterParam, so those two are + # deliberately not forwarded here. A name this entry point does not + # accept would be an "unused argument" error, so the only way this can + # go wrong is by OMITTING a setting -- which test_fineMappingPipeline.R + # pins. fineMappingPipeline( data = qd, methods = m, jointSpecification = NULL, - contexts = contexts, + contexts = .selectedContexts(cfg$contexts, s), traitId = .studyTraitIdArg(cfg$traitId, s), region = cfg$region, cisWindow = cfg$cisWindow, @@ -3395,7 +3374,7 @@ setMethod( crossValidationParam = cfg$crossValidationParam, residualizationParam = cfg$residualizationParam, seed = cfg$seed, - naAction = cfg$naAction, + phenotypeFilterParam = cfg$phenotypeFilterParam, signalScreenParam = cfg$signalScreenParam, genotypeFilterParam = cfg$genotypeFilterParam, usePCA = cfg$usePCA, @@ -3422,17 +3401,18 @@ setMethod( if (!any(keepRows)) { return(NULL) } - # Summary statistics carry no genotypes and no per-study region - # selection: the region is already baked into the input, and there is - # nothing to residualize, screen, cross-validate or PCA. `cfg` carries - # those settings for the individual-level sibling and they are not - # forwarded here. + # Summary statistics carry no genotypes: each tuple's window is in the + # input, narrowed by `cisWindow` around its trait position as on the + # QtlDataset side, and there is nothing to residualize, screen, + # cross-validate or PCA. `cfg` carries those settings for the + # individual-level sibling and they are not forwarded here. fineMappingPipeline( data = if (all(keepRows)) ss else ss[which(keepRows)], methods = m, jointSpecification = NULL, contexts = NULL, traitId = NULL, + cisWindow = cfg$cisWindow, initializeWithSusieInf = cfg$initializeWithSusieInf, credibleSetParam = cfg$credibleSetParam, fineMappingResult = cfg$fineMappingResult, @@ -3446,7 +3426,6 @@ setMethod( ) } - # The joint-specification phase for the MultiStudyQtlDataset path: dispatch # whatever the spec covers, narrow the tokens the joint fits consumed, and # report whether anything is left for the per-component recursion. @@ -3575,20 +3554,25 @@ setMethod( usePCA = FALSE, nPCs = 10L, seed = NULL, - naAction = c("drop", "impute"), + phenotypeFilterParam = PhenotypeFilterParam(), verbose = 1, fitRetention = c("slim", "full"), dataType = NULL ) { fitRetention <- arg_match(fitRetention) + # Resolved once here so a bad choice fails before any study runs; the + # record carries the bundle itself, as each component resolves its own. + .fmResolvePhenotypeFilter(phenotypeFilterParam) + build <- .inputsBuild( + list(data, region, fineMappingResult), + "fineMappingPipeline(MultiStudyQtlDataset)" + ) inputs <- .msResolveInputs( - naAction, region, cisWindow, jointRegions, "fineMappingPipeline(MultiStudyQtlDataset)" ) - naAction <- inputs$naAction if (!is.null(seed)) { withr::local_seed(as.integer(seed)) } @@ -3606,7 +3590,7 @@ setMethod( crossValidationParam = crossValidationParam, residualizationParam = residualizationParam, seed = seed, - naAction = naAction, + phenotypeFilterParam = phenotypeFilterParam, signalScreenParam = signalScreenParam, genotypeFilterParam = genotypeFilterParam, panelFilterParam = panelFilterParam, @@ -3618,6 +3602,7 @@ setMethod( dataDrivenPriorWeightsCutoff = dataDrivenPriorWeightsCutoff, dataType = dataType ) + .msAssertTraitsSelected(data, cfg, "fineMappingPipeline") jointCfg <- .fmMsJointCfg(cfg, data, inputs$xRegions) rt <- .fmMsResolveTokens( jointSpecification, @@ -3630,20 +3615,23 @@ setMethod( rt$result, dataType, .fmMsDataSource(data), - .fmMsScaleResiduals(data, residualizationParam) + .qtlScaleResiduals(residualizationParam) ) if (rt$done) { - return(jointResult) + return(.withGenome(jointResult, build)) } - .multiStudyPipelineDriver( - data, - jointResult, - .fmPerStudy, - .fmSumStats, - list_assign(cfg, methods = rt$methods), - .rbindFineMappingResult, - QtlFineMappingResult, - "fineMappingPipeline" + .withGenome( + .multiStudyPipelineDriver( + data, + jointResult, + .fmPerStudy, + .fmSumStats, + list_assign(cfg, methods = rt$methods), + .rbindFineMappingResult, + QtlFineMappingResult, + "fineMappingPipeline" + ), + build ) } @@ -3658,6 +3646,10 @@ setMethod( list_assign( .fmIndividualJointCfg( data = data, + genotypeFilter = .qtlResolveFilter(cfg$genotypeFilterParam), + phenotypeFilter = .fmResolvePhenotypeFilter( + cfg$phenotypeFilterParam + ), contexts = cfg$contexts, traitId = cfg$traitId, cisWindow = cfg$cisWindow, @@ -3712,7 +3704,6 @@ setMethod( ) } - # The joint-specification phase for the QtlSumStats path: dispatch whatever # the spec covers, narrow the tokens the joint fits consumed, and report # whether anything is left for the per-tuple loop. `done = TRUE` means the @@ -4132,20 +4123,22 @@ NULL if (length(rows) == 0L) { return(NULL) } + rowStudy <- map_chr(rows, "study") rowContext <- map_chr(rows, "context") rowTrait <- map_chr(rows, "trait") .fmBuildQtlResult( - map_chr(rows, "study"), + rowStudy, rowContext, rowTrait, map_chr(rows, "method"), map(rows, "entry"), traitPos = try_fetch( - .anchorVector(data, rowContext, rowTrait, "traitPos"), + .anchorVector(data, rowStudy, rowContext, rowTrait, "traitPos"), error = function(cnd) NULL ), region = .fmRowWindows( data, + rowStudy, rowContext, rowTrait, NULL, @@ -4191,16 +4184,38 @@ NULL ) } +# A QtlSumStats fine-mapping run's inputs: its data, checked for a QC record, +# and its selection parsed once, with `cisWindow` laid on the tuples selected. +# @noRd +.fmQssInputs <- function(data, contexts, traitId, cisWindow) { + .fmAssertQcd(data) + .qssSelection(data, contexts, traitId, cisWindow, "fineMappingPipeline") +} + # QtlSumStats fine-mapping worker. The resolved tokens, row selection and LD # sketch are ordinary locals, handed to the per-entry dispatch helpers as # named arguments. # @noRd +# The checks a summary-statistics fineMappingPipeline() method opens with -- +# cross-validation needs individual-level data, and the inputs must share a +# genome build -- returning that build. +# @noRd +.fmSumstatsBuild <- function(crossValidationParam, data, fineMappingResult) { + .cvRefuseOnSumstats( + crossValidationParam, + "fineMappingPipeline", + class(data)[[1L]] + ) + .inputsBuild(list(data, fineMappingResult), "fineMappingPipeline") +} + .fmPipelineQtlSumStats <- function( data, methods, initializeWithSusieInf, contexts, traitId, + cisWindow, jointSpecification, credibleSetParam, fineMappingResult, @@ -4212,18 +4227,16 @@ NULL panelFilterParam, dataType = NULL ) { - .fmAssertQcd(data) - contexts <- parseContexts(contexts, data) - traitId <- parseTraitIds(traitId, data) + inputs <- .fmQssInputs(data, contexts, traitId, cisWindow) cfgs <- .fmQssConfigs( - data = data, + data = inputs$data, credibleSetParam = credibleSetParam, fineMappingResult = fineMappingResult, fitRetention = fitRetention, verbose = verbose, panelFilterParam = panelFilterParam, - contexts = contexts, - traitId = traitId, + contexts = inputs$contexts, + traitId = inputs$traitId, mrmashPrior = mrmashPrior, dataDrivenPriorWeightsCutoff = dataDrivenPriorWeightsCutoff ) @@ -4235,11 +4248,11 @@ NULL cfgs$joint ) out <- .fmQssAfterJoint( - data, + inputs$data, rt = rt, cfgs = cfgs, - contexts = contexts, - traitId = traitId, + contexts = inputs$contexts, + traitId = inputs$traitId, initializeWithSusieInf = initializeWithSusieInf, susieRssParam = susieRssParam ) @@ -4333,6 +4346,7 @@ setMethod( methods, contexts = NULL, traitId = NULL, + cisWindow = NULL, jointSpecification = NULL, initializeWithSusieInf = TRUE, credibleSetParam = CredibleSetParam(), @@ -4348,17 +4362,14 @@ setMethod( dataType = NULL ) { fitRetention <- arg_match(fitRetention) - .cvRefuseOnSumstats( - crossValidationParam, - "fineMappingPipeline", - "QtlSumStats" - ) - .fmPipelineQtlSumStats( + build <- .fmSumstatsBuild(crossValidationParam, data, fineMappingResult) + res <- .fmPipelineQtlSumStats( data = data, methods = methods, initializeWithSusieInf = initializeWithSusieInf, contexts = contexts, traitId = traitId, + cisWindow = cisWindow, jointSpecification = jointSpecification, credibleSetParam = credibleSetParam, fineMappingResult = fineMappingResult, @@ -4370,6 +4381,7 @@ setMethod( panelFilterParam = panelFilterParam, dataType = dataType ) + .withGenome(res, build) } ) @@ -4422,10 +4434,9 @@ setMethod( # GwasSumStats fine-mapping worker. The resolved tokens, LD sketch and # finite-sample size are ordinary locals, handed to the per-entry dispatch -# helpers as named arguments. One GwasSumStats is one LD block (the caller -# builds one collection per block when sweeping the genome); we fine-map each -# (study, method) tuple across the whole entry, with no in-pipeline block -# partitioning. +# helpers as named arguments. Each row of the GwasSumStats -- an LD block when +# it was built with a `region`, else a chromosome -- is fine-mapped as one +# region, per method. # @noRd .fmPipelineGwas <- function( data, @@ -4440,6 +4451,7 @@ setMethod( dataType = NULL ) { .fmAssertQcd(data) + .fmWarnChromosomeRows(data) norm <- .fmNormalizeMethods( methods, maxNumSingleEffects = credibleSetParam$maxNumSingleEffects %||% 10L, @@ -4471,6 +4483,44 @@ setMethod( .fmRecordProvenance(out, dataType, "sumstat", TRUE) } +# The widest stretch a GWAS row can span and still read as an LD block. LD +# blocks run a few megabases; a chromosome's variants span over 30 Mb even on +# chr21 and chr22. +# @noRd +.FM_MAX_BLOCK_SPAN <- 2e7 + +# Fine-mapping is meant to run one LD block at a time. A row spanning a whole +# chromosome -- what a GwasSumStats built from genome-wide statistics without +# a `region` holds -- is rarely feasible to fit as one region. Only the caller +# knows what was loaded, so it is allowed, but said. +# @noRd +.fmWarnChromosomeRows <- function(data) { + spans <- range(data) + big <- which(sum(IRanges::width(spans)) > .FM_MAX_BLOCK_SPAN) + if (length(big) == 0L) { + return(invisible(NULL)) + } + shown <- big[seq_len(min(length(big), 5L))] + warn(glue( + "fineMappingPipeline: {length(big)} GWAS row(s) span more than ", + "{.FM_MAX_BLOCK_SPAN / 1e6} Mb, as a whole chromosome does ", + "({str_flatten(.fmChromosomeRowLabels(data, spans, shown), ', ')}", + "{if (length(big) > length(shown)) ', ...' else ''}). Each is ", + "fine-mapped as one region, which is rarely feasible; build the ", + "GwasSumStats with a `region` to fine-map it block by block." + )) +} + +# "study chrom_start_end" for each of the rows `idx`. +# @noRd +.fmChromosomeRowLabels <- function(data, spans, idx) { + str_c( + as.character(data$study)[idx], + map_chr(as.list(spans)[idx], .rtlOneRangeKey), + sep = " " + ) +} + # Fine-map every row of the GWAS collection and assemble the result. # @noRd .fmGwasRunEntries <- function( @@ -4487,11 +4537,14 @@ setMethod( .fmGwasEntryRows, studyCol = studyCol, tokens = tokens, - cfg = .fmRssRunCfg( - commonCfg, - initializeWithSusieInf = initializeWithSusieInf, - methodArgs = methodArgs, - susieRssParam = susieRssParam + cfg = list_assign( + .fmRssRunCfg( + commonCfg, + initializeWithSusieInf = initializeWithSusieInf, + methodArgs = methodArgs, + susieRssParam = susieRssParam + ), + gwasRegions = .rowRegions(data) ) ) rows <- list_flatten(map(entryOut, "rows")) @@ -4503,10 +4556,9 @@ setMethod( map_chr(rows, "method"), map(rows, "entry"), blockIds = map_chr(rows, "blockId"), - # The block BOUNDARY where blockId carries one, else the entry's span: - # the same window .fmRssFitWindow() gives the per-row grange columns, - # so the two cannot disagree. - region = .fmGwasRowWindows(rows), + # The same window each fit was given (.fmGwasBlock()), so the stored + # region and the fit's own cannot disagree. + regions = .fmGwasRowRegions(rows), ldReference = map(rows, "ldReference"), allowEmpty = (nSkipped > 0L || nrow(data) == 0L) ) @@ -4532,12 +4584,8 @@ setMethod( dataType = NULL ) { fitRetention <- arg_match(fitRetention) - .cvRefuseOnSumstats( - crossValidationParam, - "fineMappingPipeline", - "GwasSumStats" - ) - .fmPipelineGwas( + build <- .fmSumstatsBuild(crossValidationParam, data, fineMappingResult) + res <- .fmPipelineGwas( data = data, methods = methods, initializeWithSusieInf = initializeWithSusieInf, @@ -4549,6 +4597,7 @@ setMethod( panelFilterParam = panelFilterParam, dataType = dataType ) + .withGenome(res, build) } ) @@ -4585,13 +4634,13 @@ setMethod( } # @noRd -.fmGwasRowFor <- function(tk, st, blockId, ents) { - .fmGwasRow(st, tk, blockId, ents[[tk]]) +.fmGwasRowFor <- function(tk, st, block, ents) { + .fmGwasRow(st, tk, block, ents[[tk]]) } # @noRd -.fmGwasRowFromLookup <- function(l, st, blockId) { - .fmGwasRow(st, l$tk, blockId, l$cached) +.fmGwasRowFromLookup <- function(l, st, block) { + .fmGwasRow(st, l$tk, block, l$cached) } # @noRd @@ -4710,8 +4759,9 @@ setMethod( # postprocessFinemappingFits() -- so changing them needs a refit while a # stored fit can be re-post-processed under a different coverage. # -# `addSusieInf` is a standalone argument, not a bundle field: it selects a -# chained initialisation between methods rather than describing credible sets. +# `initializeWithSusieInf` is a standalone argument, not a bundle field: it +# selects a chained initialisation between methods rather than describing +# credible sets. # # `fitRetention` is a plain arg_match() enum on each pipeline, not a bundle: # see colocPipeline(), crossValidation() and fineMappingPipeline(). @@ -4974,10 +5024,12 @@ setValidity("CredibleSetParam", function(object) { #' \code{NULL} (the default) leaves the engine's own default in place. #' @return \code{CredibleSetParam} returns a \code{CredibleSetParam} #' object, a \code{\link{MethodParam}}. Each accessor returns that -#' setting's value; each replacement form returns a modified copy. -#' \code{maxNumSingleEffects} and \code{maxNumSingleEffectsGreedy} have -#' no replacement form: they are seeded onto the fitting tokens, so -#' changing one needs a refit rather than a re-summary. +#' setting's value. Change a setting with \code{x$ <- value} (the +#' field for \code{csCoverage()} is \code{coverage}), which returns a +#' modified copy; \code{maxNumSingleEffects} and +#' \code{maxNumSingleEffectsGreedy} cannot be changed that way: they are +#' seeded onto the fitting tokens, so changing one needs a refit rather +#' than a re-summary. #' @examples #' CredibleSetParam(coverage = 0.9, includeAllCs = TRUE) #' @export @@ -5008,82 +5060,30 @@ CredibleSetParam <- function( } # --- CredibleSetParam accessors -------------------------------------------- -# Setters revalidate: slot assignment checks the declared type on its own but -# does not re-run a validity method, and this package does write those (see -# SignalScreenParam). #' @rdname CredibleSetParam setMethod("csCoverage", "CredibleSetParam", function(x) x@coverage) -#' @rdname CredibleSetParam -setReplaceMethod("csCoverage", "CredibleSetParam", function(x, value) { - x@coverage <- value - validObject(x) - x -}) - #' @rdname CredibleSetParam setMethod("secondaryCoverage", "CredibleSetParam", function(x) { x@secondaryCoverage }) -#' @rdname CredibleSetParam -setReplaceMethod("secondaryCoverage", "CredibleSetParam", function(x, value) { - x@secondaryCoverage <- value - validObject(x) - x -}) - #' @rdname CredibleSetParam setMethod("signalCutoff", "CredibleSetParam", function(x) x@signalCutoff) -#' @rdname CredibleSetParam -setReplaceMethod("signalCutoff", "CredibleSetParam", function(x, value) { - x@signalCutoff <- value - validObject(x) - x -}) - #' @rdname CredibleSetParam setMethod("minAbsCorr", "CredibleSetParam", function(x) x@minAbsCorr) -#' @rdname CredibleSetParam -setReplaceMethod("minAbsCorr", "CredibleSetParam", function(x, value) { - x@minAbsCorr <- value - validObject(x) - x -}) - #' @rdname CredibleSetParam setMethod("medianAbsCorr", "CredibleSetParam", function(x) x@medianAbsCorr) -#' @rdname CredibleSetParam -setReplaceMethod("medianAbsCorr", "CredibleSetParam", function(x, value) { - x@medianAbsCorr <- value - validObject(x) - x -}) - #' @rdname CredibleSetParam setMethod("includeAllCs", "CredibleSetParam", function(x) x@includeAllCs) -#' @rdname CredibleSetParam -setReplaceMethod("includeAllCs", "CredibleSetParam", function(x, value) { - x@includeAllCs <- value - validObject(x) - x -}) - #' @rdname CredibleSetParam setMethod("perCsColumns", "CredibleSetParam", function(x) x@perCsColumns) -#' @rdname CredibleSetParam -setReplaceMethod("perCsColumns", "CredibleSetParam", function(x, value) { - x@perCsColumns <- value - validObject(x) - x -}) - #' @rdname CredibleSetParam setMethod("maxNumSingleEffects", "CredibleSetParam", function(x) { x@maxNumSingleEffects diff --git a/R/fineMappingRow.R b/R/fineMappingRow.R index 793f7681..8824150d 100644 --- a/R/fineMappingRow.R +++ b/R/fineMappingRow.R @@ -22,13 +22,20 @@ NULL #' @title Fine-Mapping Row #' @description One row's worth of fine-mapping: the variants and the stored -#' fit. Build one with \code{\link{fineMappingRow}} and pass a list of them +#' fit. Build one with \code{\link{FineMappingRow}} and pass a list of them #' as a collection's \code{entry} argument. #' @slot variants A \code{GRanges} of the fit's variants whose metadata #' columns are the per-variant \code{topLoci} values. #' @slot susieFit The stored fine-mapping fit, or \code{NULL}. #' @slot cvResult Cross-validation payload, or \code{NULL}. -#' @seealso \code{\link{fineMappingRow}}, +#' @slot fitVariants The ids of the variants the stored fit was made with, in +#' the fit's own order, recorded when the row is built; empty for a row with +#' no fit. A row narrowed to fewer variants keeps them, which is how reading +#' the fit can tell it describes more variants than the row now holds. +#' @section Coercion: \code{as(x, "GRanges")} gives the row's variants with +#' their per-variant \code{topLoci} columns: the element a collection +#' stores for it. +#' @seealso \code{\link{FineMappingRow}}, #' \code{\linkS4class{TwasWeightsRow}} #' @export setClass( @@ -36,9 +43,10 @@ setClass( representation( variants = "GRanges", susieFit = "ANY", - cvResult = "ANY" + cvResult = "ANY", + fitVariants = "character" ), - prototype(susieFit = NULL, cvResult = NULL) + prototype(susieFit = NULL, cvResult = NULL, fitVariants = character(0)) ) #' @importFrom checkmate makeAssertCollection assertList @@ -78,19 +86,19 @@ methods::setValidity("FineMappingRow", function(object) { #' \code{variantIds}. #' @param cvResult Optional cross-validation payload. #' @return A \code{\linkS4class{FineMappingRow}}. -#' @seealso \code{\link{twasWeightsRow}} +#' @seealso \code{\link{TwasWeightsRow}} #' @examples #' tl <- data.frame( #' variant_id = c("chr1:100:A:G", "chr1:200:C:T"), #' pip = c(0.9, 0.1) #' ) -#' row <- fineMappingRow(tl$variant_id, susieFit = list(), topLoci = tl) +#' row <- FineMappingRow(tl$variant_id, susieFit = list(), topLoci = tl) #' QtlFineMappingResult( #' studyName = "s1", context = "c1", trait = "g1", method = "susie", #' entry = list(row) #' ) #' @export -fineMappingRow <- function(variantIds, susieFit, topLoci, cvResult = NULL) { +FineMappingRow <- function(variantIds, susieFit, topLoci, cvResult = NULL) { vids <- as.character(variantIds) bare <- .variantIdsToGRanges(vids, "variantIds") tl <- as_tibble(topLoci) @@ -113,14 +121,14 @@ fineMappingRow <- function(variantIds, susieFit, topLoci, cvResult = NULL) { .fmRowCheckIdOrder(vids, as.character(tl$variant_id)) } gr <- .fmRowAttachPayload(bare, tl) - obj <- new( + fitted <- length(susieFit) > 0L || !is.null(cvResult) + new( "FineMappingRow", variants = gr, susieFit = susieFit, - cvResult = cvResult + cvResult = cvResult, + fitVariants = if (fitted) .grVariantIds(bare) else character(0) ) - validObject(obj) - obj } # The row a cross-validation-only fit leaves (CrossValidationParam(fitFullData = @@ -129,7 +137,7 @@ fineMappingRow <- function(variantIds, susieFit, topLoci, cvResult = NULL) { # a resume cache only reuses them for another cross-validation-only run. # @noRd .fmCvOnlyRow <- function(cvResult = NULL) { - fineMappingRow( + FineMappingRow( variantIds = character(0), susieFit = NULL, topLoci = tibble(), @@ -187,7 +195,7 @@ fineMappingRow <- function(variantIds, susieFit, topLoci, cvResult = NULL) { (!is.null(fit$fitted_wc2) && !is.null(fit$alpha))) } -# Chromosome of the fit's variants (matches topLoci's `chrom`, no "chr"). +# Chromosome of the fit's variants, as topLoci's `chrom` spells it. # @noRd .fsusieChrom <- function(fit) { vid <- names(fit$csd_X) @@ -857,28 +865,61 @@ fineMappingRow <- function(variantIds, susieFit, topLoci, cvResult = NULL) { !(inCs & !is.na(pur) & pur < minPurity) } -# Project a posterior-view data.frame to GRanges (empty GRanges when empty). +# A tabular view handed back as a Bioconductor DataFrame. The views assemble +# tibbles (dplyr is how they are built); a table attached to an S4 result is +# a DataFrame, as mcols() and colData() are, so the conversion happens once, +# at the accessor. check.names = FALSE keeps names such as PP.H4.abf. +# @noRd +.asViewDataFrame <- function(tbl) { + S4Vectors::DataFrame(tbl, check.names = FALSE) +} + +# A per-variant table as ranges: one width-1 range per row at the position its +# `variant_id` names, every column kept as mcols. topLoci(), credibleSets(), +# marginalEffects() and lbf() all convert through here once their rows are +# stacked, so the aggregate form is a GRanges as well as the single-entry +# one, and either narrows with subsetByOverlaps(). # @noRd -.fmeTopLociGRanges <- function(out) { +.variantTableGRanges <- function(out) { if (is.null(out)) { return(GenomicRanges::GRanges()) } - # Keep the column schema when there are no retained variants, so an - # empty result is inspectable the same way a populated one is. if (nrow(out) == 0L) { - return(S4Vectors::`mcols<-`( - GenomicRanges::GRanges(), - value = S4Vectors::DataFrame(out) - )) + return(.emptyTableGRanges(out)) } parsed <- parseVariantId(out$variant_id) gr <- GenomicRanges::GRanges( - seqnames = str_c("chr", parsed$chrom), + seqnames = parsed$chrom, ranges = IRanges::IRanges(start = parsed$pos, width = 1L) ) S4Vectors::`mcols<-`(gr, value = S4Vectors::DataFrame(out)) } +# An fSuSiE credible-band table as ranges: one width-1 range per grid point, +# on the chromosome and at the position its `chrom` / `pos` columns give -- +# the same placement fsusieAffectedRegions() uses for its regions. +# @noRd +.bandTableGRanges <- function(out) { + if (nrow(out) == 0L) { + return(.emptyTableGRanges(out)) + } + gr <- GenomicRanges::GRanges( + seqnames = out$chrom, + ranges = IRanges::IRanges(start = as.integer(out$pos), width = 1L) + ) + S4Vectors::`mcols<-`(gr, value = S4Vectors::DataFrame(out)) +} + +# An empty table as an empty GRanges that keeps the column schema, so an +# empty result is inspectable the same way a populated one is. +# @noRd +.emptyTableGRanges <- function(out) { + S4Vectors::`mcols<-`( + GenomicRanges::GRanges(), + value = S4Vectors::DataFrame(out) + ) +} + # Match the entry's variants to `keepVariants` by (chrom, pos, allele) so a # chr-prefix / separator difference does not read as no-overlap. PIP / LBF are @@ -897,6 +938,21 @@ fineMappingRow <- function(variantIds, susieFit, topLoci, cvResult = NULL) { sort(m$idxA) } +# Where each of `common` sits among the variables `fitted` the fit was made +# with. An element replaced through `[[<-` can hold a variant its fit never +# had, which leaves no column to restrict to. +# @noRd +.adjustPipsFitIdx <- function(common, fitted) { + idx <- .fitColumnOf(common, fitted) + if (anyNA(idx)) { + abort(glue( + "adjustPips: {sum(is.na(idx))} of the row's variants are not ", + "among the {length(fitted)} its fit was made with." + )) + } + idx +} + # Restrict the SuSiE fit to `keepIdx` and renormalize every single-effect # posterior over the retained variants. # @noRd @@ -1582,9 +1638,15 @@ fineMappingRow <- function(variantIds, susieFit, topLoci, cvResult = NULL) { #' @noRd setMethod("adjustPips", "FineMappingRow", function(x, keepVariants) { vids <- variantIds(x) - keepIdx <- .adjustPipsKeepIdx(vids, keepVariants) - common <- vids[keepIdx] - fit <- .adjustPipsSubsetFit(susieFit(x), keepIdx, length(vids)) + common <- vids[.adjustPipsKeepIdx(vids, keepVariants)] + # The fit's columns are its own variables, which a row narrowed since + # holds only some of, so the kept variants are found in it by id. + fitted <- .partsFitIds(x) + fit <- .adjustPipsSubsetFit( + susieFit(x), + .adjustPipsFitIdx(common, fitted), + length(fitted) + ) newTopLoci <- .adjustPipsRebuildTopLoci( .fmeTopLociFromElement(variants(x)), fit, @@ -1592,7 +1654,7 @@ setMethod("adjustPips", "FineMappingRow", function(x, keepVariants) { ) # cvResult is sample-indexed (partition + held-out predictions), not # variant-indexed, so it carries through a variant-subsetting unchanged. - fineMappingRow( + FineMappingRow( variantIds = common, susieFit = fit, topLoci = newTopLoci, @@ -1618,6 +1680,9 @@ setMethod("susieFit", "FineMappingRow", function(x) x@susieFit) #' @export setMethod("cvResult", "FineMappingRow", function(x) x@cvResult) +# @noRd +.fmRowFitVariants <- function(x) x@fitVariants + #' @rdname show-methods #' @export setMethod("show", "FineMappingRow", function(object) { @@ -1647,3 +1712,10 @@ setGeneric("variants", function(x, ...) standardGeneric("variants")) # @noRd setMethod("variants", "FineMappingRow", function(x) x@variants) + +#' @rdname FineMappingRow-class +#' @name coerce,FineMappingRow,GRanges-method +#' @aliases coerce,FineMappingRow,GRanges-method +#' @usage NULL +#' @exportMethod coerce +setAs("FineMappingRow", "GRanges", function(from) variants(from)) diff --git a/R/fineMappingWrappers.R b/R/fineMappingWrappers.R index cf29ed66..83e5f1da 100644 --- a/R/fineMappingWrappers.R +++ b/R/fineMappingWrappers.R @@ -297,8 +297,8 @@ fitSusieInfThenSusie <- function( #' @param otherQuantities Optional named list of extra per-method quantities to #' carry on the result untouched (returned as the \code{otherQuantities} #' element). Default \code{NULL}. -#' @param region Optional \code{"chr:start-end"} string naming the region the -#' fits cover; recorded on the result. Default \code{NULL}. +#' @param region Optional \code{GRanges}: the window the fits cover, recorded +#' on the result. Default \code{NULL}. #' @param priorEffTol Numeric (length 1). Effects whose prior variance #' \code{V} is at or below this tolerance are dropped as unconverged before #' the credible sets are read. Default \code{1e-9}. @@ -624,7 +624,7 @@ postprocessFinemappingFit.susiF <- function( trim, priorEffTol ) { - fmEntry <- fineMappingRow( + fmEntry <- FineMappingRow( variantIds = variantNames, susieFit = .ppStoredFit( csTables, @@ -1091,7 +1091,10 @@ computeCsTable <- function( # order; errors if any fit variant is absent (a missing one would misalign the # 1..p credible-set indices with a shrunken genotype matrix). .csGenotypesForFit <- function(qtlDataset, variantIds) { - geno <- genotypes(qtlDataset, region = .csVariantRegion(variantIds)) + geno <- .qtlExtractBlock( + qtlDataset, + window = .csVariantRegion(variantIds) + )$geno absent <- setdiff(variantIds, colnames(geno)) if (length(absent) > 0L) { abort(glue( @@ -1108,7 +1111,10 @@ setMethod( "computeCsCorrelation", signature(x = "FineMappingResultBase", ldSource = "SumStatsBase"), function(x, ldSource) { - .rowCsCorrelationSumstats(.asFmRowPayload(x), ldSource) + .rowCsCorrelationSumstats( + .fitCoverageChecked(.asFmRowPayload(x), "computeCsCorrelation()"), + ldSource + ) } ) @@ -1121,8 +1127,10 @@ setMethod( } ldReference <- .csSumstatsLdRef(ldSource) # onMissing = "error": every fit variant must be in the panel, else the - # 1..p sets$cs indices would misalign with a shrunken LD matrix. - ids <- .fmrPartsVariantIds(parts) + # 1..p sets$cs indices would misalign with a shrunken LD matrix. The + # indices are the fit's, so the ids are too, even for a row narrowed + # since. + ids <- .partsFitIds(parts) label <- "computeCsCorrelation" if (inherits(fit, "susiF")) { return(.fsusieCsCorrelationLd(fit$cs, ldReference, ids, label)) @@ -1171,7 +1179,10 @@ setMethod( "computeCsCorrelation", signature(x = "FineMappingResultBase", ldSource = "QtlDataset"), function(x, ldSource) { - .rowCsCorrelationGeno(.asFmRowPayload(x), ldSource) + .rowCsCorrelationGeno( + .fitCoverageChecked(.asFmRowPayload(x), "computeCsCorrelation()"), + ldSource + ) } ) @@ -1182,7 +1193,7 @@ setMethod( if (.csCountBelowTwo(fit)) { return(NULL) } - geno <- .csGenotypesForFit(ldSource, .fmrPartsVariantIds(parts)) + geno <- .csGenotypesForFit(ldSource, .partsFitIds(parts)) if (inherits(fit, "susiF")) { if (!requireNamespace("fsusieR", quietly = TRUE)) { abort(glue( @@ -1567,7 +1578,8 @@ setMethod( #' carries no sample count: \code{n} is left \code{NA} for the per-variant #' \code{n} argument to fill. #' @param otherQuantities Optional list. Default is NULL. -#' @param region Optional \code{"chr:start-end"} string. Default is NULL. +#' @param region Optional \code{GRanges}: the window the fit covers, whose +#' bounds the table records. Default is NULL. #' @param conditionIdx Integer or \code{NULL}. Index of the conditioned effect #' (per-condition output); \code{NULL} for the unconditioned fit. #' @param credibleSetParam How credible sets are built and reported, built with @@ -2327,35 +2339,19 @@ buildTopLoci <- function( ) } -.parseGrange <- function(regionStr) { - # Every in-package source of a window is a GRanges (the pipeline's - # `region`, an X block's own range); only the documented user-facing form - # is a string. Normalize here so no caller has to. - if (methods::is(regionStr, "GRanges")) { - if (length(regionStr) == 0L) { - return(c(start = NA_integer_, end = NA_integer_)) - } - return(c( - start = as.integer(GenomicRanges::start(regionStr)[[1L]]), - end = as.integer(GenomicRanges::end(regionStr)[[1L]]) - )) - } - if ( - is.null(regionStr) || - length(regionStr) == 0L || - is.na(regionStr) || - str_length(as.character(regionStr)) == 0L - ) { +# The bounds the top-loci table records for the window the fits cover: a +# GRanges, as every source of one is (the pipeline's `region`, an X block's +# own range, a caller's), or NA bounds when there is none. +# @noRd +.parseGrange <- function(region) { + if (is.null(region) || length(region) == 0L) { return(c(start = NA_integer_, end = NA_integer_)) } - pr <- try_fetch( - parseRegion(as.character(regionStr)), - error = function(cnd) NULL + .assertRegionGRanges(region) + c( + start = as.integer(GenomicRanges::start(region)[[1L]]), + end = as.integer(GenomicRanges::end(region)[[1L]]) ) - if (is.null(pr) || !is.data.frame(pr)) { - return(c(start = NA_integer_, end = NA_integer_)) - } - c(start = as.integer(pr$start), end = as.integer(pr$end)) } trimFinemappingFit <- function(fit, effectIdx, method, csTables) { @@ -4050,7 +4046,9 @@ mergeSusieCs <- function(fineMappingResult, coverage = 0.95) { #' #' Returns the trimmed model fit underlying \code{conData$finemappingEntry} (a #' \code{FineMappingRow}, or a single-row fine-mapping result), or NULL if no -#' fine-mapping entry is attached. +#' fine-mapping entry is attached. As \code{\link{susieFit}} does, it warns +#' (condition class \code{pecotmrFitCoverage}) when the entry holds fewer +#' variants than its fit was made with. #' #' @param conData List. The method-layer entry from a finemapping pipeline #' result, expected to carry \code{$finemappingEntry} as a @@ -4074,6 +4072,7 @@ susieResult <- function(conData) { if (!is(fm, "FineMappingRow") && !is(fm, "FineMappingResultBase")) { return(NULL) } + fm <- .fitCoverageChecked(.asFmRowPayload(fm), "susieResult()") trimmed <- .fmrPartsSusieFit(fm) if (length(trimmed) == 0) { return(NULL) @@ -4086,7 +4085,7 @@ susieResult <- function(conData) { #' This function extracts and processes information for each Credible Set (CS) #' from finemapping results, typically obtained from a finemapping RDS file. #' -#' @param fmRow A \code{\link{fineMappingRow}}, or a single-row +#' @param fmRow A \code{\link{FineMappingRow}}, or a single-row #' fine-mapping collection as returned by #' \code{\link{fineMappingResult}}, carrying the SuSiE fit and #' variant ids. @@ -4132,7 +4131,7 @@ susieResult <- function(conData) { #' fit <- list(pip = c(0.1, 0.7, 0.2), sets = list(cs = list(L_1 = c(1, 2)))) #' tl <- data.frame(variant_id = vids, pip = c(0.1, 0.7, 0.2), #' z = c(1.0, 3.5, -0.5)) -#' fe <- fineMappingRow(variantIds = vids, susieFit = fit, topLoci = tl) +#' fe <- FineMappingRow(variantIds = vids, susieFit = fit, topLoci = tl) #' # A single credible set has no between-CS correlation (cs_corr_* are NA), so #' # the ldSource is not consulted here. #' extractCsInfo(fe, csNames = "L_1", topLociTable = tl, @@ -4142,9 +4141,11 @@ susieResult <- function(conData) { #' @export extractCsInfo <- function(fmRow, csNames, topLociTable, ldSource) { assertCharacter(csNames, any.missing = FALSE) - fm <- fmRow + # The credible sets index the fit's own variables, so they are named by + # the ids the fit was made with rather than the ones the row holds now. + fm <- .fitCoverageChecked(.asFmRowPayload(fmRow), "extractCsInfo()") trimmed <- .fmrPartsSusieFit(fm) - variantNames <- .fmrPartsVariantIds(fm) + variantNames <- .partsFitIds(fm) csCorr <- .rowCsCorrelation(fm, ldSource) rows <- map( seq_along(csNames), @@ -4163,7 +4164,7 @@ extractCsInfo <- function(fmRow, csNames, topLociTable, ldSource) { #' Posterior Inclusion Probability (PIP) from finemapping results, typically #' used when no Credible Sets (CS) are identified in the analysis. #' -#' @param fmRow A \code{\link{fineMappingRow}}, or a single-row +#' @param fmRow A \code{\link{FineMappingRow}}, or a single-row #' fine-mapping collection as returned by #' \code{\link{fineMappingResult}}, carrying the SuSiE fit and #' variant ids. @@ -4199,15 +4200,15 @@ extractCsInfo <- function(fmRow, csNames, topLociTable, ldSource) { #' vids <- c("chr1:100:A:G", "chr1:200:C:T", "chr1:300:G:A") #' fit <- list(pip = c(0.1, 0.7, 0.2)) #' tl <- data.frame(variant_id = vids, pip = c(0.1, 0.7, 0.2)) -#' fe <- fineMappingRow(variantIds = vids, susieFit = fit, topLoci = tl) +#' fe <- FineMappingRow(variantIds = vids, susieFit = fit, topLoci = tl) #' extractTopPipInfo(fe, sumstats = list(z = c(1.0, 3.5, -0.5))) #' #' @importFrom checkmate assertClass #' @export extractTopPipInfo <- function(fmRow, sumstats) { - fm <- fmRow + fm <- .fitCoverageChecked(.asFmRowPayload(fmRow), "extractTopPipInfo()") trimmed <- .fmrPartsSusieFit(fm) - variantNames <- .fmrPartsVariantIds(fm) + variantNames <- .partsFitIds(fm) # Find the variant with the highest PIP topPipIndex <- which.max(trimmed$pip) topPip <- trimmed$pip[topPipIndex] @@ -4622,7 +4623,7 @@ extractTopPipInfo <- function(fmRow, sumstats) { ctx, tid, cvFolds = 0, - cvThreads = 1, + cvBpparam = SerialParam(), samplePartition = NULL, af = NULL, fitRetention = "slim", @@ -4652,7 +4653,7 @@ extractTopPipInfo <- function(fmRow, sumstats) { coverage = credibleSetParam$coverage, methodArgs = methodArgs, cvFolds = cvFolds, - cvThreads = cvThreads, + cvBpparam = cvBpparam, samplePartition = samplePartition, seed = seed, verbose = verbose, @@ -4766,7 +4767,7 @@ extractTopPipInfo <- function(fmRow, sumstats) { coverage, methodArgs, cvFolds, - cvThreads, + cvBpparam, samplePartition, seed, verbose, @@ -4792,7 +4793,7 @@ extractTopPipInfo <- function(fmRow, sumstats) { samplePartition = samplePartition, coverage = coverage, verbose = verbose, - numThreads = cvThreads, + BPPARAM = cvBpparam, seed = seed ) set_names( @@ -5120,7 +5121,7 @@ extractTopPipInfo <- function(fmRow, sumstats) { # A row is immutable: rebuild it with the amended fit rather than # assigning into it. The variants and topLoci are unchanged, so this # round-trips them through the same builder the caller used. - fineMappingRow( + FineMappingRow( variantIds = variantIds(ent), susieFit = sf, topLoci = .fmrPartsTopLoci(ent), @@ -5881,7 +5882,7 @@ krigingOutlierQc <- function( fit = fit ) GenomicRanges::GRanges( - seqnames = str_c("chr", str_remove(chrom, "^chr")), + seqnames = chrom, ranges = IRanges::IRanges( start = as.integer(reg$Start), end = as.integer(reg$End) diff --git a/R/genotypeIo.R b/R/genotypeIo.R index 0fdb4fea..0ab54c6a 100644 --- a/R/genotypeIo.R +++ b/R/genotypeIo.R @@ -55,7 +55,7 @@ setMethod( pvar = NULL, psam = NULL, ldMeta = NULL, - region = NULL, + block = NULL, genoMeta = NULL, chroms = NULL, format = NULL, @@ -74,7 +74,7 @@ setMethod( pvar = pvar, psam = psam, ldMeta = ldMeta, - region = region, + block = block, genoMeta = genoMeta, chroms = chroms, format = format, @@ -98,7 +98,7 @@ setMethod( pvar = NULL, psam = NULL, ldMeta = NULL, - region = NULL, + block = NULL, genoMeta = NULL, chroms = NULL, format = NULL, @@ -112,7 +112,7 @@ setMethod( pvar = pvar, psam = psam, ldMeta = ldMeta, - region = region + block = block ) sources <- .ghResolveSources( path = NULL, @@ -134,7 +134,7 @@ setMethod( plink2Triplet = .genotypeExperiment( .genotypeHandleFromPlink2Triplet(pgen, pvar, psam) ), - ldMeta = .ghLdPathToPanel(.ghResolveLdPath(ldMeta, region), vcfArgs), + ldMeta = .ghLdPathToPanel(.ghResolveLdPath(ldMeta, block), vcfArgs), genoMeta = .chromMetaPanel(genoMeta, chroms, format) ) } @@ -255,7 +255,7 @@ setMethod( # readPvar returns: chrom, id, pos, A2 (REF), A1 (ALT) -- pecotmr convention snpInfo <- tibble( SNP = vi$id, - CHR = as.character(vi$chrom), + CHR = withChrPrefix(vi$chrom), BP = as.integer(vi$pos), A1 = vi$A1, A2 = vi$A2 @@ -458,14 +458,14 @@ extractBlockGenotypes <- function(handle, snpIdx, meanImpute = TRUE) { } # A panel's variants snpInfo-style, one row per rowRanges element: SNP (the -# file's own ids), CHR (canonical), BP, A1, A2. The inverse of -# .snpInfoRanges(), so genotypes from any backend answer alike. +# file's own ids), CHR, BP, A1, A2. The inverse of .snpInfoRanges(), so +# genotypes from any backend answer alike. # @noRd .rangesSnpInfo <- function(gr) { mc <- S4Vectors::mcols(gr) tibble( SNP = as.character(mc$SNP), - CHR = canonChrom(as.character(seqnames(gr))), + CHR = as.character(seqnames(gr)), BP = as.integer(start(gr)), A1 = as.character(mc$A1), A2 = as.character(mc$A2) @@ -473,12 +473,13 @@ extractBlockGenotypes <- function(handle, snpIdx, meanImpute = TRUE) { } # The rowRanges of variants described snpInfo-style (SNP, CHR, BP, A1, A2), -# named `variantIds`: a handle's, or a VCF, GDS or PLINK1 panel's rows. +# named `variantIds`: a handle's, or a VCF, GDS or PLINK1 panel's rows. Every +# reader spells CHR in UCSC style as it reads the file. # @noRd .snpInfoRanges <- function(si, variantIds) { `names<-`( GenomicRanges::GRanges( - seqnames = withChrPrefix(as.character(si$CHR)), + seqnames = as.character(si$CHR), ranges = IRanges::IRanges(as.integer(si$BP), width = 1L), SNP = as.character(si$SNP), A1 = as.character(si$A1), @@ -505,12 +506,8 @@ extractBlockGenotypes <- function(handle, snpIdx, meanImpute = TRUE) { # @noRd .blockGenotypesToSe <- function(geno, handle, snpIdx) { si <- slice(snpInfo(handle), snpIdx) - chr <- str_c( - "chr", - str_remove(as.character(si$CHR), regex("^chr", ignore_case = TRUE)) - ) rowRanges <- GRanges( - seqnames = chr, + seqnames = si$CHR, ranges = IRanges(start = as.integer(si$BP), width = 1L), SNP = si$SNP, A1 = si$A1, @@ -571,7 +568,7 @@ extractBlockGenotypes <- function(handle, snpIdx, meanImpute = TRUE) { if (length(snpIdx) == 0L) { return(.emptyBlockSe(sampleIds)) } - unifiedChr <- canonChrom(snpInfo(handle)$CHR) + unifiedChr <- snpInfo(handle)$CHR groups <- split(seq_along(snpIdx), unifiedChr[snpIdx]) ses <- set_names( map2( @@ -714,16 +711,30 @@ extractBlockGenotypes <- function(handle, snpIdx, meanImpute = TRUE) { #' @title Filter SNP Info by Region #' @description Return 1-based indices into snpInfo for SNPs within a genomic -#' region string. +#' window. #' @param snpInfo data.frame with CHR and BP columns. -#' @param region Character region string "chr:start-end". +#' @param region A \code{GRanges} window, of one range or several. #' @return Integer vector of matching SNP indices. #' @keywords internal .regionToSnpIdx <- function(snpInfo, region) { - parsed <- parseRegion(region) - chrMatch <- stripChrPrefix(as.character(snpInfo$CHR)) == parsed$chrom - posMatch <- snpInfo$BP >= parsed$start & snpInfo$BP <= parsed$end - which(chrMatch & posMatch) + which(.refMultiRegionMask( + as.character(snpInfo$CHR), + snpInfo$BP, + .regionTable(region) + )) +} + +# Internal: a GRanges window argument as the chrom / start / end table the +# genotype readers match variants against, one row per range, its +# chromosome in UCSC style as the LD and genotype metadata are. +# @noRd +.regionTable <- function(region, what = "`region`") { + region <- .assertRegionGRanges(region, what) + tibble( + chrom = as.character(GenomicRanges::seqnames(region)), + start = GenomicRanges::start(region), + end = GenomicRanges::end(region) + ) } #' @title Convert SNP Info to Variant Info @@ -865,7 +876,7 @@ readBim <- function(bed) { #' Read a PLINK2 allele frequency file (.afreq or .afreq.zst) #' -#' @param prefix File prefix (without .afreq extension). +#' @param path File prefix (without .afreq extension). #' @return A data.frame with columns: chrom, id, A2 (REF), A1 (ALT), alt_freq, #' obs_ct. alt_freq is the frequency of the A1 (ALT/effect) allele. #' @importFrom vroom vroom @@ -877,24 +888,33 @@ readBim <- function(bed) { #' readAfreq(stem) #' @export #' @importFrom checkmate assertString -readAfreq <- function(prefix) { - assertString(prefix) - afreqZst <- str_c(prefix, ".afreq.zst") - afreqPlain <- str_c(prefix, ".afreq") +readAfreq <- function(path) { + assertString(path) + afreqZst <- str_c(path, ".afreq.zst") + afreqPlain <- str_c(path, ".afreq") if (file.exists(afreqZst)) { - af <- vroom( - archive_read(afreqZst, format = "raw", filter = "zstd"), - delim = "\t", - show_col_types = FALSE - ) - } else if (file.exists(afreqPlain)) { - af <- vroom( - afreqPlain, + return(.readAfreqFile(afreqZst)) + } + if (file.exists(afreqPlain)) { + return(.readAfreqFile(afreqPlain)) + } + NULL +} + +# One PLINK2 .afreq table read from the file named, zstd-compressed when the +# name ends in .zst. readAfreq() finds that file from a prefix; a caller that +# holds the file itself (readStochasticMeta()'s format override) reads it +# here, so the file need not be named *.afreq. +# @noRd +.readAfreqFile <- function(file) { + af <- if (str_detect(file, "\\.zst$")) { + vroom( + archive_read(file, format = "raw", filter = "zstd"), delim = "\t", show_col_types = FALSE ) } else { - return(NULL) + vroom(file, delim = "\t", show_col_types = FALSE) } # PLINK2 .afreq: REF = A2, ALT = A1, ALT_FREQS = A1 (effect allele) # frequency @@ -927,8 +947,8 @@ readAfreq <- function(prefix) { #' Reads per-variant min/max values used to invert min-max [0,2] scaling #' of stochastic genotype data. Supports two formats: #' \itemize{ -#' \item \strong{afreq}: PLINK2 .afreq/.afreq.zst with U_MIN/U_MAX columns -#' (read via \code{readAfreq}, which also returns allele frequencies). +#' \item \strong{afreq}: a PLINK2 .afreq table with U_MIN/U_MAX columns, +#' whatever the file is named (zstd-compressed when it ends in .zst). #' \item \strong{generic}: Tab-delimited file with columns id, u_min, u_max. #' } #' @@ -956,11 +976,10 @@ readStochasticMeta <- function(path, format = NULL) { resolved <- arg_match(detected, c("afreq", "generic")) if (resolved == "afreq") { - # readAfreq expects a prefix, not a full path - strip the .afreq[.zst] - # suffix - prefix <- str_remove(path, "\\.afreq(\\.zst)?$") - af <- readAfreq(prefix) - if (is.null(af) || !all(is_in(c("u_min", "u_max"), colnames(af)))) { + # The file itself, under whatever name it has: going through + # readAfreq()'s prefix would read .afreq instead. + af <- .readAfreqFile(path) + if (!all(is_in(c("u_min", "u_max"), colnames(af)))) { return(NULL) } return(select(af, all_of(c("id", "u_min", "u_max")))) @@ -1028,7 +1047,8 @@ invertMinmaxScaling <- function(X, uMin, uMax) { abort(msg) } span <- uMax - uMin - # Monomorphic variant: the forward scaling was the identity. + # Monomorphic variant: the forward step divided by 1 rather than 0, which + # left the column all 0. denom <- replace(span, span == 0, 1) # Invert: U_original = U_scaled * (u_max - u_min) / 2 + u_min sweep(sweep(X, 2, denom / 2, "*"), 2, uMin, "+") @@ -1091,8 +1111,8 @@ readPvar <- function(pvarPath) { #' extracts variant info. #' #' @param source Genotype file path/prefix or LD metadata file path. -#' @param region Region of interest: "chr:start-end" string or data.frame with -#' chrom/start/end. If NULL, returns all variants. +#' @param which Optional \code{GRanges}: return only the variants that +#' overlap it. If NULL, returns all variants. #' @return A data.frame with columns: chrom, id, pos, A2, A1. May also include #' allele_freq, variance, n_nomiss depending on source. #' @@ -1100,20 +1120,21 @@ readPvar <- function(pvarPath) { #' @examples #' meta <- system.file("extdata", "ld_reference", "ld_meta_file.tsv", #' package = "pecotmr") -#' refVariantInfo(meta, region = "chr22:10000000-19000000") +#' refVariantInfo(meta, +#' which = GenomicRanges::GRanges("chr22:10000000-19000000")) #' @export -refVariantInfo <- function(source, region = NULL) { +refVariantInfo <- function(source, which = NULL) { resolved <- resolveLdSource(source) - dataPath <- .refDataPath(resolved, region) + dataPath <- .refDataPath(resolved, which) if (resolved$type == "plink2") { info <- .refInfoPlink2(dataPath) } else if (resolved$type == "plink1") { info <- .refInfoPlink1(dataPath) } else { - return(.refInfoVcfGds(dataPath, region)) + return(.refInfoVcfGds(dataPath, which)) } # Region filter for plink2 / plink1 (the loader-based paths self-filter). - .refRegionFilter(info, region) + .refRegionFilter(info, which) } # Resolve the per-chromosome data path when the source carries region metadata, @@ -1140,6 +1161,7 @@ refVariantInfo <- function(source, region = NULL) { afreq <- readAfreq(dataPath) mutate( info, + chrom = withChrPrefix(.data$chrom), !!!compact(list( allele_freq = if (!is.null(afreq)) { afreq$alt_freq[match(info$id, afreq$id)] @@ -1153,7 +1175,7 @@ refVariantInfo <- function(source, region = NULL) { .refInfoPlink1 <- function(dataPath) { bim <- readBim(str_c(dataPath, ".bed")) tibble( - chrom = bim$chrom, + chrom = withChrPrefix(bim$chrom), id = bim$id, pos = bim$pos, A2 = bim$a0, @@ -1167,7 +1189,7 @@ refVariantInfo <- function(source, region = NULL) { .refInfoVcfGds <- function(dataPath, region) { result <- loadGenotypeRegion( dataPath, - region = region, + which = region, returnVariantInfo = TRUE ) mutate( @@ -1182,19 +1204,15 @@ refVariantInfo <- function(source, region = NULL) { if (is.null(region)) { return(info) } - parsed <- parseRegion(region) - infoChrom <- stripChrPrefix(info$chrom) - inRegion <- if (is.data.frame(parsed) && nrow(parsed) > 1) { - .refMultiRegionMask(infoChrom, info$pos, parsed) - } else { - infoChrom == as.character(parsed$chrom) & - info$pos >= parsed$start & - info$pos <= parsed$end - } + inRegion <- .refMultiRegionMask( + info$chrom, + info$pos, + .regionTable(region) + ) info[inRegion, , drop = FALSE] } -# OR-mask across a multi-row (one row per chrom) parsed region. +# OR-mask across a region table's rows (.regionTable()), one per range. # @noRd .refMultiRegionMask <- function(infoChrom, pos, parsed) { reduce( @@ -1239,7 +1257,7 @@ matchVariantsToKeep <- function(variantInfo, keepVariantsPath) { ids <- read_lines(keepVariantsPath) keepVariants <- parseVariantId(ids) } - viChrom <- canonChrom(variantInfo$chrom) + viChrom <- variantInfo$chrom hasAlleles <- is_in("A1", names(keepVariants)) && is_in("A2", names(keepVariants)) && !any(is.na(keepVariants$A1)) && @@ -1279,7 +1297,8 @@ matchVariantsToKeep <- function(variantInfo, keepVariantsPath) { #' dosages are automatically rescaled using the stored U_MIN/U_MAX values. #' #' @param genotype Path to the genotype data file, or a PLINK prefix. -#' @param region The target region in the format "chr:start-end". +#' @param which Optional \code{GRanges}: load only the variants that overlap +#' it. If NULL, loads every variant. #' @param keepIndel Whether to keep indel SNPs. #' @param keepVariantsPath Path to a file listing variants to keep. #' @param returnVariantInfo If TRUE, return a list with X (dosage matrix) and @@ -1298,11 +1317,12 @@ matchVariantsToKeep <- function(variantInfo, keepVariantsPath) { #' @examples #' stem <- sub("[.]bed$", "", #' system.file("extdata", "toy_ref.bed", package = "pecotmr")) -#' loadGenotypeRegion(genotype = stem, region = "chr22:1-100000000") +#' loadGenotypeRegion(genotype = stem, +#' which = GenomicRanges::GRanges("chr22:1-100000000")) #' @export loadGenotypeRegion <- function( genotype, - region = NULL, + which = NULL, keepIndel = TRUE, keepVariantsPath = NULL, returnVariantInfo = FALSE, @@ -1314,7 +1334,7 @@ loadGenotypeRegion <- function( format = .requireGenotypeFormat(genotype, "loadGenotypeRegion") ) variants <- .rangesSnpInfo(SummarizedExperiment::rowRanges(panel)) - snpIdx <- .loadGenoSnpIdx(variants, region) + snpIdx <- .loadGenoSnpIdx(variants, which) # Samples x variants matrix (pecotmr convention), its columns named by # the file's own variant ids; callers handle missing. extracted <- list( @@ -1345,7 +1365,10 @@ loadGenotypeRegion <- function( } snpIdx <- .regionToSnpIdx(variants, region) if (length(snpIdx) == 0) { - msg <- glue("No SNPs found in the specified region {region}") + msg <- glue( + "No SNPs found in the specified region ", + "{str_flatten(as.character(region), ', ')}" + ) abort(msg, class = "NoSnpsError") } snpIdx @@ -1530,7 +1553,7 @@ loadGenotypeRegion <- function( a2 <- map_chr(allelesSplit, `[`, 2L) tibble( SNP = snpId, - CHR = as.character(chr), + CHR = withChrPrefix(chr), BP = as.integer(pos), A1 = a1, A2 = a2 @@ -1558,6 +1581,7 @@ loadGenotypeRegion <- function( # are read here. # @noRd #' @importFrom checkmate assertFileExists +#' @importFrom purrr walk .makeBgenHandle <- function(path) { walk(c("DBI", "RSQLite"), .bgenRequirePackage) assertFileExists(path, access = "r", .var.name = "BGEN file") @@ -1738,7 +1762,7 @@ loadGenotypeRegion <- function( named <- !is.na(index$rsid) & nzchar(index$rsid) & index$rsid != "." tibble( SNP = if_else(named, index$rsid, ids), - CHR = canonChrom(index$chromosome), + CHR = withChrPrefix(index$chromosome), BP = as.integer(index$position), A1 = index$allele2, A2 = index$allele1, @@ -1755,7 +1779,7 @@ loadGenotypeRegion <- function( others <- alleles[-1L] tibble( SNP = formatVariantId(chrom, pos, alleles[[1L]], others), - CHR = canonChrom(chrom), + CHR = withChrPrefix(chrom), BP = as.integer(pos), A1 = others, A2 = alleles[[1L]], @@ -2032,7 +2056,7 @@ loadGenotypeRegion <- function( records$id[record], formatVariantId(records$chrom[record], records$pos[record], a2, a1) ), - CHR = canonChrom(records$chrom[record]), + CHR = withChrPrefix(records$chrom[record]), BP = as.integer(records$pos[record]), A1 = a1, A2 = a2, @@ -2248,7 +2272,6 @@ loadGenotypeRegion <- function( rows <- mutate( meta$snpInfo, SNP = as.character(.data$SNP), - CHR = canonChrom(.data$CHR), record = row_number(), allele = 1L ) @@ -2454,7 +2477,7 @@ loadGenotypeRegion <- function( # pecotmr convention directly. snpInfo <- tibble( SNP = bim$SNP, - CHR = as.character(bim$CHR), + CHR = withChrPrefix(bim$CHR), BP = as.integer(bim$BP), A1 = bim$A1, A2 = bim$A2 diff --git a/R/gwasSumStats.R b/R/gwasSumStats.R index dcaddd6a..ff26229e 100644 --- a/R/gwasSumStats.R +++ b/R/gwasSumStats.R @@ -1,12 +1,13 @@ # ============================================================================= # GwasSumStats S4 class # ----------------------------------------------------------------------------- -# DFrame-subclass collection keyed by the identity tuple (study). Each -# row holds a per-study GRanges of GWAS summary statistics covering a -# single LD block; build a separate collection per block when sweeping -# the genome. Class-level slots genome + qcInfo apply uniformly across -# rows; ldReference holds each distinct LD reference once, and the -# ldReference mcols column names the one every row uses. +# GRangesList-subclass collection keyed by the identity tuple (study). A study +# is split into one row per chromosome, or per window when the constructor is +# given a `region`, each holding that part of its GWAS summary statistics; +# the accessors stitch a study's rows back together. Class-level slots genome +# + qcOptions apply uniformly across rows; ldReference holds each distinct LD +# reference once, and the ldReference mcols column names the one every row +# uses. # ============================================================================= #' @include AllClasses.R tupleSelectors.R @@ -14,12 +15,28 @@ NULL #' @title GWAS Summary-Statistic Collection #' @description S4 collection of GWAS summary statistics keyed by the identity -#' tuple \code{(study)}. Each element is that study's per-variant -#' \code{GRanges} covering a single LD block, so build one collection per -#' block when sweeping the genome. -#' @details Required column: \code{study}, unique across rows. The class-level +#' tuple \code{(study)}. A study is split into one element per chromosome, +#' or per window when \code{\link{GwasSumStats}} is given a \code{region}, +#' each a per-variant \code{GRanges}; \code{\link{sumStats}} and the other +#' accessors stitch a study's elements back together. +#' @details Required column: \code{study}; the constructor also adds +#' \code{blockId}, naming each element's chromosome or window, and the +#' element's analysis window: \code{region}, a \code{GRanges} with one +#' range per element, and \code{regionGiven}. \code{regionGiven} is +#' \code{TRUE} where the window was given as a \code{region}, and +#' \code{FALSE} where it is the span of the element's variants when the +#' collection was first built, before any QC. A QC pass carries both +#' unchanged; the span of the variants left is \code{range(x)}. +#' \code{\link{colocPipeline}}, +#' \code{\link{colocboostPipeline}} and +#' \code{\link{causalInferencePipeline}} check the QTL variants against +#' these windows. Variants past a given window lie in one that was not +#' loaded, which is an error. Variants past a computed window may only be +#' ones the GWAS lacks, so more than one in a row is a warning. +#' A study repeats across its elements, so uniqueness is on +#' \code{(study, range)}. The class-level #' slots inherited from \code{\linkS4class{SumStatsBase}} -- \code{genome} -#' and \code{qcInfo} -- apply uniformly to every row; \code{ldReference} +#' and \code{qcOptions} -- apply uniformly to every row; \code{ldReference} #' holds each distinct LD reference once, and the \code{ldReference} column #' names the one each row uses. #' @seealso \code{\link{GwasSumStats}} for the constructor and @@ -40,7 +57,7 @@ setClass( add = coll ) coll$push(.sumStatsCheckGenome(object)) - assertList(object@qcInfo, .var.name = "qcInfo", add = coll) + assertList(object@qcOptions, .var.name = "qcOptions", add = coll) slotErrors <- coll$getMessages() if (length(slotErrors) > 0L) { return(slotErrors) @@ -63,8 +80,8 @@ setClass( #' @rdname show-methods setMethod("show", "GwasSumStats", function(object) { cat(glue( - "GwasSumStats: {nrow(object)} studies, ", - "genome build {GenomeInfoDb::genome(object)}\n", + "GwasSumStats: {n_distinct(object$study)} studies in ", + "{nrow(object)} rows, genome build {.showGenomeBuild(object)}\n", .trim = FALSE )) ldSrc <- .ldRefsLabel(ldReference(object), "none (LD-free)") @@ -73,8 +90,9 @@ setMethod("show", "GwasSumStats", function(object) { #' @title GWAS Summary Statistics Handling -#' @description Constructor, accessors, and converters for \code{GwasSumStats} -#' (the post-refactor DFrame-subclass collection keyed by \code{study}). +#' @description Constructor, accessors, and converters for +#' \code{GwasSumStats}, the \code{RangedTupleList} collection of GWAS +#' summary statistics keyed by \code{study}. #' @name pecotmr-gwas-sumstats #' @keywords internal #' @importFrom GenomicRanges GRanges seqnames start @@ -102,17 +120,19 @@ NULL } #' @title Create a GwasSumStats Collection Object -#' @description Construct a \code{GwasSumStats} S4 DFrame-subclass collection -#' from per-study tuple vectors and a list of \code{GRanges} entries (one per -#' study), plus the LD reference(s) the rows were harmonized against and a -#' single genome build that applies to the whole collection. +#' @description Construct a \code{GwasSumStats} S4 collection from per-study +#' tuple vectors and a list of \code{GRanges} entries (one per study), plus +#' the LD reference(s) the rows were harmonized against and a single genome +#' build that applies to the whole collection. #' #' Each \code{GRanges} entry must carry per-variant statistics in its mcols (at #' minimum \code{SNP}, \code{A1}, \code{A2}, \code{Z}, \code{N}; optionally #' \code{MAF}, \code{INFO}, \code{BETA}, \code{SE}, \code{P}). -#' @param studyName Character vector of study identifiers (must be unique). +#' @param studyName Character vector of study identifiers, one per +#' \code{entry}. A study whose entries are already split by block repeats +#' here, once per entry, with \code{blockId} telling them apart. #' @param entry A \code{SimpleList} or \code{list} of \code{GRanges}, one per -#' study. +#' study (or per block of an already-split study). #' @param genome Single character string giving the genome build (e.g., #' \code{"hg19"}, \code{"hg38"}). One build per collection. #' @param ldReference The LD reference: a genotype panel (see @@ -136,30 +156,37 @@ NULL #' no per-variant \code{N} column and no case/control counts. Named #' \code{nSample} to avoid clashing with \code{nSamples()} (the LD-panel #' sample size). -#' @param ldBlocks Optional LD-block specification: a \code{GRanges}, a -#' data.frame with \code{chrom}/\code{start}/\code{end} (plus an optional -#' \code{blockId}), or a path to such a table. When supplied, each -#' study's variants are split into one element per block rather than one per -#' chromosome, and \code{blockId} takes the block's key (its \code{names}, -#' else a \code{blockId} metadata column, else its coordinates). cTWAS needs -#' this granularity: its EM estimates parameters across blocks, so a -#' per-chromosome split is too coarse. Variants overlapping no block are -#' dropped with a warning, because a variant outside every block has no -#' block-local LD to be fine-mapped against. -#' @param blockId Optional character vector of block keys, one per -#' \code{entry}, for entries that are \strong{already} split by block. Use -#' it to carry existing keys through a rebuild; without it a rebuild would -#' re-derive them as seqnames and collapse distinct blocks onto one key. -#' Mutually exclusive with \code{ldBlocks}. -#' @param extraCols Optional named list of additional per-study columns to +#' @param region Optional analysis windows, typically LD blocks: a +#' \code{GRanges}, or the path of a BED file, read as BED with a 0-based +#' start (a fourth column, when present, names each window). One set of +#' windows applies to every study; a list gives one set per study, +#' \code{NULL} for a study to split by chromosome. Each study's variants are +#' split into one element per window they fall in, rather than one per +#' chromosome, and each element's \code{region} is its window, recorded as +#' given. Its \code{blockId} is the window's name: its \code{names}, else +#' its \code{blockId} column (a BED file's fourth column), else its +#' coordinates. cTWAS needs this granularity: its EM estimates parameters +#' across blocks, so a per-chromosome split is too coarse. Variants outside +#' every window are dropped with a warning. +#' @param blockId Optional character vector of block names, one per +#' \code{entry}, for entries that are \strong{already} split. Use it to +#' carry existing names through a rebuild; without it a rebuild would +#' re-derive them as seqnames and collapse distinct blocks onto one name. A +#' name only: it gives no window, which comes from \code{region}. Mutually +#' exclusive with \code{region}. +#' @param extraCols Optional named list (or \code{DataFrame} / +#' \code{data.frame}) of additional per-study columns to #' attach to the collection's \code{mcols}. Named rather than variadic #' because the base class's own constructor, \code{GRangesList(...)}, uses #' \code{...} for its \emph{elements}: a bare \code{...} here would read #' as adding an entry rather than a metadata column. -#' @param qcInfo A \code{list} recording which QC steps ran. Empty \code{list()} -#' on construction; populated by \code{summaryStatsQc()} with a per-step audit -#' record. Fine-mapping / TWAS pipelines reject inputs where -#' \code{length(qcInfo(x)) == 0}. +#' @param qcOptions A \code{list} recording the QC that ran. Empty +#' \code{list()} on construction; \code{summaryStatsQc()} fills it. +#' Fine-mapping / TWAS pipelines reject inputs where +#' \code{length(qcOptions(x)) == 0}. +#' @param metadata A list of free-form metadata about the collection, +#' as \code{metadata()} holds on any Bioconductor vector. Default +#' \code{list()}. #' @return A \code{GwasSumStats} object. #' @examples #' panel <- readGenotypes( @@ -179,15 +206,17 @@ GwasSumStats <- function( nCase = NULL, nControl = NULL, nSample = NULL, - qcInfo = list(), - ldBlocks = NULL, + qcOptions = list(), + region = NULL, blockId = NULL, - extraCols = list() + extraCols = list(), + metadata = list() ) { if (missing(studyName) || missing(entry) || missing(genome)) { - abort("`study`, `entry`, and `genome` are all required.") + abort("`studyName`, `entry`, and `genome` are all required.") } varY <- .gwasValidateArgs(studyName, entry, genome, varY) + entry <- .ucscEntries(entry) cols <- list( study = as.character(studyName), varY = varY @@ -196,27 +225,58 @@ GwasSumStats <- function( .gwasAppendExtras(extraCols) dict <- .ldRefDict(.ldRefPerTuple(ldReference, length(entry))) dfArgs <- c(cols, list(ldReference = dict$keys, check.names = FALSE)) - # The per-study GRanges become the collection's ELEMENTS; everything else - # is per-study metadata and goes in mcols. There is no `entry` column. - # mcols are attached to the GRangesList BEFORE new(), because new() - # validates during initialize() and the validity method needs the identity - # columns to already be there. - # A multi-seqname entry (e.g. a genome-wide GWAS) is split into one - # element per block (or per chromosome when no block manifest is given), - # with its metadata row replicated alongside. Splitting is unconditional: - # a stored element always spans exactly one seqname. - split <- .gwasSplitEntry(entry, ldBlocks, blockId, length(entry)) - # `blockId` is always present, so downstream code (cTWAS in particular) can - # key regions without first asking how the collection was built. - md <- cbind( - exec(S4Vectors::DataFrame, !!!dfArgs)[split$fromIdx, , drop = FALSE], - S4Vectors::DataFrame(blockId = split$blockId) + grl <- .gwasElements(entry, dfArgs, region, blockId) + .withMetadata( + .sumStatsNewValidated( + "GwasSumStats", + grl, + dict$refs, + genome, + qcOptions + ), + metadata ) - grl <- S4Vectors::`mcols<-`( - GenomicRanges::GRangesList(split$entry), - value = md +} + +# The collection's elements with their metadata. The per-study GRanges become +# the ELEMENTS; everything else is per-study metadata and goes in mcols. There +# is no `entry` column. mcols are attached to the GRangesList BEFORE new(), +# because new() validates during initialize() and the validity method needs +# the identity columns to already be there. +# A multi-seqname entry (e.g. a genome-wide GWAS) is split into one element +# per `region` window (or per chromosome when there are none), with its +# metadata row replicated alongside. Splitting is unconditional: a stored +# element always spans exactly one seqname. +# @noRd +.gwasElements <- function(entry, dfArgs, region, blockId) { + split <- .gwasSplitEntry(entry, region, blockId, length(entry)) + pieces <- .rtlBindElements(split$entry) + S4Vectors::`mcols<-`( + pieces, + value = .gwasPieceMetadata(dfArgs, split, pieces) + ) +} + +# Each piece's metadata row: its entry's, replicated across the pieces the +# entry splits into, then the block the piece covers. `blockId` is always +# present, so downstream code (cTWAS in particular) can key regions without +# first asking how the collection was built. So are `region` and +# `regionGiven`, so the block range of a row, and whether the caller gave it, +# need no fallback either. +# @noRd +.gwasPieceMetadata <- function(dfArgs, split, pieces) { + cbind( + exec(S4Vectors::DataFrame, !!!dfArgs)[split$fromIdx, , drop = FALSE], + exec( + S4Vectors::DataFrame, + blockId = split$blockId, + !!!.regionColumns( + split$given, + split$hasGiven, + .rowSpanRanges(pieces) + ) + ) ) - .sumStatsNewValidated("GwasSumStats", grl, dict$refs, genome, qcInfo) } # Build and validate a SumStatsBase subclass from its GRangesList plus the @@ -225,55 +285,119 @@ GwasSumStats <- function( # coerce those slots. Used by qtlSumStats.R too. `ldReference` is the named # list of distinct references (.ldRefDict()), already keyed from the rows. # @noRd -.sumStatsNewValidated <- function(Class, grl, ldReference, genome, qcInfo) { +.sumStatsNewValidated <- function(Class, grl, ldReference, genome, qcOptions) { # The build goes into seqinfo, which is where a GRangesList keeps it and # where every Bioconductor consumer reads it from. Assigned before new() # so validity sees the finished object. - built <- GenomeInfoDb::`genome<-`(grl, value = as.character(genome)) - obj <- methods::new( + built <- .rtlNamed( + GenomeInfoDb::`genome<-`(grl, value = as.character(genome)) + ) + methods::new( Class, built, ldReference = ldReference, - qcInfo = as.list(qcInfo) + qcOptions = as.list(qcOptions) ) - methods::validObject(obj) - obj } -# Split by LD block when a manifest is supplied, else by seqname. Both return -# (entry, fromIdx); this adds the blockId the seqname path does not carry, -# which for that path is just the seqname each piece sits on. +# Split across the `region` windows when they are given, else by seqname. +# Both return (entry, fromIdx); this adds each piece's blockId -- its window's +# name, or on the seqname path the seqname it sits on -- and its given window +# (`given`, with `hasGiven` saying which pieces have one). # @noRd -.gwasSplitEntry <- function(entry, ldBlocks, blockId, n) { - if (!is.null(ldBlocks) && !is.null(blockId)) { +.gwasSplitEntry <- function(entry, region, blockId, n) { + if (!is.null(region) && !is.null(blockId)) { msg <- glue( - "pass `ldBlocks` (derive the keys) or `blockId` (supply them), ", - "not both." + "pass `region` (its windows name the rows) or `blockId` (supply ", + "the names), not both." ) abort(msg) } - if (!is.null(ldBlocks)) { - return(.rtlSplitByBlocks(entry, .asLdBlockRanges(ldBlocks))) + if (!is.null(region)) { + return(.gwasSplitByRegion(entry, region, n)) } split <- .rtlSplitBySeqname(entry) # Supplied ids are indexed by fromIdx, exactly like the other metadata # columns, so an entry that still splits further replicates its id rather # than falling out of alignment. This is what lets a rebuild (QC) carry # block keys through instead of silently re-deriving them as seqnames. + # unname(): the seqname splitter names its pieces, and those names would + # otherwise ride into the mcols column and make it inconsistent with the + # window path, which produces a bare character vector. + ids <- if (is.null(blockId)) { + unname(map_chr(split$entry, .rtlElementSeqname)) + } else { + .gwasCheckBlockId(blockId, n)[split$fromIdx] + } list_assign( split, - blockId = if (!is.null(blockId)) { - .gwasCheckBlockId(blockId, n)[split$fromIdx] - } else { - # unname(): the seqname splitter names its pieces, and those names - # would otherwise ride into the mcols column and make it - # inconsistent with the block path, which produces a bare - # character vector. - unname(map_chr(split$entry, .gwasElementSeqname)) - } + blockId = ids, + given = .placeholderRanges(length(split$entry)), + hasGiven = rep(FALSE, length(split$entry)) + ) +} + +# Each study split across its windows: one set shared by every study, or a +# list with one per study (NULL for a study to split by chromosome), as +# `ldReference` takes one reference or a list. +# @noRd +.gwasSplitByRegion <- function(entry, region, n) { + if (!.isPerStudyRegion(region)) { + return(.gwasWindowSplit(entry, .asRegionRanges(region))) + } + if (length(region) != n) { + abort(glue( + "`region` as a list must have one element per `entry` ", + "(got {length(region)} vs {n})." + )) + } + .gwasCombineSplits(map2(as.list(entry), as.list(region), .gwasSplitStudy)) +} + +# @noRd +.isPerStudyRegion <- function(region) { + methods::is(region, "GRangesList") || + (is.list(region) && !is.data.frame(region)) +} + +# @noRd +.gwasWindowSplit <- function(entry, windows) { + split <- .rtlSplitByBlocks(entry, windows) + list_assign( + split, + given = .bareRanges(split$blockRange), + hasGiven = rep(TRUE, length(split$entry)), + blockRange = zap() + ) +} + +# One study against its own windows, or by chromosome when it has none. +# @noRd +.gwasSplitStudy <- function(e, r) { + if (is.null(r)) { + return(.gwasSplitEntry(list(e), NULL, NULL, 1L)) + } + .gwasWindowSplit(list(e), .asRegionRanges(r)) +} + +# Per-study splits as one: each study's pieces in turn, with `fromIdx` +# pointing back at the study they came from. +# @noRd +.gwasCombineSplits <- function(splits) { + list( + entry = list_flatten(map(splits, "entry")), + fromIdx = rep(seq_along(splits), map_int(splits, .gwasSplitSize)), + blockId = list_c(map(splits, "blockId"), ptype = character()), + given = unname(unlist(.rtlBindElements(map(splits, "given")))), + hasGiven = list_c(map(splits, "hasGiven"), ptype = logical()) ) } +# @noRd +.gwasSplitSize <- function(split) { + length(split$entry) +} + # @noRd .gwasCheckBlockId <- function(blockId, n) { if (length(blockId) != n) { @@ -286,16 +410,6 @@ GwasSumStats <- function( as.character(blockId) } -# The one seqname an already-split element sits on. NA for an empty element, -# which carries no coordinate to name. -# @noRd -.gwasElementSeqname <- function(g) { - if (length(g) == 0L) { - return(NA_character_) - } - as.character(seqnames(g))[[1L]] -} - # Validate genome / entry / length consistency; returns the recycled varY. # @noRd .gwasValidateArgs <- function(studyName, entry, genome, varY) { @@ -344,7 +458,7 @@ GwasSumStats <- function( # Append any user-supplied extra columns (from `...`). # @noRd .gwasAppendExtras <- function(cols, extras) { - c(cols, extras) + c(cols, .extraColsList(extras)) } @@ -369,7 +483,7 @@ GwasSumStats <- function( } msg <- glue( "This GwasSumStats has {n_distinct(studies)} studies. ", - "Pass `study = ` to select one. ", + "Pass `studyName = ` to select one. ", "Available: {str_flatten(unique(studies), ', ')}" ) abort(msg) @@ -391,8 +505,6 @@ GwasSumStats <- function( #' @param x A \code{GwasSumStats} object. #' @param studyName Character (length 1) study identifier. Optional when the #' collection has a single row. -#' @param ranges Optional \code{GRanges} restricting the returned variants to -#' those it overlaps. \code{NULL} (default) returns the study's full set. #' @param context,trait,annotateSignificance QTL-only selectors, named here so #' that supplying one is an error rather than a silently ignored request. A #' GWAS has no context or trait axis and carries no significance annotation; @@ -405,7 +517,6 @@ setMethod( function( x, studyName = NULL, - ranges = NULL, context = NULL, trait = NULL, annotateSignificance = NULL @@ -416,7 +527,7 @@ setMethod( # silently ignored request -- the shared SumStatsBase accessors pass # the union of both classes' selectors. .gwasRefuseQtlSelectors(context, trait, annotateSignificance) - .ssStitchElements(x, .gwasSelectStudy(x, studyName), ranges) + .ssStitchElements(x, .gwasSelectStudy(x, studyName)) } ) @@ -433,77 +544,27 @@ setMethod( abort(glue( "sumStats(GwasSumStats): {str_flatten(names(given)[given], ', ')} ", "{if (sum(given) == 1L) 'is' else 'are'} a QtlSumStats selector. ", - "A GWAS is selected by `study` (and narrowed by `ranges`)." + "A GWAS is selected by `studyName`; narrow it first with ", + "subsetByOverlaps()." )) } # z / nSamples / maf / nSnps are provided once by SumStatsBase (AllClasses.R). -#' @title Coerce Summary Statistics to a Data Frame -#' @description Coerce one tuple of a \code{GwasSumStats} or -#' \code{QtlSumStats} collection to a per-variant \code{data.frame} in the -#' standardized layout \code{variant_id, chrom, pos, A1, A2, z, beta, se, N, -#' maf} (optional columns omitted when absent on the entry). This is the -#' table view of \code{\link{sumStats}}, which returns the same selection as -#' a \code{GRanges}; coercion rather than a return-type argument is the -#' Bioconductor idiom for choosing a representation. -#' @param x A \code{GwasSumStats} or \code{QtlSumStats} object. -#' @param row.names,optional Accepted for compatibility with -#' \code{as.data.frame} and ignored. -#' @param studyName Character (length 1) or \code{NULL}. Restrict the selection -#' to this study; \code{NULL} matches all studies. -#' @param context Character (length 1) or \code{NULL}. Restrict the selection to -#' this context; \code{NULL} matches all contexts (\code{QtlSumStats} only). -#' @param trait Character (length 1) or \code{NULL}. Restrict the selection to -#' this trait; \code{NULL} matches all traits (\code{QtlSumStats} only). -#' @param require Character vector. Columns that must be present (derived if -#' necessary) in the returned summary-statistics data frame. -#' @param derive Whether to derive missing standard columns from the available -#' ones; \code{"zFromBetaSe"} recovers \code{z} from \code{beta}/\code{se}. -#' @param keepChrPrefix Logical. If \code{TRUE}, keep the \code{chr} prefix on -#' chromosome names; otherwise strip it. -#' @param ... Unused. -#' @return A \code{data.frame}. -#' @examples -#' data(qtlSumStatsExample) -#' head(as.data.frame(qtlSumStatsExample)) -#' @rdname sumStatsDataFrame -#' @aliases sumStatsDataFrame -#' @export -setMethod( - "as.data.frame", - "GwasSumStats", - function( - x, - row.names = NULL, - optional = FALSE, - studyName = NULL, - require = character(0), - derive = c("none", "zFromBetaSe"), - keepChrPrefix = TRUE, - ... - ) { - derive <- arg_match(derive) - gr <- sumStats(x, studyName = studyName) - .entryToSumstatDf( - gr, - require = require, - derive = derive, - keepChrPrefix = keepChrPrefix, - label = glue( - "GwasSumStats[", - "{if (is.null(studyName)) '' else studyName}]" - ) - ) - } -) - - #' @rdname varY #' @export setMethod("varY", "GwasSumStats", function(x, studyName = NULL) { idx <- .gwasSelectStudy(x, studyName) - val <- x$varY[[idx]] + # One value per study, held on each of its rows; rows that disagree have + # no single answer, so that is an error rather than a pick. + val <- unique(as.numeric(x$varY[idx])) + if (length(val) > 1L) { + abort(glue( + "varY(): the {length(idx)} rows of study ", + "'{x$study[[idx[[1L]]]]}' disagree on varY ", + "({str_flatten(val, ', ')})." + )) + } if (is.na(val)) NULL else val }) @@ -522,12 +583,12 @@ setMethod("varY", "GwasSumStats", function(x, studyName = NULL) { #' #' The three collection-level slots are merged rather than taken from the first #' input: \code{genome} and the \code{\link{summaryStatsQc}} options must agree -#' across the inputs (a mismatch is an error, not a silent first-wins), the -#' per-element \code{qcInfo$entryAudit} concatenates in element order so -#' \code{\link{qcDiagnostics}} keeps addressing the right element, and every -#' row keeps its own LD reference. References that are views of one source -#' are stored once: genotype panels read from the same files union into one -#' panel over the shared genotype handle (block-parallel pipelines narrow each +#' across the inputs (a mismatch is an error, not a silent first-wins), each +#' row keeps its own QC audit, so \code{\link{qcDiagnostics}} keeps +#' addressing the right element, and every row keeps its own LD reference. +#' References that are views of one source are stored once: genotype panels +#' read from the same files union into one panel over the shared genotype +#' handle (block-parallel pipelines narrow each #' piece's panel to its own block, so a multi-block collection would otherwise #' hold one panel per block), and an \code{LdMatrix} or #' \code{GenotypeMixture} that another input's reference covers gives way to diff --git a/R/h2Annotations.R b/R/h2Annotations.R index 1a23f69b..b42afed4 100644 --- a/R/h2Annotations.R +++ b/R/h2Annotations.R @@ -19,19 +19,19 @@ NULL #' @export setMethod( "readAnnotations", - signature(paths = "character"), - function(paths, snpRanges, annotationMeta = NULL, genome = "hg19") { - if (is.null(names(paths))) { + signature(path = "character"), + function(path, snpRanges, annotationMeta = NULL, genome = "hg19") { + if (is.null(names(path))) { msg <- glue( - "'paths' must be a named character vector (names = ", + "'path' must be a named character vector (names = ", "annotation names)" ) abort(msg) } - annotNames <- names(paths) - nAnnots <- length(paths) + annotNames <- names(path) + nAnnots <- length(path) annotMat <- .readAnnotMatrix( - paths, + path, snpRanges, annotNames, length(snpRanges), @@ -41,7 +41,7 @@ setMethod( annotationMeta <- tibble( name = annotNames, tier = rep("candidate", nAnnots), - type = .readAnnotTypes(paths) + type = .readAnnotTypes(path) ) } AnnotationMatrix(annotMat, snpRanges, annotationMeta, genome) diff --git a/R/h2EstimationWrappers.R b/R/h2EstimationWrappers.R index a35a813b..7643d9cf 100644 --- a/R/h2EstimationWrappers.R +++ b/R/h2EstimationWrappers.R @@ -34,7 +34,8 @@ NULL #' @description For each LD block, find the SNP indices from a reference that #' fall within the block boundaries. #' @param snpInfo A data.frame with columns CHR, BP. -#' @param ldBlocks A \code{GRanges} of LD block intervals. +#' @param ldBlocks The LD block intervals: a \code{GRanges}, or the path +#' of a BED file, read as BED with a 0-based start. #' @return A list of integer vectors, one per block. #' @keywords internal snpsPerBlock <- function(snpInfo, ldBlocks) { @@ -967,10 +968,10 @@ NULL if (!is.null(ld$R)) { return(rawNtau * crossprod(ld$R * sqrt(d)) + ld$R) } - F <- ld$F - m1 <- nrow(F) - 1 - gram <- tcrossprod(sweep(F, 2L, sqrt(d), "*")) - crossprod(F, rawNtau / m1 * (gram %*% F) + F) / m1 + ldFactor <- ld$F + m1 <- nrow(ldFactor) - 1 + gram <- tcrossprod(sweep(ldFactor, 2L, sqrt(d), "*")) + crossprod(ldFactor, rawNtau / m1 * (gram %*% ldFactor) + ldFactor) / m1 } # One block's contribution to the GLS normal equations, L = X'Omega^-1 X and @@ -2137,14 +2138,17 @@ sldscUnivariate <- function( if (!is.null(studyName)) { return(studyName) } - if (nrow(sumstats) != 1L) { + # Studies, not rows: a genome-wide study is one row per chromosome (or + # per LD block), and its accessors stitch those rows back together. + studies <- unique(as.character(sumstats$study)) + if (length(studies) != 1L) { msg <- glue( - "`study` is required when the GwasSumStats has ", - "{nrow(sumstats)} entries." + "`studyName` is required when the GwasSumStats has ", + "{length(studies)} studies." ) abort(msg) } - as.character(sumstats$study[[1L]]) + studies } # Dispatch to the method-specific univariate estimator. @@ -2235,11 +2239,10 @@ sldscUnivariate <- function( # Element-wise coordinate check. Coordinates are compared rather than variant # ids because the two sides routinely name the same variant differently # (rsid vs chr:pos:A2:A1), while the same variant always sits at the same -# coordinate once the chr prefix is normalized. +# coordinate. # @noRd .h2CheckPositions <- function(entry, ldRef, studyName) { - same <- withChrPrefix(as.character(seqnames(entry))) == - withChrPrefix(as.character(seqnames(ldRef))) & + same <- as.character(seqnames(entry)) == as.character(seqnames(ldRef)) & start(entry) == start(ldRef) if (all(same)) { return(invisible(TRUE)) @@ -2292,7 +2295,7 @@ setMethod( studyName <- .estimateH2ResolveStudy(sumstats, studyName) .h2ValidateInputs(sumstats, studyName, ldRef, annotations) z <- z(sumstats, studyName = studyName) - rawN <- median(nSamples(sumstats, studyName = studyName)) + rawN <- median(sampleSize(sumstats, studyName = studyName)) M <- nSnps(sumstats, studyName = studyName) # Legacy heritability-wrapper correction (separate from the SuSiE RSS # binaryTraitModel handling in the fine-mapping pipeline). diff --git a/R/jointEngine.R b/R/jointEngine.R index d22c51f1..5f1ff8f9 100644 --- a/R/jointEngine.R +++ b/R/jointEngine.R @@ -108,15 +108,19 @@ NULL # column (NULL when absent -- the true position cannot be inferred # from summary statistics alone). # region = the fine-mapping window. QtlDataset -> traitPos +/- cisWindow; -# QtlSumStats -> the entry's variant span (sumstats carry no -# cis-window, so the fitted span IS the region). +# QtlSumStats -> the tuple's own `region`: the window it was +# given, or the span of its variants as first built, before QC +# (a pipeline's cisWindow sets it from traitPos first). # Each returns a length-1 GRanges, or NULL when the anchor is unavailable (the -# accumulator / builder then records a chrUn sentinel). +# accumulator / builder then records a chrUn sentinel). A row is named by its +# whole (study, context, trait) tuple: a QtlSumStats can carry the same +# (context, trait) in several studies, each with its own position and window. +# A QtlDataset holds one study, so `study` has nothing to choose there. #' @importFrom rlang try_fetch -.traitPosFor <- function(data, context, trait) { +.traitPosFor <- function(data, study, context, trait) { if (methods::is(data, "QtlDataset")) { se <- try_fetch( - molecularTraits(data, contexts = context), + .qtlContextSe(data, context = context), error = function(cnd) NULL ) if (is.null(se)) { @@ -137,10 +141,7 @@ NULL if (!is_in("traitPos", colnames(data))) { return(NULL) } - idx <- which( - as.character(data$context) == context & - as.character(data$trait) == trait - ) + idx <- .qssTupleRows(data, study, context, trait) if (length(idx) == 0L) { return(NULL) } @@ -152,9 +153,9 @@ NULL NULL } -.fitRegionFor <- function(data, context, trait, cisWindow = NULL) { +.fitRegionFor <- function(data, study, context, trait, cisWindow = NULL) { if (methods::is(data, "QtlDataset")) { - tp <- .traitPosFor(data, context, trait) + tp <- .traitPosFor(data, study, context, trait) if (is.null(tp)) { return(NULL) } @@ -168,34 +169,32 @@ NULL )) } if (methods::is(data, "QtlSumStats")) { - idx <- which( - as.character(data$context) == context & - as.character(data$trait) == trait - ) + idx <- .qssTupleRows(data, study, context, trait) if (length(idx) == 0L) { return(NULL) } - gr <- .collectionEntry(data, idx[[1L]]) - if (length(gr) == 0L) { - return(NULL) - } - return(GenomicRanges::GRanges( - as.character(GenomicRanges::seqnames(gr))[[1L]], - IRanges::IRanges( - min(GenomicRanges::start(gr)), - max(GenomicRanges::end(gr)) - ) - )) + return(.rowRegionAt(data, idx[[1L]])) } NULL } +# The rows of a QtlSumStats holding one (study, context, trait) tuple. +# @noRd +.qssTupleRows <- function(data, study, context, trait) { + which( + as.character(data$study) == study & + as.character(data$context) == context & + as.character(data$trait) == trait + ) +} + # Vectorised per-row anchors for the pushRow builders: map the scalar helper -# over aligned (context, trait) vectors and assemble ONE GRanges of length n, -# using a chrUn sentinel where the anchor is unavailable. Built from plain -# chr/start/end vectors so mixed seqlevels never trip seqinfo merging. +# over aligned (study, context, trait) vectors and assemble ONE GRanges of +# length n, using a chrUn sentinel where the anchor is unavailable. Built from +# plain chr/start/end vectors so mixed seqlevels never trip seqinfo merging. .anchorVector <- function( data, + studies, contexts, traits, kind = c("traitPos", "region"), @@ -206,6 +205,7 @@ NULL seq_along(traits), .jointAnchorAt, data = data, + studies = studies, contexts = contexts, traits = traits, kind = kind, @@ -216,10 +216,8 @@ NULL starts <- map_int(anchors, "start") ends <- map_int(anchors, "end") # Nothing resolved (e.g. a QtlSumStats with no supplied traitPos): return - # NULL - # so the builder omits the column entirely and traitPosition() reports - # NA, - # rather than a column full of chrUn sentinels. + # NULL so the builder omits the column entirely and traitPosition() + # reports an empty GRanges, rather than a column full of chrUn sentinels. if (!anyFound) { return(NULL) } @@ -233,11 +231,25 @@ NULL # records which it was, so the caller can tell "nothing resolved" from "every # anchor really is chrUn:1-1". # @noRd -.jointAnchorAt <- function(i, data, contexts, traits, kind, cisWindow) { +.jointAnchorAt <- function( + i, + data, + studies, + contexts, + traits, + kind, + cisWindow +) { g <- if (kind == "traitPos") { - .traitPosFor(data, contexts[[i]], traits[[i]]) + .traitPosFor(data, studies[[i]], contexts[[i]], traits[[i]]) } else { - .fitRegionFor(data, contexts[[i]], traits[[i]], cisWindow) + .fitRegionFor( + data, + studies[[i]], + contexts[[i]], + traits[[i]], + cisWindow + ) } if (is.null(g)) { return(list(found = FALSE, chr = "chrUn", start = 1L, end = 1L)) @@ -264,6 +276,7 @@ NULL per <- try_fetch( .anchorVector( data, + as.character(cond$study), as.character(cond$context), as.character(cond$trait), "region", @@ -286,7 +299,7 @@ NULL # taken from the fit's OWN variants rather than a trait cis-window: a joint # group spans several traits, so no single trait's window describes X. # @noRd -.jointAfForGroup <- function(data, g) { +.jointAfForGroup <- function(data, g, genotypeFilter) { if (!is(g, "IndividualJointGroup")) { return(NULL) } @@ -298,7 +311,7 @@ NULL if (is.null(rg)) { return(NULL) } - .fmAfForX(data, X, region = rg) + .fmAfForX(data, X, genotypeFilter = genotypeFilter, region = rg) } @@ -426,7 +439,7 @@ setMethod( coverage = cfg$credibleSetParam$coverage, pos = .jgTraitPos(group), verbose = verbose, - numThreads = cv$numThreads %||% 1L, + BPPARAM = cv$BPPARAM %||% SerialParam(), seed = cfg$seed ) .fmSliceCv(cv, "fsusie") @@ -624,7 +637,7 @@ setMethod( verbose = verbose, mvPrior = mvPrior, mvPriorCv = mvPriorCv, - numThreads = cv$numThreads %||% 1L, + BPPARAM = cv$BPPARAM %||% SerialParam(), seed = cfg$seed ) .fmSliceCv(cv, "mvsusie") @@ -1153,7 +1166,7 @@ setMethod( weightMethods = wm, fitRetention = "slim", maxNumVariants = maxCv, - numThreads = cfg$crossValidationParam$numThreads %||% 1, + BPPARAM = cv$BPPARAM %||% SerialParam(), dataDrivenPriorMatricesCv = args$dataDrivenPriorMatricesCv, verbose = cfg$verbose %||% 1, seed = cfg$seed @@ -1192,7 +1205,7 @@ setMethod( NULL } if (is.null(full$W)) { - return(twasWeightsRow( + return(TwasWeightsRow( variantIds = character(0), weights = NULL, cvResult = cvR, @@ -1200,7 +1213,7 @@ setMethod( weightsDataType = cfg$dataType )) } - twasWeightsRow( + TwasWeightsRow( variantIds = full$vids, weights = full$W[, r], methodFits = full$fitParts, @@ -1292,7 +1305,7 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { scopedTraits, .enumCrossContextGroupFor, data = data, - study = studyName, + studyName = studyName, scopedContexts = scopedContexts, args = args, verbose = verbose @@ -1317,7 +1330,9 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { verbose, label = "jointCrossContext", region = args$region, - residualizationParam = args$residualizationParam + residualizationParam = args$residualizationParam, + genotypeFilter = args$genotypeFilter, + phenotypeFilter = args$phenotypeFilter ) if (is.null(xy)) { return(NULL) @@ -1470,7 +1485,7 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { scopedContexts, .enumCrossTraitGroupFor, data = data, - study = studyName, + studyName = studyName, scopedTraits = scopedTraits, args = args, verbose = verbose @@ -1496,7 +1511,9 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { label = "jointCrossTrait", studyName = studyName, region = args$region, - residualizationParam = args$residualizationParam + residualizationParam = args$residualizationParam, + genotypeFilter = args$genotypeFilter, + phenotypeFilter = args$phenotypeFilter ) if (is.null(xy)) { return(NULL) @@ -1712,7 +1729,9 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { verbose, label = "composed", region = args$region, - residualizationParam = args$residualizationParam + residualizationParam = args$residualizationParam, + genotypeFilter = args$genotypeFilter, + phenotypeFilter = args$phenotypeFilter ) if (is.null(xy)) { return(list()) @@ -1729,6 +1748,20 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { list(new("IndividualJointGroup", conditions = conds, X = xy$X, Y = xy$Y)) } +# The run's resolved phenotype QC, or the univariate fits' own default -- drop +# a sample with a missing value, keep outliers -- when the engine record +# carries none. +# @noRd +.jointPhenotypeFilter <- function(args) { + args$phenotypeFilter %||% + .qtlResolvePhenotypeFilter( + PhenotypeFilterParam(), + naDefault = "drop", + naAllowed = c("drop", "impute"), + caller = "the joint engine" + ) +} + # univariate / individual: one 1-condition group per (study, context, trait) in # scope -- the per-(context, trait) iteration expressed as engine groups, so # univariate methods (lasso / enet / susie / ...) flow through the SAME per- @@ -1738,15 +1771,15 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { if (!is_in(studyName, scope$studies)) { return(list()) } - naAction <- if (is.null(args$naAction)) "drop" else args$naAction + phenotypeFilter <- .jointPhenotypeFilter(args) .jeConcat(map( scope$contexts[[studyName]], .enumUnivariateForContext, data = data, scope = scope, args = args, - study = studyName, - naAction = naAction + studyName = studyName, + phenotypeFilter = phenotypeFilter )) } @@ -1758,9 +1791,9 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { scope, args, studyName, - naAction + phenotypeFilter ) { - se <- molecularTraits(data, contexts = cx) + se <- .qtlContextSe(data, context = cx) traits <- keep( intersect(scope$traits[[studyName]], rownames(se)), .traitSelectedAt, @@ -1773,21 +1806,28 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { .enumUnivariateGroupFor, data = data, args = args, - study = studyName, + studyName = studyName, cx = cx, - naAction = naAction + phenotypeFilter = phenotypeFilter )) } # One (context, trait) univariate group, or NULL when fewer than two samples # are shared between its genotypes and its phenotype. # @noRd -.enumUnivariateGroupFor <- function(tid, data, args, studyName, cx, naAction) { +.enumUnivariateGroupFor <- function( + tid, + data, + args, + studyName, + cx, + phenotypeFilter +) { Y <- .fmResidPheno( data, contexts = cx, traitId = tid, - naAction = naAction, + phenotypeFilter = phenotypeFilter, residualizationParam = args$residualizationParam ) X <- if (is.null(args$region)) { @@ -1796,14 +1836,16 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { contexts = cx, traitId = tid, cisWindow = args$cisWindow, - residualizationParam = args$residualizationParam + residualizationParam = args$residualizationParam, + genotypeFilter = args$genotypeFilter ) } else { .fmResidGeno( data, contexts = cx, region = args$region, - residualizationParam = args$residualizationParam + residualizationParam = args$residualizationParam, + genotypeFilter = args$genotypeFilter ) } common <- intersect(rownames(X), rownames(Y)) @@ -2097,7 +2139,7 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { ldReference = .jgLdRefOf(g) ) fitArgs <- .twasGroupArgs(g, pipeline, args) - fitArgs$af <- .jointAfForGroup(data, g) + fitArgs$af <- .jointAfForGroup(data, g, args$genotypeFilter) fitArgs$region <- args$region perTokenEntries <- compact(set_names( map( @@ -2328,7 +2370,7 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { ew <- ens$ensembleTwasWeights vids <- (if (!is.null(names(ew))) names(ew) else rownames(ew)) %||% variantIds(perTokenEntries[[passing[1L]]][[r]]) - twasWeightsRow( + TwasWeightsRow( variantIds = vids, weights = as.numeric(ew), cvResult = list( @@ -2352,21 +2394,28 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { if (!is_in(studyName, scope$studies)) { return(list()) } - naAction <- if (is.null(args$naAction)) "drop" else args$naAction + phenotypeFilter <- .jointPhenotypeFilter(args) .jeConcat(map( scope$contexts[[studyName]], .enumTopPcForContext, data = data, scope = scope, args = args, - study = studyName, - naAction = naAction + studyName = studyName, + phenotypeFilter = phenotypeFilter )) } # @noRd -.enumTopPcForContext <- function(cx, data, scope, args, studyName, naAction) { - se <- molecularTraits(data, contexts = cx) +.enumTopPcForContext <- function( + cx, + data, + scope, + args, + studyName, + phenotypeFilter +) { + se <- .qtlContextSe(data, context = cx) traits <- keep( intersect(scope$traits[[studyName]], rownames(se)), .traitSelectedAt, @@ -2382,7 +2431,7 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { data, contexts = cx, traitId = traits, - naAction = naAction, + phenotypeFilter = phenotypeFilter, residualizationParam = args$residualizationParam ) scores <- .fmTopPcScores(Y, args$nPCs %||% 10L) @@ -2399,7 +2448,7 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { .enumTopPcGroup, X = X[common, , drop = FALSE], scores = scores[common, , drop = FALSE], - study = studyName, + studyName = studyName, cx = cx )) } @@ -2412,14 +2461,16 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { contexts = cx, traitId = traits, cisWindow = args$cisWindow, - residualizationParam = args$residualizationParam + residualizationParam = args$residualizationParam, + genotypeFilter = args$genotypeFilter )) } .fmResidGeno( data, contexts = cx, region = args$region, - residualizationParam = args$residualizationParam + residualizationParam = args$residualizationParam, + genotypeFilter = args$genotypeFilter ) } @@ -2622,7 +2673,7 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { if (length(ctxs) == 0L) { return(scope$traits[[st]]) } - se <- molecularTraits(data, contexts = ctxs[[1L]]) + se <- .qtlContextSe(data, context = ctxs[[1L]]) .fmTraitsInRegion( se, intersect(scope$traits[[st]], rownames(se)), @@ -2690,7 +2741,7 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { # One per-condition TwasWeightsRow from column `r` of a joint weight matrix. # @noRd .jointColEntry <- function(r, vids, weights, fitParts, cfg) { - twasWeightsRow( + TwasWeightsRow( variantIds = vids, weights = weights[, r], methodFits = fitParts, @@ -2733,20 +2784,22 @@ setMethod("construct", "TwasJointPipeline", function(pipeline, records) { # One joint output record for condition `i`, or NULL when that entry is absent. # traitPos = the bare trait position (NULL when a QtlSumStats caller supplied -# none -> the column is omitted and traitPosition() reports NA). The -# fine-mapping window is NOT recorded: the element's own span is the region -# (section 4.4), and a stored window would go stale under subsetRegion(). +# none -> the column is omitted and traitPosition() reports an empty +# GRanges). region = the window the joint group was analysed over +# (.jointGroupWindow(): an explicit region, else the union of its traits' cis +# windows). # @noRd .jointEntryRecordAt <- function(i, entries, cond, method, grp, data) { e <- entries[[i]] if (is.null(e)) { return(NULL) } + st <- as.character(cond$study[[i]]) ctx <- as.character(cond$context[[i]]) tid <- as.character(cond$trait[[i]]) - tpos <- .traitPosFor(data, ctx, tid) + tpos <- .traitPosFor(data, st, ctx, tid) list( - study = as.character(cond$study[[i]]), + study = st, context = ctx, trait = tid, method = method, diff --git a/R/jointSpecification.R b/R/jointSpecification.R index 2cbc1075..36341743 100644 --- a/R/jointSpecification.R +++ b/R/jointSpecification.R @@ -20,7 +20,7 @@ return(unique(as.character(data$study))) } if (is(data, "MultiStudyQtlDataset")) { - indStudies <- names(qtlDatasets(data)) + indStudies <- names(data) ss <- sumStats(data) ssStudies <- if (is.null(ss)) { character(0) @@ -59,7 +59,7 @@ return("sumstats") } if (is(data, "MultiStudyQtlDataset")) { - if (is_in(studyName, names(qtlDatasets(data)))) { + if (is_in(studyName, names(data))) { return("individual") } ss <- sumStats(data) @@ -105,7 +105,7 @@ ))) } if (is(data, "MultiStudyQtlDataset")) { - indDatasets <- qtlDatasets(data) + indDatasets <- as.list(data) ss <- sumStats(data) if (is.null(studyName)) { fromInd <- .spConcat( @@ -137,7 +137,7 @@ # The trait ids present in one context of a QtlDataset. # @noRd .spTraitsInContext <- function(context, data) { - rownames(molecularTraits(data, context)) + rownames(.qtlContextSe(data, context)) } # Traits available in a single individual-level QtlDataset (optionally scoped). @@ -153,18 +153,18 @@ # Checked here rather than left to the accessor: `.spListTraits` answers # "which traits are in this scope", and an absent context is an empty # answer, not an error. The raw slot read this replaced returned NULL for - # an unknown context; molecularTraits() rejects one, so the empty case + # an unknown context; .qtlContextSe() rejects one, so the empty case # has to # be stated instead of falling out of a NULL. if (!is_in(context, contexts(data))) { return(character(0)) } - rownames(molecularTraits(data, context)) + rownames(.qtlContextSe(data, context)) } # Traits across a MultiStudyQtlDataset (individual studies + sumstats). .spListTraitsMultiStudy <- function(data, studyName, context) { - indDatasets <- qtlDatasets(data) + indDatasets <- as.list(data) ss <- sumStats(data) # No study filter: aggregate across every component (individual + sumstats). # Must precede per-study branches so a present sumStats slot does not shadow @@ -719,6 +719,66 @@ parseTraitIds <- function(traitId, data) { if (is.list(entry)) set_names(list(entry), s) else entry } +# The traits a run selects in context `cx` of study `qd`: its share of the +# parsed `traitId` (all of them when the selection leaves the context out), +# else -- when no trait was named at all -- those `region` overlaps, else all. +# @noRd +.contextSelectedTraits <- function(cx, qd, traitId, region) { + se <- .qtlContextSe(qd, context = cx) + ids <- rownames(se) + if (!is.null(traitId)) { + intersect(ids, .selectedTraits(traitId, studyName(qd), cx) %||% ids) + } else if (!is.null(region)) { + rr <- SummarizedExperiment::rowRanges(se) + ids[IRanges::overlapsAny(rr, region)] + } else { + ids + } +} + +# Whether context `cx` of study `qd` has a trait selected. +# @noRd +.contextHasSelectedTraits <- function(cx, qd, traitId, region) { + length(.contextSelectedTraits(cx, qd, traitId, region)) > 0L +} + +# Whether study `qd` has a trait selected in a context it runs on. In a +# multi-study run a study without one sits out, as one with none of its +# contexts selected does, rather than failing the run. +# @noRd +.studyHasSelectedTraits <- function(qd, contexts, traitId, region) { + useCtx <- .selectedContexts(contexts, studyName(qd)) %||% contexts(qd) + any(map_lgl( + useCtx, + .contextHasSelectedTraits, + qd = qd, + traitId = traitId, + region = region + )) +} + +# A multi-study run in which no component has a selected trait is refused: +# each one without sits out, so the run would otherwise come back empty. An +# embedded summary-statistics row counts when the selection keeps it. `cfg` +# is the run's record, carrying the parsed selection and its `region`. +# @noRd +.msAssertTraitsSelected <- function(data, cfg, pipeline) { + inStudies <- map_lgl( + as.list(data), + .studyHasSelectedTraits, + contexts = cfg$contexts, + traitId = cfg$traitId, + region = cfg$region + ) + ss <- sumStats(data) + inSumStats <- !is.null(ss) && + any(.sumStatsRowsSelected(ss, cfg$contexts, cfg$traitId)) + if (!any(inStudies) && !inSumStats) { + abort(glue("{pipeline}(MultiStudyQtlDataset): no traits selected.")) + } + invisible(NULL) +} + # ============================================================================= # Joint-specification dispatchers (merged from former R/jointDispatchers.R) # ============================================================================= @@ -829,7 +889,7 @@ parseTraitIds <- function(traitId, data) { context = as.character(data$context), trait = as.character(data$trait) ) - allDf <- as.data.frame( + allDf <- .sumStatsDf( data, studyName = cols$study[[tupleRows[[1L]]]], context = cols$context[[tupleRows[[1L]]]], @@ -867,7 +927,7 @@ parseTraitIds <- function(traitId, data) { errorLabel ) { i <- tupleRows[[kk]] - d <- as.data.frame( + d <- .sumStatsDf( data, studyName = cols$study[[i]], context = cols$context[[i]], @@ -928,7 +988,7 @@ parseTraitIds <- function(traitId, data) { # Does context `cx` carry trait `tid`? # @noRd .ccContextHasTrait <- function(cx, data, tid) { - is_in(tid, rownames(molecularTraits(data, contexts = cx))) + is_in(tid, rownames(.qtlContextSe(data, context = cx))) } # Scoped contexts in which a trait is present; NULL if fewer than 2. @@ -1019,7 +1079,9 @@ parseTraitIds <- function(traitId, data) { verbose, label, region = NULL, - residualizationParam + residualizationParam, + genotypeFilter, + phenotypeFilter = NULL ) { perTraitContexts <- .crossContextPerTrait( data, @@ -1037,12 +1099,14 @@ parseTraitIds <- function(traitId, data) { tid, cisWindow, region, - residualizationParam + residualizationParam, + genotypeFilter ) Yres <- .fmResidPheno( data, contexts = perTraitContexts, traitId = tid, + phenotypeFilter = phenotypeFilter, residualizationParam = residualizationParam ) .crossContextAssemble(X, Yres, perTraitContexts, verbose, label, tid) @@ -1094,9 +1158,11 @@ parseTraitIds <- function(traitId, data) { label, studyName, region = NULL, - residualizationParam + residualizationParam, + genotypeFilter, + phenotypeFilter = NULL ) { - se <- molecularTraits(data, contexts = cx) + se <- .qtlContextSe(data, context = cx) # scopedTraits is already region-restricted upstream (.runJointSpecs) when # region mode is used without an explicit traitId. traitsHere <- intersect(scopedTraits, rownames(se)) @@ -1109,14 +1175,23 @@ parseTraitIds <- function(traitId, data) { traitsHere, cisWindow, region, - residualizationParam + residualizationParam, + genotypeFilter ) allY <- .fmResidPheno( data, contexts = cx, traitId = traitsHere, + phenotypeFilter = phenotypeFilter, residualizationParam = residualizationParam ) + .crossTraitAssemble(allX, allY, traitsHere, se) +} + +# The cross-trait X / Y on the samples they share, keeping only the samples +# observed for every trait; NULL when fewer than two remain at either step. +# @noRd +.crossTraitAssemble <- function(allX, allY, traitsHere, se) { common <- intersect(rownames(allX), rownames(allY)) if (length(common) < 2L) { return(NULL) @@ -1145,7 +1220,8 @@ parseTraitIds <- function(traitId, data) { traitId, cisWindow, region, - residualizationParam + residualizationParam, + genotypeFilter ) { if (is.null(region)) { .fmResidGeno( @@ -1153,14 +1229,16 @@ parseTraitIds <- function(traitId, data) { contexts = contexts, traitId = traitId, cisWindow = cisWindow, - residualizationParam = residualizationParam + residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter ) } else { .fmResidGeno( data, contexts = contexts, region = region, - residualizationParam = residualizationParam + residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter ) } } @@ -1176,7 +1254,7 @@ parseTraitIds <- function(traitId, data) { # The (context, trait) tuples context `cx` contributes. # @noRd .composedTuplesForContext <- function(cx, data, scopedTraits) { - se <- molecularTraits(data, contexts = cx) + se <- .qtlContextSe(data, context = cx) # scopedTraits is region-restricted upstream (.runJointSpecs) if needed. map(intersect(scopedTraits, rownames(se)), .composedTuple, cx = cx) } @@ -1242,7 +1320,9 @@ parseTraitIds <- function(traitId, data) { allTraits, cisWindow, region, - residualizationParam + residualizationParam, + genotypeFilter, + phenotypeFilter = NULL ) { # Genotypes first, as the inline version did: reading them is what # fails on a missing panel file, and that error must stay the one the @@ -1253,12 +1333,14 @@ parseTraitIds <- function(traitId, data) { allTraits, cisWindow, region, - residualizationParam + residualizationParam, + genotypeFilter ) resid <- .fmResidPheno( data, contexts = allContexts, traitId = allTraits, + phenotypeFilter = phenotypeFilter, residualizationParam = residualizationParam ) list( @@ -1283,7 +1365,9 @@ parseTraitIds <- function(traitId, data) { verbose, label, region = NULL, - residualizationParam + residualizationParam, + genotypeFilter, + phenotypeFilter = NULL ) { tuples <- .composedTuples(data, scope, studyName, verbose, label) if (is.null(tuples)) { @@ -1297,19 +1381,26 @@ parseTraitIds <- function(traitId, data) { allTraits, cisWindow, region, - residualizationParam + residualizationParam, + genotypeFilter, + phenotypeFilter ) - allX <- sides$X - YresList <- sides$YresList + .composedAlignXy(sides, tuples) +} + +# X and the tuples' Y columns on the samples both sides share, without the +# samples any Y column misses; NULL when fewer than two samples remain. +# @noRd +.composedAlignXy <- function(sides, tuples) { commonSamples <- reduce( - c(list(rownames(allX)), map(YresList, rownames)), + c(list(rownames(sides$X)), map(sides$YresList, rownames)), intersect ) if (length(commonSamples) < 2L) { return(NULL) } - X <- allX[commonSamples, , drop = FALSE] - Y <- .composedYCols(YresList, tuples, commonSamples) + X <- sides$X[commonSamples, , drop = FALSE] + Y <- .composedYCols(sides$YresList, tuples, commonSamples) if (is.null(Y)) { return(NULL) } @@ -1447,7 +1538,7 @@ parseTraitIds <- function(traitId, data) { # by-key / cross-study rebuilds keep the trait position instead of silently # dropping it. There is no `region` counterpart -- the fine-mapping window # retired (section 4.4) because the element's own span is the region and a - # stored window had no correct update rule under subsetRegion(). + # stored window had no correct update rule when variants are narrowed. list( jointStudies = .jointStrCol("jointStudies", df), jointContexts = .jointStrCol("jointContexts", df), @@ -1538,7 +1629,7 @@ parseTraitIds <- function(traitId, data) { noun = "a result" ) { out <- .msDriverAccumulate( - qtlDatasets(data), + as.list(data), sumStats(data), perStudyFn, sumStatsFn, @@ -1674,7 +1765,9 @@ parseTraitIds <- function(traitId, data) { verbose = cfg$verbose, pipCutoffToSkip = cfg$screen, cache = cfg$fineMappingResult, - residualizationParam = cfg$residualizationParam + residualizationParam = cfg$residualizationParam, + genotypeFilter = cfg$genotypeFilter, + phenotypeFilter = cfg$phenotypeFilter ) } @@ -1723,7 +1816,7 @@ parseTraitIds <- function(traitId, data) { methodArgs, cfg ) { - qtlDatasets <- qtlDatasets(cfg$data) + qtlDatasets <- as.list(cfg$data) specs <- .fmSplitStudyAxisSpecs(parsedJointSpec) .fmMultiStudyWarnExcluded(specs$study, qtlDatasets, cfg$verbose) out <- if (length(specs$nonStudy) == 0L) { @@ -1757,11 +1850,21 @@ parseTraitIds <- function(traitId, data) { .fmStudyJointResult <- function(qd, specs, tokens, methodArgs, cfg) { studyCfg <- list_assign( cfg, - data = .qtlApplyFilterOverrides(qd, cfg$genotypeFilterParam) + data = .qtlRestrictSamples(qd, cfg$genotypeFilter$keepSamples) ) .fmDispatchJointSpecsQtlDataset(specs, tokens, methodArgs, studyCfg) } +# A MultiStudyQtlDataset's summary statistics as its joint fits read them: +# with `cfg$cisWindow` laid on the tuples the parsed selection keeps, as the +# per-study recursion has its QtlSumStats run lay it. The joint fits read the +# collection directly rather than recursing, so they lay it here. +# @noRd +.msJointSumStats <- function(ss, cfg, caller) { + rows <- which(.sumStatsRowsSelected(ss, cfg$contexts, cfg$traitId)) + .qssApplyCisWindow(ss, cfg$cisWindow, caller, rows) +} + # Fine-map every spec on the summary-statistics component and rbind onto the # individual-level results `out`. # @noRd @@ -1788,7 +1891,10 @@ parseTraitIds <- function(traitId, data) { parsedJointSpec, tokens, methodArgs, - list_assign(cfg, data = sumStats) + list_assign( + cfg, + data = .msJointSumStats(sumStats, cfg, "fineMappingPipeline") + ) ) if (is.null(ssRes)) { return(out) @@ -1964,7 +2070,7 @@ parseTraitIds <- function(traitId, data) { methods, cfg ) { - qtlDatasets <- qtlDatasets(cfg$data) + qtlDatasets <- as.list(cfg$data) specs <- .fmSplitStudyAxisSpecs(parsedJointSpec) .twasMultiStudyWarnExcluded(specs$study, qtlDatasets, cfg$verbose) out <- if (length(specs$nonStudy) == 0L) { @@ -1996,7 +2102,7 @@ parseTraitIds <- function(traitId, data) { # @noRd .twasStudyJointResult <- function(qd, specs, tokens, methods, cfg) { setup <- .twasJointSetup( - .qtlApplyFilterOverrides(qd, cfg$genotypeFilterParam), + .qtlRestrictSamples(qd, cfg$genotypeFilter$keepSamples), .twasNormalizeMethods(methods), cfg ) @@ -2036,7 +2142,10 @@ parseTraitIds <- function(traitId, data) { parsedJointSpec, tokens, .twasSumStatsMethodTokens(methods)$methodArgs, - list_assign(cfg, data = sumStats) + list_assign( + cfg, + data = .msJointSumStats(sumStats, cfg, "twasWeightsPipeline") + ) ) if (is.null(ssRes)) { return(out) @@ -2111,7 +2220,7 @@ parseTraitIds <- function(traitId, data) { if (!length(hit)) { return(NULL) } - .rowParts(r, hit[[1L]]) + .collectionEntry(r, hit[[1L]]) } # The merged FM entry for base row `i`: gather that key's entry from every diff --git a/R/ld.R b/R/ld.R index ff679c74..fb48f095 100644 --- a/R/ld.R +++ b/R/ld.R @@ -5,7 +5,7 @@ NULL #' @importFrom dplyr distinct arrange #' @noRd orderDedupRegions <- function(df) { - mutate(df, chrom = canonChrom(.data$chrom)) |> + df |> distinct(.data$chrom, .data$start, .keep_all = TRUE) |> arrange(chromOrder(.data$chrom), .data$start) } @@ -175,7 +175,7 @@ extractFilePaths <- function(genomicData, intersectionRows, columnToExtract) { #' #' @param ldReferenceMetaFile TSV with columns chrom, start, end, path. The path #' column may be comma-separated: "ld_file,bim_file". -#' @param region "chr:start-end" string or data.frame with chrom/start/end. +#' @param region A \code{GRanges} window. #' @param completeCoverageRequired If TRUE, error when the region extends beyond #' available LD blocks. #' @return A list with: intersections (LD_file_paths, bimFilePaths), ldMetaData, @@ -193,14 +193,11 @@ regionalLdMeta <- function( vroom(ldReferenceMetaFile), c("chrom", "start", "end", "path") ) |> + mutate(chrom = withChrPrefix(.data$chrom)) |> .ldMetaWidenWholeChrom() |> orderDedupRegions() |> .regionalLdParsePaths() - region <- `names<-`( - parseRegion(region), - c("chrom", "start", "end") - ) |> - orderDedupRegions() + region <- orderDedupRegions(.regionTable(region)) intersectionRows <- findIntersectionRows( genomicData, region$chrom, @@ -335,11 +332,16 @@ resolveLdSource <- function(path) { #' @importFrom vroom vroom #' @noRd resolveGenotypePathForRegion <- function(metaPath, region) { - parsed <- parseRegion(region) + queryChrom <- unique(.regionTable(region)$chrom) + if (length(queryChrom) != 1L) { + abort(glue( + "`region` spans chromosomes {str_flatten(queryChrom, ', ')}; ", + "a genotype file is resolved for one chromosome at a time." + )) + } meta <- as.data.frame(vroom(metaPath, show_col_types = FALSE)) |> `colnames<-`(c("chrom", "start", "end", "path")) |> - mutate(chrom = canonChrom(.data$chrom)) - queryChrom <- canonChrom(parsed$chrom) + mutate(chrom = withChrPrefix(.data$chrom)) matching <- meta[meta$chrom == queryChrom, , drop = FALSE] if (nrow(matching) == 0) { @@ -558,9 +560,13 @@ resolveGenotypePathForRegion <- function(metaPath, region) { # `object` as saved before its references became per-row -- one reference, # or NULL, in the slot and no row key -- brought up to date: that reference # becomes the slot's one entry and every row is keyed to it (every row is -# LD-free when it held none). A current object is returned as it is. +# LD-free when it held none). A current object -- or a collection that keeps +# no LD references, such as a CtwasResult -- is returned as it is. # @noRd .updateRowLdRefs <- function(object) { + if (!methods::.hasSlot(object, "ldReference")) { + return(object) + } old <- methods::slot(object, "ldReference") if (is.list(old) && !is.object(old)) { return(object) @@ -938,7 +944,8 @@ resolveGenotypePathForRegion <- function(metaPath, region) { return(.gmRanges(x)) } if (methods::is(x, "RangedSummarizedExperiment")) { - return(SummarizedExperiment::rowRanges(x)) + # A panel built outside pecotmr may spell its chromosomes otherwise. + return(.ucscRanges(SummarizedExperiment::rowRanges(x))) } .genotypeSnpRanges(x, normalizeVariantId(as.character(snpInfo(x)$SNP))) } @@ -978,10 +985,10 @@ resolveGenotypePathForRegion <- function(metaPath, region) { .repairVariantIds(ids, as.character(mc$A2), as.character(mc$A1)) } -# Per-variant chromosome, canonical (no chr prefix). +# Per-variant chromosome. # @noRd .ldRefChrom <- function(x) { - canonChrom(as.character(GenomicRanges::seqnames(.ldRefRanges(x)))) + as.character(GenomicRanges::seqnames(.ldRefRanges(x))) } # A panel's sample ids. An LdMatrix has no samples, so asking is a bug in the @@ -1442,12 +1449,12 @@ resolveGenotypePathForRegion <- function(metaPath, region) { # returns, largest first. R's other p - min(m, p) eigenvalues are exactly # zero; `nNull` counts them, for an estimator that counts every direction. # @noRd -.ldFactorEigen <- function(F) { - s <- svd(F, nu = 0L) +.ldFactorEigen <- function(ldFactor) { + s <- svd(ldFactor, nu = 0L) list( - values = s$d^2 / (nrow(F) - 1), + values = s$d^2 / (nrow(ldFactor) - 1), vectors = s$v, - nNull = ncol(F) - length(s$d) + nNull = ncol(ldFactor) - length(s$d) ) } @@ -1604,7 +1611,7 @@ resolveGenotypePathForRegion <- function(metaPath, region) { if (length(chromPaths) == 0L) { return(.genotypeStem(.resolveGenotypeResourcePath(source$path))) } - spanned <- unique(canonChrom(as.character(chroms))) + spanned <- unique(as.character(chroms)) paths <- unname(chromPaths[is_in(names(chromPaths), spanned)]) .genotypeStem(map_chr(paths, .resolveGenotypeResourcePath)) } @@ -1961,7 +1968,7 @@ resolveGenotypePathForRegion <- function(metaPath, region) { gr <- .ldRefRanges(x) mc <- S4Vectors::mcols(gr) stem <- str_c( - canonChrom(as.character(GenomicRanges::seqnames(gr))), + as.character(GenomicRanges::seqnames(gr)), ":", as.character(GenomicRanges::start(gr)) ) @@ -2296,6 +2303,8 @@ resolveGenotypePathForRegion <- function(metaPath, region) { # on different chromosomes. # @noRd .overlapsOnShared <- function(query, subject) { + query <- .locusRanges(query) + subject <- .locusRanges(subject) qChr <- as.character(GenomicRanges::seqnames(query)) sChr <- as.character(GenomicRanges::seqnames(subject)) shared <- intersect(qChr, sChr) @@ -2319,11 +2328,39 @@ resolveGenotypePathForRegion <- function(metaPath, region) { .rowSpans <- function(x) { rr <- range(x) list( - spans = unlist(rr, use.names = FALSE), + spans = .locusRanges(unlist(rr, use.names = FALSE)), rows = rep(seq_along(rr), lengths(rr)) ) } +# Where `gr`'s ranges sit, for comparing collections' ranges: strand and +# metadata dropped, the genome build kept, which is what stops ranges of two +# builds from meeting. +# @noRd +#' @importFrom BiocGenerics unstrand +.locusRanges <- function(gr) { + GenomicRanges::granges(unstrand(gr)) +} + +# The one LD reference rows `rows` of `x` share, for an analysis that reads +# their statistics together against one LD matrix. Rows on different +# references are refused rather than read from one of them; `what` names the +# rows in the error. +# @noRd +.rowsSharedLdRef <- function(x, rows, what) { + keys <- unique(.ldRefKeys(x)[rows]) + if (length(keys) > 1L) { + abort(c( + glue("{what} use {length(keys)} different LD references."), + i = str_c( + "Their statistics are read together against one LD matrix; ", + "give them one LD reference." + ) + )) + } + .rowLdRef(x, rows[[1L]]) +} + # `gr` with exactly the sequence levels `levels`. # @noRd .onSeqlevels <- function(gr, levels) { @@ -2363,15 +2400,20 @@ filterVariantsByLdReference <- function( assertFlag(keepIndel) variantsDf <- parseVariantId(variantIds) - # Derive region to scope the reference lookup - regionDf <- variantsDf |> + # The span of the variants on each chromosome scopes the reference lookup. + spans <- variantsDf |> group_by(.data$chrom) |> summarise(start = min(.data$pos), end = max(.data$pos)) # Use shared helper -- no genotype loading - refInfo <- refVariantInfo(ldReferenceMetaFile, regionDf) - refChrom <- canonChrom(refInfo$chrom) - refKey <- str_c(refChrom, ":", refInfo$pos) + refInfo <- refVariantInfo( + ldReferenceMetaFile, + GenomicRanges::GRanges( + spans$chrom, + IRanges::IRanges(spans$start, spans$end) + ) + ) + refKey <- str_c(refInfo$chrom, ":", refInfo$pos) variantKey <- str_c(variantsDf$chrom, ":", variantsDf$pos) inRef <- which(is_in(variantKey, refKey)) @@ -3156,7 +3198,7 @@ enforceDesignFullRank <- function( #' which case bigsnpr falls back to minor allele frequency computed from #' \code{X}. #' @param chr Integer or character vector of length \code{ncol(X)} giving the -#' chromosome for each variant. +#' chromosome for each variant, in any style (\code{"chr1"} or \code{1}). #' @param pos Integer vector of length \code{ncol(X)} giving the base-pair #' position for each variant. #' @param r2 Numeric in (0, 1]. r-squared threshold for clumping (variants @@ -3205,7 +3247,7 @@ ldClumpByScore <- function( G <- .ldClumpFbm(X) keep <- bigsnpr::snp_clumping( G = G, - infos.chr = as.integer(chr), + infos.chr = as.integer(chromOrder(chr)), infos.pos = as.integer(pos), S = score, thr.r2 = r2, diff --git a/R/manifestLoaders.R b/R/manifestLoaders.R index ab6999b0..56893088 100644 --- a/R/manifestLoaders.R +++ b/R/manifestLoaders.R @@ -10,8 +10,8 @@ # loadMultiStudyQtlDatasetFromManifest -> MultiStudyQtlDataset # # These are pure readers: they never run summaryStatsQc() (the loaded -# sumstats objects carry qcInfo = list()) and never filter genotypes (the -# QtlDataset QC knobs are stored as lazy slots, applied at extraction time). +# sumstats objects carry qcOptions = list()) and never filter genotypes (that is +# the pipelines' GenotypeFilterParam, applied per extracted block). # # A manifest is either a data.frame or a path to a delimited file. A ".csv" # extension is read with readr::read_csv; anything else is read with @@ -45,6 +45,41 @@ NULL } } +# The windows a BED file holds, as a GRanges. BED's columns are positional -- +# chromosome, start and end, then a name for the window -- and its start is +# 0-based, so it is shifted by one here. Blank, comment, `track` and +# `browser` lines are skipped, and so is a header line naming the columns, +# which LD-block files often have. +# @noRd +.readBedWindows <- function(path, what) { + lines <- discard( + readr::read_lines(path, skip_empty_rows = TRUE, progress = FALSE), + str_detect, + "^(#|track|browser)" + ) + record <- str_detect(lines, "^[^\t]+\t[0-9]+\t[0-9]+(\t|$)") + if (length(lines) > 0L && !record[[1L]]) { + lines <- lines[-1L] + record <- record[-1L] + } + if (length(lines) == 0L || !all(record)) { + abort(glue( + "{what}: '{path}' is not a BED file with windows in it; each ", + "line must give a chromosome, a start and an end, tab-separated." + )) + } + fields <- str_split(lines, "\t", simplify = TRUE) + exec( + GenomicRanges::GRanges, + seqnames = fields[, 1L], + ranges = IRanges::IRanges( + start = as.integer(fields[, 2L]) + 1L, + end = as.integer(fields[, 3L]) + ), + !!!compact(list(blockId = if (ncol(fields) > 3L) fields[, 4L])) + ) +} + # Directory a manifest's relative paths resolve against: the file's own # directory when the manifest was a path, otherwise NULL (paths used as-is). .manifestBase <- function(manifest) { @@ -70,54 +105,6 @@ NULL file.path(base, p) } -# The QtlDataset pass-through arguments, asserted at the loader so a bad value -# is reported against the argument the caller passed rather than surfacing from -# QtlDataset's validity several hundred lines later. Types match -# .qtlValidateScalars exactly, so this tightens nothing. -# @noRd -#' @importFrom checkmate assertLogical assertNumber assertFlag assertCharacter -.assertQtlPassThrough <- function(scaleResiduals, genotypeFilterParam) { - assertLogical(scaleResiduals, len = 1L) - .assertMethodParam( - genotypeFilterParam, - "GenotypeFilterParam" - ) - # Only what the caller actually set: an unset field defers to QtlDataset's - # own default and has nothing to check here. - walk( - c("mafCutoff", "macCutoff", "xvarCutoff", "imissCutoff"), - .assertQtlFilterNumber, - genotypeFilterParam = genotypeFilterParam - ) - walk( - c("keepSamples", "keepVariants"), - .assertQtlFilterCharacter, - genotypeFilterParam = genotypeFilterParam - ) - if (!is.null(genotypeFilterParam$keepIndel)) { - assertFlag(genotypeFilterParam$keepIndel) - } - invisible(NULL) -} - -# @noRd -.assertQtlFilterNumber <- function(field, genotypeFilterParam) { - v <- genotypeFilterParam[[field]] - if (!is.null(v)) { - assertNumber(v, lower = 0, finite = TRUE, .var.name = field) - } - invisible(NULL) -} - -# @noRd -.assertQtlFilterCharacter <- function(field, genotypeFilterParam) { - v <- genotypeFilterParam[[field]] - if (!is.null(v)) { - assertCharacter(v, .var.name = field) - } - invisible(NULL) -} - #' @importFrom checkmate assertNames # The existing column an alias set points at, or NULL when the canonical name # is already present or nothing matches. @@ -200,6 +187,63 @@ NULL NULL } +# The build a summary-statistics load names: the one given, checked against +# any its GWAS-VCF files record on ##reference, or else theirs. Files that +# disagree, or that disagree with the one given, are refused. +# @noRd +.manifestBuild <- function(genome, recorded, caller) { + if (length(recorded) > 1L) { + abort(glue( + "{caller}: the GWAS-VCF files record different genome builds ", + "({str_flatten(recorded, ', ')})." + )) + } + if (is.null(genome)) { + if (length(recorded) == 1L) { + return(recorded) + } + abort("`genome` must be provided as an argument or a manifest column.") + } + if (length(recorded) == 1L && !identical(as.character(genome), recorded)) { + abort(glue( + "{caller}: `genome` is '{genome}', but the GWAS-VCF files ", + "record '{recorded}'." + )) + } + genome +} + +# The build the manifest's rows are on: the `genome` argument or column, +# reconciled with the builds its GWAS-VCF files record. +# @noRd +.manifestGenome <- function(df, genome, base, caller) { + .manifestBuild( + .reconcileScalar(df[["genome"]], genome, "genome", required = FALSE), + .manifestVcfBuilds(df, base), + caller + ) +} + +# The genome builds the manifest's GWAS-VCF files record, read from their +# headers alone. +# @noRd +.manifestVcfBuilds <- function(df, base) { + paths <- map_chr(as.character(df$sumStatsPath), .resolveRel, base = base) + vcfs <- paths[str_detect(str_to_lower(paths), "\\.vcf(\\.b?gz)?$")] + if (length(vcfs) == 0L) { + return(character(0)) + } + if (!requireNamespace("VariantAnnotation", quietly = TRUE)) { + return(character(0)) + } + unique(discard(map_chr(vcfs, .vcfHeaderBuild), is.na)) +} + +# @noRd +.vcfHeaderBuild <- function(path) { + .vcfMetaBuild(VariantAnnotation::scanVcfHeader(path)) +} + # ============================================================================= # Genotype-format detection + LD-sketch resolution # ============================================================================= @@ -387,7 +431,7 @@ NULL .resolveLdRef(spec, chroms = chroms) } -# Canonical chromosomes present across a list of sumstats entry GRanges. NULL / +# The chromosomes present across a list of sumstats entry GRanges. NULL / # empty entries contribute nothing; NA seqnames are dropped. Always returns a # character vector (character(0) when nothing is present, never NULL). .entriesChroms <- function(entries) { @@ -401,13 +445,13 @@ NULL # LD-sketch containment check (validation only; no filtering) # ============================================================================= -# Canonical chromosomes present in an LD reference: for a panel read from a +# The chromosomes present in an LD reference: for a panel read from a # per-chromosome manifest these are the manifest's chromosomes; otherwise the # chromosomes of its variants. .ldRefChroms <- function(ldReference) { chromPaths <- .ldRefChromPaths(ldReference) if (length(chromPaths) > 0L) { - return(canonChrom(names(chromPaths))) + return(names(chromPaths)) } unique(.ldRefChrom(ldReference)) } @@ -443,9 +487,7 @@ NULL # The entry's chromosomes must all be present in the LD sketch; returns them. # @noRd .ldContainmentCheckChroms <- function(entryGr, ldReference, label) { - reqChrom <- unique(canonChrom( - as.character(GenomicRanges::seqnames(entryGr)) - )) + reqChrom <- unique(as.character(GenomicRanges::seqnames(entryGr))) availChrom <- .ldRefChroms(ldReference) missingChrom <- setdiff(reqChrom, availChrom) if (length(missingChrom) > 0L) { @@ -468,10 +510,7 @@ NULL minLdOverlapWarn, label ) { - keep <- is_in( - canonChrom(as.character(GenomicRanges::seqnames(sketchGr))), - reqChrom - ) + keep <- is_in(as.character(GenomicRanges::seqnames(sketchGr)), reqChrom) # Same matching relation `.ldFromRef()` will use when the LD is # actually loaded, palindromes included -- otherwise this counts an A/T # variant as absent, under-reports the overlap and warns about a panel @@ -506,70 +545,25 @@ NULL # Summary-statistic file readers # ============================================================================= -# Coerce a region argument (chr:start-end string, GRanges, or one-row -# data.frame with chrom/start/end) into a GRanges. -.asGRegion <- function(region) { - if (methods::is(region, "GRanges")) { - return(region) - } - if (is.data.frame(region)) { - return(GenomicRanges::GRanges( - seqnames = as.character(region$chrom), - ranges = IRanges::IRanges( - start = as.integer(region$start), - end = as.integer(region$end) - ) - )) - } - if (is.character(region) && length(region) == 1L) { - # "chr1_100_200" is the LD-block / region-id spelling of - # "chr1:100-200". Normalized here so one matcher below handles both - # and the seqname survives verbatim (parseRegion() canonicalizes the - # chromosome, which would drop a "chr" prefix the variants still use). - region <- str_replace( - region, - "^([^:]+)_([0-9,]+)_([0-9,]+)$", - "\\1:\\2-\\3" - ) - m <- str_match(region, "^([^:]+):([0-9,]+)-([0-9,]+)$")[1L, ] - if (is.na(m[[1L]])) { - msg <- glue( - "`region` must be a 'chr:start-end' or 'chr_start_end' ", - "string, a GRanges, or a one-row data.frame with ", - "chrom/start/end." - ) - abort(msg) - } - return(GenomicRanges::GRanges( - seqnames = m[[2L]], - ranges = IRanges::IRanges( - start = as.integer(str_remove_all(m[[3L]], ",")), - end = as.integer(str_remove_all(m[[4L]], ",")) - ) - )) - } - msg <- glue( - "`region` must be a 'chr:start-end' string, a GRanges, or a ", - "one-row data.frame with chrom/start/end." - ) - abort(msg) -} - # Remap a region's seqnames to the seqnames actually present in a tabix file -# (tolerant of chr-prefix differences). Returns NULL when no seqname matches. +# (tolerant of chr-prefix differences), merging windows that overlap so no line +# is read twice. A window on a chromosome the file does not hold reads nothing, +# so it is left out; NULL when no window matches. A genome-wide set of windows +# against a one-chromosome file reads that chromosome's windows. .matchRegionSeqnames <- function(gr, available) { want <- as.character(GenomicRanges::seqnames(gr)) mapped <- map_chr(want, .mlMatchSeqname, available = available) - if (anyNA(mapped)) { + ok <- !is.na(mapped) + if (!any(ok)) { return(NULL) } - GenomicRanges::GRanges( - seqnames = mapped, + GenomicRanges::reduce(GenomicRanges::GRanges( + seqnames = mapped[ok], ranges = IRanges::IRanges( - start = GenomicRanges::start(gr), - end = GenomicRanges::end(gr) + start = GenomicRanges::start(gr)[ok], + end = GenomicRanges::end(gr)[ok] ) - ) + )) } # Read the region of a bgzipped + tabix-indexed delimited file into a @@ -582,7 +576,7 @@ NULL } else { NULL } - gr <- .matchRegionSeqnames(.asGRegion(region), Rsamtools::seqnamesTabix(tf)) + gr <- .matchRegionSeqnames(region, Rsamtools::seqnamesTabix(tf)) emptyDf <- if (!is.null(colLine)) { # A header-only read yields a 0-row tibble with the right columns. readr::read_tsv(I(colLine), show_col_types = FALSE, progress = FALSE) @@ -1069,7 +1063,7 @@ NULL chrom = as.character(GenomicRanges::seqnames(rr)), pos = unname(as.integer(GenomicRanges::start(rr))), SNP = names(rr), - A1 = unname(map_chr(as.list(altList), .mlFirstAlt)), + A1 = .mlFirstAlts(altList), A2 = unname(as.character(VariantAnnotation::ref(vcf))), Z = z$z, z_supplied = z$supplied, @@ -1153,7 +1147,7 @@ NULL if (!is.null(region) && hasTbi) { tf <- Rsamtools::TabixFile(path) gr <- .matchRegionSeqnames( - .asGRegion(region), + region, Rsamtools::seqnamesTabix(tf) ) vcf <- if (is.null(gr)) { @@ -1164,8 +1158,9 @@ NULL } else { if (!is.null(region) && !hasTbi) { msg <- glue( - "{label}: VCF '{path}' is not bgzipped + tabix-indexed; ", - "region ignored, reading the whole file." + "{label}: VCF '{path}' is not bgzipped + tabix-indexed, so ", + "the whole file is read; `which` still selects the variants ", + "kept." ) warn(msg) } @@ -1174,8 +1169,6 @@ NULL .vcfToSumstatDf(vcf, sampleSelect, formatMapping, label) } -# Read one delimited-text sumstats file. Region reads only when a .tbi -# sidecar exists; otherwise the whole file is read and any region is ignored. # --------------------------------------------------------------------------- # Raw-table prefilters. Applied to a sumstats table as read, before # `.resolveSumstatCols()` maps it onto the canonical schema. @@ -1183,7 +1176,7 @@ NULL # Keep only the rows belonging to one trait. A cis-QTL scan writes every gene's # window into a single table (tensorqtl does), so without this a manifest row -# pulls in every other gene too; restricting by `region` only helps when the +# pulls in every other gene too; restricting by `which` only helps when the # file is tabix-indexed, and cis windows of neighbouring genes overlap anyway. # @noRd .filterSumstatsByTrait <- function(df, traitColumn, trait, label) { @@ -1276,6 +1269,10 @@ NULL ) } +# Read one delimited-text sumstats file. Region reads only when a .tbi +# sidecar exists; otherwise the whole file is read, with a warning, and the +# region selects the variants kept further on. +# @noRd .readSumStatsText <- function( path, region, @@ -1290,8 +1287,8 @@ NULL } else { if (!is.null(region) && !hasTbi) { msg <- glue( - "{label}: '{path}' is not tabix-indexed; ", - "region ignored, reading the whole file." + "{label}: '{path}' is not tabix-indexed, so the whole file ", + "is read; `which` still selects the variants kept." ) warn(msg) } @@ -1432,7 +1429,8 @@ NULL ) } -# Read a phenotype BED into an expression matrix (genes x samples) + rowRanges. +# Read a phenotype BED into an expression matrix (genes x samples) + rowRanges, +# their chromosomes in UCSC style whatever the file writes (1, chr1). # @noRd .readPhenotypeBed <- function(bedPath) { bed <- readr::read_tsv( @@ -1464,7 +1462,7 @@ NULL ) rr <- `names<-`( GenomicRanges::GRanges( - seqnames = meta$chrom, + seqnames = withChrPrefix(meta$chrom), ranges = IRanges::IRanges(start = meta$start + 1L, end = meta$end) ), meta$gene_id @@ -1535,7 +1533,6 @@ NULL studyName, base, transposeCov, - qc, genotypesOverride = NULL, genoCovOverride = NULL ) { @@ -1545,7 +1542,7 @@ NULL contexts, .buildOneContextSe, rows = rows, - study = studyName, + studyName = studyName, base = base, transposeCov = transposeCov ), @@ -1559,16 +1556,12 @@ NULL transposeCov, genoCovOverride ) - qtlArgs <- c( - list( - study = studyName, - genotypes = genotypes, - phenotypes = phenotypes, - genotypeCovariates = genoCov - ), - qc + QtlDataset( + studyName = studyName, + genotypes = genotypes, + phenotypes = phenotypes, + genotypeCovariates = genoCov ) - exec(QtlDataset, !!!qtlArgs) } # The SummarizedExperiment for one context: exactly one phenotypePath (+ at most @@ -1694,10 +1687,6 @@ NULL #' a genotype path/prefix; reconciled with a \code{genotypePath} column. #' @param genotypeCovariates A numeric matrix (samples x covariates) or a path #' to a covariate TSV; reconciled with a \code{genotypeCovariatePath} column. -#' @param scaleResiduals Pass-through \code{\link{QtlDataset}} argument. -#' @param genotypeFilterParam Pass-through \code{\link{QtlDataset}} filtering -#' options, built with \code{\link{GenotypeFilterParam}} and stored as lazy -#' QC slots. #' @param transposeCovariates Transpose covariate TSVs (QTLtools layout) before #' treating them as samples-as-rows. #' @return A \code{QtlDataset} object. @@ -1715,13 +1704,10 @@ loadQtlDatasetFromManifest <- function( studyName = NULL, genotypes = NULL, genotypeCovariates = NULL, - scaleResiduals = TRUE, - genotypeFilterParam = GenotypeFilterParam(), transposeCovariates = FALSE ) { assertString(studyName, null.ok = TRUE) assertFlag(transposeCovariates) - .assertQtlPassThrough(scaleResiduals, genotypeFilterParam) base <- .manifestBase(manifest) df <- .canonManifestCols( .readManifest(manifest), @@ -1732,19 +1718,27 @@ loadQtlDatasetFromManifest <- function( # df[["study"]] (not df$study): study is optional here (it may be passed as # the `study` arg instead), and a tibble `$` on an absent column warns. studyName <- .reconcileScalar(df[["study"]], studyName, "study") - qc <- .msqQcArgs(scaleResiduals, genotypeFilterParam) .buildQtlDatasetFromRows( df, studyName, base, transposeCovariates, - qc, genotypesOverride = genotypes, genoCovOverride = genotypeCovariates ) } -# Aliases shared by the sumstats manifests. +# Aliases shared by the sumstats manifests: the column names a manifest may +# spell its BED-style window coordinates with -- BED's own (`chrom`, +# `chromStart`, `chromEnd`), the short `start` / `end`, and a leading `#` on +# the header's first column. +# @noRd +.BED_ALIASES <- list( + chrom = c("chrom", "#chrom", "chr", "#chr"), + start = c("start", "chromStart"), + end = c("end", "chromEnd") +) + .gwasSumStatsManifestAliases <- list( study = c("study", "study_id", "studyId"), sumStatsPath = c( @@ -1767,7 +1761,8 @@ loadQtlDatasetFromManifest <- function( varY = c("varY", "var_y"), genome = c("genome"), ldReferencePath = c("ldReferencePath", "ld_reference_path", "ld_reference") -) +) |> + c(.BED_ALIASES) .qtlSumStatsManifestAliases <- list( study = c("study", "study_id", "studyId"), @@ -1789,8 +1784,11 @@ loadQtlDatasetFromManifest <- function( nSample = c("nSample", "n_sample"), varY = c("varY", "var_y"), genome = c("genome"), - ldReferencePath = c("ldReferencePath", "ld_reference_path", "ld_reference") -) + ldReferencePath = c("ldReferencePath", "ld_reference_path", "ld_reference"), + traitStart = c("traitStart", "trait_start"), + traitEnd = c("traitEnd", "trait_end") +) |> + c(.BED_ALIASES) # TRUE if study `i` has usable case/control counts OR a total-N scalar, so a # missing per-variant N is acceptable for that study. @@ -1806,10 +1804,10 @@ loadQtlDatasetFromManifest <- function( #' @title Load a GwasSumStats collection from a manifest #' @description Build a \code{\link{GwasSumStats}} from a manifest with one row -#' per study. No QC is run (the result carries \code{qcInfo = list()}). Each -#' sumstats file needs a \code{z} column, or \code{beta}+\code{se} from which -#' the Wald z (\code{z = beta/se}) is derived when \code{z} is absent (a -#' supplied \code{z} takes precedence). +#' per study. No QC is run (the result carries empty \code{qcOptions()}). +#' Each sumstats file needs a \code{z} column, or \code{beta}+\code{se} from +#' which the Wald z (\code{z = beta/se}) is derived when \code{z} is absent +#' (a supplied \code{z} takes precedence). #' @param manifest A data.frame or path. Columns (snake_case aliases accepted): #' \code{study} (required, unique), \code{sumStatsPath} (required), #' \code{columnMapping} (optional), \code{nCase} / \code{nControl} (optional), @@ -1820,15 +1818,27 @@ loadQtlDatasetFromManifest <- function( #' supplies a study-level scalar (\code{nCase} + \code{nControl}, or #' \code{nSample}), its sumstats file need not carry a per-variant \code{N} #' column; -#' \code{\link{summaryStatsQc}} fills \code{N} from the scalar. +#' \code{\link{summaryStatsQc}} fills \code{N} from the scalar. Optional +#' BED-style \code{chrom}/\code{start}/\code{end} columns, with a 0-based +#' \code{start} as in BED, give each study its own window, read and kept as +#' with \code{which}; a manifest that has them cannot also be given +#' \code{which}. #' @param genome Genome build; reconciled with a \code{genome} column. #' @param ldReference A genotype panel (see \code{\link{readGenotypes}}) or a #' spec (path/prefix/genoMeta), used for every study; where a row also names #' an \code{ldReferencePath} the two must agree. Omit it to give each study #' the reference its \code{ldReferencePath} names. -#' @param region Optional \code{chr:start-end} string, GRanges, or one-row -#' data.frame restricting the variants read (honoured only for tabix-indexed -#' text and bgzipped+tabixed VCF; ignored with a warning otherwise). +#' @param which Optional analysis windows shared by every study, typically +#' LD blocks: a \code{GRanges}, or the path of a BED file, read as BED +#' with a 0-based start. Only the variants inside them are read, when the +#' file is tabix-indexed text or a bgzipped + tabixed VCF (otherwise the +#' whole file is read, with a warning), and each study is split into one +#' element per window it has variants in, each window recorded as that +#' element's \code{region}, as \code{\link{GwasSumStats}} does with its +#' \code{region}; a named \code{GRanges} names the blocks. Without +#' windows a genome-wide file splits +#' into one element per chromosome; split by LD block, it has the +#' granularity \code{\link{assembleCtwasInputs}} needs. #' @param minLdOverlapWarn Warn when the fraction of sumstats variants present #' in the LD reference falls below this (default 0.5). #' @param columnMapping Optional default column mapping (a named list/vector, or @@ -1837,11 +1847,6 @@ loadQtlDatasetFromManifest <- function( #' @param sampleSelect Optional GWAS-VCF FORMAT sample (study) column to read. #' @param formatMapping Optional GWAS-VCF FORMAT tag mapping (canonical stat -> #' FORMAT field), overriding ES/SE/LP/SS/EAF defaults. -#' @param ldBlocks Optional LD-block specification (a \code{GRanges}, a -#' data.frame with \code{chrom}/\code{start}/\code{end}, or a path to such -#' a table). Without it a genome-wide file splits into one -#' element per chromosome; with it, into one element per LD block, which is -#' the granularity \code{\link{assembleCtwasInputs}} needs. #' @return A \code{GwasSumStats} object. #' @examples #' gwasTsv <- system.file("extdata", "manifests", @@ -1850,30 +1855,31 @@ loadQtlDatasetFromManifest <- function( #' package = "pecotmr"), "protocol_example.LD.chr22") #' manifest <- data.frame(study = "g1", sumStatsPath = gwasTsv) #' loadGwasSumStatsFromManifest(manifest = manifest, genome = "hg38", -#' ldReference = ldStem, region = "chr22:10000000-19000000") +#' ldReference = ldStem, +#' which = GenomicRanges::GRanges("chr22:10000000-19000000")) #' @export loadGwasSumStatsFromManifest <- function( manifest, genome = NULL, ldReference = NULL, - region = NULL, + which = NULL, minLdOverlapWarn = 0.5, columnMapping = NULL, sampleSelect = NULL, - formatMapping = NULL, - ldBlocks = NULL + formatMapping = NULL ) { base <- .manifestBase(manifest) df <- .gwasSumStatsManifest(manifest) - genome <- .reconcileScalar(df[["genome"]], genome, "genome") + genome <- .manifestGenome(df, genome, base, "loadGwasSumStatsFromManifest") ldReferenceSpecs <- .resolveLdRefSpecs(df, ldReference, base) ns <- .gwasStudyScalars(df) + windows <- .manifestWindows(df, which, "GwasSumStats") entries <- map( seq_len(nrow(df)), .loadGwasEntry, df = df, base = base, - region = region, + windows = windows, columnMapping = columnMapping, sampleSelect = sampleSelect, formatMapping = formatMapping, @@ -1886,16 +1892,108 @@ loadGwasSumStatsFromManifest <- function( minLdOverlapWarn, check = .checkGwasLdContainment ) - # Without a block manifest a genome-wide file splits by chromosome, which - # is too coarse for cTWAS; with one, each study becomes one element per LD - # block. The constructor does the splitting either way. + # Without windows a genome-wide file splits by chromosome, which is too + # coarse for cTWAS; with them -- typically LD blocks -- each study becomes + # one element per window. The constructor does the splitting either way. gwasArgs <- list_assign( .gwasSumStatsArgs(df, entries, genome, ldReference, ns), - ldBlocks = ldBlocks + region = .gwasManifestRegion(windows) ) exec(GwasSumStats, !!!gwasArgs) } +# The windows a manifest load reads and keeps: the `which` argument, shared +# by every row, or the manifest's BED-style chrom/start/end columns, one +# window per row. Both is an error, being two answers to one question. +# @noRd +.manifestWindows <- function(df, which, label) { + perRow <- .manifestRowWindows(df, label) + if (!is.null(perRow) && !is.null(which)) { + abort(glue( + "{label} manifest gives each row a window in its ", + "chrom/start/end columns, so `which` cannot give them too." + )) + } + list( + perRow = perRow, + shared = if (!is.null(which)) .asRegionRanges(which, "`which`") + ) +} + +# The window a manifest row reads: its own, else the shared ones. +# @noRd +.manifestWindowFor <- function(i, windows) { + if (!is.null(windows$perRow)) windows$perRow[i] else windows$shared +} + +# The GwasSumStats `region` a load builds: the shared windows, or a list with +# each study's own. +# @noRd +.gwasManifestRegion <- function(windows) { + if (is.null(windows$perRow)) { + return(windows$shared) + } + unname(as.list(GenomicRanges::split( + windows$perRow, + seq_along(windows$perRow) + ))) +} + +# The window each manifest row gives in its chrom/start/end columns, or NULL +# when it has no such columns. +# @noRd +.manifestRowWindows <- function(df, label) { + if (!any(is_in(c("start", "end"), names(df)))) { + return(NULL) + } + .manifestRanges(df, "start", "end", label, "window") +} + +# The trait position each manifest row gives in its traitStart / traitEnd +# columns, on the row's `chrom`, or NULL when it has no such columns. A trait +# sits on the chromosome its window does, so there is no second chromosome +# column. +# @noRd +.manifestTraitPos <- function(df, label) { + if (!any(is_in(c("traitStart", "traitEnd"), names(df)))) { + return(NULL) + } + .manifestRanges(df, "traitStart", "traitEnd", label, "trait position") +} + +# Ranges read from a manifest's BED-style columns: `chrom` plus a start and +# an end column, the start 0-based as in BED. Every row must fill them in. +# The chromosomes come back in UCSC style, as every range read from a file +# does. +# @noRd +.manifestRanges <- function(df, startCol, endCol, label, what) { + need <- c("chrom", startCol, endCol) + absent <- setdiff(need, names(df)) + if (length(absent) > 0L) { + abort(glue( + "{label} manifest: a {what} needs the columns ", + "{str_flatten(need, ', ')}; missing {str_flatten(absent, ', ')}." + )) + } + empty <- which( + is.na(df$chrom) | is.na(df[[startCol]]) | is.na(df[[endCol]]) + ) + if (length(empty) > 0L) { + abort(glue( + "{label} manifest: row(s) ", + "{str_flatten(utils::head(empty, 5L), ', ')} ", + "leave their {what} empty; give every row one, or none." + )) + } + GenomicRanges::GRanges( + withChrPrefix(df$chrom), + IRanges::IRanges( + start = as.integer(df[[startCol]]) + 1L, + end = as.integer(df[[endCol]]) + ) + ) +} + # A GwasSumStats manifest's rows, its columns under their canonical names, the # required ones present and one row per study. # @noRd @@ -1938,7 +2036,7 @@ loadGwasSumStatsFromManifest <- function( i, df, base, - region, + windows, columnMapping, sampleSelect, formatMapping, @@ -1956,7 +2054,7 @@ loadGwasSumStatsFromManifest <- function( } .loadSumStatsEntry( .resolveRel(as.character(df$sumStatsPath[[i]]), base), - region, + .manifestWindowFor(i, windows), mapping, sampleSelect, formatMapping, @@ -2016,7 +2114,7 @@ loadGwasSumStatsFromManifest <- function( .loadQtlSumStatsEntries <- function( df, base, - region, + windows, columnMapping, sampleSelect, formatMapping, @@ -2029,7 +2127,7 @@ loadGwasSumStatsFromManifest <- function( .loadQtlSumStatsEntry, df = df, base = base, - region = region, + windows = windows, columnMapping = columnMapping, sampleSelect = sampleSelect, formatMapping = formatMapping, @@ -2055,19 +2153,32 @@ loadGwasSumStatsFromManifest <- function( #' its sumstats file need not carry a per-variant \code{N} column; #' \code{\link{summaryStatsQc}} fills \code{N} from the scalar. (Unlike the #' GWAS loader, there are no \code{nCase}/\code{nControl} columns: molecular -#' QTL traits are quantitative.) +#' QTL traits are quantitative.) Optional BED-style +#' \code{chrom}/\code{start}/\code{end} columns, with a 0-based +#' \code{start} as in BED, give each tuple its own window, read and kept as +#' with \code{which}; a manifest that has them cannot also be given +#' \code{which}. Optional \code{traitStart}/\code{traitEnd} columns, on +#' the row's \code{chrom} and 0-based the same way, give the trait's +#' position (\code{traitPos}). #' @param genome Genome build; reconciled with a \code{genome} column. #' @param ldReference A genotype panel (see \code{\link{readGenotypes}}) or #' spec, used for every row; where a row also names an #' \code{ldReferencePath} the two must agree. Omit it to give each row the #' reference its \code{ldReferencePath} names. -#' @param region,minLdOverlapWarn,columnMapping,sampleSelect,formatMapping As -#' for \code{\link{loadGwasSumStatsFromManifest}}. +#' @param which Optional analysis window shared by every tuple: a +#' \code{GRanges}, or the path of a BED file, read as BED with a 0-based +#' start. One window only, since a tuple has one: tuples with windows +#' of their own give them in the manifest's columns. Only the variants +#' inside it are read, when the file is tabix-indexed (otherwise the whole +#' file is read, with a warning), and it is each tuple's \code{region} (see +#' \code{\link{QtlSumStats}}). +#' @param minLdOverlapWarn,columnMapping,sampleSelect,formatMapping As for +#' \code{\link{loadGwasSumStatsFromManifest}}. #' @param traitColumn Optional column of the sumstats file naming the trait of #' each row (e.g. \code{"molecular_trait_id"} in a cis-QTL scan, which writes #' every gene into one table). When set, each manifest row keeps only the #' rows whose \code{traitColumn} equals that row's \code{trait}. Without it -#' a multi-trait file loads whole, since \code{region} restriction needs a +#' a multi-trait file loads whole, since \code{which} restriction needs a #' tabix index and neighbouring cis windows overlap regardless. #' @param variantIdAlleles Where to find the alleles when the file has no #' \code{A1}/\code{A2} columns -- a cis-QTL scan reports effect + se against @@ -2088,13 +2199,14 @@ loadGwasSumStatsFromManifest <- function( #' manifest <- data.frame(study = "s1", context = "brain", #' trait = "ENSG1", sumStatsPath = tsv) #' loadQtlSumStatsFromManifest(manifest = manifest, genome = "hg38", -#' ldReference = ldStem, region = "chr22:10000000-19000000") +#' ldReference = ldStem, +#' which = GenomicRanges::GRanges("chr22:10000000-19000000")) #' @export loadQtlSumStatsFromManifest <- function( manifest, genome = NULL, ldReference = NULL, - region = NULL, + which = NULL, minLdOverlapWarn = 0.5, columnMapping = NULL, sampleSelect = NULL, @@ -2105,13 +2217,14 @@ loadQtlSumStatsFromManifest <- function( variantIdAlleles <- arg_match(variantIdAlleles) base <- .manifestBase(manifest) df <- .qtlSumStatsManifest(manifest) - genome <- .reconcileScalar(df[["genome"]], genome, "genome") + genome <- .manifestGenome(df, genome, base, "loadQtlSumStatsFromManifest") ldReferenceSpecs <- .resolveLdRefSpecs(df, ldReference, base) nSample <- .qtlManifestNSample(df) + windows <- .qtlManifestWindows(df, which) entries <- .loadQtlSumStatsEntries( df, base, - region, + windows, columnMapping, sampleSelect, formatMapping, @@ -2134,10 +2247,29 @@ loadQtlSumStatsFromManifest <- function( genome, ldReference, nSample$nSampleCol - ) + ), + region = windows$perRow %||% windows$shared, + traitPos = .manifestTraitPos(df, "QtlSumStats") ) } +# A QTL load's windows (.manifestWindows()). A tuple has one window, so the +# `which` argument, which every tuple shares, must be one; tuples with +# windows of their own give them in the manifest's chrom/start/end columns. +# @noRd +.qtlManifestWindows <- function(df, which) { + windows <- .manifestWindows(df, which, "QtlSumStats") + if (length(windows$shared) > 1L) { + abort(glue( + "loadQtlSumStatsFromManifest(): `which` must be one window, ", + "which every tuple shares (got {length(windows$shared)}). A ", + "tuple with a window of its own gives it in the manifest's ", + "chrom/start/end columns." + )) + } + windows +} + # A QtlSumStats manifest's rows, its columns under their canonical names and # the required ones present. # @noRd @@ -2226,16 +2358,11 @@ loadQtlSumStatsFromManifest <- function( #' \code{study}); one \code{QtlDataset} is built per study group. #' @param sumStatsManifest Optional QtlSumStats manifest (see #' \code{\link{loadQtlSumStatsFromManifest}}). -#' @param genome,ldReference,region,minLdOverlapWarn Passed to the QtlSumStats +#' @param genome,ldReference,which,minLdOverlapWarn Passed to the QtlSumStats #' loader for \code{sumStatsManifest}. #' @param columnMapping,sampleSelect,formatMapping Passed to the QtlSumStats #' loader for \code{sumStatsManifest}. #' @param transposeCovariates Transpose covariate TSVs (QTLtools layout). -#' @param scaleResiduals Pass-through \code{\link{QtlDataset}} argument, -#' applied to every study. -#' @param genotypeFilterParam Pass-through \code{\link{QtlDataset}} filtering -#' options, built with \code{\link{GenotypeFilterParam}} and applied to -#' every study. #' @return A \code{MultiStudyQtlDataset} object. #' @examples #' d <- system.file("extdata", "qtl_mini", package = "pecotmr") @@ -2250,29 +2377,21 @@ loadMultiStudyQtlDatasetFromManifest <- function( sumStatsManifest = NULL, genome = NULL, ldReference = NULL, - region = NULL, + which = NULL, minLdOverlapWarn = 0.5, columnMapping = NULL, sampleSelect = NULL, formatMapping = NULL, - transposeCovariates = FALSE, - scaleResiduals = TRUE, - genotypeFilterParam = GenotypeFilterParam() + transposeCovariates = FALSE ) { assertFlag(transposeCovariates) assertNumber(minLdOverlapWarn, lower = 0, upper = 1) - .assertQtlPassThrough(scaleResiduals, genotypeFilterParam) - qc <- .msqQcArgs(scaleResiduals, genotypeFilterParam) - qtlDatasets <- .msqBuildDatasets( - qtlDatasetsManifest, - transposeCovariates, - qc - ) + qtlDatasets <- .msqBuildDatasets(qtlDatasetsManifest, transposeCovariates) sumStats <- .msqLoadSumStats( sumStatsManifest, genome, ldReference, - region, + which, minLdOverlapWarn, columnMapping, sampleSelect, @@ -2281,20 +2400,9 @@ loadMultiStudyQtlDatasetFromManifest <- function( MultiStudyQtlDataset(qtlDatasets = qtlDatasets, sumStats = sumStats) } -# Bundle the per-study QC / sample-filter arguments into a list. What remains -# after GenotypeFilterParam() absorbed the seven filter fields: this is what is -# spliced into QtlDataset(). -# @noRd -.msqQcArgs <- function(scaleResiduals, genotypeFilterParam) { - list( - scaleResiduals = scaleResiduals, - genotypeFilterParam = genotypeFilterParam - ) -} - # Read the qtlDatasets manifest and build one QtlDataset per study. # @noRd -.msqBuildDatasets <- function(qtlDatasetsManifest, transposeCovariates, qc) { +.msqBuildDatasets <- function(qtlDatasetsManifest, transposeCovariates) { base <- .manifestBase(qtlDatasetsManifest) df <- .canonManifestCols( .readManifest(qtlDatasetsManifest), @@ -2309,8 +2417,7 @@ loadMultiStudyQtlDatasetFromManifest <- function( .msqDatasetForStudy, df = df, base = base, - transposeCovariates = transposeCovariates, - qc = qc + transposeCovariates = transposeCovariates ), studies ) @@ -2322,7 +2429,7 @@ loadMultiStudyQtlDatasetFromManifest <- function( sumStatsManifest, genome, ldReference, - region, + which, minLdOverlapWarn, columnMapping, sampleSelect, @@ -2335,7 +2442,7 @@ loadMultiStudyQtlDatasetFromManifest <- function( sumStatsManifest, genome = genome, ldReference = ldReference, - region = region, + which = which, minLdOverlapWarn = minLdOverlapWarn, columnMapping = columnMapping, sampleSelect = sampleSelect, @@ -2345,13 +2452,13 @@ loadMultiStudyQtlDatasetFromManifest <- function( # ---- map/apply helpers (lambda-free callbacks) --------------------------- -# One sumstats entry's canonical chromosomes (empty for NULL / 0-length gr). +# One sumstats entry's chromosomes (empty for NULL / 0-length gr). # @noRd .mlEntryChroms <- function(gr) { if (is.null(gr) || length(gr) == 0L) { return(character(0)) } - canonChrom(as.character(GenomicRanges::seqnames(gr))) + as.character(GenomicRanges::seqnames(gr)) } # The tabix seqname matching query seqname `w` (chr-prefix tolerant); NA if @@ -2368,10 +2475,18 @@ loadMultiStudyQtlDatasetFromManifest <- function( is.na(x) || is.null(x) } -# The first ALT allele (as character) of one VCF row's alt set. +# Each VCF row's first ALT allele, as character: one unlist() of the alt sets +# and an index into it, not an as.list() walk that pulls the rows out one at +# a time (about two seconds on three thousand variants). A row with no ALT +# allele gives NA. # @noRd -.mlFirstAlt <- function(a) { - as.character(a)[[1L]] +.mlFirstAlts <- function(altList) { + n <- lengths(altList) + flat <- as.character(unlist(altList, use.names = FALSE)) + first <- cumsum(n) - n + 1L + out <- rep(NA_character_, length(n)) + out[n > 0L] <- flat[first[n > 0L]] + out } # One QtlSumStats entry for manifest row `i` (per-row columnMapping override). @@ -2380,7 +2495,7 @@ loadMultiStudyQtlDatasetFromManifest <- function( i, df, base, - region, + windows, columnMapping, sampleSelect, formatMapping, @@ -2408,7 +2523,7 @@ loadMultiStudyQtlDatasetFromManifest <- function( } .loadSumStatsEntry( .resolveRel(as.character(df$sumStatsPath[[i]]), base), - region, + .manifestWindowFor(i, windows), mapping, sampleSelect, formatMapping, @@ -2424,12 +2539,11 @@ loadMultiStudyQtlDatasetFromManifest <- function( # One study's QtlDataset from its manifest rows. # @noRd -.msqDatasetForStudy <- function(s, df, base, transposeCovariates, qc) { +.msqDatasetForStudy <- function(s, df, base, transposeCovariates) { .buildQtlDatasetFromRows( df[as.character(df$study) == s, , drop = FALSE], s, base, - transposeCovariates, - qc + transposeCovariates ) } diff --git a/R/mashPipeline.R b/R/mashPipeline.R index 055d4c25..89c27f13 100644 --- a/R/mashPipeline.R +++ b/R/mashPipeline.R @@ -926,7 +926,7 @@ MashComponentParam <- function( return(list()) } ctors <- .mashComponentCtors() - .nestedAssertEngines(given, ctors, NULL, "MashComponentParam") + .nestedAssertEngines(given, ctors, "MashComponentParam") imap(given, .nestedElement, ctors = ctors, label = "MashComponentParam") } @@ -2545,20 +2545,29 @@ mergeMashData <- function(resData, oneData) { # lead (max PIP) variant. # @noRd .mashFmrMatrices <- function(obj, coverage) { - rawMe <- marginalEffects(obj) - rawCs <- credibleSets(obj, coverage = coverage) - if (!all(is_in(c("variant_id", "context", "beta", "se"), names(rawMe)))) { + # Both views are ranged; the pivot works on their per-variant columns. + rawMe <- as_tibble( + as.data.frame(S4Vectors::mcols(marginalEffects(obj)), optional = TRUE) + ) + rawCs <- as_tibble( + as.data.frame( + S4Vectors::mcols(credibleSets(obj, coverage = coverage)), + optional = TRUE + ) + ) + cond <- .mashFmrConditionColumn(obj) + if (!all(is_in(c("variant_id", cond, "beta", "se"), names(rawMe)))) { msg <- glue( - "mashInput: marginalEffects() must return variant_id/context/", - "beta/se columns; a fine-mapping result with >= 2 contexts is ", - "required." + "mashInput: marginalEffects() must return variant_id/{cond}/", + "beta/se columns; a fine-mapping result with >= 2 ", + "{if (cond == 'study') 'studies' else 'contexts'} is required." ) abort(msg) } pinned <- .mashFmrMethodPin(rawMe, rawCs) me <- pinned$me cs <- pinned$cs - contexts <- unique(me$context) + contexts <- unique(me[[cond]]) variants <- unique(me$variant_id) empty <- matrix( NA_real_, @@ -2566,15 +2575,23 @@ mergeMashData <- function(resData, oneData) { length(contexts), dimnames = list(variants, contexts) ) - # One (variant, context) cell per long-format row; the rest stay NA. - cell <- cbind(match(me$variant_id, variants), match(me$context, contexts)) + # One (variant, condition) cell per long-format row; the rest stay NA. + cell <- cbind(match(me$variant_id, variants), match(me[[cond]], contexts)) list( b = replace(empty, cell, me$beta), s = replace(empty, cell, me$se), - strongRows = .mashFmrStrongRows(cs, variants) + strongRows = .mashFmrStrongRows(cs, variants, cond) ) } +# The column a fine-mapping result's conditions are read from. A QTL result's +# are its contexts. A GWAS result has no context axis, so its conditions are +# its studies -- as they are for a GwasSumStats. +# @noRd +.mashFmrConditionColumn <- function(obj) { + if (methods::is(obj, "GwasFineMappingResult")) "study" else "context" +} + # A multi-method fine-mapping result would duplicate (variant, context) cells; # pin the first method so the pivot is unambiguous. # @noRd @@ -2595,6 +2612,11 @@ mergeMashData <- function(resData, oneData) { list(me = me, cs = cs) } +# @noRd +.mashKeyNa <- function(v) { + replace(as.character(v), is.na(v), "\u0001NA") +} + # The max-PIP variant among one credible set's rows. # @noRd .mashLeadVariant <- function(rows, cs) { @@ -2602,13 +2624,18 @@ mergeMashData <- function(resData, oneData) { } # Row indices (into `variants`) of each credible set's lead (max PIP) variant. +# A set is named by its condition and its index -- and, for a GWAS study +# fine-mapped block by block, its block, since set indices restart in each. # @noRd -.mashFmrStrongRows <- function(cs, variants) { +.mashFmrStrongRows <- function(cs, variants, cond = "context") { csCol <- names(cs)[str_detect(names(cs), "^cs_")] strongVar <- if ( nrow(cs) > 0L && length(csCol) > 0L && is_in("pip", names(cs)) ) { - grp <- interaction(cs$context, cs[[csCol[[1L]]]], drop = TRUE) + keys <- c(cond, intersect("blockId", names(cs)), csCol[[1L]]) + # NA spelled out: the view NA-fills an axis a row lacks (a QTL row's + # blockId), and interaction() would drop every NA-keyed row. + grp <- interaction(map(as.list(cs[keys]), .mashKeyNa), drop = TRUE) map_chr(split(seq_len(nrow(cs)), grp), .mashLeadVariant, cs = cs) } else { character(0) @@ -2739,7 +2766,8 @@ mergeMashData <- function(resData, oneData) { #' fine-mapping result objects, one per region. Names disambiguate #' rownames across regions (defaults to \code{region1}, \code{region2}, ...). #' For \code{QtlSumStats} inputs \code{\link{summaryStatsQc}} must have been -#' run (the matrix builder rejects un-QC'd SumStats). +#' run (the matrix builder rejects un-QC'd SumStats). The conditions are a +#' QTL object's contexts and a GWAS object's studies. #' @param nRandom,nNull Per-object random / null sample sizes (default 10 each). #' @param excludeCondition Character vector of condition (column) names to drop. #' @param coverage Credible-set coverage for the strong selection on @@ -2942,7 +2970,7 @@ mashInput <- function( #' \code{\link{parseVariantId}} (with a synthetic-position fallback for ids #' that do not encode coordinates); \code{A1} / \code{A2} / \code{N} are #' placeholders because a Z-only input carries no alleles or sample sizes -#' (mash reads only Z). A pass-through \code{qcInfo} record is set so the +#' (mash reads only Z). Pass-through \code{qcOptions()} are set so the #' result clears the mash QC gate. #' @param z Numeric matrix (variants x conditions). \code{rownames(z)} are #' variant ids (ideally \code{chr:pos:A2:A1}); \code{colnames(z)} label the @@ -2962,7 +2990,7 @@ mashInput <- function( #' @param genome Genome build. Default \code{"GRCh38"}. #' @param n Placeholder per-variant sample size. Default \code{1000}. #' @param a1,a2 Placeholder alleles. Defaults \code{"A"} / \code{"G"}. -#' @param role Tag stored in the \code{qcInfo} record. Default \code{"mash"}. +#' @param role Tag stored in the \code{qcOptions()}. Default \code{"mash"}. #' @return A \code{\link{QtlSumStats}} with one entry per condition (column). #' @importFrom GenomicRanges GRanges #' @importFrom IRanges IRanges @@ -3034,7 +3062,7 @@ qtlSumStatsFromZMatrix <- function( #' @param genome Genome build. Default \code{"GRCh38"}. #' @param n Placeholder per-variant sample size. Default \code{1000}. #' @param a1,a2 Placeholder alleles. Defaults \code{"A"} / \code{"G"}. -#' @param role Tag stored in the \code{qcInfo} record. Default \code{"mash"}. +#' @param role Tag stored in the \code{qcOptions()}. Default \code{"mash"}. #' @return A \code{\link{QtlSumStats}} with one entry per condition (column). #' @seealso \code{\link{qtlSumStatsFromZMatrix}}, \code{\link{mashModelFit}} #' @importFrom GenomicRanges GRanges @@ -3110,7 +3138,7 @@ qtlSumStatsFromBetaMatrix <- function( # Decode chrom/pos from the variant ids, synthesising where they do not # parse. An unparseable id still needs a placeable coordinate: the GRanges # is keyed by the variant id, so the range only has to be unique and -# ordered, not correct. +# ordered, not correct. Chromosomes come out in UCSC style (chr1). # @noRd #' @importFrom rlang try_fetch .qszmCoords <- function(vids) { @@ -3177,7 +3205,7 @@ qtlSumStatsFromBetaMatrix <- function( entry = entries, genome = genome, ldReference = ldReference, - qcInfo = list(role = role, entryAudit = vector("list", nCond)) + qcOptions = list(role = role) ) } @@ -3262,10 +3290,10 @@ qtlSumStatsFromBetaMatrix <- function( ) abort(msg) } - if (length(qcInfo(x)) == 0L) { + if (length(qcOptions(x)) == 0L) { msg <- glue( "mashPipeline: '{role}' SumStats has no QC info ", - "(length(qcInfo(x)) == 0L). ", + "(length(qcOptions(x)) == 0L). ", "Run summaryStatsQc() on the SumStats before passing it to ", "mashPipeline()." ) @@ -3384,8 +3412,11 @@ qtlSumStatsFromBetaMatrix <- function( } else { c("SNP", "Z") } + # One read per context. A GWAS study split by chromosome or LD block is + # several rows of one context (its study), and each read already stitches + # every row of it, so reading once per row would read the study k times. rows <- map( - rowsInBlock, + rowsInBlock[!duplicated(setup$contextCol[rowsInBlock])], .mashContextRow, x = x, setup = setup, @@ -3393,19 +3424,11 @@ qtlSumStatsFromBetaMatrix <- function( resolvedScale = resolvedScale ) contexts <- map_chr(rows, "context") - # A later row overwrites an earlier one sharing a context, as the keyed - # assignment did; the variant order is first-seen across all rows. - lastPerContext <- !duplicated(contexts, fromLast = TRUE) + # The variant order is first-seen across the contexts. list( variantOrder = unique(.mashConcatChr(map(rows, "snps"))), - perContextB = set_names( - map(rows[lastPerContext], "b"), - contexts[lastPerContext] - ), - perContextSe = set_names( - map(rows[lastPerContext], "se"), - contexts[lastPerContext] - ) + perContextB = set_names(map(rows, "b"), contexts), + perContextSe = set_names(map(rows, "se"), contexts) ) } @@ -3440,7 +3463,7 @@ qtlSumStatsFromBetaMatrix <- function( # @noRd .mashRowDf <- function(x, rIdx, setup, requireCols) { if (setup$isQtl) { - as.data.frame( + .sumStatsDf( x, studyName = setup$studyCol[[rIdx]], context = setup$contextCol[[rIdx]], @@ -3448,7 +3471,7 @@ qtlSumStatsFromBetaMatrix <- function( require = requireCols ) } else { - as.data.frame( + .sumStatsDf( x, studyName = setup$studyCol[[rIdx]], require = requireCols diff --git a/R/overlapTopLoci.R b/R/overlapTopLoci.R index 272dd66f..9c1027d3 100644 --- a/R/overlapTopLoci.R +++ b/R/overlapTopLoci.R @@ -79,7 +79,9 @@ #' @return A \code{GRanges} keyed on the QTL variant #' (\code{variant_id, chrom, pos, A1, A2} in \code{mcols()}) with all other #' columns prefixed \code{qtl_} / \code{gwas_}. Zero ranges when there is no -#' allele-aware overlap. Take a table with \code{as.data.frame()}. +#' allele-aware overlap. Take a table with \code{as.data.frame()}. Its +#' \code{seqinfo()} names the genome build the two results name; results +#' naming different builds are refused. #' @seealso \code{\link{topLoci}}, \code{matchVariants} #' @examples #' data(qtlFineMappingLbfExample) @@ -98,6 +100,7 @@ setMethod( "overlapTopLoci", signature("QtlFineMappingResult", "GwasFineMappingResult"), function(qtl, gwas, signalCutoff = 0.025) { + build <- .inputsBuild(list(qtl, gwas), "overlapTopLoci") keyCols <- c("variant_id", "chrom", "pos", "A1", "A2") coordCols <- c("chrom", "pos", "A1", "A2") # mcols() rather than as.data.frame() on the ranges: the join @@ -107,14 +110,20 @@ setMethod( qtlTl <- .overlapTopLociTable(qtl, signalCutoff) gwasTl <- .overlapTopLociTable(gwas, signalCutoff) if (nrow(qtlTl) == 0L || nrow(gwasTl) == 0L) { - return(.overlapEmptyReturn(qtlTl, gwasTl, coordCols, keyCols)) + return(.withGenome( + .overlapEmptyReturn(qtlTl, gwasTl, coordCols, keyCols), + build + )) } # Allele-aware correspondence between the unique QTL + GWAS variant # sets. target = GWAS, ref = QTL, so `sign` is the flip applied to the # GWAS side. vmap <- .overlapVariantMap(qtlTl, gwasTl) if (is.null(vmap)) { - return(.overlapEmptyReturn(qtlTl, gwasTl, coordCols, keyCols)) + return(.withGenome( + .overlapEmptyReturn(qtlTl, gwasTl, coordCols, keyCols), + build + )) } # No zero-row check on `g`: every gwas_vid in `vmap` is drawn from # gwasTl$variant_id, so once vmap is non-NULL the inner join above @@ -131,7 +140,7 @@ setMethod( intersect(keyCols, names(merged)), setdiff(names(merged), keyCols) ) - .overlapToGRanges(select(merged, all_of(ordered))) + .withGenome(.overlapToGRanges(select(merged, all_of(ordered))), build) } ) @@ -215,7 +224,7 @@ setMethod( } p <- parseVariantId(df$variant_id) gr <- GenomicRanges::GRanges( - seqnames = str_c("chr", p$chrom), + seqnames = p$chrom, ranges = IRanges::IRanges(start = p$pos, width = 1L) ) S4Vectors::`mcols<-`( diff --git a/R/pvalCombineWrappers.R b/R/pvalCombineWrappers.R index 10cfbf11..234d021c 100644 --- a/R/pvalCombineWrappers.R +++ b/R/pvalCombineWrappers.R @@ -121,19 +121,28 @@ pvalHmp <- function(pvals) { abort(msg) } +# poolr's empirical adjustment works out which test it is running from its +# own call, as.character(sys.call()[1]) with any "poolr::" prefix stripped. +# So the test is called as poolr::(...): a function object inlined +# into the call, as exec() would do, names no test and fails there. +# @noRd +#' @importFrom rlang call2 pvalPoolr <- function(pvals, method, R, methodArgs = PoolrOptions()) { if (!requireNamespace("poolr", quietly = TRUE)) { abort("Package 'poolr' is required for this method.") } - fn <- switch( - method, - fisher = poolr::fisher, - stouffer = poolr::stouffer, - invchisq = poolr::invchisq, + if (!is_in(method, c("fisher", "stouffer", "invchisq"))) { .abortUnknownMethod("poolr", method) - ) + } args <- as.list(methodArgs) - exec(fn, pvals, R = .poolrDependence(R, method, args), !!!args)$p + test <- call2( + method, + pvals, + R = .poolrDependence(R, method, args), + !!!args, + .ns = "poolr" + ) + eval(test)$p } # `R` in the form poolr's adjustment reads it. `R` holds the correlations @@ -917,6 +926,6 @@ PvalMethodsParam <- function( return(list()) } ctors <- .pvalMethodCtors() - .nestedAssertEngines(given, ctors, NULL, "PvalMethodsParam") + .nestedAssertEngines(given, ctors, "PvalMethodsParam") imap(given, .nestedElement, ctors = ctors, label = "PvalMethodsParam") } diff --git a/R/qtlAssociationPostprocess.R b/R/qtlAssociationPostprocess.R index 375fb9d1..b41f89e4 100644 --- a/R/qtlAssociationPostprocess.R +++ b/R/qtlAssociationPostprocess.R @@ -166,7 +166,7 @@ QvalueOptions <- function(...) { # fdrThreshold stashed by qtlAssociationPostprocess. Uses the SAME package math # as the correction (p.adjust for the Bonferroni-adjusted per-variant p). .qapSignificanceMask <- function(x, method, threshold = NULL) { - recipe <- qcInfo(x)$associationPostprocess + recipe <- qcOptions(x)$associationPostprocess if (is.null(recipe)) { msg <- glue( "This QtlSumStats was not produced by ", @@ -348,11 +348,10 @@ setMethod( } ) -# Rebuild a QtlSumStats with extra row columns added + a new qcInfo. Column +# Rebuild a QtlSumStats with extra row columns added + new qcOptions. Column # assignment on the S4 subclass itself coerces per-element, so we coerce to a -# plain DFrame, add the columns, and re-wrap (the same rebuild idiom as -# subsetChr). -.qapRebuild <- function(x, newCols, qcInfo) { +# plain DFrame, add the columns, and re-wrap. +.qapRebuild <- function(x, newCols, qcOptions) { # The collection is a GRangesList now, not a DFrame: the per-variant # GRanges are the elements and `newCols` are per-tuple metadata, so the # rebuild keeps the elements as-is and only rewrites mcols. @@ -369,11 +368,11 @@ setMethod( } else { cbind(kept, S4Vectors::DataFrame(added, check.names = FALSE)) } - # Rebuilding from as.list() starts from the elements' own seqinfo, so the + # Rebuilding from the elements starts from their own seqinfo, so the # build is written back explicitly -- it is collection-level state, and # there is no genome slot to carry it any more. built <- .withGenomeBuild( - GenomicRanges::GRangesList(as.list(x)), + .rtlJoinParts(list(x)), TRUE, unique(unname(GenomeInfoDb::genome(x))) ) @@ -382,7 +381,7 @@ setMethod( "QtlSumStats", grl, ldReference = ldReference(x), - qcInfo = qcInfo + qcOptions = qcOptions ) } @@ -442,7 +441,7 @@ setMethod( # annotateSignificance can reproduce significance cheaply (thresholds, # not flags). qc <- list_assign( - qcInfo(x), + qcOptions(x), associationPostprocess = list( fdrThreshold = fdrThreshold, mafCutoff = mafCutoff, diff --git a/R/qtlEnrichmentPipeline.R b/R/qtlEnrichmentPipeline.R index e5b30bb3..c2903b1c 100644 --- a/R/qtlEnrichmentPipeline.R +++ b/R/qtlEnrichmentPipeline.R @@ -20,7 +20,7 @@ setClass( #' @title Arguments For The QTL Enrichment Estimator #' @description The algorithmic settings \code{\link{qtlEnrichment}} takes, #' as one checked bundle. Everything else that function accepts --- the two -#' data arguments, \code{numThreads}, \code{seed}, \code{verbose}, and the +#' data arguments, \code{BPPARAM}, \code{seed}, \code{verbose}, and the #' \code{alignNames} switch --- is the pipeline's own business and is not #' settable here. #' @param numGwas Number of GWAS variants used to estimate \code{piGwas}. @@ -81,17 +81,22 @@ QtlEnrichmentParam <- function( #' \itemize{ #' \item \code{gwasFineMappingResult}: the genome-wide outcome collection. #' Each row's stored fit (\code{\link{susieFit}}) must carry a \code{pip} -#' vector. One PIP vector is built per outcome trait -- keyed by -#' \code{study} for a GWAS collection (one trait per study) and by -#' (\code{study}, \code{context}, \code{trait}) for a QTL one, since a -#' variant's PIP differs between molecular traits and pooling them would -#' collide. +#' vector. One PIP vector is built per outcome fit, across all its LD +#' blocks -- keyed by (\code{study}, \code{method}) for a GWAS collection +#' (one trait per study) and by (\code{study}, \code{context}, +#' \code{trait}, \code{method}) for a QTL one, since a variant's PIP +#' differs between molecular traits and between fine-mapping methods, and +#' pooling them would collide. #' \item \code{qtlFineMappingResult}: the annotation collection. Each row's #' stored fit must carry \code{alpha}, \code{pip}, and #' prior-variance fields (\code{V}). Its region fits are pooled per -#' (\code{study}, \code{context}) -- per \code{study} alone for a GWAS -#' collection, which has no context axis. +#' (\code{study}, \code{context}, \code{method}) -- per (\code{study}, +#' \code{method}) for a GWAS collection, which has no context axis -- so +#' each method's fits make their own estimate rather than counting every +#' region once per method. #' } +#' Both sides' fits are read whole, so a row narrowed since its fit warns +#' (condition class \code{pecotmrFitCoverage}). #' #' @section LD reference compatibility check: Every row of a GWAS outcome #' collection must have an \code{ldReference} (it should be RSS-derived). @@ -113,17 +118,19 @@ QtlEnrichmentParam <- function( #' \code{lambda}, \code{impN}, \code{doubleShrinkage} and #' \code{besselCorrection}. A bare list is refused, since it cannot be #' checked. -#' @param numThreads Number of threads used by \code{qtlEnrichment}. Default -#' \code{1}. +#' @param BPPARAM A \code{BiocParallelParam} handed to +#' \code{\link{qtlEnrichment}}, whose multiple-imputation threads number +#' its workers. Default \code{SerialParam()}. #' @param seed Integer or \code{NULL}. Base random seed forwarded to #' \code{\link{qtlEnrichment}} for reproducible multiple imputation. #' \code{NULL} (default) draws a nondeterministic seed. #' @param verbose Logical. Print progress messages. Default \code{TRUE}. -#' @return A tibble with one row per (outcome trait, annotation unit) pair. +#' @return A tibble with one row per (outcome fit, annotation unit) pair. #' The identity columns are \code{gwasStudy}, \code{gwasContext}, -#' \code{gwasTrait}, \code{qtlStudy}, \code{qtlContext}; the axes a side does -#' not have are \code{NA} (\code{gwasContext} / \code{gwasTrait} for a GWAS -#' outcome, \code{qtlContext} for a GWAS annotation). Suitable as the +#' \code{gwasTrait}, \code{gwasMethod}, \code{qtlStudy}, \code{qtlContext}, +#' \code{qtlMethod}; the axes a side does not have are \code{NA} +#' (\code{gwasContext} / \code{gwasTrait} for a GWAS outcome, +#' \code{qtlContext} for a GWAS annotation). Suitable as the #' \code{enrichment} argument to \code{\link{colocPipeline}}, which joins on #' those columns. #' @@ -153,11 +160,12 @@ qtlEnrichmentPipeline <- function( gwasFineMappingResult, qtlFineMappingResult, qtlEnrichmentParam = QtlEnrichmentParam(), - numThreads = 1L, + BPPARAM = SerialParam(), seed = NULL, verbose = TRUE ) { .assertMethodParam(qtlEnrichmentParam, "QtlEnrichmentParam") + .assertBpparam(BPPARAM) .enrValidateInputs(gwasFineMappingResult, qtlFineMappingResult) prep <- .enrPrepare(gwasFineMappingResult, qtlFineMappingResult) gwasTuples <- prep$gwasTuples @@ -170,7 +178,7 @@ qtlEnrichmentPipeline <- function( qtlRegionsByTuple = prep$qtlRegionsByTuple, alignedByTuple = alignedByTuple, qtlEnrichmentParam = qtlEnrichmentParam, - numThreads = numThreads, + BPPARAM = BPPARAM, seed = seed, verbose = verbose, gwasFineMappingResult = gwasFineMappingResult, @@ -232,6 +240,11 @@ qtlEnrichmentPipeline <- function( ) abort(msg) } + # Each row's fit is read whole, so a row narrowed since its fit warns. + .fitCoverageCheckedAll( + list(gwasFineMappingResult, qtlFineMappingResult), + "qtlEnrichmentPipeline()" + ) gwasPipByTuple <- map( seq_len(nrow(gwasTuples)), .enrGwasPipForRow, @@ -259,27 +272,32 @@ qtlEnrichmentPipeline <- function( ) } -# The outcome side's per-trait keys: one PIP vector is built per key. A GWAS +# The outcome side's per-fit keys: one PIP vector is built per key. A GWAS # collection carries one trait per study, so its QTL-only axes read NA and the -# key collapses to (study). +# key collapses to (study, method). The method is part of it: two methods' +# fits of one trait are two PIP vectors, and pooling them would put two +# different PIPs on every variant. # @noRd .enrOutcomeTuples <- function(fmr) { distinct(tibble( gwasStudy = .fmrIdentityColumn(fmr, "study"), gwasContext = .fmrIdentityColumn(fmr, "context"), - gwasTrait = .fmrIdentityColumn(fmr, "trait") + gwasTrait = .fmrIdentityColumn(fmr, "trait"), + gwasMethod = .fmrIdentityColumn(fmr, "method") )) } -# The annotation side's keys: (study, context), the unit whose region fits are -# pooled into one enrichment estimate. The joint key matters -- context alone -# would silently merge two studies sharing a context label -- and a GWAS -# annotation pools its blocks under one NA-context key. +# The annotation side's keys: (study, context, method), the unit whose region +# fits are pooled into one enrichment estimate. The joint key matters -- +# context alone would silently merge two studies sharing a context label, and +# without the method each region would count once per method that fit it -- +# and a GWAS annotation pools its blocks under one NA-context key. # @noRd .enrAnnotationTuples <- function(fmr) { distinct(tibble( qtlStudy = .fmrIdentityColumn(fmr, "study"), - qtlContext = .fmrIdentityColumn(fmr, "context") + qtlContext = .fmrIdentityColumn(fmr, "context"), + qtlMethod = .fmrIdentityColumn(fmr, "method") )) } @@ -290,7 +308,8 @@ qtlEnrichmentPipeline <- function( list( study = gwasTuples$gwasStudy[[k]], context = gwasTuples$gwasContext[[k]], - trait = gwasTuples$gwasTrait[[k]] + trait = gwasTuples$gwasTrait[[k]], + method = gwasTuples$gwasMethod[[k]] ) } @@ -298,7 +317,8 @@ qtlEnrichmentPipeline <- function( .enrAnnotationIdent <- function(qtlTuples, k) { list( study = qtlTuples$qtlStudy[[k]], - context = qtlTuples$qtlContext[[k]] + context = qtlTuples$qtlContext[[k]], + method = qtlTuples$qtlMethod[[k]] ) } @@ -352,7 +372,7 @@ qtlEnrichmentPipeline <- function( qtlRegionsByTuple, alignedByTuple = alignedByTuple, qtlEnrichmentParam, - numThreads, + BPPARAM, seed, verbose, gwasFineMappingResult = gwasFineMappingResult, @@ -378,7 +398,7 @@ qtlEnrichmentPipeline <- function( qtlRegionsByTuple = qtlRegionsByTuple, alignedByTuple = alignedByTuple, qtlEnrichmentParam = qtlEnrichmentParam, - numThreads = numThreads, + BPPARAM = BPPARAM, seed = seed, verbose = verbose, gwasFineMappingResult = gwasFineMappingResult, @@ -398,7 +418,7 @@ qtlEnrichmentPipeline <- function( qtlRegionsByTuple, alignedByTuple = alignedByTuple, qtlEnrichmentParam, - numThreads, + BPPARAM, seed, verbose, gwasFineMappingResult = gwasFineMappingResult, @@ -421,7 +441,7 @@ qtlEnrichmentPipeline <- function( k, alignedByTuple = alignedByTuple, qtlEnrichmentParam = qtlEnrichmentParam, - numThreads = numThreads, + BPPARAM = BPPARAM, seed = seed, verbose = verbose, gwasFineMappingResult = gwasFineMappingResult, @@ -466,7 +486,7 @@ qtlEnrichmentPipeline <- function( k, alignedByTuple, qtlEnrichmentParam, - numThreads, + BPPARAM, seed, verbose, gwasFineMappingResult, @@ -487,7 +507,7 @@ qtlEnrichmentPipeline <- function( qtlEnrichment, gwasPip = gwasPip, susieQtlRegions = aligned, - numThreads = numThreads, + BPPARAM = BPPARAM, seed = seed, verbose = verbose, alignNames = FALSE, @@ -522,7 +542,15 @@ qtlEnrichmentPipeline <- function( # annotation unit's. # @noRd .enrIdCols <- function() { - c("gwasStudy", "gwasContext", "gwasTrait", "qtlStudy", "qtlContext") + c( + "gwasStudy", + "gwasContext", + "gwasTrait", + "gwasMethod", + "qtlStudy", + "qtlContext", + "qtlMethod" + ) } # The empty enrichment result table, with the same columns a populated one has. @@ -563,19 +591,20 @@ qtlEnrichmentPipeline <- function( return(NULL) } pip <- as.numeric(fit$pip) - ids <- names(fit$pip) %||% .fmrPartsVariantIds(parts) + ids <- names(fit$pip) %||% .partsFitIds(parts) if (length(ids) != length(pip)) { return(NULL) } set_names(pip, as.character(ids)) } -# Build a named outcome PIP vector for one trait. Walks every row of the -# collection carrying that identity, extracts the per-row pip from each -# FineMappingRow, and concatenates with variant-id names. Errors if any single -# variant appears with conflicting PIP values across rows -- which is why the -# identity is the full trait tuple: pooling two molecular traits of one study -# would collide on every variant they share. +# Build a named outcome PIP vector for one fit. Walks every row of the +# collection carrying that identity -- the fit's LD blocks -- extracts the +# per-row pip from each FineMappingRow, and concatenates with variant-id +# names. Errors if any single variant appears with conflicting PIP values +# across rows -- which is why the identity is the full fit tuple: pooling two +# molecular traits of one study, or two methods' fits of one trait, would +# collide on every variant they share. #' @importFrom dplyr add_count #' @noRd .enrBuildGwasPipVector <- function(gwasFmr, ident) { @@ -633,7 +662,7 @@ qtlEnrichmentPipeline <- function( # One row's region payload for qtlEnrichment, or NULL when the row lacks a # fit, an alpha, PIPs, or a prior variance. The PIP names fall back to the -# row's own variant ids when the fit did not carry any. +# ids the fit was made with when the fit did not carry any. # @noRd .enrRowRegion <- function(i, qtlFmr) { parts <- .fmrRowParts(qtlFmr, i) @@ -649,7 +678,7 @@ qtlEnrichmentPipeline <- function( alpha = fit$alpha, pip = set_names( fit$pip, - names(fit$pip) %||% .fmrPartsVariantIds(parts) + names(fit$pip) %||% .partsFitIds(parts) ), prior_variance = priorVariance ) @@ -769,8 +798,10 @@ qtlEnrichmentPipeline <- function( #' When it is set to 0, no shrinkage will be applied. A large value indicates #' strong shrinkage. The default value is set to 1.0. #' @param impN Rounds of multiple imputation to draw QTL from, default is 25. -#' @param numThreads Number of Simultaneous running CPU threads for multiple -#' imputation, default is 1. +#' @param BPPARAM A \code{BiocParallelParam} whose workers number the threads +#' the multiple imputation runs on when they run on this machine +#' (\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +#' thread. Default \code{SerialParam()}. #' @param alignNames Logical; when TRUE (default) QTL pip names are aligned to #' the GWAS variant-naming convention via \code{matchVariants}. Set FALSE when #' the caller has already aligned them (e.g. \code{qtlEnrichmentPipeline} @@ -823,11 +854,10 @@ qtlEnrichmentPipeline <- function( #' # Set other parameters #' impN <- 10 #' lambda <- 1 -#' numThreads <- 1 #' library(pecotmr) #' en <- qtlEnrichment( #' gwasPip, susieFits, lambda = lambda, impN = impN, -#' numThreads = numThreads) +#' BPPARAM = BiocParallel::SerialParam()) #' #' @seealso \code{\link[susieR]{susie}} #' @useDynLib pecotmr, .registration = TRUE @@ -842,11 +872,12 @@ qtlEnrichment <- function( impN = 25, doubleShrinkage = FALSE, besselCorrection = TRUE, - numThreads = 1, + BPPARAM = SerialParam(), verbose = TRUE, alignNames = TRUE, seed = NULL ) { + .assertBpparam(BPPARAM) piGwas <- .enrEstimatePiGwas(gwasPip, numGwas, verbose) piQtl <- .enrEstimatePiQtl(susieQtlRegions, piQtl, verbose) .enrValidatePi(piGwas, piQtl) @@ -865,7 +896,7 @@ qtlEnrichment <- function( shrinkageLambda = lambda, doubleShrinkage = doubleShrinkage, besselCorrection = besselCorrection, - numThreads = as.integer(numThreads), + numThreads = .bpLocalThreads(BPPARAM, "qtlEnrichment"), seed = if (is.null(seed)) NULL else as.integer(seed) ) list_assign(en, unused_xqtl_variants = unmatchedVariants) diff --git a/R/qtlSumStats.R b/R/qtlSumStats.R index 097117be..88c6cecf 100644 --- a/R/qtlSumStats.R +++ b/R/qtlSumStats.R @@ -1,13 +1,13 @@ # ============================================================================= # QtlSumStats S4 class # ----------------------------------------------------------------------------- -# DFrame-subclass collection keyed by the identity tuple (study, context, +# RangedTupleList collection keyed by the identity tuple (study, context, # trait). Each row holds a per-tuple GRanges of summary statistics # (variant_id + per-variant Z/N/MAF mcols). The genome build applies # uniformly across rows; the ldReference slot holds each distinct LD # reference once and the ldReference mcols column names the one every row -# uses. Built-in qcInfo slot tracks which summaryStatsQc() passes have been -# run. +# uses. The qcOptions slot records the summaryStatsQc() options that ran, and +# the qcAudit column what QC did to each row. # ============================================================================= #' @include AllClasses.R tupleSelectors.R @@ -19,10 +19,19 @@ NULL #' per-variant \code{GRanges} -- \code{variant_id} plus the per-variant #' Z / N / MAF mcols. #' @details Required columns: \code{study}, \code{context} and \code{trait}; -#' the 3-tuple is unique. The class-level slots inherited from -#' \code{\linkS4class{SumStatsBase}} -- \code{genome} and \code{qcInfo} -- -#' apply uniformly to every row, and \code{qcInfo} records which -#' \code{\link{summaryStatsQc}} passes have run; \code{ldReference} holds +#' the 3-tuple is unique. The constructor also adds each tuple's analysis +#' window: \code{region}, a \code{GRanges} with one range per element, and +#' \code{regionGiven}, \code{TRUE} where the window was given as a +#' \code{region} and \code{FALSE} where it is the span of the tuple's +#' variants when the collection was first built, before any QC. A QC pass +#' carries both unchanged; the span of the variants left is +#' \code{range(x)}. An optional \code{traitPos} gives the trait's own +#' coordinates, from which a pipeline's \code{cisWindow} derives a cis +#' window. The class-level slots inherited from +#' \code{\linkS4class{SumStatsBase}} -- \code{genome} and +#' \code{qcOptions} -- apply uniformly to every row, and \code{qcOptions} +#' records the \code{\link{summaryStatsQc}} options that ran (what QC did +#' to each row is \code{\link{qcInfo}}); \code{ldReference} holds #' each distinct LD reference once, and the \code{ldReference} column names #' the one each row uses. #' @seealso \code{\link{QtlSumStats}} for the constructor and @@ -85,7 +94,8 @@ setClass( #' @title QTL Summary Statistics Handling #' @description Constructor and accessor methods for \code{QtlSumStats}, the -#' DFrame-subclass collection keyed by \code{(study, context, trait)}. +#' \code{RangedTupleList} collection keyed by \code{(study, context, +#' trait)}. #' @name pecotmr-qtl-sumstats #' @keywords internal #' @importFrom GenomicRanges GRanges seqnames start @@ -98,14 +108,13 @@ NULL # ============================================================================= #' @title Create a QtlSumStats Collection Object -#' @description Construct a \code{QtlSumStats} S4 DFrame-subclass collection -#' from per-tuple vectors and a list of \code{GRanges} entries (one per -#' tuple), plus the LD reference(s) the rows were harmonized against and a -#' single genome build that applies to the whole collection. Each -#' \code{GRanges} entry must carry per-variant -#' statistics in its mcols (\code{SNP}, \code{A1}, \code{A2}, \code{Z}, -#' \code{N}; plus optional \code{MAF}, \code{INFO}, \code{BETA}, \code{SE}, -#' \code{P}). +#' @description Construct a \code{QtlSumStats} S4 collection from per-tuple +#' vectors and a list of \code{GRanges} entries (one per tuple), plus the LD +#' reference(s) the rows were harmonized against and a single genome build +#' that applies to the whole collection. Each \code{GRanges} entry must +#' carry per-variant statistics in its mcols (\code{SNP}, \code{A1}, +#' \code{A2}, \code{Z}, \code{N}; plus optional \code{MAF}, \code{INFO}, +#' \code{BETA}, \code{SE}, \code{P}). #' @param studyName Character vector of study identifiers (per tuple). #' @param context Character vector of context labels (per tuple). #' @param trait Character vector of trait identifiers (per tuple). @@ -127,18 +136,30 @@ NULL #' \code{nSamples()} (the LD-panel sample size). Unlike GWAS, QTL #' collections carry no case/control counts (molecular traits are #' quantitative), so only this total-N fallback is exposed. -#' @param extraCols Optional named list of additional per-tuple columns to +#' @param extraCols Optional named list (or \code{DataFrame} / +#' \code{data.frame}) of additional per-tuple columns to #' attach to the collection's \code{mcols}. Named rather than variadic #' because the base class's own constructor, \code{GRangesList(...)}, uses #' \code{...} for its \emph{elements}: a bare \code{...} here would read #' as adding an entry rather than a metadata column. -#' @param qcInfo A \code{list} recording which QC steps ran. Empty \code{list()} -#' on construction; populated by \code{summaryStatsQc()} with a per-step audit -#' record. Fine-mapping / TWAS pipelines reject inputs where -#' \code{length(qcInfo(x)) == 0}. +#' @param qcOptions A \code{list} recording the QC that ran. Empty +#' \code{list()} on construction; \code{summaryStatsQc()} fills it. +#' Fine-mapping / TWAS pipelines reject inputs where +#' \code{length(qcOptions(x)) == 0}. #' @param traitPos Optional per-row trait genomic anchor (a \code{GRanges} or #' \code{NULL}), carried forward as provenance; not part of the identity key. -#' \code{NULL} (default) omits the column. +#' \code{NULL} (default) omits the column. A pipeline given a +#' \code{cisWindow} analyses each tuple over \code{traitPos} \eqn{\pm} +#' \code{cisWindow}. +#' @param region Optional analysis window of each tuple: a \code{GRanges}, +#' or the path of a BED file, read as BED with a 0-based start. One window +#' for every tuple, or one per tuple. A tuple's variants outside its window +#' are dropped with a warning, and its \code{region} is the window, +#' recorded as given in \code{regionGiven}. Without it, a tuple's +#' \code{region} is the span of its variants as built, before any QC. +#' @param metadata A list of free-form metadata about the collection, +#' as \code{metadata()} holds on any Bioconductor vector. Default +#' \code{list()}. #' @return A \code{QtlSumStats} object. #' @examples #' panel <- readGenotypes( @@ -158,9 +179,11 @@ QtlSumStats <- function( ldReference = NULL, varY = NA_real_, nSample = NULL, - qcInfo = list(), + qcOptions = list(), traitPos = NULL, - extraCols = list() + region = NULL, + extraCols = list(), + metadata = list() ) { if ( missing(studyName) || @@ -170,34 +193,231 @@ QtlSumStats <- function( missing(genome) ) { msg <- glue( - "`study`, `context`, `trait`, `entry`, and `genome` ", + "`studyName`, `context`, `trait`, `entry`, and `genome` ", "are all required." ) abort(msg) } n <- length(studyName) varY <- .qssValidateArgs(context, trait, entry, genome, varY, n) - entry <- .qssAddTraitDistances(entry, traitPos, n) + windows <- .qssWindows(region, n) + entry <- .qssWithinWindows(.ucscEntries(entry), windows) |> + .qssAddTraitDistances(traitPos, n) cols <- .qssBaseCols(studyName, context, trait, varY) |> .qssAppendNSample(nSample, n) |> .appendTraitPosCol(traitPos, n) |> .qssAppendExtras(extraCols) dict <- .ldRefDict(.ldRefPerTuple(ldReference, n)) dfArgs <- c(cols, list(ldReference = dict$keys, check.names = FALSE)) - # The per-tuple GRanges become the collection's ELEMENTS; the tuple keys - # and per-tuple scalars go in mcols. There is no `entry` column. - # mcols are attached to the GRangesList BEFORE new(), because new() - # validates during initialize() and the validity method needs the identity - # columns to already be there. - # A multi-seqname entry (e.g. a genome-wide GWAS) is split into one - # element per chromosome, with its metadata row replicated alongside. split <- .rtlSplitBySeqname(entry) - md <- exec(S4Vectors::DataFrame, !!!dfArgs) + pieces <- .rtlBindElements(split$entry) grl <- S4Vectors::`mcols<-`( - GenomicRanges::GRangesList(split$entry), - value = md[split$fromIdx, , drop = FALSE] + pieces, + value = .qssPieceMetadata(dfArgs, split, pieces, windows) + ) + .withMetadata( + .sumStatsNewValidated("QtlSumStats", grl, dict$refs, genome, qcOptions), + metadata + ) +} + +# Each piece's metadata row, its tuple's, with the tuple's analysis window: +# the `region` it was given, else the span of its variants as built, before +# any QC. `regionGiven` records which. +# +# The per-tuple GRanges become the collection's ELEMENTS; the tuple keys and +# per-tuple scalars go in mcols. There is no `entry` column. mcols are +# attached to the GRangesList BEFORE new(), because new() validates during +# initialize() and the validity method needs the identity columns to already +# be there. A multi-seqname entry (e.g. a trans tuple) is split into one +# element per chromosome, with its metadata row replicated alongside. +# @noRd +.qssPieceMetadata <- function(dfArgs, split, pieces, windows) { + n <- length(split$entry) + given <- if (is.null(windows)) { + .placeholderRanges(n) + } else { + windows[split$fromIdx] + } + cbind( + exec(S4Vectors::DataFrame, !!!dfArgs)[split$fromIdx, , drop = FALSE], + exec( + S4Vectors::DataFrame, + !!!.regionColumns( + given, + rep(!is.null(windows), n), + .rowSpanRanges(pieces) + ) + ) + ) +} + +# The window each tuple was given, as bare ranges, one per tuple; NULL when +# none was. A single window stands for every tuple. +# @noRd +.qssWindows <- function(region, n) { + if (is.null(region)) { + return(NULL) + } + windows <- .asRegionRanges(region) + if (!is_in(length(windows), c(1L, n))) { + abort(glue( + "`region` must give one window, or one per tuple ", + "(got {length(windows)} for {n} tuples)." + )) + } + .bareRanges(rep(windows, length.out = n)) +} + +# Each tuple's variants inside its window. Those outside it were not asked +# for, so they are dropped, with a warning saying how many. +# @noRd +.qssWithinWindows <- function(entry, windows) { + if (is.null(windows)) { + return(entry) + } + kept <- map( + seq_along(entry), + .qssWithinWindowAt, + entry = as.list(entry), + windows = windows + ) + dropped <- sum(lengths(entry)) - sum(lengths(kept)) + if (dropped > 0L) { + warn(glue( + "{dropped} variant(s) lie outside their tuple's `region` and ", + "were dropped." + )) + } + kept +} + +# @noRd +.qssWithinWindowAt <- function(i, entry, windows) { + .withinWindow(entry[[i]], windows[i]) +} + +# Narrow the tuples a pipeline selected -- `rows`, picked by its own +# `contexts` / `traitId` rules -- to their traits' cis windows: traitPos +/- +# cisWindow, within the window each tuple already had. That window becomes +# the tuple's `region`, recorded as given, since the caller asked for it. A +# selected tuple with no trait position has no cis window, which is an error. +# NULL `cisWindow` leaves `x` as it is. The one step behind every pipeline +# that takes a QtlSumStats and a `cisWindow`; `caller` names it in messages. +# @noRd +#' @importFrom checkmate assertNumber +.qssApplyCisWindow <- function(x, cisWindow, caller, rows) { + if (is.null(cisWindow)) { + return(x) + } + assertNumber(cisWindow, lower = 0, finite = TRUE, .var.name = "cisWindow") + if (length(rows) == 0L) { + return(x) + } + regions <- .rowRegions(x) + windows <- .clipWindows( + .cisWindowsAround(.qssTraitPositions(x, rows, caller), cisWindow), + regions$region[rows] + ) + elements <- replace( + as.list(x), + rows, + map( + seq_along(rows), + .qssWithinWindowAt, + entry = as.list(x)[rows], + windows = windows + ) + ) + region <- regions$region + region[rows] <- windows + .withRegionColumns( + .rtlRebuild(x, elements, seq_len(nrow(x))), + list( + region = region, + regionGiven = replace(regions$regionGiven, rows, TRUE) + ) + ) +} + +# A QtlSumStats run's selection, parsed once (parseContexts() / +# parseTraitIds()), and its data with `cisWindow` laid on the tuples that +# selection keeps -- so the windows cover exactly the tuples the run fits. +# @noRd +.qssSelection <- function(data, contexts, traitId, cisWindow, caller) { + contexts <- parseContexts(contexts, data) + traitId <- parseTraitIds(traitId, data) + rows <- which(.sumStatsRowsSelected(data, contexts, traitId)) + list( + data = .qssApplyCisWindow(data, cisWindow, caller, rows), + contexts = contexts, + traitId = traitId + ) +} + +# Each trait position widened by `cisWindow` on both sides, kept on the +# chromosome. +# @noRd +.cisWindowsAround <- function(tp, cisWindow) { + w <- as.integer(cisWindow) + GenomicRanges::GRanges( + as.character(GenomicRanges::seqnames(tp)), + IRanges::IRanges(start = pmax(1L, start(tp) - w), end = end(tp) + w) + ) +} + +# The trait position of each of `rows`; an error naming the tuples that have +# none, since a cis window is laid around the trait. +# @noRd +.qssTraitPositions <- function(x, rows, caller) { + tp <- if (is_in("traitPos", .tupleColumnNames(x))) { + .tupleColumn(x, "traitPos")[rows] + } + missing <- if (is.null(tp)) { + rows + } else { + rows[as.character(GenomicRanges::seqnames(tp)) == "chrUn"] + } + if (length(missing) > 0L) { + labels <- str_c( + as.character(x$study)[missing], + as.character(x$context)[missing], + as.character(x$trait)[missing], + sep = "/" + ) + abort(c( + glue( + "{caller}: `cisWindow` is laid around each tuple's trait ", + "position, which {length(missing)} tuple(s) do not have: ", + "{str_flatten(utils::head(labels, 5L), ', ')}." + ), + i = str_c( + "Give one with `traitPos` (or a manifest's traitStart / ", + "traitEnd columns), or drop `cisWindow` to analyse each ", + "tuple over its `region`." + ) + )) + } + tp +} + +# Each window clipped to its row's `regions` entry. A window that misses it, +# on another chromosome or past its ends, keeps nothing, so it becomes a +# zero-width placeholder at its start. +# @noRd +.clipWindows <- function(windows, regions) { + same <- as.character(GenomicRanges::seqnames(windows)) == + as.character(GenomicRanges::seqnames(regions)) + s <- pmax(start(windows), start(regions)) + e <- pmin(end(windows), end(regions)) + hit <- same & e >= s + GenomicRanges::GRanges( + as.character(GenomicRanges::seqnames(windows)), + IRanges::IRanges( + start = if_else(hit, s, start(windows)), + end = if_else(hit, e, start(windows) - 1L) + ) ) - .sumStatsNewValidated("QtlSumStats", grl, dict$refs, genome, qcInfo) } # Validate genome / entry / length consistency and recycle varY. Returns the @@ -218,7 +438,7 @@ QtlSumStats <- function( } if (length(context) != n || length(trait) != n || length(entry) != n) { msg <- glue( - "`study`, `context`, `trait`, and `entry` must all have the ", + "`studyName`, `context`, `trait`, and `entry` must all have the ", "same length." ) abort(msg) @@ -284,7 +504,17 @@ QtlSumStats <- function( # Append any user-supplied extra columns (from `...`). # @noRd .qssAppendExtras <- function(cols, extras) { - c(cols, extras) + c(cols, .extraColsList(extras)) +} + +# `extraCols` as a named list of columns: a list as it is, a DataFrame or +# data.frame column by column. +# @noRd +.extraColsList <- function(extras) { + if (methods::is(extras, "DataFrame") || is.data.frame(extras)) { + return(as.list(extras)) + } + extras } # Annotate each entry's variants with tss_distance / tes_distance from the @@ -328,7 +558,7 @@ QtlSumStats <- function( return(seq_len(nrow(x))) } msg <- glue( - "This QtlSumStats has {nrow(x)} entries. Pass `study`, ", + "This QtlSumStats has {nrow(x)} entries. Pass `studyName`, ", "`context`, and `trait` to select one." ) abort(msg) @@ -379,10 +609,8 @@ QtlSumStats <- function( #' \code{"bonferroni_filtered"} / \code{"qvalue"}). When set on a QtlSumStats #' enriched by \code{\link{qtlAssociationPostprocess}}, a logical #' \code{significant} mcol for that method is added to the returned entry (the -#' significance is derived on the fly, not stored). Flat export flattens this -#' full entry GRanges (all mcols) directly; note -#' \code{\link{as.data.frame}} is a fixed GWAS-schema view and does not -#' carry the association columns. +#' significance is derived on the fly, not stored). Take a table of the +#' whole entry, every mcol included, with \code{as.data.frame()}. #' @export setMethod( "sumStats", @@ -392,11 +620,10 @@ setMethod( studyName = NULL, context = NULL, trait = NULL, - annotateSignificance = NULL, - ranges = NULL + annotateSignificance = NULL ) { idx <- .qtlSumStatsSelectRow(x, studyName, context, trait) - stitched <- .ssStitchElements(x, idx, ranges) + stitched <- .ssStitchElements(x, idx) gr <- if (is.null(annotateSignificance)) { stitched } else { @@ -425,46 +652,6 @@ setMethod( # z / nSamples / maf / nSnps are provided once by SumStatsBase (AllClasses.R); # they only delegate to sumStats(). -#' @rdname sumStatsDataFrame -#' @export -setMethod( - "as.data.frame", - "QtlSumStats", - function( - x, - row.names = NULL, - optional = FALSE, - studyName = NULL, - context = NULL, - trait = NULL, - require = character(0), - derive = c("none", "zFromBetaSe"), - keepChrPrefix = TRUE, - ... - ) { - derive <- arg_match(derive) - gr <- sumStats( - x, - studyName = studyName, - context = context, - trait = trait - ) - .entryToSumstatDf( - gr, - require = require, - derive = derive, - keepChrPrefix = keepChrPrefix, - label = glue( - "QtlSumStats[", - "{if (is.null(studyName)) '' else studyName}/", - "{if (is.null(context)) '' else context}/", - "{if (is.null(trait)) '' else trait}]" - ) - ) - } -) - - #' @rdname varY #' @export setMethod( @@ -495,18 +682,15 @@ setMethod("traitNames", "QtlSumStats", function(x) { # or a scalar NA when no trait position was supplied. #' @rdname traitPosition #' @export -setMethod("traitPosition", "QtlSumStats", function(x, traitId = NULL) { +setMethod("traitPosition", "QtlSumStats", function(x, trait = NULL) { tp <- .getTraitPosColumn(x) - if (!methods::is(tp, "GRanges") || is.null(traitId)) { + if (is.null(trait) || length(tp) == 0L) { return(tp) } - idx <- which(is_in(as.character(x$trait), as.character(traitId))) - if (length(idx) == 0L) { - return(NA) - } + idx <- which(is_in(as.character(x$trait), as.character(trait))) # The trait position is per-TUPLE, but a tuple split across chromosomes # owns several elements and the column is replicated across them, so the - # matches collapse back to the one position. + # matches collapse back to the one position. No match is an empty GRanges. unique(tp[idx]) }) @@ -519,7 +703,7 @@ setMethod("traitPosition", "QtlSumStats", function(x, traitId = NULL) { setMethod("show", "QtlSumStats", function(object) { cat(glue( "QtlSumStats: {nrow(object)} entries, ", - "genome build {GenomeInfoDb::genome(object)}\n", + "genome build {.showGenomeBuild(object)}\n", .trim = FALSE )) if (nrow(object) > 0L) { @@ -580,9 +764,9 @@ setMethod("show", "QtlSumStats", function(object) { #' #' The three collection-level slots are merged rather than taken from the first #' input, on the same rules as \code{\link{combineGwasSumStats}}: \code{genome} -#' and the \code{\link{summaryStatsQc}} options must agree, the per-element -#' \code{qcInfo$entryAudit} concatenates in element order, and the rows keep -#' their own LD references, stored the same way. +#' and the \code{\link{summaryStatsQc}} options must agree, each row keeps +#' its own QC audit, and the rows keep their own LD references, stored the +#' same way. #' #' @param ... Two or more \code{QtlSumStats} objects, or a single \code{list} #' of them. diff --git a/R/regularizedRegressionWrappers.R b/R/regularizedRegressionWrappers.R index 2a3f00f5..1e8817f9 100644 --- a/R/regularizedRegressionWrappers.R +++ b/R/regularizedRegressionWrappers.R @@ -340,7 +340,6 @@ prsCsWeights <- function( #' @param iter Number of iterations for MCMC. Default is 1000. #' @param burn Number of burn-in iterations for MCMC. Default is 200. #' @param thin Thinning interval for MCMC. Default is 5. -#' @param numThreads Number of threads to use. Default is 1. #' @param optLlk Which likelihood to evaluate. 1 for equation 6 (slightly shrink #' the correlation of SNPs) and 2 for equation 5 (SNPs genotyped on different #' arrays in a separate cohort). Default is 1. @@ -371,7 +370,6 @@ sdpr <- function( iter = 1000, burn = 200, thin = 5, - numThreads = 1, optLlk = 1, verbose = TRUE, seed = NULL @@ -391,7 +389,6 @@ sdpr <- function( iter, burn, thin, - numThreads, optLlk, verbose, seed @@ -416,7 +413,6 @@ sdpr <- function( iter, burn, thin, - numThreads, optLlk, verbose, seed @@ -436,7 +432,9 @@ sdpr <- function( iter = as.integer(iter), burn = as.integer(burn), thin = as.integer(thin), - numThreads = as.integer(numThreads), + # The kernel's thread pool splits its work across LD blocks, and a + # window is always one block, so a second thread would sit idle. + numThreads = 1L, optLlk = as.integer(optLlk), verbose = verbose, seed = seed @@ -536,7 +534,6 @@ sdprWeights <- function( "iter", "burn", "thin", - "numThreads", "optLlk", "verbose", "seed" @@ -902,8 +899,10 @@ mrmashRssWeights <- function( #' A method's individual-level and summary-statistic paths often run #' DIFFERENT engines, and then each takes its own constructor: #' \code{lassoWeights} fits with glmnet (\code{GlmnetOptions}) while -#' \code{lassosumRssWeights} runs pecotmr's lassosum solver -#' (\code{LassosumOptions}); \code{scadWeights} / \code{mcpWeights} / +#' \code{lassosumRssWeights} runs pecotmr's lassosum +#' (\code{LassosumOptions}); \code{enetWeights} / \code{ridgeWeights} fit +#' with glmnet too, while \code{enetRssWeights} / \code{ridgeRssWeights} +#' use \code{PenalizedRssOptions}; \code{scadWeights} / \code{mcpWeights} / #' \code{l0learnWeights} use ncvreg and L0Learn while their \code{*Rss} #' counterparts use \code{PenalizedRssOptions}; \code{dprGibbsWeights} uses #' RcppDPR and \code{sdprWeights} uses \code{SdprOptions}. Splitting them is @@ -974,7 +973,10 @@ GlmnetOptions <- function(...) { # lasso from enet from ridge -- so it belongs to the calling # wrapper. Refused here rather than in glmnetWeights() so the # failure lands where the value was written. - alpha = "the calling wrapper (lassoWeights, enetWeights)" + alpha = str_c( + "the calling wrapper: enetWeights' own `alpha`, or ", + "lassoWeights / ridgeWeights, which fix it" + ) ), "GlmnetOptions" ) @@ -1217,12 +1219,31 @@ LassosumOptions <- function(...) { #' @export PenalizedRssOptions <- function(...) { extra <- list(...) + # The penalty and its shape belong to the calling wrapper: each one fixes + # its penalty, and those that let it vary take `alpha` / `gamma` / + # `lambda0` / `lambda2` / `maxSwaps` as their own arguments. `lambda` + # stays settable here, the only route to it for the wrappers without one. .configRefuseOwned( extra, c( bhat = "supplied from the data by the pipeline", R = "supplied from the data by the pipeline", - n = "supplied from the data by the pipeline" + n = "supplied from the data by the pipeline", + penalty = str_c( + "the calling wrapper, which fixes it (scadRssWeights, ", + "mcpRssWeights, ...)" + ), + alpha = str_c( + "the calling wrapper's `alpha` (enetRssWeights, ", + "scadRssWeights, mcpRssWeights); ridgeRssWeights fixes it at 0" + ), + gamma = str_c( + "the calling wrapper's `gamma` (scadRssWeights, ", + "mcpRssWeights)" + ), + lambda0 = "l0learnRssWeights' own `lambda0`", + lambda2 = "l0learnRssWeights' own `lambda2`", + maxSwaps = "l0learnRssWeights' own `maxSwaps`" ), "PenalizedRssOptions" ) @@ -1270,7 +1291,7 @@ MrmashOptions <- function(...) { mu1_init = "the wrapper's `bInit`", standardize = "the wrapper's `standardize`", update_V_method = "the wrapper's `updateVMethod`", - nthreads = "the wrapper's `numThreads`" + nthreads = "the wrapper's `BPPARAM`" ), "MrmashOptions" ) @@ -1443,9 +1464,12 @@ glmnetWeights <- function(X, y, alpha, methodArgs = GlmnetOptions()) { replace(eff.wgt, keep, coef(enet, s = "lambda.min")[2:(sum(keep) + 1)]) } -#' Compute TWAS weights via elastic net (glmnet, alpha = 0.5) +#' Compute TWAS weights via elastic net (glmnet) #' -#' Convenience wrapper for \code{\link{glmnetWeights}} with \code{alpha = 0.5}. +#' Convenience wrapper for \code{\link{glmnetWeights}} at a mixing between the +#' lasso and ridge, \code{alpha = 0.5} unless set. +#' @param alpha Elastic-net mixing in \code{[0, 1]}: the L1 share of the +#' penalty. Default 0.5. #' @inheritParams glmnetWeights #' @return Numeric vector of length \code{ncol(X)} of per-variant weights. #' @examples @@ -1453,10 +1477,30 @@ glmnetWeights <- function(X, y, alpha, methodArgs = GlmnetOptions()) { #' X <- eqtlRegionExample$X[, 1:30] #' y <- eqtlRegionExample$yRes #' enetWeights(X, y) +#' # A larger ridge share: +#' enetWeights(X, y, alpha = 0.2) +#' @importFrom checkmate assertNumber +#' @export +enetWeights <- function(X, y, alpha = 0.5, methodArgs = GlmnetOptions()) { + .assertMethodOptions(methodArgs, "GlmnetOptions", "methodArgs") + assertNumber(alpha, lower = 0, upper = 1) + glmnetWeights(X, y, alpha, methodArgs = methodArgs) +} + +#' Compute TWAS weights via ridge regression (glmnet, alpha = 0) +#' +#' Convenience wrapper for \code{\link{glmnetWeights}} with \code{alpha = 0}. +#' @inheritParams glmnetWeights +#' @return Numeric vector of length \code{ncol(X)} of per-variant weights. +#' @examples +#' data(eqtlRegionExample) +#' X <- eqtlRegionExample$X[, 1:30] +#' y <- eqtlRegionExample$yRes +#' ridgeWeights(X, y) #' @export -enetWeights <- function(X, y, methodArgs = GlmnetOptions()) { +ridgeWeights <- function(X, y, methodArgs = GlmnetOptions()) { .assertMethodOptions(methodArgs, "GlmnetOptions", "methodArgs") - glmnetWeights(X, y, 0.5, methodArgs = methodArgs) + glmnetWeights(X, y, 0, methodArgs = methodArgs) } #' Compute TWAS weights via lasso (glmnet, alpha = 1) @@ -2278,7 +2322,10 @@ bayesRWeights <- function( #' \hat\beta / \sqrt{n}}. #' #' Based on Mak et al (2017) "Polygenic scores via penalized regression on -#' summary statistics", Genetic Epidemiology 41(6):469-480. +#' summary statistics", Genetic Epidemiology 41(6):469-480. It runs on the +#' solver of \code{\link{penalizedRss}}, whose LASSO at \code{alpha = 1} is +#' lassosum's coordinate descent: the same updates in the same order, so the +#' same coefficients bit for bit. #' #' Internal: \code{\link{lassosumRssWeights}} is the public interface. It #' runs this over a grid of LD shrinkage values, forwards \code{lambda}, @@ -2291,7 +2338,7 @@ bayesRWeights <- function( #' window), as in \code{susieR::susie_rss()}. If shrinkage is desired, apply #' it before passing (e.g., \code{(1-s)*R + s*I}). #' @param n Sample size of the GWAS. -#' @param lambda A vector of L1 penalty values. Default: 20 values from 0.001 to +#' @param lambda A vector of L1 penalty values. Default: 20 values from 1e-4 to #' 0.1 on log scale. #' @param thr Convergence threshold. Default: 1e-4. #' @param maxiter Maximum number of iterations. Default: 10000. @@ -2315,35 +2362,15 @@ lassosumRss <- function( thr = 1e-4, maxiter = 10000 ) { - .lassosumRssPath(bhat, list(R = R), n, lambda, thr, maxiter) -} - -# lassosumRss() on an LD source: the matrix, or a factor of it with its -# shrinkage, which the factor solver applies without forming R. -# @noRd -.lassosumRssPath <- function(bhat, ld, n, lambda, thr, maxiter) { - assertNumeric(lambda, lower = 0, any.missing = FALSE) - assertNumber(thr, lower = 0, finite = TRUE) - assertCount(maxiter, positive = TRUE) - .rssSolvePath( + .penalizedRssPath( bhat, - ld, + list(R = R), n, - lambda, - .rssLassosumSolve, - solveArgs = list(thr = thr, maxiter = maxiter) - ) -} - -# .lassosumRssPath() with lassosumRss()'s own defaults under `args`, the -# caller's options. A matrix takes exactly the path lassosumRss() does. -# @noRd -.lassosumRssOn <- function(bhat, ld, n, args) { - settings <- list_modify( - .formalDefaults(lassosumRss, c("lambda", "thr", "maxiter")), - !!!args + spec = .rssPenalty("lasso"), + lambda = lambda, + thr = thr, + maxiter = maxiter ) - exec(.lassosumRssPath, bhat = bhat, ld = ld, n = n, !!!settings) } # The values `fn` declares as the defaults of its formals `fmlNames`, @@ -2486,17 +2513,15 @@ lassosumRss <- function( ) } -# Per-`s` fit for one RSS method (`method` selects the solver + which `config` -# fields apply). Returns list(beta, meta); l0learn's inner lambda0 sweep is -# here. +# Per-`s` fit for one RSS method: one penalized path at the wrapper's +# penalty, or, for l0learn, one per value of its lambda0 grid. Returns +# list(beta, meta). # @noRd -.rssFitOne <- function(method, solverInput, ld, n, sVal, config) { - switch( - method, - lassosum = .rssFitLassosum(solverInput, ld, n, sVal, config), - penalized = .rssFitPenalized(solverInput, ld, n, sVal, config), - l0learn = .rssFitL0learn(solverInput, ld, n, sVal, config) - ) +.rssFitOne <- function(solverInput, ld, n, sVal, config) { + if (identical(config$method, "l0learn")) { + return(.rssFitL0learn(solverInput, ld, n, sVal, config)) + } + .rssFitPenalized(solverInput, ld, n, sVal, config) } # Shared per-candidate frame for a single-path model: the shrinkage s and @@ -2514,27 +2539,17 @@ lassosumRss <- function( ) } -# lassosum shrinkage path for one s, against `ld` shrunk to that s. -# @noRd -.rssFitLassosum <- function(solverInput, ld, n, sVal, config) { - model <- .lassosumRssOn(solverInput, ld, n, as.list(config$dotArgs)) - list(beta = model$beta, meta = .rssPathMeta(sVal, model)) -} - -# ncvreg-penalized shrinkage path for one s, against `ld` shrunk to that s. +# The penalized path for one s, against `ld` shrunk to that s: the wrapper's +# penalty, `config$spec`, under the caller's path options. # @noRd .rssFitPenalized <- function(solverInput, ld, n, sVal, config) { - settings <- c( - list( - penalty = config$penalty, - gamma = config$gamma, - alpha = config$alpha, - lambda0 = config$lambda0, - lambda2 = config$lambda2 - ), - as.list(config$dotArgs) + model <- .penalizedRssOn( + solverInput, + ld, + n, + config$spec, + config$options ) - model <- .penalizedRssOn(solverInput, ld, n, settings) list(beta = model$beta, meta = .rssPathMeta(sVal, model)) } @@ -2561,10 +2576,10 @@ lassosumRss <- function( # Attach the method-specific selection attribute to the chosen coefficient # vector. # @noRd -.rssFinalize <- function(method, bestBeta, sel, meta, config) { +.rssFinalize <- function(bestBeta, sel, meta, config) { base <- c(mode = sel$mode, index = sel$index) selection <- switch( - method, + config$method, lassosum = c( base, s = meta$s[sel$index], @@ -2572,19 +2587,20 @@ lassosumRss <- function( ), penalized = c( base, - penalty = config$penalty, + penalty = config$spec$penalty, + alpha = config$spec$alpha, s = meta$s[sel$index], lambda = meta$lambda[sel$index] ), l0learn = c( base, - penalty = config$penalty, + penalty = config$spec$penalty, s = meta$s[sel$index], lambda0 = meta$lambda0[sel$index], lambda = meta$lambda[sel$index] ) ) - attrName <- if (method == "lassosum") { + attrName <- if (config$method == "lassosum") { "lassosum_selection" } else { "penalized_rss_selection" @@ -2644,8 +2660,8 @@ lassosumRss <- function( # One shrinkage level's fit against R_s = (1 - s) R + s I. # @noRd -.rssFitAtS <- function(sVal, method, solverInput, ld, n, config) { - .rssFitOne(method, solverInput, .rssShrunkLd(ld, sVal), n, sVal, config) +.rssFitAtS <- function(sVal, solverInput, ld, n, config) { + .rssFitOne(solverInput, .rssShrunkLd(ld, sVal), n, sVal, config) } # An LD source shrunk to R_s = (1 - s) R + s I: the source carries s to the @@ -2661,14 +2677,15 @@ lassosumRss <- function( # statistics `stat` against the LD source `ld` (see .rssLdSource()). # Standardizes the stat -> solverInput conversion, the outer LD-shrinkage grid # over `s`, the candidate accumulation, and the ldQuadratic / minFbeta -# selection. `method` + `config` pick the per-`s` solver (.rssFitOne) and the -# finalizer (.rssFinalize); `fitRetention` how much of the search is kept. +# selection. `config` is the run: `method` (which selection record the +# weights carry; "l0learn" also sweeps `lambda0`), the penalty `spec` +# (.rssPenalty()) and the caller's path `options`; `fitRetention` is how much +# of the search is kept. # @noRd .rssShrinkGridWeights <- function( stat, ld, s, - method, config, selection = c("ldQuadratic", "minFbeta"), fitRetention = c("none", "slim", "full") @@ -2682,7 +2699,6 @@ lassosumRss <- function( fits <- map( s, .rssFitAtS, - method = method, solverInput = solverInput, ld = ld, n = n, @@ -2696,13 +2712,7 @@ lassosumRss <- function( .lassosumSelectMinFbeta(candidateBeta, candidateMeta) } bestBeta <- as.numeric(selectorResult$beta) - weights <- .rssFinalize( - method, - bestBeta, - selectorResult, - candidateMeta, - config - ) + weights <- .rssFinalize(bestBeta, selectorResult, candidateMeta, config) .rssAttachGridFit( weights, candidateBeta, @@ -2815,8 +2825,11 @@ lassosumRssWeights <- function( stat, .rssLdSource(stat, ldReference, "lassosumRssWeights"), s, - "lassosum", - list(dotArgs = methodArgs), + list( + method = "lassosum", + spec = .rssPenalty("lasso"), + options = as.list(methodArgs) + ), selection, fitRetention ) @@ -2824,13 +2837,15 @@ lassosumRssWeights <- function( #' Penalized Regression on RSS (Summary Statistics) Objective #' -#' Generalizes \code{lassosumRss()} to support LASSO, MCP, SCAD, L0, L0L1, -#' and L0L2 penalties. Uses coordinate descent on the objective +#' The RSS penalized-regression solver: LASSO with its elastic-net and ridge +#' mixtures, MCP, SCAD, L0, L0L1 and L0L2. Uses coordinate descent on the +#' objective #' \deqn{\beta^T R \beta - 2 \beta^T z + \mathrm{penalty}(\beta)} #' where \eqn{R} is a (possibly pre-shrunk) LD matrix and \eqn{z = \hat\beta / -#' \sqrt{n}}. +#' \sqrt{n}}. \code{lassosumRss()} is its LASSO at \code{alpha = 1}. #' -#' Internal: \code{\link{scadRssWeights}}, \code{\link{mcpRssWeights}} and +#' Internal: \code{\link{enetRssWeights}}, \code{\link{ridgeRssWeights}}, +#' \code{\link{scadRssWeights}}, \code{\link{mcpRssWeights}} and #' \code{\link{l0learnRssWeights}} are the public interface, with #' \code{\link{lassosumRssWeights}} for the lasso. They run this over a grid #' of LD shrinkage values, forward its options through @@ -2846,11 +2861,17 @@ lassosumRssWeights <- function( #' @param lambda Numeric vector of regularization parameter values along which #' to trace a solution path (warm-started, largest-first). For LASSO/MCP/SCAD #' this is the primary penalty strength; for L0 variants it controls the L1 -#' component. +#' component. \code{NULL} (default) is 20 values from 1e-4 to 0.1 on a log +#' scale, divided by \code{max(alpha, 0.001)} as glmnet sizes its path, so +#' the L1 share spans the same range at any \code{alpha} and a ridge path +#' runs from 0.1 to 100. #' @param gamma Concavity parameter for MCP (default 3) or SCAD (default 3.7). #' Ignored for LASSO and L0 variants. -#' @param alpha Elastic-net mixing for MCP/SCAD: \eqn{l_1 = \lambda \alpha}, -#' \eqn{l_2 = \lambda (1-\alpha)}. Default 1 (pure L1, no ridge). +#' @param alpha Elastic-net mixing for LASSO, MCP and SCAD, in \code{[0, 1]}: +#' \eqn{l_1 = \lambda \alpha} and \eqn{l_2 = \lambda (1-\alpha)}, so the +#' penalty is \eqn{2 P(\beta; l_1) + l_2 \beta^T \beta}, glmnet's mixing. +#' Default 1, no ridge term. For LASSO, 0.5 is the elastic net and 0 ridge; +#' MCP and SCAD need \code{alpha > 0}. Ignored by the L0 variants. #' @param lambda0 L0 penalty weight (number of non-zeros). Required for L0 #' variants; ignored otherwise. Default 0. #' @param lambda2 L2 penalty weight for L0L2 variant. Default 0. @@ -2877,7 +2898,7 @@ penalizedRss <- function( R, n, penalty = c("lasso", "MCP", "SCAD", "L0", "L0L1", "L0L2"), - lambda = exp(seq(log(0.0001), log(0.1), length.out = 20)), + lambda = NULL, gamma = NULL, alpha = 1.0, lambda0 = 0, @@ -2890,129 +2911,157 @@ penalizedRss <- function( bhat, list(R = R), n, - arg_match(penalty), - lambda, - gamma, - alpha, - lambda0, - lambda2, - thr, - maxiter, - maxSwaps + spec = .rssPenalty( + arg_match(penalty), + alpha = alpha, + gamma = gamma, + lambda0 = lambda0, + lambda2 = lambda2, + maxSwaps = maxSwaps + ), + lambda = lambda, + thr = thr, + maxiter = maxiter ) } -# penalizedRss() on an LD source: the matrix, or a factor of it with its -# shrinkage, which the factor solver applies without forming R. +# The penalty a fit minimizes, as one checked record: the solver's penalty +# name, the elastic-net mixing `alpha`, the MCP / SCAD concavity `gamma` +# (their usual default when NULL) and the L0 settings. Each weight wrapper +# builds it from its own arguments before its shrinkage grid starts, so the +# penalty is the wrapper's alone and only the path (lambda, thr, maxiter) is +# left to the caller's options. # @noRd -.penalizedRssPath <- function( - bhat, - ld, - n, +#' @importFrom checkmate assertCount assertNumber +.rssPenalty <- function( penalty, - lambda, - gamma, - alpha, - lambda0, - lambda2, - thr, - maxiter, - maxSwaps + alpha = 1, + gamma = NULL, + lambda0 = 0, + lambda2 = 0, + maxSwaps = 0 ) { - # Default gamma per penalty - gamma <- gamma %||% switch(penalty, SCAD = 3.7, MCP = 3.0, 0.0) + .rssCheckAlpha(penalty, alpha) + assertNumber(gamma, finite = TRUE, null.ok = TRUE) + assertNumber(lambda0, lower = 0, finite = TRUE) + assertNumber(lambda2, lower = 0, finite = TRUE) + assertCount(maxSwaps) + list( + penalty = penalty, + alpha = alpha, + gamma = gamma %||% switch(penalty, SCAD = 3.7, MCP = 3.0, 0.0), + lambda0 = lambda0, + lambda2 = lambda2, + maxSwaps = maxSwaps + ) +} + +# `alpha` for `penalty`: a share in [0, 1], and above 0 for MCP and SCAD, +# where 0 leaves only the ridge term, which ridgeRssWeights() fits. +# @noRd +.rssCheckAlpha <- function(penalty, alpha) { + assertNumber(alpha, lower = 0, upper = 1) + if (alpha == 0 && is_in(penalty, c("MCP", "SCAD"))) { + abort(glue( + "`alpha` must be above 0 for {penalty}: at 0 only the ridge term ", + "is left, which ridgeRssWeights() fits." + )) + } + invisible(NULL) +} + +# penalizedRss() on an LD source: the matrix, or a factor of it with its +# shrinkage, which the factor solver applies without forming R. `spec` is the +# penalty (.rssPenalty()); the rest is the path, its default sized by the L1 +# share. +# @noRd +.penalizedRssPath <- function(bhat, ld, n, spec, lambda, thr, maxiter) { + lambda <- lambda %||% .rssDefaultLambda(spec$alpha) + assertNumeric(lambda, lower = 0, any.missing = FALSE) + assertNumber(thr, lower = 0, finite = TRUE) + assertCount(maxiter, positive = TRUE) .rssSolvePath( bhat, ld, n, lambda, .rssPenalizedSolve, - solveArgs = list( - penalty = penalty, - gamma = gamma, - alpha = alpha, - lambda0 = lambda0, - lambda2 = lambda2, - thr = thr, - maxiter = maxiter, - maxSwaps = maxSwaps - ) + solveArgs = c(spec, list(thr = thr, maxiter = maxiter)) ) } -# .penalizedRssPath() with penalizedRss()'s own defaults under `args`, the -# caller's settings, which always name the penalty. A matrix takes exactly -# the path penalizedRss() does. +# The default lambda path: 20 values from 1e-4 to 0.1, sized for an L1 +# penalty on correlation-scale effects, divided by max(alpha, 0.001) as glmnet +# sizes its own. The L1 share then spans the same range at any alpha, and a +# ridge path (alpha = 0) runs from 0.1 to 100; at alpha = 1 it is the +# lassosum default unchanged. # @noRd -.penalizedRssOn <- function(bhat, ld, n, args) { - settings <- list_modify( - .formalDefaults( - penalizedRss, - c( - "lambda", - "gamma", - "alpha", - "lambda0", - "lambda2", - "thr", - "maxiter", - "maxSwaps" - ) - ), - !!!args +.rssDefaultLambda <- function(alpha) { + exp(seq(log(1e-4), log(0.1), length.out = 20L)) / max(alpha, 1e-3) +} + +# .penalizedRssPath() for the penalty `spec` under the caller's path +# `options` -- lambda, thr and maxiter, all an options bag may hold -- +# penalizedRss()'s own defaults filling the rest. A matrix takes exactly the +# path penalizedRss() does. +# @noRd +.penalizedRssOn <- function(bhat, ld, n, spec, options) { + path <- list_modify( + .formalDefaults(penalizedRss, c("lambda", "thr", "maxiter")), + !!!options + ) + exec( + .penalizedRssPath, + bhat = bhat, + ld = ld, + n = n, + spec = spec, + !!!path ) - exec(.penalizedRssPath, bhat = bhat, ld = ld, n = n, !!!settings) } #' RSS Weights Helper for Penalized Methods #' -#' Shared implementation for \code{scadRssWeights()} and \code{mcpRssWeights()}. +#' Shared implementation for \code{scadRssWeights()}, \code{mcpRssWeights()}, +#' \code{enetRssWeights()} and \code{ridgeRssWeights()}. #' (\code{l0learnRssWeights()} uses the lower-level \code{.rssShrinkGridWeights} #' scaffold directly, since it sweeps an additional \code{lambda0} path.) #' Searches over a shrinkage grid \code{s} (LD matrix shrinkage \code{(1-s)R + #' sI}) and selects the best candidate via LD-quadratic pseudovalidation or #' minimum penalized objective. #' -#' @param stat,ldReference,s,selection,penalty,gamma,alpha,lambda0,lambda2 See -#' the public wrappers for details. +#' @param stat,ldReference,s,selection See the public wrappers for details. +#' @param spec The penalty, built by the calling wrapper from its own +#' arguments (internal \code{.rssPenalty()}). #' @param fitRetention How much of the search is kept as the \code{"fit"} #' attribute; see \code{\link{scadRssWeights}}. #' @param methodArgs Options forwarded to \code{penalizedRss}, built with -#' \code{\link{PenalizedRssOptions}}. +#' \code{\link{PenalizedRssOptions}}: the path only, since the penalty is +#' the wrapper's. +#' @param label The calling wrapper's name, for its error messages. #' @return Numeric weight vector, one weight per variant of \code{stat}. #' @keywords internal .penalizedRssWeights <- function( stat, ldReference, - penalty, + spec, s = c(0.2, 0.5, 0.9, 1.0), - gamma = NULL, - alpha = 1.0, - lambda0 = 0, - lambda2 = 0, selection = c("ldQuadratic", "minFbeta"), fitRetention = c("none", "slim", "full"), - methodArgs = PenalizedRssOptions() + methodArgs = PenalizedRssOptions(), + label = str_c(str_to_lower(spec$penalty), "RssWeights") ) { .assertMethodOptions(methodArgs, "PenalizedRssOptions", "methodArgs") selection <- arg_match(selection) fitRetention <- arg_match(fitRetention) .rssShrinkGridWeights( stat, - .rssLdSource( - stat, - ldReference, - str_c(str_to_lower(penalty), "RssWeights") - ), + .rssLdSource(stat, ldReference, label), s, - "penalized", list( - penalty = penalty, - gamma = gamma, - alpha = alpha, - lambda0 = lambda0, - lambda2 = lambda2, - dotArgs = methodArgs + method = "penalized", + spec = spec, + options = as.list(methodArgs) ), selection, fitRetention @@ -3038,7 +3087,9 @@ penalizedRss <- function( #' @param s Numeric vector of LD shrinkage parameters. Default: \code{c(0.2, #' 0.5, 0.9, 1.0)}. #' @param gamma SCAD concavity parameter. Default 3.7. -#' @param alpha Elastic-net mixing (1 = pure L1). Default 1. +#' @param alpha Elastic-net mixing in \code{(0, 1]}: the SCAD share of +#' the penalty, the rest a ridge term, as \code{\link{penalizedRss}} +#' mixes them. Default 1, no ridge term. #' @param selection Selection strategy: \code{"ldQuadratic"} (default) or #' \code{"minFbeta"}. #' @param methodArgs Options forwarded to the solver, @@ -3079,15 +3130,13 @@ scadRssWeights <- function( fitRetention <- arg_match(fitRetention) assertList(stat) assertNumeric(s, lower = 0, any.missing = FALSE) - assertNumber(gamma, finite = TRUE) - assertNumber(alpha, finite = TRUE) + # Built before the grid starts, so a bad penalty fails here. + spec <- .rssPenalty("SCAD", alpha = alpha, gamma = gamma) .penalizedRssWeights( stat = stat, ldReference = ldReference, - penalty = "SCAD", + spec = spec, s = s, - gamma = gamma, - alpha = alpha, selection = selection, fitRetention = fitRetention, methodArgs = methodArgs @@ -3113,7 +3162,9 @@ scadRssWeights <- function( #' @param s Numeric vector of LD shrinkage parameters. Default: \code{c(0.2, #' 0.5, 0.9, 1.0)}. #' @param gamma MCP concavity parameter. Default 3. -#' @param alpha Elastic-net mixing (1 = pure L1). Default 1. +#' @param alpha Elastic-net mixing in \code{(0, 1]}: the MCP share of +#' the penalty, the rest a ridge term, as \code{\link{penalizedRss}} +#' mixes them. Default 1, no ridge term. #' @param selection Selection strategy: \code{"ldQuadratic"} (default) or #' \code{"minFbeta"}. #' @param methodArgs Options forwarded to the solver, @@ -3154,21 +3205,142 @@ mcpRssWeights <- function( fitRetention <- arg_match(fitRetention) assertList(stat) assertNumeric(s, lower = 0, any.missing = FALSE) - assertNumber(gamma, finite = TRUE) - assertNumber(alpha, finite = TRUE) + # Built before the grid starts, so a bad penalty fails here. + spec <- .rssPenalty("MCP", alpha = alpha, gamma = gamma) .penalizedRssWeights( stat = stat, ldReference = ldReference, - penalty = "MCP", + spec = spec, s = s, - gamma = gamma, - alpha = alpha, selection = selection, fitRetention = fitRetention, methodArgs = methodArgs ) } +#' Compute Elastic-Net Weights from Summary Statistics +#' +#' Fits the elastic net on the RSS objective -- the lasso penalty mixed with +#' a ridge term, as glmnet mixes them -- searching over a shrinkage grid +#' \code{s} and a lambda path. Model selection uses LD-quadratic +#' pseudovalidation by default. +#' +#' \code{alpha} is the L1 share of the penalty: with \eqn{l_1 = \lambda +#' \alpha} and \eqn{l_2 = \lambda (1 - \alpha)} the penalty is +#' \eqn{2 l_1 \|\beta\|_1 + l_2 \beta^T \beta}, so \code{alpha = 1} is the +#' lasso and \code{alpha = 0} ridge (\code{\link{ridgeRssWeights}}). The +#' default lambda path is divided by \code{max(alpha, 0.001)}, as glmnet +#' sizes its own, so the L1 share spans the same range at any \code{alpha}. +#' +#' The LD shrinkage adds a ridge term of its own, since +#' \eqn{\beta^T R_s \beta = (1 - s) \beta^T R \beta + s \beta^T \beta}: every +#' RSS lasso is already partly a ridge, and \code{alpha} adds a second ridge +#' term that grows with \eqn{\lambda}. Expect the lasso and the elastic net +#' to differ less on summary statistics than glmnet's do on genotypes. +#' +#' @param alpha Elastic-net mixing in \code{[0, 1]}: the L1 share of the +#' penalty. Default 0.5. +#' @inheritParams scadRssWeights +#' @inheritParams lassosumRssWeights +#' @return A numeric vector of SNP coefficient weights. Unless +#' \code{fitRetention = "none"}, the search is attached as attribute +#' \code{"fit"}. +#' @examples +#' data(eqtlRegionExample) +#' X <- eqtlRegionExample$X[, 1:30] +#' y <- eqtlRegionExample$yRes +#' ss <- lapply( +#' seq_len(ncol(X)), function(j) coef(summary(lm(y ~ X[, j])))[2, 1:2]) +#' stat <- list( +#' b = vapply(ss, `[`, numeric(1), 1L), +#' seb = vapply(ss, `[`, numeric(1), 2L), +#' n = rep(nrow(X), ncol(X)), +#' variantNames = colnames(X) +#' ) +#' enetRssWeights(stat, LdMatrix(cor(X))) +#' # A larger ridge share: +#' enetRssWeights(stat, LdMatrix(cor(X)), alpha = 0.2) +#' @importFrom checkmate assertList assertNumeric +#' @export +enetRssWeights <- function( + stat, + ldReference, + alpha = 0.5, + s = c(0.2, 0.5, 0.9, 1.0), + selection = c("ldQuadratic", "minFbeta"), + fitRetention = c("none", "slim", "full"), + methodArgs = PenalizedRssOptions() +) { + .assertMethodOptions(methodArgs, "PenalizedRssOptions", "methodArgs") + fitRetention <- arg_match(fitRetention) + assertList(stat) + assertNumeric(s, lower = 0, any.missing = FALSE) + # Built before the grid starts, so a bad mixing fails here. + spec <- .rssPenalty("lasso", alpha = alpha) + .penalizedRssWeights( + stat = stat, + ldReference = ldReference, + spec = spec, + s = s, + selection = selection, + fitRetention = fitRetention, + methodArgs = methodArgs, + label = "enetRssWeights" + ) +} + +#' Compute Ridge Weights from Summary Statistics +#' +#' Fits ridge regression on the RSS objective, \code{\link{enetRssWeights}} +#' at \code{alpha = 0}: the penalty is \eqn{\lambda \beta^T \beta}, and the +#' default lambda path runs from 0.1 to 100. Searches over a shrinkage grid +#' \code{s} as well, whose own ridge term \eqn{s \beta^T \beta} adds to it; +#' model selection uses LD-quadratic pseudovalidation by default. +#' +#' @inheritParams scadRssWeights +#' @inheritParams lassosumRssWeights +#' @return A numeric vector of SNP coefficient weights. Unless +#' \code{fitRetention = "none"}, the search is attached as attribute +#' \code{"fit"}. +#' @examples +#' data(eqtlRegionExample) +#' X <- eqtlRegionExample$X[, 1:30] +#' y <- eqtlRegionExample$yRes +#' ss <- lapply( +#' seq_len(ncol(X)), function(j) coef(summary(lm(y ~ X[, j])))[2, 1:2]) +#' stat <- list( +#' b = vapply(ss, `[`, numeric(1), 1L), +#' seb = vapply(ss, `[`, numeric(1), 2L), +#' n = rep(nrow(X), ncol(X)), +#' variantNames = colnames(X) +#' ) +#' ridgeRssWeights(stat, LdMatrix(cor(X))) +#' @importFrom checkmate assertList assertNumeric +#' @export +ridgeRssWeights <- function( + stat, + ldReference, + s = c(0.2, 0.5, 0.9, 1.0), + selection = c("ldQuadratic", "minFbeta"), + fitRetention = c("none", "slim", "full"), + methodArgs = PenalizedRssOptions() +) { + .assertMethodOptions(methodArgs, "PenalizedRssOptions", "methodArgs") + fitRetention <- arg_match(fitRetention) + assertList(stat) + assertNumeric(s, lower = 0, any.missing = FALSE) + .penalizedRssWeights( + stat = stat, + ldReference = ldReference, + spec = .rssPenalty("lasso", alpha = 0), + s = s, + selection = selection, + fitRetention = fitRetention, + methodArgs = methodArgs, + label = "ridgeRssWeights" + ) +} + #' Compute L0-Penalized Weights from Summary Statistics #' #' Fits L0-penalized regression (with optional L1/L2 components) on the RSS @@ -3245,9 +3417,18 @@ l0learnRssWeights <- function( methodArgs = PenalizedRssOptions() ) { .assertMethodOptions(methodArgs, "PenalizedRssOptions", "methodArgs") + # Its own `lambda` is the path; one in the options would replace it. + .configRefuseOwned( + methodArgs, + c(lambda = "l0learnRssWeights' own `lambda`"), + "l0learnRssWeights" + ) penalty <- arg_match(penalty) selection <- arg_match(selection) fitRetention <- arg_match(fitRetention) + # The L0 penalty, lambda0 left to the sweep over its grid. + spec <- .rssPenalty(penalty, lambda2 = lambda2, maxSwaps = maxSwaps) + assertNumeric(lambda0, lower = 0, finite = TRUE, any.missing = FALSE) # Default lambda (L1 component) depends on variant if (is.null(lambda)) { @@ -3262,14 +3443,11 @@ l0learnRssWeights <- function( stat, .rssLdSource(stat, ldReference, "l0learnRssWeights"), s, - "l0learn", list( - penalty = penalty, - lambda = lambda, + method = "l0learn", + spec = spec, lambda0 = lambda0, - lambda2 = lambda2, - maxSwaps = maxSwaps, - dotArgs = methodArgs + options = list_assign(as.list(methodArgs), lambda = lambda) ), selection, fitRetention @@ -3771,14 +3949,14 @@ dprAdaptiveGibbsWeights <- function( # Starting coefficients as a plain matrix: .mrmashInitCoefficients() # returns the fit it used, and only its Bhat is wanted here. # @noRd -.mrmashInitB <- function(X, Y, bInitMethod, standardize, numThreads) { +.mrmashInitB <- function(X, Y, bInitMethod, standardize, BPPARAM) { as.matrix( .mrmashInitCoefficients( X, Y, bInitMethod, standardize, - numThreads + BPPARAM )$Bhat ) } @@ -3797,7 +3975,7 @@ dprAdaptiveGibbsWeights <- function( bInitMethod, sumstats, standardize, - numThreads + threads ) { .mrmashRequirePackages() .assertMethodParam(prior, "MrmashPriorParam") @@ -3810,7 +3988,7 @@ dprAdaptiveGibbsWeights <- function( canonicalPriorMatrices = priorOpts$canonicalPriorMatrices %||% FALSE ) if (is.null(sumstats)) { - sumstats <- .mrmashComputeSumstats(X, Y, standardize, numThreads) + sumstats <- .mrmashComputeSumstats(X, Y, standardize, threads) } list( bInitMethod = .mrmashResolveBInit(Y, bInitMethod), @@ -3850,8 +4028,12 @@ dprAdaptiveGibbsWeights <- function( #' data. Default is FALSE. Used by the summary-statistic and initialisation #' steps as well as the fit, so it is set here rather than in #' \code{methodArgs}. -#' @param numThreads The number of threads to use for parallel computation. -#' Default is 1. Used by the same three steps as \code{standardize}. +#' @param BPPARAM A \code{BiocParallelParam}. The univariate glmnet fits that +#' initialise the coefficients run on its workers, and mr.mash's own +#' threads (the summary statistics and the fit) number its workers when +#' they run on this machine (\code{SerialParam}, \code{MulticoreParam}); +#' for other backends mr.mash runs on one thread. Default +#' \code{SerialParam()}. #' @param methodArgs Options forwarded to \code{mr.mashr::mr.mash} under its #' own names, built with \code{\link{MrmashOptions}} #' (\code{update_w0}, \code{max_iter}, \code{tol}, \code{w0_threshold}, @@ -3912,9 +4094,11 @@ mrmashWrapper <- function( updateV = TRUE, updateVMethod = "full", standardize = FALSE, - numThreads = 1, + BPPARAM = SerialParam(), methodArgs = MrmashOptions() ) { + .assertBpparam(BPPARAM) + threads <- .bpLocalThreads(BPPARAM, "mrmashWrapper") setup <- .mrmashWrapperSetup( X = X, Y = Y, @@ -3924,12 +4108,12 @@ mrmashWrapper <- function( bInitMethod = bInitMethod, sumstats = sumstats, standardize = standardize, - numThreads = numThreads + threads = threads ) bInitMethod <- setup$bInitMethod priorBuilt <- setup$priorBuilt time1 <- proc.time() - bInit <- .mrmashInitB(X, Y, bInitMethod, standardize, numThreads) + bInit <- .mrmashInitB(X, Y, bInitMethod, standardize, BPPARAM) vInit <- .mrmashInitV(X, Y, V, updateV, updateVMethod) fitMrmash <- .mrmashFit( priorBuilt$S0, @@ -3938,7 +4122,7 @@ mrmashWrapper <- function( X = X, Y = Y, standardize = standardize, - numThreads = numThreads, + threads = threads, updateVMethod = updateVMethod, methodArgs = methodArgs ) @@ -4003,13 +4187,13 @@ mrmashWrapper <- function( # Univariate summary statistics (Bhat/Shat) for the prior + init. # @noRd -.mrmashComputeSumstats <- function(X, Y, standardize, numThreads) { +.mrmashComputeSumstats <- function(X, Y, standardize, threads) { mr.mashr::compute_univariate_sumstats( X, Y, standardize = standardize, standardize.response = FALSE, - mc.cores = numThreads + mc.cores = threads ) } @@ -4020,14 +4204,13 @@ mrmashWrapper <- function( Y, bInitMethod, standardize, - numThreads + BPPARAM ) { if (bInitMethod == "glasso") { return(computeCoefficientsGlasso( X, Y, standardize = standardize, - numThreads = numThreads, Xnew = NULL )) } @@ -4036,7 +4219,7 @@ mrmashWrapper <- function( Y, alpha = 0.5, standardize = standardize, - numThreads = numThreads, + BPPARAM = BPPARAM, Xnew = NULL ) } @@ -4093,7 +4276,7 @@ mrmashWrapper <- function( X, Y, standardize, - numThreads, + threads, updateVMethod, methodArgs ) { @@ -4107,7 +4290,7 @@ mrmashWrapper <- function( update_V_method = updateVMethod, mu1_init = bInit, standardize = standardize, - nthreads = numThreads + nthreads = threads ) user <- as.list(methodArgs) clash <- intersect(names(user), names(derived)) @@ -4146,7 +4329,6 @@ mrmashWrapper <- function( #' @param Y Numeric response matrix (samples x conditions). #' @param standardize Logical; standardize the columns of \code{X} before #' fitting. -#' @param numThreads Integer; number of threads for the group-lasso fit. #' @param Xnew Optional new design matrix for prediction; \code{NULL} returns #' in-sample coefficients. #' @return A numeric matrix of initial coefficient estimates (variants x @@ -4155,19 +4337,11 @@ mrmashWrapper <- function( #' data(eqtlRegionExample) #' X <- eqtlRegionExample$X[, 1:30] #' Y <- matrix(rnorm(nrow(X) * 3), nrow(X), 3) -#' computeCoefficientsGlasso(X = X, Y = Y, standardize = TRUE, -#' numThreads = 1L, Xnew = NULL) -#' @importFrom checkmate assertFlag assertInt +#' computeCoefficientsGlasso(X = X, Y = Y, standardize = TRUE, Xnew = NULL) +#' @importFrom checkmate assertFlag #' @export -computeCoefficientsGlasso <- function( - X, - Y, - standardize, - numThreads, - Xnew = NULL -) { +computeCoefficientsGlasso <- function(X, Y, standardize, Xnew = NULL) { assertFlag(standardize) - assertInt(numThreads) p <- ncol(X) r <- ncol(Y) conditionNames <- colnames(Y) @@ -4239,33 +4413,28 @@ computeCoefficientsGlasso <- function( } # Initial mr.mash coefficients from one cv.glmnet per response. The fits are -# independent, so with `numThreads` >= 2 they run in parallel, each worker on -# its own seeded RNG stream (cv.glmnet draws its folds at random); one thread -# runs them in turn on the session RNG, as before. +# independent, so they run on BPPARAM's workers, each on its own seeded +# random-number stream (cv.glmnet draws its folds at random). The data go by +# position: a named `X` would be taken for bplapply()'s own X. # @noRd computeCoefficientsUnivGlmnet <- function( X, Y, alpha, standardize, - numThreads = 1L, + BPPARAM = SerialParam(), Xnew = NULL ) { - r <- ncol(Y) - out <- if (numThreads >= 2L) { - bplapply( - seq_len(r), - .linreg, - X = X, - Y = Y, - alpha = alpha, - standardize = standardize, - Xnew = Xnew, - BPPARAM = .bpSeedParam(numThreads) - ) - } else { - map(seq_len(r), .linreg, X, Y, alpha, standardize, Xnew) - } + out <- .bpMap( + seq_len(ncol(Y)), + .linreg, + X, + Y, + alpha, + standardize, + Xnew, + BPPARAM = BPPARAM + ) bhatList <- map(out, "bhat") Bhat <- exec(cbind, !!!bhatList) @@ -4628,32 +4797,9 @@ buildMrmashPriorMatrices <- function( # ---- map/apply helpers (lambda-free callbacks) --------------------------- -# `.rssSolvePath` solver for lassosum: RSS lasso over the ordered lambda path, -# on the LD matrix or on a factor of it (never forming R). -# @noRd -.rssLassosumSolve <- function(z, lam, ld, thr, maxiter) { - if (!is.null(ld$F)) { - return(lassosumRssFactorCpp( - zR = z, - factorR = ld$F, - shrink = ld$shrink %||% 0, - lambdaR = lam, - thr = thr, - maxiter = as.integer(maxiter) - )) - } - lassosumRssCpp( - zR = z, - LD = list(blk1 = ld$R), - shrink = ld$shrink %||% 0, - lambdaR = lam, - thr = thr, - maxiter = as.integer(maxiter) - ) -} - -# `.rssSolvePath` solver for the penalized (MCP/SCAD/L0...) RSS path, on the -# LD matrix or on a factor of it (never forming R). +# `.rssSolvePath` solver for the penalized RSS path (lasso and its elastic-net +# and ridge mixtures, MCP, SCAD, L0...), on the LD matrix or on a factor of it +# (never forming R). # @noRd .rssPenalizedSolve <- function( z, @@ -4700,17 +4846,13 @@ buildMrmashPriorMatrices <- function( # One L0Learn fit at lambda0 = `l0Val`: penalizedRss over the lambda path. # @noRd .rssL0LambdaFit <- function(l0Val, solverInput, ld, n, sVal, config) { - settings <- c( - list( - penalty = config$penalty, - lambda = config$lambda, - lambda0 = l0Val, - lambda2 = config$lambda2, - maxSwaps = config$maxSwaps - ), - as.list(config$dotArgs) + model <- .penalizedRssOn( + solverInput, + ld, + n, + list_assign(config$spec, lambda0 = l0Val), + config$options ) - model <- .penalizedRssOn(solverInput, ld, n, settings) list( beta = model$beta, meta = mutate(.rssPathMeta(sVal, model), lambda0 = l0Val, .after = "s") diff --git a/R/relatednessQc.R b/R/relatednessQc.R index 54e690ee..38d1b2ee 100644 --- a/R/relatednessQc.R +++ b/R/relatednessQc.R @@ -174,7 +174,8 @@ PlinkQcOptions <- function( analysisType, phenoData, phenoCol, - columns + columns, + relatednessThreshold ) .relatednessIterativeCleanup( filtered$kin, @@ -275,7 +276,8 @@ filterRelatedness <- function( analysisType, phenoData, phenoCol, - columns + columns, + relatednessThreshold ) { if (analysisType == "maximizeUnrelated") { return(list( @@ -283,7 +285,14 @@ filterRelatedness <- function( kin = kin )) } - .relatednessMaximizeCases(kin, pqArgs, phenoData, phenoCol, columns) + .relatednessMaximizeCases( + kin, + pqArgs, + phenoData, + phenoCol, + columns, + relatednessThreshold + ) } # @noRd @@ -459,7 +468,8 @@ filterRelatedness <- function( pqArgs, phenoData, phenoCol, - columns + columns, + relatednessThreshold ) { iid1Col <- columns$iid1 iid2Col <- columns$iid2 @@ -483,7 +493,8 @@ filterRelatedness <- function( kin, casesKeep, relatedControls, - columns + columns, + relatednessThreshold ) # Step 3: filter among the remaining controls. controlsKeep <- setdiff(relatedControls, controlsExclude) @@ -497,15 +508,21 @@ filterRelatedness <- function( # Controls related to a retained case (row order preserved; a case--control # edge excludes the control, mirroring the original per-row if / else-if). +# Related means above `relatednessThreshold`, the test plinkQC applies to the +# case and control steps on either side of this one. The xqtl-protocol +# GWAS_QC.R this was ported from took every listed pair, so a control whose +# kinship with a kept case fell below the threshold was dropped too. # @noRd .relatednessControlsToExclude <- function( kin, casesKeep, relatedControls, - columns + columns, + relatednessThreshold ) { - iid1 <- kin[[columns$iid1]] - iid2 <- kin[[columns$iid2]] + related <- filter(kin, .data[[columns$value]] > relatednessThreshold) + iid1 <- related[[columns$iid1]] + iid2 <- related[[columns$iid2]] mask1 <- is_in(iid1, casesKeep) & is_in(iid2, relatedControls) mask2 <- is_in(iid2, casesKeep) & is_in(iid1, relatedControls) contrib <- case_when( diff --git a/R/resultReaders.R b/R/resultReaders.R index 5b9a3f87..e0bc54af 100644 --- a/R/resultReaders.R +++ b/R/resultReaders.R @@ -2,7 +2,7 @@ # Published result readers # ----------------------------------------------------------------------------- # The inverse of R/resultWriters.R: take a file that was published -- by -# `exportToBed()` / `exportToVcf()`, or by another tool writing the same +# `writeBed()` / `writeGwasVcf()`, or by another tool writing the same # vocabulary -- and rebuild the S4 collection. # # readFineMappingResult(path, ...) -> Qtl / GwasFineMappingResult @@ -85,7 +85,8 @@ NULL weight_standardized = "standardized", joint_studies = "jointStudies", joint_contexts = "jointContexts", - joint_traits = "jointTraits" + joint_traits = "jointTraits", + region_given = "regionGiven" ) # The published columns that are structural or per-row, and so are never @@ -115,21 +116,22 @@ NULL # be uniformly "T" within a region would otherwise be type-guessed as logical, # silently corrupting the variant identity. # @noRd -.prdReadTable <- function(path, region, label) { +.prdReadTable <- function(path, which, label) { if (!file.exists(path)) { abort(glue("{label}: file '{path}' does not exist.")) } - if (!is.null(region)) { + if (!is.null(which)) { if (file.exists(str_c(path, ".tbi"))) { - return(.readTabixRegion(path, region)) + return(.readTabixRegion(path, which)) } warn(glue( - "{label}: '{path}' is not bgzipped + tabix-indexed; `region` ", + "{label}: '{path}' is not bgzipped + tabix-indexed; `which` ", "ignored, reading the whole file." )) } readr::read_tsv( path, + skip = length(.prdBedMetaLines(path)), show_col_types = FALSE, progress = FALSE, col_types = readr::cols(.default = readr::col_character()) @@ -156,8 +158,8 @@ NULL # off the `##SAMPLE` header block. Each sample is one fitted model, so each # contributes its own block of rows. # @noRd -.prdVcfTable <- function(path, region, sampleSelect, label) { - vcf <- .prdReadVcf(path, region, label) +.prdVcfTable <- function(path, which, sampleSelect, label) { + vcf <- .prdReadVcf(path, which, label) samples <- colnames(vcf) if (!is.null(sampleSelect)) { absent <- setdiff(as.character(sampleSelect), samples) @@ -185,27 +187,84 @@ NULL meta <- .prdVcfSampleMeta(vcf) pieces <- map(samples, .prdVcfSampleTable, vcf = vcf, meta = meta) list( + build = .prdVcfBuild(vcf), table = list_rbind(pieces), - fits = compact(set_names( - map(samples, .prdVcfPartialFit, meta = meta), - map_chr(pieces, .prdFirstKey) - )) + fits = compact(list_flatten(unname(map2( + samples, + pieces, + .prdVcfSampleFits, + meta = meta + )))) ) } -# The identity key of a sample's block, so its header-recorded partial fit can -# be found again once every sample's rows are stacked into one table. +# The genome build a VCF records on its ##reference line, or NA. +# @noRd +.prdVcfBuild <- function(vcf) { + .vcfMetaBuild(VariantAnnotation::header(vcf)) +} + +# @noRd +.vcfMetaBuild <- function(hdr) { + ref <- VariantAnnotation::meta(hdr)$reference + if (is.null(ref) || nrow(ref) == 0L) { + return(NA_character_) + } + as.character(ref$Value[[1L]]) +} + +# A sample's partial fits, keyed by the group each belongs to: one for a +# single fit, or one per LD block of a sample that joined several, taken from +# the header's "|"-packed values in the order its block list gives. The keys +# are the ones .prdGroups() splits the stacked table by, so each partial fit +# is found again once every sample's rows are stacked together. +# @noRd +.prdVcfSampleFits <- function(sample, tbl, meta) { + if (is.null(meta) || !is_in(sample, rownames(meta)) || nrow(tbl) == 0L) { + return(list()) + } + row <- meta[sample, , drop = FALSE] + keys <- .pubIdentityKey(tbl, .PRD_GROUP_COLS) + first <- which(!duplicated(keys)) + pos <- .prdBlockPositions(row, tbl$block_id[first]) %||% + rep(1L, length(first)) + set_names(map(pos, .prdVcfPartialFit, row = row), keys[first]) +} + +# Where each block sits in a joined sample's header lists, or NULL for a +# sample holding one block. +# @noRd +.prdBlockPositions <- function(row, blocks) { + listed <- .prdBlockList(row) + if (length(listed) < 2L || is.null(blocks) || all(is.na(blocks))) { + return(NULL) + } + # An NA block is a variant this sample does not have -- another sample of + # the file contributed it -- and it stays NA. + pos <- match(blocks, listed) + unknown <- !is.na(blocks) & is.na(pos) + if (any(unknown)) { + abort(glue( + "readFineMappingResult: the BID field names block(s) ", + "{str_flatten(unique(blocks[unknown]), ', ')} that the ", + "sample's header does not list." + )) + } + pos +} + +# The LD blocks a sample's `##SAMPLE` line lists, in packing order. # @noRd -.prdFirstKey <- function(tbl) { - cols <- intersect(.PRD_GROUP_COLS, names(tbl)) - if (nrow(tbl) == 0L || length(cols) == 0L) { - return("") +.prdBlockList <- function(row) { + cell <- row[["block_id"]] + if (is.null(cell) || is.na(cell[[1L]])) { + return(character(0)) } - .pubIdentityKey(tbl, cols)[[1L]] + str_split_1(as.character(cell[[1L]]), fixed("|")) } # @noRd -.prdReadVcf <- function(path, region, label) { +.prdReadVcf <- function(path, which, label) { if (!requireNamespace("VariantAnnotation", quietly = TRUE)) { abort(glue( "{label}: reading a published VCF requires the ", @@ -215,18 +274,18 @@ NULL if (!file.exists(path)) { abort(glue("{label}: file '{path}' does not exist.")) } - if (is.null(region) || !file.exists(str_c(path, ".tbi"))) { - if (!is.null(region)) { + if (is.null(which) || !file.exists(str_c(path, ".tbi"))) { + if (!is.null(which)) { warn(glue( "{label}: '{path}' is not bgzipped + tabix-indexed; ", - "`region` ignored, reading the whole file." + "`which` ignored, reading the whole file." )) } return(VariantAnnotation::readVcf(path)) } tf <- Rsamtools::TabixFile(path) gr <- .matchRegionSeqnames( - .asGRegion(region), + which, Rsamtools::seqnamesTabix(tf) ) if (is.null(gr)) { @@ -236,7 +295,7 @@ NULL } # The per-fit `##SAMPLE` block as a plain data.frame keyed by sample id, or -# NULL when the file has none. This is where `exportToVcf()` records the +# NULL when the file has none. This is where `writeGwasVcf()` records the # identity, the analysis window and the two per-EFFECT fit quantities (`V`, # `cs_index`) that no per-variant column could hold. # @noRd @@ -274,16 +333,30 @@ NULL end = as.integer(GenomicRanges::start(rr)), ID = names(rr) %||% rep(NA_character_, n), REF = unname(as.character(VariantAnnotation::ref(vcf))), - ALT = unname(map_chr(as.list(VariantAnnotation::alt(vcf)), .mlFirstAlt)) + ALT = .mlFirstAlts(VariantAnnotation::alt(vcf)) ) fmt <- set_names( map(names(geno), .prdVcfFormatColumn, geno = geno, sample = sample), map_chr(names(geno), .prdVcfKeyName) ) - ident <- .prdVcfIdentity(meta, sample, n) - bind_cols(fixed, as_tibble(fmt, .name_repair = "minimal"), ident) + # BID is structure, not a statistic: it says which LD block of a joined + # sample each variant belongs to, and so feeds the identity columns. + ident <- .prdVcfIdentity(meta, sample, n, fmt[["BID"]]) + fmt[["BID"]] <- NULL + # The records are the union of every sample's variants, and a sample + # leaves the cells of a variant it does not have empty. Those rows are + # not its results, so they are dropped rather than read back as variants + # with no statistics. + has <- reduce(map(fmt, .prdNotNa), `|`, .init = rep(FALSE, n)) + slice( + bind_cols(fixed, as_tibble(fmt, .name_repair = "minimal"), ident), + which(has) + ) } +# @noRd +.prdNotNa <- function(v) !is.na(v) + # One FORMAT field's column for one sample. A field the sample does not report # is all-NA, which is what an absent column means on the way back in. # @noRd @@ -302,7 +375,7 @@ NULL # A FORMAT key as the published column name. The fixed vocabulary is already # shared between the two formats, so only the per-credible-set `fullFit` -# fields need undoing: `exportToVcf()` uppercases those column names because a +# fields need undoing: `writeGwasVcf()` uppercases those column names because a # FORMAT key is conventionally uppercase, and nothing else in the schema is # case-ambiguous. # @noRd @@ -322,7 +395,7 @@ NULL # several merge into one identity-less row, and the reader's own arguments # supply whatever else is wanted. # @noRd -.prdVcfIdentity <- function(meta, sample, n) { +.prdVcfIdentity <- function(meta, sample, n, bid = NULL) { if (is.null(meta) || !is_in(sample, rownames(meta))) { return(tibble(study = rep(sample, length.out = n))) } @@ -339,13 +412,28 @@ NULL if (length(cols) == 0L) { return(tibble(study = rep(sample, length.out = n))) } + pos <- .prdBlockPositions(row, bid) out <- as_tibble( - set_names(map(cols, .prdMetaValue, row = row, n = n), cols), + set_names( + map(cols, .prdMetaValue, row = row, n = n, pos = pos), + cols + ), .name_repair = "minimal" ) .prdVcfRegionStart(out) } +# The header fields a sample joining several LD blocks packs one value per +# block of, separated by "|" (see writeGwasVcf). +# @noRd +.PRD_BLOCK_FIELDS <- c( + "block_id", + "region_id", + "region_start", + "region_end", + "region_given" +) + # A VCF header's `RegionStart` is 1-based, because VCF coordinates are; a # published table's `region_start` is 0-based half-open, because BED # coordinates are. Each format is right on its own terms, so the long form @@ -368,9 +456,17 @@ NULL # missing value and `.vcfHeaderValue()` writes it for a field one sample has # and another does not, so it is restored as NA rather than as the string ".". # @noRd -.prdMetaValue <- function(nm, row, n) { +.prdMetaValue <- function(nm, row, n, pos = NULL) { v <- as.character(row[[nm]][[1L]]) - rep(if (!is.na(v) && v == ".") NA_character_ else v, length.out = n) + if (is.na(v) || v == ".") { + return(rep(NA_character_, length.out = n)) + } + if (is.null(pos) || !is_in(nm, .PRD_BLOCK_FIELDS)) { + return(rep(v, length.out = n)) + } + # A joined sample: each variant takes its own block's value. + perBlock <- str_split_1(v, fixed("|"))[pos] + replace(perBlock, perBlock == "", NA_character_) } # The per-effect fit quantities the `##SAMPLE` block carried, as the partial @@ -381,13 +477,9 @@ NULL # the posterior matrices) is not published, so this is deliberately partial: # `NULL` when the header recorded neither. # @noRd -.prdVcfPartialFit <- function(meta, sample) { - if (is.null(meta) || !is_in(sample, rownames(meta))) { - return(NULL) - } - row <- meta[sample, , drop = FALSE] - v <- .prdUnpackNumeric(row[["V"]]) - csIndex <- .prdUnpackNumeric(row[["cs_index"]]) +.prdVcfPartialFit <- function(pos, row) { + v <- .prdUnpackNumeric(.prdBlockPiece(row[["V"]], pos)) + csIndex <- .prdUnpackNumeric(.prdBlockPiece(row[["cs_index"]], pos)) out <- compact(list( V = v, sets = if (!is.null(csIndex)) list(cs_index = as.integer(csIndex)) @@ -395,6 +487,22 @@ NULL if (length(out) == 0L) NULL else out } +# The `pos`-th block's part of a header cell: a sample joining several LD +# blocks packs one value per block, separated by "|", and a single-block +# sample's cell is its one value whole. +# @noRd +.prdBlockPiece <- function(cell, pos) { + if (is.null(cell) || length(cell) == 0L) { + return(NULL) + } + chr <- as.character(cell[[1L]]) + if (is.na(chr) || chr == "." || is.na(pos)) { + return(NULL) + } + pieces <- str_split_1(chr, fixed("|")) + if (length(pieces) == 1L) pieces else pieces[[pos]] +} + # A ";"-packed header value as a numeric vector, or NULL when it was NA. # @noRd .prdUnpackNumeric <- function(cell) { @@ -668,14 +776,45 @@ NULL # One published table read into the long form both readers work from. # @noRd -.prdRead <- function(path, region, format, sampleSelect, label) { +.prdRead <- function(path, which, format, sampleSelect, label) { assertString(path) + if (!is.null(which)) { + .assertRegionGRanges(which, "`which`") + } if (.prdFormat(path, format) == "vcf") { - return(.prdVcfTable(path, region, sampleSelect, label)) + return(.prdVcfTable(path, which, sampleSelect, label)) } # A published table has no header to carry a fit in -- only the VCF's # `##SAMPLE` block does -- so a BED read restores no fit at all. - list(table = .prdReadTable(path, region, label), fits = list()) + list( + table = .prdReadTable(path, which, label), + fits = list(), + build = .prdBedBuild(path) + ) +} + +# The genome build a published BED records on its `##genome=` line, or NA. +# @noRd +.prdBedBuild <- function(path) { + meta <- .prdBedMetaLines(path) + hit <- meta[str_detect(meta, "^##genome=")] + if (length(hit) == 0L) { + NA_character_ + } else { + str_remove(hit[[1L]], "^##genome=") + } +} + +# The `##` lines a published BED opens with, above its column header. +# @noRd +.prdBedMetaLines <- function(path) { + head <- readr::read_lines(path, n_max = 20L, progress = FALSE) + head[seq_len(.prdLeadingCount(str_detect(head, "^##")))] +} + +# @noRd +.prdLeadingCount <- function(flags) { + if (all(flags)) length(flags) else which(!flags)[[1L]] - 1L } # The row groups of a published table, in first-appearance order: one per @@ -773,6 +912,7 @@ NULL # file did not publish it. `region_start` is 0-based half-open like every # other published coordinate, so it is shifted back by one; `region_id` stays # the 1-based `chrom_start_end` identifier and is not a coordinate source. +# The chromosome is spelled in UCSC style, as the variants' ranges are. # @noRd .prdRowRegion <- function(df, idx, label) { start <- .prdGroupValue(df, "region_start", idx, label) @@ -782,7 +922,7 @@ NULL return(NULL) } GenomicRanges::GRanges( - chrom, + withChrPrefix(chrom), IRanges::IRanges( start = as.integer(start) + 1L, end = as.integer(end) @@ -821,7 +961,7 @@ NULL # back to the list method and hands back a list, which the constructor # then rejects as "not a GRanges". Names come from the group keys and # would otherwise land on the stored ranges. - unname(unlist(GenomicRanges::GRangesList(regions))) + unname(unlist(.rtlBindElements(regions))) } # A per-row character column for a constructor argument, or NULL when no row @@ -904,10 +1044,10 @@ NULL #' @title Read A Published Fine-Mapping Result #' @description Rebuild a \code{QtlFineMappingResult} or -#' \code{GwasFineMappingResult} from a file \code{\link{exportToBed}} or -#' \code{\link{exportToVcf}} wrote -- or from any file in the same -#' vocabulary, which is what makes this the way into pecotmr for results -#' produced elsewhere. +#' \code{GwasFineMappingResult} from a file \code{\link{writeBed}} or +#' \code{\link{writeGwasVcf}} wrote -- or from any file in +#' the same vocabulary, which is what makes this the way into pecotmr for +#' results produced elsewhere. #' #' A merged table holding several \code{(study, context, trait, method)} #' tuples reads back as a multi-row collection, one row per tuple. Which @@ -935,7 +1075,7 @@ NULL #' Every published quantity comes back identical, in either format. Three #' things are not identities: #' \itemize{ -#' \item \code{exportToBed()} publishes the \strong{filtered} top-loci +#' \item \code{writeBed()} publishes the \strong{filtered} top-loci #' table, so a default export holds the variants that passed #' \code{signalCutoff} / \code{minPurity} rather than every variant of #' the fit. Export with \code{signalCutoff = 0} for the whole table. @@ -950,11 +1090,11 @@ NULL #' } #' #' @param path Path to the published file. Bgzipped and tabix-indexed files -#' can be read by region. -#' @param region Optional region to restrict the read to -- a -#' \code{"chr:start-end"} string, a \code{GRanges}, or a one-row -#' \code{data.frame} with chrom/start/end. Ignored with a warning when the -#' file is not tabix-indexed. +#' can be read in part, with \code{which}. +#' @param which Optional \code{GRanges}: read only the records that overlap +#' it, as \code{which} does for \code{rtracklayer::import()} and +#' \code{VariantAnnotation::ScanVcfParam()}. Ignored with a warning when +#' the file is not tabix-indexed. #' @param format \code{"auto"} (default) reads a \code{.vcf} / \code{.bcf} #' path as a VCF and anything else as a published table; \code{"bed"} / #' \code{"vcf"} say so explicitly for a file named otherwise. @@ -975,12 +1115,12 @@ NULL #' \code{LBF}. These are an approximation under a prior you chose, not #' susie's \code{lbf_variable}, so nothing derives them unasked. #' @return A \code{QtlFineMappingResult} or \code{GwasFineMappingResult}. -#' @seealso \code{\link{exportToBed}}, \code{\link{exportToVcf}}, +#' @seealso \code{\link{writeBed}}, \code{\link{writeGwasVcf}}, #' \code{\link{readTwasWeights}} #' @examples #' data(qtlFineMappingExample) #' path <- file.path(tempdir(), "top_loci.bed") -#' exportToBed(qtlFineMappingExample, path) +#' writeBed(qtlFineMappingExample, path) #' # This fit predates the provenance columns, so its published table does #' # not say which genotype scale its posterior effects are on -- the reader #' # will not guess. @@ -990,7 +1130,7 @@ NULL #' @export readFineMappingResult <- function( path, - region = NULL, + which = NULL, format = c("auto", "bed", "vcf"), studyName = NULL, context = NULL, @@ -1002,7 +1142,7 @@ readFineMappingResult <- function( priorVariance = NULL ) { label <- "readFineMappingResult" - src <- .prdRead(path, region, format, sampleSelect, label) + src <- .prdRead(path, which, format, sampleSelect, label) df <- src$table .prdRequirePip(df, label) .prdRequireStandardized(df, weightStandardized, label) @@ -1024,7 +1164,10 @@ readFineMappingResult <- function( priorVariance = priorVariance, fits = src$fits ) - .prdBuildFineMapping(rows, df, context, trait, label) + .withGenome( + .prdBuildFineMapping(rows, df, context, trait, label), + src$build %||% NA_character_ + ) } # A fine-mapping result is a posterior, and the PIP is the posterior. A table @@ -1051,7 +1194,7 @@ readFineMappingResult <- function( list( fields = fields, region = .prdRowRegion(df, idx, label), - entry = fineMappingRow( + entry = FineMappingRow( variantIds = tl$variant_id, susieFit = .prdFitFor(fits, key), topLoci = tl @@ -1086,7 +1229,7 @@ readFineMappingResult <- function( return(.prdBuildQtl(rows, fields, regions, label)) } .prdRequireIdentity(fields, c("study", "method"), label) - GwasFineMappingResult( + out <- GwasFineMappingResult( studyName = .prdRowColumn(fields, "study"), method = .prdRowColumn(fields, "method"), entry = map(rows, "entry"), @@ -1096,6 +1239,22 @@ readFineMappingResult <- function( dataSource = .prdRowColumn(fields, "dataSource"), weightStandardized = .prdStandardizedColumn(fields) ) + .prdRestoreRegionGiven(out, rows) +} + +# Whether each block range was given is what the file says. The constructor +# counts every range it is handed as given, but a range read from a file is +# the analysis window, which says nothing of where it came from, so a file +# that does not record it reads back as computed. A group spanning several +# chromosomes is split into a row per chromosome, each keeping its group's. +# @noRd +.prdRestoreRegionGiven <- function(out, rows) { + recorded <- as.logical( + map_chr(map(rows, "fields"), .prdRowField, nm = "regionGiven") + ) + fromIdx <- .rtlSplitBySeqname(map(map(rows, "entry"), variants))$fromIdx + out$regionGiven <- !is.na(recorded[fromIdx]) & recorded[fromIdx] + out } @@ -1166,8 +1325,8 @@ readFineMappingResult <- function( #' @title Read Published TWAS Weights #' @description Rebuild a \code{TwasWeights} from a file -#' \code{\link{exportToBed}} or \code{\link{exportToVcf}} wrote, or from any -#' file in the same vocabulary. +#' \code{\link{writeBed}} or \code{\link{writeGwasVcf}} +#' wrote, or from any file in the same vocabulary. #' #' A merged table reads back as a multi-row collection, one row per #' \code{(study, context, trait, method)} tuple. A fitted model whose @@ -1194,17 +1353,17 @@ readFineMappingResult <- function( #' standardized genotype scale. Required when the file does not record it: #' the scale is not recoverable from the weights themselves. #' @return A \code{TwasWeights}. -#' @seealso \code{\link{exportToBed}}, \code{\link{readFineMappingResult}} +#' @seealso \code{\link{writeBed}}, \code{\link{readFineMappingResult}} #' @examples #' data(twasWeightsExample) #' path <- file.path(tempdir(), "weights.bed") -#' exportToBed(twasWeightsExample, path) +#' writeBed(twasWeightsExample, path) #' readTwasWeights(path) #' @export readTwasWeights <- function( path, - region = NULL, + which = NULL, format = c("auto", "bed", "vcf"), studyName = NULL, context = NULL, @@ -1215,7 +1374,7 @@ readTwasWeights <- function( sampleSelect = NULL ) { label <- "readTwasWeights" - src <- .prdRead(path, region, format, sampleSelect, label) + src <- .prdRead(path, which, format, sampleSelect, label) df <- src$table .prdRequireWgt(df, label) .prdRequireStandardized(df, weightStandardized, label) @@ -1234,7 +1393,7 @@ readTwasWeights <- function( supplied = supplied, label = label ) - .prdTwFromRows(rows, label) + .withGenome(.prdTwFromRows(rows, label), src$build %||% NA_character_) } # @noRd @@ -1294,7 +1453,7 @@ readTwasWeights <- function( list( fields = fields, region = .prdRowRegion(df, idx, label), - entry = twasWeightsRow( + entry = TwasWeightsRow( variantIds = tl$variant_id, weights = suppressWarnings(as.numeric(sub$WGT)), weightStandardized = isTRUE(.prdFlag(fields$standardized)), diff --git a/R/resultWriters.R b/R/resultWriters.R index fc838d7a..ac80dc36 100644 --- a/R/resultWriters.R +++ b/R/resultWriters.R @@ -4,11 +4,12 @@ # Every pecotmr output format that leaves the package as a FILE lives here, # behind TWO generics rather than one entry point per class: # -# exportToVcf(x, path, ...) GWAS-VCF-style: one record per variant, one -# SAMPLE per study / fitted model, the statistics -# as FORMAT fields. GwasSumStats, every -# FineMappingResultBase, TwasWeights. -# exportToBed(x, path, ...) the published long-format tables, one row per +# writeGwasVcf(obj, filename, ...) GWAS-VCF-style: one record per variant, +# one SAMPLE per study / fitted model, the +# statistics as FORMAT fields. GwasSumStats, +# every FineMappingResultBase, TwasWeights. +# VariantAnnotation (a Suggests) writes the file. +# writeBed(obj, filename, ...) the published long-format tables, one row per # published observation, bgzipped + tabix-indexed # on request. FineMappingResultBase, # TwasWeights. @@ -285,7 +286,7 @@ NULL } # Rows of a TwasWeights with no full-data weights: a CV-only row has an empty -# element AND no `weight` metadata column (twasWeightsRow() drops the column +# element AND no `weight` metadata column (TwasWeightsRow() drops the column # when `weights` is NULL). # @noRd .twbIncompleteRows <- function(x) { @@ -423,7 +424,8 @@ genomicOrder <- function(chrom, start, end = NULL) { index, emptySchema = .pubSchema(character(0)), keepColumns = character(0), - extraColumns = NULL + extraColumns = NULL, + build = NA_character_ ) { if (is.null(out) || nrow(out) == 0L) { # A header-only file documents the whole vocabulary rather than @@ -443,24 +445,30 @@ genomicOrder <- function(chrom, start, end = NULL) { if (nrow(out) > 0L) { out <- slice(out, genomicOrder(out[["#chr"]], out[["start"]])) } - .pubEmitTable(out, path, naString, index) + .pubEmitTable(out, path, naString, index, build) } # Materialise the ordered table at `path`, compressing and indexing it when the -# extension asks for it. +# extension asks for it. A named genome build goes first, as a `##genome=` +# line above the column header; tabix skips both as comments. # @noRd -.pubEmitTable <- function(out, path, naString, index) { +.pubEmitTable <- function(out, path, naString, index, build = NA_character_) { dir.create(dirname(path), showWarnings = FALSE, recursive = TRUE) compress <- str_detect(path, "\\.(gz|bgz)$") plain <- if (compress) str_remove(path, "\\.(gz|bgz)$") else path + con <- file(plain, "w") + if (!is.na(build)) { + writeLines(str_c("##genome=", build), con) + } utils::write.table( out, - plain, + con, sep = "\t", quote = FALSE, row.names = FALSE, na = naString ) + close(con) if (!compress) { return(invisible(path)) } @@ -475,18 +483,19 @@ genomicOrder <- function(chrom, start, end = NULL) { # ---- shared: output-path decoration ----------------------------------------- -# Decorate `outputPath` with the spec's context / trait tags when split flags -# are set. Preserves the file extension. Examples: "out.vcf" + (context="brain") -# -> "out.brain.vcf" "out.vcf.bgz" + (context="brain", trait="ENSG1") -> -# "out.brain.ENSG1.vcf.bgz" +# Decorate `outputPath` with the spec's context / trait / block tags when split +# flags are set. Preserves the file extension. Examples: "out.vcf" + +# (context="brain") -> "out.brain.vcf" "out.vcf.bgz" + (context="brain", +# trait="ENSG1") -> "out.brain.ENSG1.vcf.bgz" # @noRd .decorateOutputPath <- function( outputPath, spec, splitByContext, - splitByTrait + splitByTrait, + splitByBlock = FALSE ) { - if (!isTRUE(splitByContext) && !isTRUE(splitByTrait)) { + if (!isTRUE(splitByContext) && !isTRUE(splitByTrait) && !splitByBlock) { return(outputPath) } ext <- str_to_lower(tools::file_ext(outputPath)) @@ -506,7 +515,8 @@ genomicOrder <- function(chrom, start, end = NULL) { ) tags <- c( if (isTRUE(splitByContext)) .pubPathTag(spec$context), - if (isTRUE(splitByTrait)) .pubPathTag(spec$trait) + if (isTRUE(splitByTrait)) .pubPathTag(spec$trait), + if (splitByBlock) .pubPathTag(spec$block) ) if (length(tags) == 0L) { return(outputPath) @@ -526,30 +536,30 @@ genomicOrder <- function(chrom, start, end = NULL) { # ---- VCF: entry points ------------------------------------------------------ -#' @rdname exportToVcf +#' @rdname writeGwasVcf #' @export setMethod( - "exportToVcf", + "writeGwasVcf", signature("list"), - function(x, outputPath, sampleName = NULL, ...) { - exportToVcf( - .pubCombineList(x), - outputPath, + function(obj, filename, sampleName = NULL, ...) { + writeGwasVcf( + .pubCombineList(obj), + filename, sampleName = sampleName, ... ) } ) -#' @rdname exportToVcf +#' @rdname writeGwasVcf #' @export setMethod( - "exportToVcf", + "writeGwasVcf", signature("GwasSumStats"), - function(x, outputPath, sampleName = NULL, studyName = NULL) { + function(obj, filename, sampleName = NULL, studyName = NULL) { .vcfRequireVariantAnnotation() - studyName <- .vcfResolveStudy(x, studyName) - ss <- sumStats(x, studyName = studyName) + studyName <- .vcfResolveStudy(obj, studyName) + ss <- sumStats(obj, studyName = studyName) mc <- mcols(ss) .writeVcfImpl( chrom = as.character(seqnames(ss)), @@ -560,16 +570,17 @@ setMethod( geno = .vcfSumstatsGeno(mc, length(ss)), genoHeader = .vcfSumstatsGenoHeader(), sampleName = sampleName %||% studyName, - outputPath = outputPath + outputPath = filename, + build = .oneBuild(obj) ) } ) -# VariantAnnotation is a Suggests, and every VCF path needs it. +# VariantAnnotation writes the file; it is a Suggests, so the writer checks. # @noRd .vcfRequireVariantAnnotation <- function() { if (!requireNamespace("VariantAnnotation", quietly = TRUE)) { - abort("Package 'VariantAnnotation' is required for exportToVcf") + abort("Package 'VariantAnnotation' is required for writeGwasVcf().") } invisible(NULL) } @@ -581,14 +592,17 @@ setMethod( if (!is.null(studyName)) { return(studyName) } - if (nrow(x) != 1L) { + # Studies, not rows: one study is several rows once split by chromosome + # or LD block, and sumStats() stitches them back together. + studies <- unique(as.character(x$study)) + if (length(studies) != 1L) { msg <- glue( - "This GwasSumStats has {nrow(x)} studies. ", - "Pass `study = ` to select one." + "This GwasSumStats has {length(studies)} studies. ", + "Pass `studyName = ` to select one." ) abort(msg) } - as.character(x$study[[1L]]) + studies } # Per-sample geno matrices for the GWAS-VCF fields the mcols can fill. @@ -667,40 +681,41 @@ setMethod( ) } -#' @rdname exportToVcf +#' @rdname writeGwasVcf #' @export setMethod( - "exportToVcf", + "writeGwasVcf", signature("FineMappingResultBase"), function( - x, - outputPath, + obj, + filename, sampleName = NULL, studyName = NULL, context = NULL, trait = NULL, method = NULL, splitByContext = FALSE, - splitByTrait = FALSE + splitByTrait = FALSE, + splitByBlock = FALSE ) { .vcfRequireVariantAnnotation() + rows <- .pubMatchingRows(obj, studyName, context, trait, method) + .fitCoverageCheckedRows(obj[rows], "writeGwasVcf()") # Resolve what goes in each FILE. Without a split flag every matching - # fit is a SAMPLE of one file; with one, each fit gets its own file at - # a decorated path. + # fit is a SAMPLE of one file; with one, each context, trait or LD + # block gets its own file at a decorated path. groups <- .resolveFineMappingGroups( - x, - outputPath = outputPath, - studyName = studyName, - context = context, - trait = trait, - method = method, + obj, + outputPath = filename, + rows = rows, splitByContext = splitByContext, - splitByTrait = splitByTrait + splitByTrait = splitByTrait, + splitByBlock = splitByBlock ) invisible(map_chr( groups, .fmvWriteGroup, - x = x, + x = obj, sampleName = sampleName )) } @@ -709,66 +724,122 @@ setMethod( # Resolve what each OUTPUT FILE holds. Without a split flag every matching fit # becomes a SAMPLE of one multi-sample VCF -- which is GWAS-VCF's own shape, # where the samples are the studies -- so comparing two methods over a region -# means reading one file rather than two. `splitByContext` / `splitByTrait` -# still emit one single-sample file per fit, at a decorated path. +# means reading one file rather than two. A GWAS fit is every LD block of its +# (study, method), so its blocks share one sample. `splitByContext` / +# `splitByTrait` emit one file per context / trait and `splitByBlock` one per +# block, each at a decorated path; the fits that land on one path share it. # @noRd .resolveFineMappingGroups <- function( x, outputPath, - studyName, - context, - trait, - method, + rows, splitByContext, - splitByTrait + splitByTrait, + splitByBlock ) { - rows <- .pubMatchingRows(x, studyName, context, trait, method) if (length(rows) == 0L) { - abort("exportToVcf: no rows match the supplied selectors.") + abort("writeGwasVcf: no rows match the supplied selectors.") } - specs <- map(rows, .rowSpec, x = x) - if (!isTRUE(splitByContext) && !isTRUE(splitByTrait)) { + .fmvCheckSplitByBlock(x, splitByBlock) + specs <- map( + .fmvFitRows(x, rows), + .fitSpec, + x = x, + blockIds = .fmvBlockIds(x) + ) + if (isTRUE(splitByBlock)) { + specs <- list_flatten(map(specs, .fmvSpecPerBlock)) + } + if (!isTRUE(splitByContext) && !isTRUE(splitByTrait) && !splitByBlock) { return(list(list(path = outputPath, specs = specs))) } - map( + paths <- map_chr( specs, - .fmvSplitGroup, + .decorateOutputPath, outputPath = outputPath, splitByContext = splitByContext, - splitByTrait = splitByTrait + splitByTrait = splitByTrait, + splitByBlock = splitByBlock ) + unname(imap( + split(specs, factor(paths, levels = unique(paths))), + .fmvPathGroup + )) } # @noRd -.fmvSplitGroup <- function(spec, outputPath, splitByContext, splitByTrait) { - list( - path = .decorateOutputPath( - outputPath, - spec, - splitByContext, - splitByTrait - ), - specs = list(spec) +.fmvPathGroup <- function(specs, path) { + list(path = path, specs = unname(specs)) +} + +# Blocks are a GWAS notion: a QTL fit is one row, so there is nothing to split. +# @noRd +.fmvCheckSplitByBlock <- function(x, splitByBlock) { + assertFlag(splitByBlock) + if (!splitByBlock || methods::is(x, "GwasFineMappingResult")) { + return(invisible(NULL)) + } + abort(glue( + "writeGwasVcf: `splitByBlock` splits a GWAS fit into its LD blocks; a ", + "{class(x)[[1L]]} fit is one row. Use `splitByContext` / ", + "`splitByTrait` instead." + )) +} + +# The matching rows grouped into fits, in first-appearance order. A GWAS fit is +# every LD block of one (study, method); a QTL row is a fit of its own, its +# joint-membership columns being part of what identifies it. +# @noRd +.fmvFitRows <- function(x, rows) { + if (!methods::is(x, "GwasFineMappingResult")) { + return(as.list(rows)) + } + key <- str_c( + .fmrIdentityColumn(x, "study")[rows], + .fmrIdentityColumn(x, "method")[rows], + sep = "\r" + ) + unname(split(rows, factor(key, levels = unique(key)))) +} + +# One spec per block of a fit, each carrying the block it is for. +# @noRd +.fmvSpecPerBlock <- function(spec) { + map(unique(spec$blocks), .fmvBlockSpec, spec = spec) +} + +# @noRd +.fmvBlockSpec <- function(block, spec) { + on <- spec$blocks == block + list_assign( + spec, + rows = spec$rows[on], + blocks = spec$blocks[on], + block = block ) } -# Build a (study, context, trait, method) spec list for one row index. +# The LD block each row of a GWAS result covers: its `blockId`, which keys the +# block manifest, else its own range. # @noRd -.rowSpec <- function(r, x) { +.fmvBlockIds <- function(x) { + ids <- .fmrIdentityColumn(x, "blockId") + if_else(is.na(ids), .rtlRangeKeys(x), ids) +} + +# Build a (study, context, trait, method) spec for one fit: its rows -- one, +# or one per LD block of a GWAS fit -- their blocks, and the identity they +# share. +# @noRd +.fitSpec <- function(rows, x, blockIds) { + r <- rows[[1L]] list( - row = r, - study = as.character(x$study)[r], - context = if (is_in("context", .tupleColumnNames(x))) { - as.character(x$context)[r] - } else { - NA_character_ - }, - trait = if (is_in("trait", .tupleColumnNames(x))) { - as.character(x$trait)[r] - } else { - NA_character_ - }, - method = as.character(x$method)[r] + rows = rows, + blocks = blockIds[rows], + study = .fmrIdentityAt(x, "study", r), + context = .fmrIdentityAt(x, "context", r), + trait = .fmrIdentityAt(x, "trait", r), + method = .fmrIdentityAt(x, "method", r) ) } @@ -980,7 +1051,10 @@ setMethod( error = function(cnd) NULL ) marg <- try_fetch( - as_tibble(marginalEffects(entry)), + as_tibble(as.data.frame( + S4Vectors::mcols(marginalEffects(entry)), + optional = TRUE + )), error = function(cnd) NULL ) hasPost <- !is.null(post) && nrow(post) > 0L @@ -992,7 +1066,7 @@ setMethod( base <- marg m <- marg } else { - msg <- glue("exportToVcf: entry [{sn}] has no variants to write") + msg <- glue("writeGwasVcf: entry [{sn}] has no variants to write") abort(msg) } list(base = base, m = m, hasPost = hasPost) @@ -1032,7 +1106,9 @@ setMethod( # variant leaves its cells empty. # @noRd .fmvWriteGroup <- function(group, x, sampleName) { - rows <- map(group$specs, .fmvRowSpecs, x = x) + # Every row's window at once: a genome-wide study's blocks join one + # sample, and asking per block would rebuild them all for each. + rows <- map(group$specs, .fmvRowSpecs, x = x, rg = genomicRegion(x)) sn <- .vcfSampleNames(map_chr(rows, "sampleName"), sampleName) variants <- .fmvVariantUnion(rows) specs <- keep( @@ -1049,38 +1125,144 @@ setMethod( genoHeader = .vcfGenoHeader(specs), sampleName = sn, outputPath = group$path, - sampleMeta = .fmvSampleMeta(rows, sn) + sampleMeta = .fmvSampleMeta(rows, sn), + build = .oneBuild(x) ) group$path } # One fit's body, its FORMAT specs, and the variants they are aligned to. # @noRd -.fmvRowSpecs <- function(spec, x) { - entry <- fineMappingResult( - x, - spec$study, - spec$context, - spec$trait, - spec$method - ) +.fmvRowSpecs <- function(spec, x, rg = genomicRegion(x)) { sn <- .fmvSampleLabel(spec) - body <- .vcfResolveBody(entry, sn) - nSnps <- nrow(body$base) + blocks <- map2( + spec$rows, + spec$blocks, + .fmvBlockBody, + x = x, + sn = sn, + rg = rg + ) + base <- bind_rows(map(blocks, "base")) + nSnps <- nrow(base) list( sampleName = sn, spec = spec, - perFit = .pubPerFitFields(x, spec$row, susieFit(entry)), - base = body$base, + perFit = .fmvJoinPerFit(map(blocks, "perFit")), + base = base, nVariants = nSnps, - variantIds = as.character(.pubCol(body$base, "variant_id", nSnps)), + variantIds = as.character(.pubCol(base, "variant_id", nSnps)), formats = c( - .vcfCoreSpecs(body$base, body$m, nSnps), - if (body$hasPost) .vcfPosteriorSpecs(body$base, nSnps) else list() + .vcfCoreSpecs(base, .fmvJoinMarginals(blocks), nSnps), + if (any(map_lgl(blocks, "hasPost"))) { + .vcfPosteriorSpecs(base, nSnps) + } else { + list() + }, + .fmvBlockIdSpec(blocks) ) ) } +# One row's body and its per-fit header values. A GWAS fit fine-mapped block +# by block is several rows, and each contributes one of these to the sample. +# @noRd +.fmvBlockBody <- function(r, block, x, sn, rg) { + entry <- x[r] + list_assign( + .vcfResolveBody(entry, sn), + perFit = .pubPerFitFields( + x, + r, + .fmrPartsSusieFit(.fmrRowParts(x, r)), + rg + ), + block = block + ) +} + +# The marginals of every block, row-aligned with the stacked bases. A block +# with none still holds its rows, as NA; with none anywhere the table has no +# columns, which the marginal fields read as missing, as they read NULL. +# @noRd +.fmvJoinMarginals <- function(blocks) { + bind_rows(map2(map(blocks, "m"), blocks, .fmvMarginalsOrEmpty)) +} + +# @noRd +.fmvMarginalsOrEmpty <- function(m, block) { + m %||% tibble(.rows = nrow(block$base)) +} + +# The BID field: each variant's LD block, written only when a sample joins +# several, since credible-set indices are numbered within a block. +# @noRd +.fmvBlockIdSpec <- function(blocks) { + if (length(blocks) < 2L) { + return(list()) + } + list(.vcfSpec( + "BID", + list_c(map(blocks, .fmvBlockColumn)), + "String", + "LD block of the variant; credible sets are numbered within a block" + )) +} + +# @noRd +.fmvBlockColumn <- function(block) { + rep(block$block, nrow(block$base)) +} + +# The per-fit header fields that differ between the blocks of one fit, packed +# in block order with "|" when a sample joins several. +# @noRd +.FMV_BLOCK_FIELDS <- c( + "block_id", + "region_id", + "region_start", + "region_end", + "region_given", + "V", + "cs_index" +) + +# The header values of a fit spread over several LD blocks: the per-block +# fields packed, the rest -- which describe the fit -- taken once, after +# checking every block agrees on them. +# @noRd +.fmvJoinPerFit <- function(perFits) { + if (length(perFits) == 1L) { + return(perFits[[1L]]) + } + fields <- names(perFits[[1L]]) + set_names(map(fields, .fmvJoinField, perFits = perFits), fields) +} + +# @noRd +.fmvJoinField <- function(nm, perFits) { + vals <- map_chr(perFits, .fmvFieldText, nm = nm) + if (all(is.na(vals))) { + return(NA_character_) + } + if (is_in(nm, .FMV_BLOCK_FIELDS)) { + return(str_flatten(replace_na(vals, ""), "|")) + } + if (n_distinct(vals) > 1L) { + abort(glue( + "writeGwasVcf: the LD blocks of one fit disagree on `{nm}` ", + "({str_flatten(unique(vals), ', ')}), so they cannot be written ", + "as one sample. Pass `splitByBlock = TRUE`." + )) + } + perFits[[1L]][[nm]] +} + +# @noRd +.fmvFieldText <- function(perFit, nm) { + as.character(perFit[[nm]] %||% NA_character_) +} + # @noRd .fmvSampleLabel <- function(spec) { as.character(glue( @@ -1150,7 +1332,12 @@ setMethod( # sample is missing a variant. # @noRd .fmvFormatColumn <- function(r, nm, unionIds, type) { - fill <- if (identical(type, "Integer")) NA_integer_ else NA_real_ + fill <- switch( + type, + Integer = NA_integer_, + String = NA_character_, + NA_real_ + ) out <- rep(fill, length(unionIds)) f <- .fmvFindFormat(r, nm) if (is.null(f)) { @@ -1197,6 +1384,7 @@ setMethod( region_id = "RegionId", region_start = "RegionStart", region_end = "RegionEnd", + region_given = "RegionGiven", V = "V", cs_index = "CsIndex" ) @@ -1233,9 +1421,11 @@ setMethod( # @noRd .fmvSampleMetaRow <- function(r) { + # As text: a sample joining several LD blocks packs its per-block fields + # into one string, and one header holds both kinds of sample. bind_cols( tibble(total_variants = r$nVariants), - as_tibble(r$perFit) + as_tibble(map(r$perFit, as.character)) ) } @@ -1249,8 +1439,7 @@ setMethod( # colocPipeline's row filter reads them off the fit -- `sets$cs_index` or `V`. # Without them a round-tripped LBF matrix could be read but not filtered. # @noRd -.pubPerFitFields <- function(x, row, fit) { - rg <- genomicRegion(x) +.pubPerFitFields <- function(x, row, fit, rg = genomicRegion(x)) { inRange <- !is.null(row) && length(rg) >= row md <- mcols(x) list( @@ -1268,6 +1457,7 @@ setMethod( region_id = if (inRange) .pubRegionIds(rg)[[row]] else NA_character_, region_start = if (inRange) start(rg)[[row]] else NA_integer_, region_end = if (inRange) end(rg)[[row]] else NA_integer_, + region_given = .pubRowValue(md, "regionGiven", row), V = .pubPackOrNa(.fitField(fit, "V")), cs_index = .pubPackOrNa(.fitField(fit, "sets", "cs_index")) ) @@ -1293,14 +1483,14 @@ setMethod( # ---- VCF: TWAS weights ------------------------------------------------------ -#' @rdname exportToVcf +#' @rdname writeGwasVcf #' @export setMethod( - "exportToVcf", + "writeGwasVcf", signature("TwasWeights"), function( - x, - outputPath, + obj, + filename, sampleName = NULL, studyName = NULL, context = NULL, @@ -1308,29 +1498,29 @@ setMethod( method = NULL ) { .vcfRequireVariantAnnotation() - .pubRequireFullFit(x, .twbIncompleteRows(x), "exportToVcf") - rows <- .pubMatchingRows(x, studyName, context, trait, method) + .pubRequireFullFit(obj, .twbIncompleteRows(obj), "writeGwasVcf") + rows <- .pubMatchingRows(obj, studyName, context, trait, method) if (length(rows) == 0L) { - abort("exportToVcf: no rows match the supplied selectors.") + abort("writeGwasVcf: no rows match the supplied selectors.") } # The same rule the BED path applies, and for the same reason: a # fine-mapping method's "weights" are the posterior re-expressed, so # the fine-mapping result says strictly more. This path used to publish # them, which made the two formats disagree about what a weights file # contains. - rows <- intersect(rows, .twbExportableRows(x, "exportToVcf")) + rows <- intersect(rows, .twbExportableRows(obj, "writeGwasVcf")) if (length(rows) == 0L) { abort(str_c( - "exportToVcf: every selected row is fine-mapping-derived, so ", - "there is nothing to write as weights. Export the ", + "writeGwasVcf: every selected row is fine-mapping-derived, so ", + "there is nothing to write as weights. Write the ", "fine-mapping result." )) } .twvWriteSamples( - x, - .twvSampleSpecs(x, rows), + obj, + .twvSampleSpecs(obj, rows), sampleName, - outputPath + filename ) } ) @@ -1367,7 +1557,8 @@ setMethod( meta, colSums(!is.na(wgt)), x - ) + ), + build = .oneBuild(x) ) } @@ -1526,14 +1717,20 @@ setMethod( genoHeader, sampleName, outputPath, - sampleMeta = NULL + sampleMeta = NULL, + build = NA_character_ ) { - # Ensure chromosome names have the "chr" prefix. - if (!all(str_detect(chrom, "^chr"))) { - chrom <- str_c("chr", chrom) - } + # UCSC chromosome names (chr1, chrX, chrM), as the package's ranges use. + chrom <- withChrPrefix(chrom) gr <- .vcfBuildRanges(chrom, pos, ref, alt, snpIds) - hdr <- .vcfBuildHeader(sampleName, genoHeader, geno, sampleMeta) + hdr <- .vcfBuildHeader( + sampleName, + genoHeader, + geno, + sampleMeta, + build, + unique(chrom) + ) vcf <- .vcfBuildObject(gr, sampleName, hdr, geno, ref, alt) .vcfWriteByFormat(vcf, outputPath, chrom) invisible(outputPath) @@ -1552,12 +1749,31 @@ setMethod( ) } -# VCF header (VCFv4.2, the optional ##SAMPLE block, and the geno header subset -# to the fields actually present). +# VCF header (VCFv4.2, the genome build when the object names one, the +# optional ##SAMPLE block, and the geno header subset to the fields actually +# present). The build is written as ##reference and as the assembly of each +# ##contig, the two places a VCF reader looks for it. # @noRd -.vcfBuildHeader <- function(sampleName, genoHeader, geno, sampleMeta = NULL) { +.vcfBuildHeader <- function( + sampleName, + genoHeader, + geno, + sampleMeta = NULL, + build = NA_character_, + contigs = character(0) +) { + named <- !is.na(build) sections <- compact(list( fileformat = DataFrame(Value = "VCFv4.2", row.names = "fileformat"), + reference = if (named) { + DataFrame(Value = build, row.names = "reference") + }, + contig = if (named && length(contigs) > 0L) { + DataFrame( + assembly = rep(build, length(contigs)), + row.names = contigs + ) + }, SAMPLE = sampleMeta )) hdr <- VariantAnnotation::VCFHeader( @@ -1611,7 +1827,8 @@ setMethod( CharacterList(as.list(alt)) } -# Write the VCF in the format implied by the output extension. writeVcf appends +# Write the VCF in the format implied by the output extension. +# VariantAnnotation::writeVcf() appends # ".bgz" when index = TRUE, so paths are passed WITHOUT the .bgz/.gz suffix. # @noRd .vcfWriteByFormat <- function(vcf, outputPath, chrom) { @@ -1649,7 +1866,7 @@ setMethod( ), error = function(cnd) { msg <- glue( - "exportToVcf: BCF output needs a working ", + "writeGwasVcf: BCF output needs a working ", "Rsamtools::asBcf(), which the installed Rsamtools does not ", "provide. Write a bgzipped VCF instead by giving the output ", "path a .vcf.bgz extension." @@ -1659,7 +1876,8 @@ setMethod( ) } -# bgzip / gzip path: writeVcf always creates .bgz; rename to .gz on request. +# bgzip / gzip path: VariantAnnotation::writeVcf() always creates .bgz; +# renamed to .gz on request. # @noRd .vcfWriteBgz <- function(vcf, outputPath) { vcfStem <- str_remove(outputPath, "\\.(bgz|gz)$") @@ -1763,7 +1981,7 @@ setMethod( levels <- .pubCsLevels(view, coverage) if (length(levels) == 0L) { abort(str_c( - "exportToBed(schema = 'fsusie'): the result carries no ", + "writeBed(schema = 'fsusie'): the result carries no ", "credible-set column, so there are no rows to key on." )) } @@ -1896,18 +2114,21 @@ setMethod( if (nrow(fs) == 0L) { return(NULL) } - band <- as.data.frame(fsusieCredibleBand(fs)) + band <- as.data.frame( + S4Vectors::mcols(fsusieCredibleBand(fs)), + optional = TRUE + ) if (nrow(band) == 0L) { abort(str_c( - "exportToBed(schema = 'fsusie'): the functional fields ", + "writeBed(schema = 'fsusie'): the functional fields ", "are absent from every row. Refit with a retention level that ", "keeps the fSuSiE curves." )) } - csTbl <- as.data.frame(credibleSets(fs)) + csTbl <- as.data.frame(S4Vectors::mcols(credibleSets(fs)), optional = TRUE) primary <- .fmbPrimaryCsLevel(csTbl, coverage) csCols <- .pubCsColumns(csTbl, coverage) - marks <- as.data.frame(fsusieTraitEffects(fs)) + marks <- as.data.frame(.fsusieTraitEffectsTable(fs)) rowRegions <- genomicRegion(fs) rowRegionIds <- set_names( .pubRegionIds(rowRegions), @@ -2017,10 +2238,12 @@ setMethod( "joint_contexts", "joint_traits", # The window ANALYSED, without which a read-back result's genomicRegion() - # silently degrades to the span of the variants that survived QC. + # silently degrades to the span of the variants that survived QC, and, + # for a GWAS block, whether its range was given or is that span. "region_id", "region_start", - "region_end" + "region_end", + "region_given" ) # Always written, so the output is always a valid BED even when every optional @@ -2162,6 +2385,15 @@ setMethod( "p" ) +# The marginal estimates of `x`'s variants joined onto its posterior table. +# @noRd +.fmbMarginalsFor <- function(tl, x) { + .pubJoinMarginals( + tl, + as.data.frame(S4Vectors::mcols(marginalEffects(x)), optional = TRUE) + ) +} + # The topLoci BED table. # # `tl$beta`/`tl$se` are the POSTERIOR mean and sd -- topLoci() is the @@ -2178,7 +2410,7 @@ setMethod( if (nrow(tl) == 0L) { return(NULL) } - mm <- .pubJoinMarginals(tl, as.data.frame(marginalEffects(x))) + mm <- .fmbMarginalsFor(tl, x) win <- .fmbRowWindows(x, tl) pos <- .pubCol(tl, "pos") p <- suppressWarnings(as.numeric(.pubCol(mm, "p"))) @@ -2209,7 +2441,8 @@ setMethod( list( region_id = win$id, region_start = win$start, - region_end = win$end + region_end = win$end, + region_given = win$given ) ) out <- .pubFrame(cols, .pubSchema(csCols)) @@ -2330,14 +2563,18 @@ setMethod( # The analysis window of the collection row each long-view row came from, # matched on the row identity so a folded multi-row table keeps each row's own -# window rather than the first one's. +# window rather than the first one's. Both keys are built from the SAME +# columns -- those the view and the collection both carry -- since a GWAS view +# NA-fills a context and trait its collection does not have; and `blockId` is +# among them, as it is what tells the blocks of one GWAS fit apart. # @noRd .fmbRowWindows <- function(x, df) { rg <- genomicRegion(x) - idx <- match( - .pubIdentityKey(df, .PUB_ROW_COLS), - .pubCollectionKey(x, .PUB_ROW_COLS) + cols <- intersect( + intersect(c(.PUB_ROW_COLS, "blockId"), names(df)), + .tupleColumnNames(x) ) + idx <- match(.pubIdentityKey(df, cols), .pubCollectionKey(x, cols)) # 0-based half-open, like every other coordinate in a BED -- that is the # format's requirement, not a pecotmr choice. `region_id` stays the # canonical 1-based `chrom_start_end`, because it is an IDENTIFIER matched @@ -2345,19 +2582,30 @@ setMethod( list( id = .pubRegionIds(rg)[idx], start = start(rg)[idx] - 1L, - end = end(rg)[idx] + end = end(rg)[idx], + given = .pubRegionGiven(x)[idx] ) } +# Whether each row's block range was given, or NA where the collection does +# not record it (only a GWAS result does). +# @noRd +.pubRegionGiven <- function(x) { + if (!is_in("regionGiven", .tupleColumnNames(x))) { + return(rep(NA, nrow(x))) + } + as.logical(.tupleColumn(x, "regionGiven")) +} + # ---- BED: fine-mapping entry point ------------------------------------------ -#' @rdname exportToBed +#' @rdname writeBed #' @export setMethod( - "exportToBed", + "writeBed", signature("list"), - function(x, outputPath, ...) { - exportToBed(.pubCombineList(x), outputPath, ...) + function(obj, filename, ...) { + writeBed(.pubCombineList(obj), filename, ...) } ) @@ -2365,14 +2613,14 @@ setMethod( # window each row was ANALYSED over. A nominal TAD boundary is what a # publication table means by its region, not the narrower span of whichever # variants survived QC. -#' @rdname exportToBed +#' @rdname writeBed #' @export setMethod( - "exportToBed", + "writeBed", signature("FineMappingResultBase"), function( - x, - outputPath, + obj, + filename, schema = c("topLoci", "fsusie"), signalCutoff = 0.025, minPurity = NULL, @@ -2383,25 +2631,27 @@ setMethod( ) { schema <- arg_match(schema) levels <- arg_match(levels, multiple = TRUE) - assertString(outputPath) - .pubRequireFullFit(x, .fmbIncompleteRows(x), "exportToBed") + assertString(filename) + .pubRequireFullFit(obj, .fmbIncompleteRows(obj), "writeBed") if (identical(schema, "fsusie")) { return(.pubWriteTable( - .fmbFsusieTable(x, columns, levels, coverage), - outputPath, + .fmbFsusieTable(obj, columns, levels, coverage), + filename, naString = "NA", index = TRUE, emptySchema = .fmbFsusieColumns(levels), - extraColumns = extraColumns + extraColumns = extraColumns, + build = .oneBuild(obj) )) } .pubWriteTable( - .fmbTopLociTable(x, signalCutoff, minPurity, columns, coverage), - outputPath, + .fmbTopLociTable(obj, signalCutoff, minPurity, columns, coverage), + filename, naString = "NA", index = TRUE, keepColumns = .pubNamedColumns(columns), - extraColumns = extraColumns + extraColumns = extraColumns, + build = .oneBuild(obj) ) } ) @@ -2529,7 +2779,7 @@ setMethod( ) # @noRd -.twbExportableRows <- function(x, label = "exportToBed") { +.twbExportableRows <- function(x, label = "writeBed") { methods <- .pubTupleColumn("method", x) skip <- which(is_in(methods, .TWB_FINE_MAPPING_METHODS)) if (length(skip) > 0L) { @@ -2647,7 +2897,7 @@ setMethod( rows <- .twbExportableRows(x) if (length(rows) == 0L) { abort(str_c( - "exportToBed: every row is fine-mapping-derived, so there is ", + "writeBed: every row is fine-mapping-derived, so there is ", "nothing to write as weights. Export the fine-mapping result." )) } @@ -2677,27 +2927,28 @@ setMethod( # held-out FOLDS, nothing about them is per-variant, and a published file has # no data-secure way to express anything fold-level. They stay on the object, # where cvResult() returns them and the caller tabulates whatever they need. -#' @rdname exportToBed +#' @rdname writeBed #' @export setMethod( - "exportToBed", + "writeBed", signature("TwasWeights"), function( - x, - outputPath, + obj, + filename, coverage = NULL, columns = NULL, extraColumns = NULL ) { - assertString(outputPath) - .pubRequireFullFit(x, .twbIncompleteRows(x), "exportToBed") + assertString(filename) + .pubRequireFullFit(obj, .twbIncompleteRows(obj), "writeBed") .pubWriteTable( - .twbWeightsTable(x, columns, coverage), - outputPath, + .twbWeightsTable(obj, columns, coverage), + filename, naString = "NA", index = TRUE, keepColumns = .pubNamedColumns(columns), - extraColumns = extraColumns + extraColumns = extraColumns, + build = .oneBuild(obj) ) } ) diff --git a/R/sldscPostprocessingPipeline.R b/R/sldscPostprocessingPipeline.R index 0e277c5f..2d03dff8 100644 --- a/R/sldscPostprocessingPipeline.R +++ b/R/sldscPostprocessingPipeline.R @@ -176,8 +176,8 @@ sldscPostprocessingPipeline <- function( # first single run. # @noRd .sldscPivotRun <- function(sldscData, trait1) { - pivotRun <- sldscResults(sldscData, trait1, "joint") %||% - sldscResults(sldscData, trait1, "single", 1L) + pivotRun <- .sldscRun(sldscData, trait1, "joint") %||% + .sldscRun(sldscData, trait1, "single", 1L) pivotRun } @@ -242,7 +242,7 @@ sldscPostprocessingPipeline <- function( # Baseline categories = the first trait's joint categories minus the targets. # @noRd .sldscBaselineCategories <- function(sldscData, traitNames, targetCategories) { - jointPivot <- sldscResults(sldscData, traitNames[1], "joint") + jointPivot <- .sldscRun(sldscData, traitNames[1], "joint") baselineCategories <- if (!is.null(jointPivot)) { setdiff(jointPivot$categories, targetCategories) } else { @@ -319,7 +319,7 @@ sldscPostprocessingPipeline <- function( # list(singleDf, blocksSingle, singleH2gs). # @noRd .sldscTraitSingle <- function(trait, ctx) { - singleRuns <- sldscResults(ctx$sldscData, trait, "single") %||% list() + singleRuns <- .sldscRun(ctx$sldscData, trait, "single") %||% list() nRun <- min(length(ctx$targetCategories), length(singleRuns)) stds <- compact(map( seq_len(nRun), @@ -395,7 +395,7 @@ sldscPostprocessingPipeline <- function( jointH2g = NA_real_, nBlocks = NA_integer_ ) - if (is.null(sldscResults(ctx$sldscData, trait, "joint"))) { + if (is.null(.sldscRun(ctx$sldscData, trait, "joint"))) { return(empty) } std <- try_fetch( diff --git a/R/sldscWrapper.R b/R/sldscWrapper.R index 61a0f5a3..d9b12bd6 100644 --- a/R/sldscWrapper.R +++ b/R/sldscWrapper.R @@ -37,7 +37,7 @@ #' tidy list ready for downstream standardization. Hides the underlying file #' formats; downstream code consumes only modeling quantities. #' -#' @param prefix Character. Path prefix to the polyfun outputs for one +#' @param path Character. Path prefix to the polyfun outputs for one #' trait/run. The function appends `.results`, `.log`, and `.part_delete` to #' this prefix. Example: `"/path/to/cwd/CAD_META.filtered.sumstats.gz"`. #' @@ -55,8 +55,8 @@ #' @importFrom vroom vroom #' @importFrom readr read_lines #' @export -readSldscTrait <- function(prefix) { - files <- str_c(prefix, c(".results", ".log", ".part_delete")) +readSldscTrait <- function(path) { + files <- str_c(path, c(".results", ".log", ".part_delete")) assertFileExists(files, access = "r", .var.name = "readSldscTrait input") results <- vroom(files[1], show_col_types = FALSE) cats <- as.character(results$Category) @@ -133,7 +133,7 @@ readSldscTrait <- function(prefix) { #' (\code{\link{computeSldscAnnotSd}}, \code{\link{isBinarySldscAnnot}}) then #' runs on the loaded table, not on paths. #' -#' @param targetAnnoDir Character. Directory of `.annot.gz` files. +#' @param path Character. Directory of `.annot.gz` files. #' @param annotCols Character or integer vector, default NULL. Annotation #' columns to keep. NULL keeps all non-standard columns (auto-detected). #' @return A \code{data.frame}: \code{CHR}, \code{SNP}, and annotation columns. @@ -143,19 +143,19 @@ readSldscTrait <- function(prefix) { #' sldsc <- system.file("extdata", "sldsc", package = "pecotmr") #' readSldscAnnot(sldsc) #' @export -readSldscAnnot <- function(targetAnnoDir, annotCols = NULL) { +readSldscAnnot <- function(path, annotCols = NULL) { assertDirectoryExists( - targetAnnoDir, + path, access = "r", - .var.name = "targetAnnoDir" + .var.name = "path" ) annoFiles <- list.files( - targetAnnoDir, + path, pattern = "\\.annot\\.gz$", full.names = TRUE ) if (length(annoFiles) == 0L) { - msg <- glue("readSldscAnnot: no .annot.gz files in: {targetAnnoDir}") + msg <- glue("readSldscAnnot: no .annot.gz files in: {path}") abort(msg) } @@ -184,7 +184,7 @@ readSldscAnnot <- function(targetAnnoDir, annotCols = NULL) { #' \code{SNP}, \code{MAF}. Feeds the \code{frq} slot of #' \code{\link{SldscData}}. #' -#' @param frqfileDir Character. Directory of `.frq` files. +#' @param path Character. Directory of `.frq` files. #' @param plinkName Character. Filename prefix (files at #' `.frq`). Falls back to all `*.frq` in the directory when #' the prefix matches nothing. @@ -195,8 +195,8 @@ readSldscAnnot <- function(targetAnnoDir, annotCols = NULL) { #' sldsc <- system.file("extdata", "sldsc", package = "pecotmr") #' head(readSldscFrq(sldsc, plinkName = "reference.")) #' @export -readSldscFrq <- function(frqfileDir, plinkName = "ADSP_chr") { - assertDirectoryExists(frqfileDir, access = "r", .var.name = "frqfileDir") +readSldscFrq <- function(path, plinkName = "ADSP_chr") { + assertDirectoryExists(path, access = "r", .var.name = "path") pat <- str_c( "^", str_replace_all(plinkName, "([.])", "\\\\\\1"), @@ -204,14 +204,14 @@ readSldscFrq <- function(frqfileDir, plinkName = "ADSP_chr") { ) # The per-chromosome pattern first; a directory holding a single # unnumbered .frq falls back to the bare extension. - matched <- list.files(frqfileDir, pattern = pat, full.names = TRUE) + matched <- list.files(path, pattern = pat, full.names = TRUE) frqFiles <- if (length(matched) > 0L) { matched } else { - list.files(frqfileDir, pattern = "\\.frq$", full.names = TRUE) + list.files(path, pattern = "\\.frq$", full.names = TRUE) } if (length(frqFiles) == 0L) { - msg <- glue("readSldscFrq: no .frq files in: {frqfileDir}") + msg <- glue("readSldscFrq: no .frq files in: {path}") abort(msg) } @@ -267,8 +267,8 @@ readSldscFrq <- function(frqfileDir, plinkName = "ADSP_chr") { #' @export computeSldscAnnotSd <- function(sldscData, mafCutoff = 0.05, annotCols = NULL) { assertClass(sldscData, "SldscData") - annot <- annotData(sldscData) - frq <- frqData(sldscData) + annot <- .sdAnnot(sldscData) + frq <- .sdFrq(sldscData) if (mafCutoff > 0 && nrow(frq) == 0L) { msg <- glue( "computeSldscAnnotSd: mafCutoff = {mafCutoff} requires frq ", @@ -391,7 +391,7 @@ computeSldscAnnotSd <- function(sldscData, mafCutoff = 0.05, annotCols = NULL) { #' @export computeSldscMRef <- function(sldscData, mafCutoff = 0.05) { assertClass(sldscData, "SldscData") - frq <- frqData(sldscData) + frq <- .sdFrq(sldscData) if (nrow(frq) > 0L) { return(as.integer( if (mafCutoff > 0) { @@ -408,7 +408,7 @@ computeSldscMRef <- function(sldscData, mafCutoff = 0.05) { ) abort(msg) } - as.integer(nrow(annotData(sldscData))) + as.integer(nrow(.sdAnnot(sldscData))) } @@ -453,7 +453,7 @@ computeSldscMRef <- function(sldscData, mafCutoff = 0.05) { #' @export isBinarySldscAnnot <- function(sldscData, annotCols = NULL) { assertClass(sldscData, "SldscData") - annot <- annotData(sldscData) + annot <- .sdAnnot(sldscData) colsUse <- if (is.null(annotCols)) { annotCols(sldscData) } else if (is.numeric(annotCols)) { @@ -585,7 +585,7 @@ standardizeSldscTrait <- function( # Fetch the requested trait's single/joint run (error when absent). # @noRd .stdTraitRun <- function(sldscData, trait, mode, idx) { - traitData <- sldscResults(sldscData, trait, mode, idx) + traitData <- .sldscRun(sldscData, trait, mode, idx) if (is.null(traitData)) { idxNote <- if (!is.null(idx)) glue(" (idx={idx})") else "" msg <- glue( diff --git a/R/sumstatsQc.R b/R/sumstatsQc.R index 07292576..9798ae60 100644 --- a/R/sumstatsQc.R +++ b/R/sumstatsQc.R @@ -334,7 +334,7 @@ resolveLdInput <- function( #' @param dentistParam The DENTIST algorithm settings, built with #' \code{\link{DentistParam}}: \code{pValueThreshold}, \code{propSVD}, #' \code{gcControl}, \code{nIter}, \code{gPvalueThreshold}, -#' \code{duprThreshold}, \code{numThreads}, \code{correctChenEtAlBug} +#' \code{duprThreshold}, \code{BPPARAM}, \code{correctChenEtAlBug} #' and \code{seed}. This is the same record #' \code{\link{ldMismatchQc}} takes as #' \code{method = DentistParam(...)}, so a setting means the same thing @@ -529,7 +529,7 @@ dentist <- function( p$gcControl, as.integer(p$nIter), p$gPvalueThreshold, - as.integer(p$numThreads), + p$threads, p$correctChenEtAlBug, verboseIter, if (is.null(p$seed)) NULL else as.integer(p$seed) @@ -593,7 +593,10 @@ dentist <- function( #' @param nIter Number of iterations. Default is 10. #' @param gPvalueThreshold Grouping p-value threshold. Default is 0.05. #' @param duprThreshold Duplicate r-squared threshold. Default is 0.99. -#' @param numThreads Number of CPU cores. Default is 1. +#' @param BPPARAM A \code{BiocParallelParam} whose workers number the +#' threads DENTIST's OpenMP loops use when they run on this machine +#' (\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +#' thread. Default \code{SerialParam()}. #' @param correctChenEtAlBug Correct the original DENTIST operator! bug. Default #' is TRUE. #' @param ldMethod Character string specifying the LD computation method when @@ -626,11 +629,12 @@ dentistSingleWindow <- function( nIter = 10, gPvalueThreshold = 0.05, duprThreshold = 0.99, - numThreads = 1, + BPPARAM = SerialParam(), correctChenEtAlBug = TRUE, ldMethod = "sample", seed = NULL ) { + .assertBpparam(BPPARAM) ld <- .dentistLdInput(R, X, nSample, ldMethod) nSample <- ld$nSample .dentistValidateInput(zScore, ld) @@ -640,7 +644,7 @@ dentistSingleWindow <- function( gcControl = gcControl, nIter = nIter, gPvalueThreshold = gPvalueThreshold, - numThreads = numThreads, + threads = .bpLocalThreads(BPPARAM, "dentistSingleWindow"), correctChenEtAlBug = correctChenEtAlBug, seed = seed ) @@ -1487,7 +1491,12 @@ slalom <- function( #' @param df Data frame. Contains information about Credible Sets for a specific #' study and block. #' @param highCorrCols Character vector. Names of columns in df that represent -#' high correlations. +#' high correlations; a non-top CS whose value in any of them is 1 is +#' tagged. A CS's own column of \code{\link{extractCsInfo}}'s between-CS +#' correlations (\code{cs_corr_} for row \code{i}, its self-correlation) +#' is never read, so passing every \code{cs_corr_*} column tags a CS only by +#' its correlation with the other sets. Rows are taken in +#' \code{extractCsInfo()}'s order. #' #' @return A modified data frame with additional columns attached to the #' diagnostic table: @@ -1649,9 +1658,9 @@ autoDecision <- function(df, highCorrCols) { # reference this dominates: 43 observed multi-allelic positions produced 2969 # imputed variants in one block before this guard. # -# Keyed on canonical (chrom, pos) so a "chr1"/"1" difference does not read as -# two different sites. A position with no GWAS observation still imputes every -# panel form it has, multi-allelic included. +# Keyed on (chrom, pos), which raiss() spells in UCSC style on both tables. A +# position with no GWAS observation still imputes every panel form it has, +# multi-allelic included. # @noRd .raissObservedPosition <- function(refPanel, knownZ) { n <- nrow(refPanel) @@ -1664,10 +1673,10 @@ autoDecision <- function(df, highCorrCols) { ) } -# Canonical "chrom:pos" keys, so a "chr1"/"1" difference is one site. +# "chrom:pos" keys. # @noRd .raissPositionKey <- function(chrom, pos) { - str_c(canonChrom(as.character(chrom)), ":", as.character(pos)) + str_c(as.character(chrom), ":", as.character(pos)) } # Imputation targets: panel rows the sumstats do not carry, minus the rows no @@ -1988,29 +1997,56 @@ raissSingleMatrixFromX <- function( } # An LD reference brings its own variant table, which refPanel defaults to. -# Known and imputed rows are merged on chrom, and the table labels -# chromosomes canonically ("22"), so knownZscores has to as well; say so here -# rather than in a failed join. +# Known and imputed rows are merged on chrom, so known z-scores on none of the +# reference's chromosomes have nothing to impute from; say so here rather +# than in an empty join. # @noRd .raissRefPanelOf <- function(ref, knownZscores) { panel <- .refVariantsFromLdRef(ref) - sameLabels <- is.character(knownZscores$chrom) && - any(is_in(knownZscores$chrom, panel$chrom)) - if (!sameLabels) { + if (!any(is_in(knownZscores[["chrom"]], panel$chrom))) { abort(c( - str_c( - "`knownZscores$chrom` must use the LD reference's chromosome ", - "labels." - ), + "`knownZscores` shares no chromosome with the LD reference.", i = glue( - "They are canonical character labels, like ", - "'{panel$chrom[[1L]]}'." + "The reference covers ", + "{str_flatten(unique(panel$chrom), ', ')}." ) )) } panel } +# knownZscores as raiss() reads it: a table as given, or a summary-statistics +# entry -- the GRanges sumStats() returns -- as the table summaryStatsQc() +# builds from one. +# @noRd +.raissKnownTable <- function(knownZscores) { + if (!methods::is(knownZscores, "GRanges")) { + return(knownZscores) + } + need <- c("SNP", "A1", "A2", "Z") + absent <- setdiff(need, colnames(mcols(knownZscores))) + if (length(absent) > 0L) { + abort(c( + glue( + "`knownZscores` as a GRanges lacks column(s) ", + "{str_flatten(absent, ', ')}." + ), + i = "Pass a summary-statistics entry, as sumStats(x) returns it." + )) + } + .qcRaissKnownZ(.entryGrangesToDf(knownZscores)) +} + +# A table handed to raiss() with its `chrom` column in UCSC style, so its rows +# meet the reference's and each other's on equal labels. NULL stays NULL. +# @noRd +.raissUcscChrom <- function(df) { + if (is.null(df) || is.null(df[["chrom"]])) { + return(df) + } + `[[<-`(df, "chrom", value = withChrPrefix(df[["chrom"]])) +} + # The genotypes' LD factor for refPanel's variants (see .ldRefFactor()), the # way summaryStatsQc() hands it to the SVD route, re-signed into refPanel's # allele coding. @@ -2042,11 +2078,15 @@ raissSingleMatrixFromX <- function( #' #' @param refPanel A data frame containing 'chrom', 'pos', 'variant_id', 'A1', #' and 'A2'. Optional when the LD comes as an \code{LdMatrix} or a genotype -#' panel, whose own variants are used; \code{knownZscores} must then label -#' chromosomes canonically, as character (e.g. \code{"22"}). Required -#' with a plain \code{ldMatrix}, whose rows and columns follow it. +#' panel, whose own variants are used. Required with a plain +#' \code{ldMatrix}, whose rows and columns follow it. #' @param knownZscores A data frame containing 'chrom', 'pos', 'variant_id', -#' 'A1', 'A2', and 'z' values. +#' 'A1', 'A2', and 'z' values, or a summary-statistics \code{GRanges} -- +#' one entry as \code{\link{sumStats}} returns it, with its \code{SNP}, +#' \code{A1}, \code{A2} and \code{Z} columns. Here and in \code{refPanel} +#' a chromosome may be labelled in any style (\code{22}, \code{"22"}, +#' \code{"chr22"}); both are read in UCSC style (\code{"chr22"}), which +#' the result uses. #' @param ldMatrix A square LD matrix over \code{refPanel}'s variants, in its #' order, or an \code{LdMatrix} covering them. Provide either #' \code{ldMatrix} or \code{genotypes}, not both. @@ -2107,6 +2147,8 @@ raiss <- function( if (is.null(genotypes) && is.null(ldMatrix)) { abort("Provide either ldMatrix or genotypes.") } + knownZscores <- .raissUcscChrom(.raissKnownTable(knownZscores)) + refPanel <- .raissUcscChrom(refPanel) ref <- .raissReferenceOf(ldMatrix, genotypes) if (!is.null(ref)) { refPanel <- refPanel %||% .raissRefPanelOf(ref, knownZscores) @@ -2178,7 +2220,12 @@ setClass( #' this and \code{mafCutoff} applies. Default \code{0}. #' @param imissCutoff Missingness ceiling for a target. Default \code{1}. #' @param flank Base pairs by which to widen the analysis-region window on -#' each side, retaining LD context for edge variants. Default \code{0}. +#' each side, retaining LD context for edge variants. The window never +#' widens into another row of the same study on its chromosome -- the +#' neighbouring LD block of a block-split GWAS -- since that row imputes +#' its own variants, nor past a row's block range where that was given +#' (\code{regionGiven}, see \code{\linkS4class{GwasSumStats}}). Default +#' \code{0}. #' @return A \code{RaissParam} object, a \code{\link{MethodParam}}. #' @seealso \code{\link{summaryStatsQc}}, \code{\link{raiss}} #' @examples @@ -2244,10 +2291,17 @@ raissModel <- function( batch = TRUE, reportConditionNumber = FALSE ) { - sigTInv <- invertMatRecursive(sigT, lamb, rcond) - assertNumeric(zt) + # Checked before sigT is used: the inversion retries on any error, so a + # bad input would otherwise surface as base R's error from its third try. + # sigT is the known x known LD and sigIT the unknown x known LD, so both + # carry one column per known z-score. + assertNumeric(zt, min.len = 1L) assertNumeric(sigT) assertNumeric(sigIT) + k <- length(zt) + assertMatrix(sigT, nrows = k, ncols = k) + assertMatrix(sigIT, min.rows = 1L, ncols = k) + sigTInv <- invertMatRecursive(sigT, lamb, rcond) checks <- .raissInversionChecks( sigT, sigTInv, @@ -2605,7 +2659,7 @@ setClass( nIter = "numeric", gPvalueThreshold = "numeric", duprThreshold = "numeric", - numThreads = "numeric", + BPPARAM = "BiocParallelParam", correctChenEtAlBug = "logical", seed = "numeric_OR_NULL" ) @@ -2626,7 +2680,10 @@ setClass( #' @param nIter Number of DENTIST iterations. Default \code{10}. #' @param gPvalueThreshold Grouping p-value threshold. Default \code{0.05}. #' @param duprThreshold Duplicate r-squared threshold. Default \code{0.99}. -#' @param numThreads Number of CPU cores. Default \code{1}. +#' @param BPPARAM A \code{BiocParallelParam} whose workers number the +#' threads DENTIST's OpenMP loops use when they run on this machine +#' (\code{SerialParam}, \code{MulticoreParam}); any other backend gives one +#' thread. Default \code{SerialParam()}. #' @param correctChenEtAlBug Logical; apply the Chen et al. correction. #' Default \code{TRUE}. #' @param seed Integer or \code{NULL}. Random seed for the iteration. @@ -2641,7 +2698,7 @@ DentistParam <- function( nIter = 10, gPvalueThreshold = 0.05, duprThreshold = 0.99, - numThreads = 1, + BPPARAM = SerialParam(), correctChenEtAlBug = TRUE, seed = NULL ) { @@ -2653,7 +2710,7 @@ DentistParam <- function( nIter = nIter, gPvalueThreshold = gPvalueThreshold, duprThreshold = duprThreshold, - numThreads = numThreads, + BPPARAM = .assertBpparam(BPPARAM), correctChenEtAlBug = correctChenEtAlBug, seed = seed ) @@ -2811,10 +2868,7 @@ effectiveN <- function(nCase, nControl) { .entryGrangesToDf <- function(gr) { mc <- as.data.frame(S4Vectors::mcols(gr), stringsAsFactors = FALSE) out <- tibble( - chrom = str_remove( - as.character(GenomicRanges::seqnames(gr)), - regex("^chr", ignore_case = TRUE) - ), + chrom = as.character(GenomicRanges::seqnames(gr)), pos = GenomicRanges::start(gr) ) bind_cols(out, mc) @@ -3014,6 +3068,41 @@ effectiveN <- function(nCase, nControl) { mutate(df, z = .data$beta / .data$se) } +# One tuple of a GwasSumStats / QtlSumStats collection as the flat table +# .entryToSumstatDf() builds. `studyName` / `context` / `trait` select the +# tuple as sumStats() does; a GWAS takes `studyName` only. +# @noRd +.sumStatsDf <- function( + x, + studyName = NULL, + context = NULL, + trait = NULL, + require = character(0), + derive = c("none", "zFromBetaSe") +) { + .entryToSumstatDf( + sumStats(x, studyName = studyName, context = context, trait = trait), + require = require, + derive = derive, + label = .sumStatsDfLabel(x, studyName, context, trait) + ) +} + +# The tuple a .sumStatsDf() error names; "" marks a selector left to +# resolve on its own. +# @noRd +.sumStatsDfLabel <- function(x, studyName, context, trait) { + parts <- c( + studyName %||% "", + context %||% "", + trait %||% "" + ) + if (is(x, "GwasSumStats")) { + parts <- parts[[1L]] + } + glue("{class(x)[[1L]]}[{str_flatten(parts, '/')}]") +} + # Derive BETA and SE columns from signed Z when the entry has only Z. # Formula (Zhu et al. 2016 / RAISS): # se = 1 / sqrt(2 * maf * (1 - maf) * (N + z^2)) @@ -3157,42 +3246,17 @@ effectiveN <- function(nCase, nControl) { list(df = derived, audit = list(nDerived = sum(!is.na(se)))) } -# Drop variants whose (chrom, pos) overlaps any user-supplied skipRegion. -# skipRegion may be a character vector of "chr:start-end" strings or a GRanges. -# Parse one 'chr:start-end' skip-region string into a 1-row data.frame. -.parseSkipRegionEntry <- function(s) { - m <- str_match(s, "^([^:]+):([0-9]+)-([0-9]+)$")[1L, ] - if (is.na(m[[1L]])) { - msg <- glue("skipRegion entry must be 'chr:start-end'; got '{s}'") - abort(msg) - } - tibble( - chrom = str_remove(m[[2L]], regex("^chr", ignore_case = TRUE)), - start = as.integer(m[[3L]]), - end = as.integer(m[[4L]]) - ) -} - -# Normalise skipRegion (character vector or GRanges) to a chrom/start/end frame. +# Drop variants whose (chrom, pos) overlaps any user-supplied skipRegion, a +# GRanges -- as every window given in R is. +# Normalise skipRegion to a chrom/start/end frame. +# @noRd .parseSkipRegion <- function(skipRegion) { - if (is.character(skipRegion)) { - return(bind_rows(map(skipRegion, .parseSkipRegionEntry))) - } - if (methods::is(skipRegion, "GRanges")) { - return(tibble( - chrom = str_remove( - as.character(GenomicRanges::seqnames(skipRegion)), - regex("^chr", ignore_case = TRUE) - ), - start = GenomicRanges::start(skipRegion), - end = GenomicRanges::end(skipRegion) - )) - } - msg <- glue( - "skipRegion must be a character vector of 'chr:start-end' ", - "strings or a GRanges." + skipRegion <- .assertRegionGRanges(skipRegion, "`skipRegion`") + tibble( + chrom = as.character(GenomicRanges::seqnames(skipRegion)), + start = GenomicRanges::start(skipRegion), + end = GenomicRanges::end(skipRegion) ) - abort(msg) } # Rows falling inside skip region `i`. @@ -3206,10 +3270,7 @@ effectiveN <- function(nCase, nControl) { return(df) } parsed <- .parseSkipRegion(skipRegion) - dfChr <- str_remove( - as.character(df$chrom), - regex("^chr", ignore_case = TRUE) - ) + dfChr <- as.character(df$chrom) dropMask <- reduce( map( seq_len(nrow(parsed)), @@ -3398,9 +3459,10 @@ effectiveN <- function(nCase, nControl) { # Steps (in order; each contributes a count to audit): # - coerceNumeric: cast signed columns to numeric (catches stray "0.5" # strings). NA-introducing coercions are counted. -# - normalizeChr: strip "chr"/"ch" prefix, uppercase X/Y/MT, map -# 23->X, 24->Y, M->MT. Optional dropNonstandardChr removes rows -# whose CHR is outside 1..22, X, Y, MT after normalization. +# - normalizeChr: spell chromosomes in UCSC style (withChrPrefix(): +# 23->chrX, 24->chrY, M/MT->chrM). Optional dropNonstandardChr +# removes rows whose chromosome is outside chr1..chr22, chrX, chrY, +# chrM after normalization. # - dropMissData: drop rows with NA in any vital column (chrom, pos, # A1, A2, and at least one of Z / BETA). # - dropPOutOfRange: drop rows where P < 0 or P > 1 (corrupt p-values). @@ -3464,16 +3526,12 @@ effectiveN <- function(nCase, nControl) { if (!normalizeChr || !is_in("chrom", colnames(df))) { return(list(df = df, audit = list())) } - chr <- as.character(df$chrom) |> - str_remove(regex("^chr", ignore_case = TRUE)) |> - str_remove(regex("^ch", ignore_case = TRUE)) |> - str_to_upper() |> - canonChromLabel() + chr <- withChrPrefix(df$chrom) normalized <- mutate(df, chrom = chr) if (!dropNonstandardChr) { return(list(df = normalized, audit = list())) } - standardChrs <- c(as.character(seq_len(22)), "X", "Y", "MT") + standardChrs <- str_c("chr", c(as.character(seq_len(22)), "X", "Y", "M")) kept <- filter(normalized, is_in(chr, standardChrs)) list( df = kept, @@ -3632,7 +3690,7 @@ effectiveN <- function(nCase, nControl) { # filtered df, outlier count, and the full per-variant diagnostics table # (the data.frame returned by ldMismatchQc(), prepended with a # variant_id column for downstream joins). Callers record `diagnostics` -# in the entry's qcInfo audit so the per-variant detail is available +# in the entry's QC audit so the per-variant detail is available # for plotting / postprocessing instead of just the outlier count. # Panel LD for an entry's variants, via the shared LD-from-sketch helper (tuple # match with chr-prefix tolerance, strand-ambiguous variants kept), with the @@ -3938,12 +3996,13 @@ effectiveN <- function(nCase, nControl) { # Internal: per-entry pipeline. Returns the cleaned GRanges and an audit list. # --- .runEntrySummaryStatsQc: RAISS imputation step helpers ---------------- -# Panel/dosage window indices for the entry, scoped per chromosome. -.qcRaissWindowIdx <- function(df, ldReference, flank) { - # canonChrom on BOTH sides: the panel answers in its own seqnames - # convention, so the two are only comparable once canonicalized. +# Panel/dosage window indices for the entry, scoped per chromosome. `clamp` +# (see .ssqcRaissBounds) is the stretch of a chromosome the entry may impute +# into when other rows of its study share that chromosome; the flank stops at +# it. +.qcRaissWindowIdx <- function(df, ldReference, flank, clamp = NULL) { bounds <- tibble( - chrom = canonChrom(as.character(df$chrom)), + chrom = as.character(df$chrom), pos = as.integer(df$pos) ) |> group_by(.data$chrom) |> @@ -3951,7 +4010,8 @@ effectiveN <- function(nCase, nControl) { lo = min(.data$pos, na.rm = TRUE) - flank, hi = max(.data$pos, na.rm = TRUE) + flank, .groups = "drop" - ) + ) |> + .qcRaissClampBounds(clamp) # inner_join keeps only sketch SNPs whose chromosome appears in df (the # old is_in(skChrom, names(loByChr)) guard); filter keeps those inside the # [lo, hi] window. idx carries the original sketch row positions. @@ -3966,6 +4026,20 @@ effectiveN <- function(nCase, nControl) { pull("idx") } +# Narrow the flanked window to the entry's own stretch of the chromosome. +# @noRd +.qcRaissClampBounds <- function(bounds, clamp) { + if (is.null(clamp)) { + return(bounds) + } + on <- bounds$chrom == as.character(seqnames(clamp)) + mutate( + bounds, + lo = if_else(on, pmax(.data$lo, start(clamp)), .data$lo), + hi = if_else(on, pmin(.data$hi, end(clamp)), .data$hi) + ) +} + # Assemble refPanel, knownZ table, and scaled dosage for the window. # The sumstats side of the RAISS inputs: the required columns as a plain # frame, plus whichever of N / BETA / SE the caller carries, sorted by position @@ -4244,7 +4318,7 @@ effectiveN <- function(nCase, nControl) { .qcRaissImpute <- function(df, ldReference, opts, lbl) { imputeBefore <- nrow(df) flank <- as.integer(opts$raissParam$flank) - windowIdx <- .qcRaissWindowIdx(df, ldReference, flank) + windowIdx <- .qcRaissWindowIdx(df, ldReference, flank, opts$raissBounds) if (length(windowIdx) == 0L) { .qcEmit( lbl, @@ -5258,15 +5332,110 @@ effectiveN <- function(nCase, nControl) { # options; the per-entry fields are derived here rather than carried over from # the previous entry. # @noRd -.ssqcRunEntry <- function(i, sumstats, opts, refs, keys, isQtl) { +.ssqcRunEntry <- function(i, sumstats, opts, refs, keys, isQtl, bounds) { .runEntrySummaryStatsQc( gr = .collectionEntry(sumstats, i), ldReference = .ldRefForKey(keys[[i]], refs), - opts = .ssqcEntryOpts(opts, sumstats, i), + opts = list_assign( + .ssqcEntryOpts(opts, sumstats, i), + raissBounds = bounds[[i]] + ), entryLabel = .ssqcEntryLabel(sumstats, i, isQtl) ) } +# The stretch of its chromosome each row may impute into, or NULL for a row +# with no window of its own that shares its chromosome with no other row of +# its tuple. A study split into LD blocks is several rows on one chromosome, +# and RAISS widening one row's window by `flank` would impute its neighbours' +# variants -- a second, imputed copy of a variant the next row observes. So +# each row keeps to its own window: the `region` it was given, which bounds it +# whether or not its neighbours were loaded, else the midpoints between its +# span and its neighbours'. Without a flank a row's window is its own +# variants' span, which needs no bound. +# @noRd +.ssqcRaissBounds <- function(sumstats, opts) { + n <- nrow(sumstats) + if (!isTRUE(opts$impute) || as.integer(opts$raissParam$flank) <= 0L) { + return(vector("list", n)) + } + chrom <- map_chr(as.list(sumstats), .rtlElementSeqname) + map( + seq_len(n), + .ssqcRowBounds, + group = str_c(.ssqcTupleKey(sumstats), chrom, sep = "\r"), + spans = range(sumstats), + blocks = .ssqcGivenBlocks(sumstats) + ) +} + +# Each row's given window, or NULL where it has none: a computed window is +# only the span the midpoints are taken from. +# @noRd +.ssqcGivenBlocks <- function(sumstats) { + regions <- .rowRegions(sumstats) + map(seq_len(nrow(sumstats)), .ssqcGivenBlockAt, regions = regions) +} + +# @noRd +.ssqcGivenBlockAt <- function(i, regions) { + if (regions$regionGiven[[i]]) regions$region[i] else NULL +} + +# The rows of one tuple: a GWAS study, or a QTL (study, context, trait). +# @noRd +.ssqcTupleKey <- function(sumstats) { + cols <- intersect( + c("study", "context", "trait"), + .tupleColumnNames(sumstats) + ) + exec(str_c, !!!map(cols, .ssqcKeyPart, sumstats = sumstats), sep = "\r") +} + +# @noRd +.ssqcKeyPart <- function(col, sumstats) { + as.character(.tupleColumn(sumstats, col)) +} + +# @noRd +.ssqcRowBounds <- function(i, group, spans, blocks) { + if (!is.null(blocks[[i]])) { + return(blocks[[i]]) + } + if (is.na(group[[i]])) { + return(NULL) + } + sibs <- setdiff(which(group == group[[i]]), i) + if (length(sibs) == 0L) { + return(NULL) + } + .ssqcMidpointBounds(spans[[i]], unlist(spans[sibs], use.names = FALSE)) +} + +# Halfway to the nearest neighbour on each side; a neighbour overlapping the +# row leaves it only its own span. +# @noRd +.ssqcMidpointBounds <- function(own, sib) { + s <- start(own) + e <- end(own) + if (any(start(sib) <= e & end(sib) >= s)) { + return(own) + } + below <- end(sib)[end(sib) < s] + above <- start(sib)[start(sib) > e] + GenomicRanges::GRanges( + seqnames(own), + IRanges::IRanges( + if (length(below) == 0L) 1L else (max(below) + s) %/% 2L + 1L, + if (length(above) == 0L) { + .Machine$integer.max + } else { + (e + min(above)) %/% 2L + } + ) + ) +} + # Run the per-entry QC pipeline across all entries, each against its own # row's LD reference. .ssqcRunEntries <- function(sumstats, opts) { @@ -5288,7 +5457,8 @@ effectiveN <- function(nCase, nControl) { opts = opts, refs = pruned, keys = keys, - isQtl = isQtl + isQtl = isQtl, + bounds = .ssqcRaissBounds(sumstats, opts) ) list( newEntries = map(results, "gr"), @@ -5298,7 +5468,7 @@ effectiveN <- function(nCase, nControl) { ) } -# One screen metric's cutoff as qcInfo echoes it. The bundle leaves an unset +# One screen metric's cutoff as qcOptions echoes it. The bundle leaves an unset # metric absent; the echoed record has always spelled "off" as 0, and readers # like qcDiagnostics() index these four names, so the output shape is kept # even though the input is now one argument. @@ -5307,9 +5477,8 @@ effectiveN <- function(nCase, nControl) { signalScreenParam[[metric]] %||% 0 } -# Assemble the qcInfo record (echoed options + per-entry audits). -.ssqcBuildQcInfo <- function( - entryAudits, +# Assemble the qcOptions record: the options QC ran with, echoed. +.ssqcBuildQcOptions <- function( sumstatsFilterParam, panelFilterParam, signalScreenParam, @@ -5352,61 +5521,110 @@ effectiveN <- function(nCase, nControl) { smallPFloor = sumstatsCleaningParam$smallPFloor, dropZeroEffect = sumstatsCleaningParam$dropZeroEffect, dropNonpositiveSe = sumstatsCleaningParam$dropNonpositiveSe - ), - entryAudit = entryAudits + ) ) } # Rebuild the SumStats object with QC'd entries, trimmed sketches (one per -# row, as a list running parallel to `newEntries`), and qcInfo. -.ssqcRebuild <- function(sumstats, newEntries, newLdReference, qcInfo) { - cols <- .tupleColumnNames(sumstats) - nSample <- if (is_in("nSample", cols)) { - as.numeric(sumstats$nSample) - } else { - NULL - } - if (methods::is(sumstats, "GwasSumStats")) { - GwasSumStats( - studyName = as.character(sumstats$study), - entry = newEntries, - genome = unique(unname(GenomeInfoDb::genome(sumstats))), - ldReference = newLdReference, - varY = as.numeric(sumstats$varY), - nCase = if (is_in("nCase", cols)) { - as.numeric(sumstats$nCase) - } else { - NULL - }, - nControl = if (is_in("nControl", cols)) { - as.numeric(sumstats$nControl) - } else { - NULL - }, - nSample = nSample, - qcInfo = qcInfo, - # Carry the existing block keys through: the entries are already - # split, so without this the constructor re-derives them from - # seqname and every block on one chromosome collapses to one key. - blockId = if (is_in("blockId", cols)) { - as.character(sumstats$blockId) - } else { - NULL - } - ) +# row, as a list running parallel to `newEntries`), the qcOptions record and +# each row's audit (the qcAudit column). Every column the constructor does +# not rebuild itself is carried across as it was. So is each row's analysis +# window: QC changes the variants, not where the window is -- the one given, +# or the span the row was first built with -- and the span of what is left +# is range(x). +.ssqcRebuild <- function( + sumstats, + newEntries, + newLdReference, + qcOptions, + audits +) { + rebuilt <- if (methods::is(sumstats, "GwasSumStats")) { + .ssqcRebuildGwas(sumstats, newEntries, newLdReference, qcOptions) } else { - QtlSumStats( - studyName = as.character(sumstats$study), - context = as.character(sumstats$context), - trait = as.character(sumstats$trait), - entry = newEntries, - genome = unique(unname(GenomeInfoDb::genome(sumstats))), - ldReference = newLdReference, - varY = as.numeric(sumstats$varY), - nSample = nSample, - qcInfo = qcInfo - ) + .ssqcRebuildQtl(sumstats, newEntries, newLdReference, qcOptions) + } + audited <- `$<-`(rebuilt, "qcAudit", S4Vectors::SimpleList(audits)) + .withRegionColumns(audited, .rowRegions(sumstats)) +} + +# @noRd +.ssqcRebuildQtl <- function(sumstats, newEntries, newLdReference, qcOptions) { + QtlSumStats( + studyName = as.character(sumstats$study), + context = as.character(sumstats$context), + trait = as.character(sumstats$trait), + entry = newEntries, + genome = unique(unname(GenomeInfoDb::genome(sumstats))), + ldReference = newLdReference, + varY = as.numeric(sumstats$varY), + nSample = .ssqcNumericColumn(sumstats, "nSample"), + qcOptions = qcOptions, + traitPos = .ssqcColumnOrNull(sumstats, "traitPos"), + extraCols = .ssqcExtraCols(sumstats, .SSQC_QTL_COLUMNS) + ) +} + +# @noRd +.ssqcRebuildGwas <- function(sumstats, newEntries, newLdReference, qcOptions) { + GwasSumStats( + studyName = as.character(sumstats$study), + entry = newEntries, + genome = unique(unname(GenomeInfoDb::genome(sumstats))), + ldReference = newLdReference, + varY = as.numeric(sumstats$varY), + nCase = .ssqcNumericColumn(sumstats, "nCase"), + nControl = .ssqcNumericColumn(sumstats, "nControl"), + nSample = .ssqcNumericColumn(sumstats, "nSample"), + qcOptions = qcOptions, + # Carry the existing block keys through: the entries are already + # split, so without this the constructor re-derives them from + # seqname and every block on one chromosome collapses to one key. + blockId = .ssqcColumnOrNull(sumstats, "blockId"), + extraCols = .ssqcExtraCols(sumstats, .SSQC_GWAS_COLUMNS) + ) +} + +# The columns each constructor builds from its own arguments. Anything else a +# collection carries -- an `extraCols` column -- goes back in through +# `extraCols`. +# @noRd +.SSQC_SHARED_COLUMNS <- c( + "study", + "varY", + "nSample", + "ldReference", + "region", + "regionGiven", + "qcAudit" +) + +# @noRd +.SSQC_QTL_COLUMNS <- c(.SSQC_SHARED_COLUMNS, "context", "trait", "traitPos") + +# @noRd +.SSQC_GWAS_COLUMNS <- c(.SSQC_SHARED_COLUMNS, "nCase", "nControl", "blockId") + +# @noRd +.ssqcExtraCols <- function(sumstats, known) { + extra <- setdiff(.tupleColumnNames(sumstats), known) + set_names(map(extra, .tupleColumn, x = sumstats), extra) +} + +# @noRd +.ssqcColumnOrNull <- function(sumstats, nm) { + if (!is_in(nm, .tupleColumnNames(sumstats))) { + return(NULL) + } + .tupleColumn(sumstats, nm) +} + +# @noRd +.ssqcNumericColumn <- function(sumstats, nm) { + if (!is_in(nm, .tupleColumnNames(sumstats))) { + return(NULL) } + as.numeric(.tupleColumn(sumstats, nm)) } #' Run QC on a SumStats Collection @@ -5423,10 +5641,12 @@ effectiveN <- function(nCase, nControl) { #' and optional RAISS imputation. No Bioconductor genome / dbSNP packages #' required. #' -#' The returned collection has its \code{qcInfo} slot populated with a per-entry -#' audit record (variant counts, drop counts at each step, which filters fired, -#' etc.). Fine-mapping and TWAS-weights pipelines reject SumStats inputs where -#' \code{length(qcInfo(x)) == 0L}. +#' The returned collection records the options QC ran with in its +#' \code{qcOptions} slot, and what QC did to each row (variant counts, drop +#' counts at each step, which filters fired, etc.) in its \code{qcAudit} +#' column, read as a table with \code{\link{qcInfo}}. Fine-mapping and +#' TWAS-weights pipelines reject SumStats inputs where +#' \code{length(qcOptions(x)) == 0L}. #' #' Column-availability error contract: a non-zero \code{infoCutoff} requires #' every entry to carry an \code{INFO} column, and a non-zero \code{nCutoff} @@ -5440,8 +5660,8 @@ effectiveN <- function(nCase, nControl) { #' \code{\link{twasWeightsPipeline}} measure them on the RSS path, so one #' number means the same thing wherever it is set. MAC is converted to a MAF #' equivalent and the stricter of the two applies, matching -#' \code{\link{QtlDataset}}. Defaults (\code{0}, \code{0}, \code{1}) filter -#' nothing. +#' \code{\link{GenotypeFilterParam}}. Defaults (\code{0}, \code{0}, +#' \code{1}) filter nothing. #' #' The panel is filtered once, before any entry is harmonized, so a variant #' the panel cannot support is absent from the LD used by kriging, @@ -5478,8 +5698,7 @@ effectiveN <- function(nCase, nControl) { #' lives here rather than being split into two that could disagree. #' @param keepVariants Optional character vector of variant IDs (SNP column) to #' retain prior to harmonization. -#' @param skipRegion Optional character vector of \code{"chr:start-end"} -#' strings, or a \code{GRanges}, of regions to drop. +#' @param skipRegion Optional \code{GRanges} of regions to drop. #' @param signalScreenParam Whether to skip an entry before fitting it, #' built with #' \code{\link{SignalScreenParam}} --- the same bundle @@ -5509,8 +5728,9 @@ effectiveN <- function(nCase, nControl) { #' overridden and the override is logged. Inputs with no counts (quantitative #' traits) are unchanged. The escape hatch \code{effectiveN = FALSE} restores #' the raw \code{N} column (or, when there is no \code{N}, the raw total -#' \code{nCase + nControl}) with no override. \code{qcInfo$options$effectiveN} -#' records the setting and each entry's \code{nSource} is one of +#' \code{nCase + nControl}) with no override. +#' \code{qcOptions(x)$options$effectiveN} records the setting and each +#' row's \code{nSource} (a \code{\link{qcInfo}} column) is one of #' \code{"effective"}, \code{"column"}, \code{"total"}, or \code{NA}. #' @param impute Logical (length 1). Run RAISS imputation against the #' \code{ldReference}'s genotype panel as the last QC step, adding z-scores @@ -5522,7 +5742,10 @@ effectiveN <- function(nCase, nControl) { #' RAISS imputation scopes its reference panel to the analysis-region window #' (so a per-chromosome / genome-wide \code{ldReference} does not materialize #' its full dosage); \code{flank} widens that window by the given number of -#' base pairs on each side to retain LD context for edge variants. +#' base pairs on each side to retain LD context for edge variants, though +#' never into the stretch of another row of the same study, nor past a +#' block range that was given: a study split into LD blocks imputes each +#' block once, in its own row. #' #' \code{mafCutoff}, \code{macCutoff} and \code{imissCutoff} bound which #' panel variants RAISS will attempt to impute. Without them every rare @@ -5552,8 +5775,8 @@ effectiveN <- function(nCase, nControl) { #' \code{dropZeroEffect} and \code{dropNonpositiveSe}. Applied before any #' filter or screen. Distinct from \code{sumstatsFilterParam}, which applies #' quality thresholds to rows that are already well formed. -#' @return A new \code{QtlSumStats} / \code{GwasSumStats} with cleaned entries -#' and \code{qcInfo} populated. +#' @return A new \code{QtlSumStats} / \code{GwasSumStats} with cleaned entries, +#' \code{qcOptions} filled and each row's QC audit attached. #' @examples #' data(gwasSumStatsS4Example) #' summaryStatsQc(gwasSumStatsS4Example) @@ -5633,8 +5856,7 @@ summaryStatsQc <- function( # The QC record and the rebuilt object around the filtered entries. # @noRd .ssqcAssemble <- function(sumstats, res, opts, signalScreenParam) { - qcInfo <- .ssqcBuildQcInfo( - res$entryAudits, + qcOptions <- .ssqcBuildQcOptions( sumstatsFilterParam = opts$sumstatsFilterParam, panelFilterParam = opts$panelFilterParam, signalScreenParam = signalScreenParam, @@ -5654,7 +5876,7 @@ summaryStatsQc <- function( keys = res$keys ) perRow <- map(res$keys, .ldRefForKey, refs = trimmed) - .ssqcRebuild(sumstats, res$newEntries, perRow, qcInfo) + .ssqcRebuild(sumstats, res$newEntries, perRow, qcOptions, res$entryAudits) } # One LD reference cut to exactly the variants of the rows keyed to it. @@ -5761,12 +5983,15 @@ summaryStatsQc <- function( if (df$p_value[i] > 1e-4) { return(TRUE) } - if (length(highCorrCols) == 0) { + # A CS's own column -- cs_corr_ in extractCsInfo()'s layout -- holds its + # self-correlation of 1, which says nothing about the other sets. + otherCols <- setdiff(highCorrCols, str_c("cs_corr_", i)) + if (length(otherCols) == 0) { return(FALSE) } rowVals <- df |> filter(row_number() == i) |> - select(all_of(highCorrCols)) + select(all_of(otherCols)) any(rowVals == 1) } @@ -5788,10 +6013,10 @@ summaryStatsQc <- function( is.na(df[[col]]) } -# One GRanges entry's canonical chromosome vector. +# One GRanges entry's chromosome vector. # @noRd .entryChrom <- function(gr) { - canonChrom(as.character(GenomicRanges::seqnames(gr))) + as.character(GenomicRanges::seqnames(gr)) } # One GRanges entry's integer start positions. diff --git a/R/tupleSelectors.R b/R/tupleSelectors.R index 5ec79bd1..6b370a4c 100644 --- a/R/tupleSelectors.R +++ b/R/tupleSelectors.R @@ -83,10 +83,11 @@ glue("{side} ({str_flatten(shown, ', ')})") } -# One collection ELEMENT, whichever shape `x` has. On a RangedTupleList the -# elements are the container itself; the DFrame-backed collections still keep -# them in an `entry` column. Both shapes coexist until every collection has -# migrated, so polymorphic call sites go through here. +# One row's payload, whichever collection `x` is -- what its constructor +# takes as `entry`: for TWAS weights and fine-mapping results, the row parts +# rebuilt from its element and the collection's mcols, where the fits sit; +# for the summary-statistics collections, the element itself. A caller +# taking either weight source reads its rows through here. # @noRd .collectionEntry <- function(x, i) { if (methods::is(x, "TwasWeights")) { @@ -98,11 +99,11 @@ x[[i]] } -# ALL elements as a plain list, whichever shape `x` has. +# Every row's payload (.collectionEntry()) as a plain list. # @noRd .collectionEntries <- function(x) { - # TwasWeights entries are derived views, so they have to be rebuilt one by - # one rather than read off as elements (which are bare GRanges). + # Weight and fine-mapping rows are rebuilt one by one: their elements + # alone are bare GRanges, without the fits. if ( methods::is(x, "TwasWeights") || methods::is(x, "FineMappingResultBase") @@ -150,7 +151,7 @@ return(1L) } msg <- glue( - "{cls} has {nrow(x)} entries. Pass `study`, `context`, ", + "{cls} has {nrow(x)} entries. Pass `studyName`, `context`, ", "`trait`, and `method` to select one." ) abort(msg) @@ -185,50 +186,102 @@ } # Internal: resolve a (study, method, blockId) tuple to a single row -# index of a GwasFineMappingResult collection. `region` may be NULL when -# the (study, method) pair maps to a single row; otherwise it disambiguates -# among per-block rows of a genome-wide collection. +# index of a GwasFineMappingResult collection. `blockId` may be NULL when the +# (study, method) pair maps to a single row; otherwise it names one of a +# genome-wide collection's per-block rows. +# @noRd #' @importFrom checkmate assertVector -.tupleSelectRowGwasFmr <- function(x, studyName, method, region = NULL) { +.tupleSelectRowGwasFmr <- function( + x, + studyName = NULL, + method = NULL, + blockId = NULL +) { if (nrow(x) == 0L) { abort("GwasFineMappingResult has no rows.") } - anyUnset <- missing(studyName) || - is.null(studyName) || - missing(method) || - is.null(method) - if (anyUnset) { + if (is.null(studyName) || is.null(method)) { if (nrow(x) == 1L) { return(1L) } msg <- glue( - "GwasFineMappingResult has {nrow(x)} entries. Pass `study` ", + "GwasFineMappingResult has {nrow(x)} entries. Pass `studyName` ", "and `method` to select one." ) abort(msg) } assertVector(studyName, len = 1L) assertVector(method, len = 1L) - assertVector(region, len = 1L, null.ok = TRUE) - .tupleMatchGwas(x, studyName, method, region) + assertVector(blockId, len = 1L, null.ok = TRUE) + .tupleMatchGwas(x, studyName, method, blockId) +} + +# Internal: every row of one (study, method) fit of a GwasFineMappingResult +# -- one per LD block -- or the block `blockId` names. `study` and `method` +# may be left NULL only while they still match a single (study, method) +# pair; a selection spanning several fits is refused rather than returned as +# if it were one. +# @noRd +.tupleSelectRowsGwasFmr <- function(x, studyName, method, blockId = NULL) { + if (nrow(x) == 0L) { + abort("GwasFineMappingResult has no rows.") + } + assertString(studyName, null.ok = TRUE) + assertString(method, null.ok = TRUE) + assertString(blockId, null.ok = TRUE) + idx <- .matchTupleRows( + x, + compact(list(study = studyName, method = method, blockId = blockId)) + ) + if (length(idx) == 0L) { + abort(glue( + "No entry for ", + "({.tupleGwasSelectionLabel(studyName, method, blockId)})." + )) + } + fits <- unique(str_c( + .fmrIdentityColumn(x, "study")[idx], + .fmrIdentityColumn(x, "method")[idx], + sep = "/" + )) + if (length(fits) > 1L) { + abort(glue( + "GwasFineMappingResult holds {length(fits)} (study, method) fits ", + "matching the selection ({str_flatten(fits, ', ')}); pass ", + "`studyName` and `method` to select one." + )) + } + idx +} + +# The selectors as they appear in a no-match message; an unset study or +# method matched anything. +# @noRd +.tupleGwasSelectionLabel <- function(studyName, method, blockId) { + parts <- c( + study = studyName %||% "", + method = method %||% "", + blockId = blockId + ) + str_flatten(str_c(names(parts), "='", parts, "'"), ", ") } # Resolve a (study, method[, blockId]) tuple to a single row index. # @noRd -.tupleMatchGwas <- function(x, studyName, method, region) { +.tupleMatchGwas <- function(x, studyName, method, blockId) { keys <- c( list(study = studyName, method = method), - compact(list(blockId = region)) + compact(list(blockId = blockId)) ) idx <- .matchTupleRows(x, keys) if (length(idx) == 0L) { - regionPart <- if (is.null(region)) { + blockPart <- if (is.null(blockId)) { "" } else { - glue(", region='{region}'") + glue(", blockId='{blockId}'") } msg <- glue( - "No entry for (study='{studyName}', method='{method}'{regionPart})." + "No entry for (study='{studyName}', method='{method}'{blockPart})." ) abort(msg) } @@ -238,17 +291,17 @@ idx[[1L]] } -# Multiple (study, method) rows matched: report the disambiguating regions. +# Multiple (study, method) rows matched: report the blocks to choose from. # @noRd .tupleGwasAmbiguous <- function(x, studyName, method, idx) { - regions <- str_flatten( + blocks <- str_flatten( shQuote(as.character(x$blockId[idx])), ", " ) msg <- glue( "GwasFineMappingResult has {length(idx)} rows matching ", - "(study='{studyName}', method='{method}'); pass `region` to ", - "disambiguate (available: {regions})." + "(study='{studyName}', method='{method}'); pass `blockId` to ", + "disambiguate (available: {blocks})." ) abort(msg) } @@ -257,23 +310,23 @@ # given selectors. NULL selectors, and selectors naming a column the # collection lacks, are ignored -- QTL rows carry study/context/trait/method, # GWAS rows carry study/method/blockId -- so the same call works on either. -# `region` matches the `blockId` column. Returns all rows when nothing -# constrains. Unlike the single-row selectors above this never errors on -# ambiguity; it is the aggregate counterpart used by topLoci(). +# Returns all rows when nothing constrains. Unlike the single-row selectors +# above this never errors on ambiguity; it is the aggregate counterpart used +# by topLoci(). .fmrRowsMatching <- function( x, studyName = NULL, context = NULL, trait = NULL, method = NULL, - region = NULL + blockId = NULL ) { supplied <- compact(list( study = studyName, context = context, trait = trait, method = method, - blockId = region + blockId = blockId )) keys <- supplied[is_in(names(supplied), .tupleColumnNames(x))] if (length(keys) == 0L) { @@ -332,23 +385,29 @@ # it on demand, and that is what callers wanting current content should use. # # Spec 4.4 removed a stored column on the grounds that it "would quietly go -# stale" under subsetRegion(). That argument holds for a SPAN, which is +# stale" under subsetting. That argument holds for a SPAN, which is # current state and must track subsetting; it does not hold for a WINDOW, # which is provenance -- subsetting a fit's variants does not retroactively # change which interval was analysed. # # Falls back to the derived span for collections built before the column # existed (older saved objects, hand-built collections), so the accessor never -# returns nothing where it used to return a range. +# returns nothing where it used to return a range. So does a row a combine +# padded with a placeholder (.naLikeColumn()), having no window of its own. # @noRd .getRegionColumn <- function(x) { if (nrow(x) == 0L) { return(GenomicRanges::GRanges()) } - if (is_in("region", .tupleColumnNames(x))) { - return(.tupleColumn(x, "region")) + if (!is_in("region", .tupleColumnNames(x))) { + return(unlist(range(x), use.names = FALSE)) + } + stored <- .tupleColumn(x, "region") + padded <- width(stored) == 0L + if (!any(padded)) { + return(stored) } - unlist(range(x), use.names = FALSE) + .pickRegions(!padded, stored, .rowSpanRanges(x)) } # Internal: append the optional `blockId` provenance column (no-op when NULL). @@ -363,7 +422,7 @@ } if (length(blockId) != n) { msg <- glue( - "`blockId` must have the same length as `study` ", + "`blockId` must have the same length as `studyName` ", "(got {length(blockId)} vs {n})." ) abort(msg) @@ -371,19 +430,15 @@ c(cols, list(blockId = as.character(blockId))) } -# Internal: normalize a caller-supplied window into the single GRanges the -# `region` column stores, or NULL when there is none. Accepts whatever the -# pipeline's `region` argument accepts (a "chr:start-end" string or a -# GRanges); a multi-range window (jointRegions) is recorded as its overall -# span, which is the interval the fit covered. +# Internal: normalize a caller-supplied window -- a GRanges, as the +# pipeline's `region` is -- into the single range the `region` column +# stores, or NULL when there is none. A multi-range window (jointRegions) is +# recorded as its overall span, which is the interval the fit covered. .asAnalysisWindow <- function(region) { if (is.null(region) || length(region) == 0L) { return(NULL) } - gr <- try_fetch(.asGRegion(region), error = function(cnd) NULL) - if (is.null(gr) || length(gr) == 0L) { - return(NULL) - } + gr <- .assertRegionGRanges(region) if (length(gr) == 1L) gr else range(gr)[1L] } @@ -450,7 +505,7 @@ if (length(region) != n) { abort("`region` must have the same length as `study`.") } - c(cols, list(region = region)) + c(cols, list(region = .ucscRanges(region))) } # Internal: validate the optional `region` GRanges column (one range per row), @@ -471,6 +526,382 @@ character(0) } +# Internal: `n` placeholder ranges, zero-width on "chrUn", for the rows of a +# range column that have no range of their own: an empty element, or the rows +# of a combined part that lacked the column. No real range is zero-width, so +# that is what marks one. +# @noRd +.placeholderRanges <- function(n) { + GenomicRanges::GRanges( + rep("chrUn", n), + IRanges::IRanges(start = rep(1L, n), width = rep(0L, n)) + ) +} + +# Internal: each element's span as one bare range (no seqinfo, strand or +# metadata), or a placeholder for an empty element. An element sits on one +# seqname, so strand aside its span is one range. +# @noRd +.rowSpanRanges <- function(x) { + spans <- range(x, ignore.strand = TRUE) + has <- lengths(spans) > 0L + flat <- unlist(spans, use.names = FALSE) + n <- length(spans) + GenomicRanges::GRanges( + replace(rep("chrUn", n), has, as.character(seqnames(flat))), + IRanges::IRanges( + start = replace(rep(1L, n), has, start(flat)), + end = replace(rep(0L, n), has, end(flat)) + ) + ) +} + +# Internal: per row, the range of `a` where `use` is TRUE, else that of `b`, +# as bare ranges. `a` and `b` have one range per row. +# @noRd +.pickRegions <- function(use, a, b) { + GenomicRanges::GRanges( + if_else(use, as.character(seqnames(a)), as.character(seqnames(b))), + IRanges::IRanges( + start = if_else(use, start(a), start(b)), + end = if_else(use, end(a), end(b)) + ) + ) +} + +# Internal: a window argument -- a `region`, or h2's `ldBlocks` -- as the +# GRanges of the windows it names. Given in an R call, a window is a GRanges, +# 1-based like everything in Bioconductor; a table or a "chr:start-end" +# string is refused rather than read, so no window is misread by one base. A +# file follows its own standard: the path of a BED file is read as BED (see +# .readBedWindows()). +# @noRd +.asRegionRanges <- function(x, what = "`region`") { + if (methods::is(x, "GRanges")) { + return(.ucscRanges(x)) + } + if (!is.character(x) || length(x) != 1L) { + abort(c( + glue( + "{what} must be a GRanges or the path of a BED file ", + "(got {class(x)[[1L]]})." + ), + i = .regionArgHint() + )) + } + if (!file.exists(x)) { + abort(c( + glue("{what}: no file exists at '{x}'."), + i = .regionArgHint() + )) + } + .ucscRanges(.readBedWindows(x, what)) +} + +# Internal: a window argument that takes no file -- a pipeline's `region`, +# or a QtlDataset's -- which must be a GRanges. It comes back in UCSC style, +# so everything it is compared with inside is compared exactly. +# @noRd +.assertRegionGRanges <- function(x, what = "`region`") { + if (!methods::is(x, "GRanges")) { + abort(c( + glue("{what} must be a GRanges (got {class(x)[[1L]]})."), + i = .regionArgHint() + )) + } + .ucscRanges(x) +} + +# Internal: how to give a window in an R call, for the errors refusing a +# window argument of the wrong kind. +# @noRd +.regionArgHint <- function() { + str_c( + "A window given in R is a GRanges, which is 1-based: for example ", + "GenomicRanges::GRanges('chr22:1-100')." + ) +} + +# Internal: the variants of `g` inside the one window `win`. A variant sits at +# its start. +# @noRd +.withinWindow <- function(g, win) { + same <- as.character(seqnames(g)) == as.character(seqnames(win))[[1L]] + g[same & start(g) >= start(win)[[1L]] & start(g) <= end(win)[[1L]]] +} + +# Internal: `gr` as bare ranges, its seqnames and intervals alone. +# @noRd +.bareRanges <- function(gr) { + GenomicRanges::GRanges( + as.character(seqnames(gr)), + IRanges::IRanges(start = start(gr), end = end(gr)) + ) +} + +# Internal: the `region` and `regionGiven` columns of a GWAS collection. A row +# whose block range was given keeps it, and every other row takes the span +# of its own variants. `given` holds one range per row and `has` says which +# of them were given. +# @noRd +.regionColumns <- function(given, has, spans) { + list(region = .pickRegions(has, given, spans), regionGiven = has) +} + +# Internal: refuse a window a fine-mapping result was given that leaves out +# its own row's variants. The check on QTL variants (.checkGwasBlockReach()) +# takes a given window as the block's true boundary, so one that does not hold +# its own variants would send it after a block that is not missing. A variant +# sits at its start, so an indel's width cannot carry it past a window end. +# `pieces` holds each row's variants, and `has` says which rows were given +# `given`. +# @noRd +.refuseUncontainedRegions <- function(given, has, pieces, caller) { + check <- has & lengths(pieces) > 0L + if (!any(check)) { + return(invisible(NULL)) + } + starts <- start(pieces[check]) + chrom <- .rtlElementSeqnames(pieces[check]) + lo <- min(starts) + hi <- max(starts) + inside <- as.character(seqnames(given[check])) == chrom & + start(given[check]) <= lo & + hi <= end(given[check]) + if (all(inside)) { + return(invisible(NULL)) + } + out <- !inside + rows <- glue( + "row {which(check)[out]}: range {as.character(given[check][out])}, ", + "variants at {chrom[out]}:{lo[out]}-{hi[out]}" + ) + abort(c( + glue( + "{caller}: each row's `region` must contain the row's variants, ", + "since it is the window the row was fit over." + ), + set_names(utils::head(rows, 5L), rep("*", min(5L, length(rows)))) + )) +} + +# Internal: each row's analysis window and whether the user gave it, from the +# `region` / `regionGiven` columns of a summary-statistic collection or a +# fine-mapping result. A collection saved before the columns existed has no +# stored window, and neither has a row a combine padded; such a row falls back +# to its span and counts as computed. +# @noRd +.rowRegions <- function(x) { + spans <- .rowSpanRanges(x) + cols <- .tupleColumnNames(x) + if (!is_in("region", cols)) { + return(list(region = spans, regionGiven = rep(FALSE, length(spans)))) + } + stored <- .tupleColumn(x, "region") + has <- width(stored) > 0L + given <- if (is_in("regionGiven", cols)) { + as.logical(.tupleColumn(x, "regionGiven")) + } else { + rep(FALSE, length(spans)) + } + list( + region = .pickRegions(has, stored, spans), + regionGiven = has & !is.na(given) & given + ) +} + +# Internal: row `i`'s analysis window alone (see .rowRegions()), read off its +# own column entry rather than every row's, for per-row lookups. NULL for an +# empty row with no window stored. +# @noRd +.rowRegionAt <- function(x, i) { + if (is_in("region", .tupleColumnNames(x))) { + stored <- .tupleColumn(x, "region")[i] + if (width(stored) > 0L) { + return(.bareRanges(stored)) + } + } + g <- x[[i]] + if (length(g) == 0L) { + return(NULL) + } + .bareRanges(range(g, ignore.strand = TRUE)[1L]) +} + +# Internal: set a GWAS collection's `region` / `regionGiven` columns, for the +# rebuilds that know them better than the constructor can: a QC pass, a union +# of blocks, a fine-mapping run, a file read back. +# @noRd +.withRegionColumns <- function(x, cols) { + md <- mcols(x, use.names = FALSE) + md$region <- cols$region + md$regionGiven <- as.logical(cols$regionGiven) + S4Vectors::`mcols<-`(x, value = md) +} + +# ---- QTL variants past the GWAS blocks -------------------------------------- +# A QTL region is scored against every block of a GWAS study it overlaps, +# merged into one. Its variants outside all of the study's loaded blocks are +# left out of that merge, which is a sign a block it reaches was not loaded. +# Past a block range the caller gave, they do lie in a block that was not +# loaded, so that is an error. Past a range computed from the GWAS variants +# they may only be variants the GWAS lacks, at a chromosome end or untyped, +# so that is a warning, and only for more than one variant in a row. + +# Internal: check `units` -- a named list of variant positions (GRanges), one +# per region the caller scores against `gws`, named as a message should call +# it -- against the block ranges of each GWAS fit in `gws`. Each variant past +# a fit's blocks counts against its nearest block, on the side it falls. +# `caller` and `what` (the units, as a plural noun) word the messages. +# @noRd +.checkGwasBlockReach <- function(units, gws, caller, what) { + if (length(units) == 0L || nrow(gws) == 0L) { + return(invisible(NULL)) + } + blocks <- .gwasBlockTable(gws) + issues <- list_rbind(imap(units, .unitBlockReach, blocks = blocks)) + .reportBlockReach(issues, caller, what) +} + +# Internal: the block ranges of `gws`, one per row with a range, each with +# the GWAS fit it belongs to (its study, and method for a fine-mapping +# result) and a label naming the block. +# @noRd +.gwasBlockTable <- function(gws) { + regions <- .rowRegions(gws) + keep <- width(regions$region) > 0L + region <- regions$region[keep] + chrom <- as.character(seqnames(region)) + ids <- as.character(.tupleColumn(gws, "blockId"))[keep] + key <- str_c(chrom, start(region), end(region), sep = "_") + span <- str_c(chrom, ":", start(region), "-", end(region)) + list( + ranges = .locusRanges(region), + given = regions$regionGiven[keep], + fit = .gwasFitLabels(gws)[keep], + # An id that only spells the range is not repeated beside it. + label = if_else( + is.na(ids) | ids == key, + span, + str_c(ids, " (", span, ")") + ) + ) +} + +# @noRd +.gwasFitLabels <- function(gws) { + study <- str_c("'", as.character(gws$study), "'") + if (!is_in("method", .tupleColumnNames(gws))) { + return(study) + } + str_c(study, " (", as.character(gws$method), ")") +} + +# Internal: one unit's variants past each GWAS fit whose blocks they meet. +# @noRd +.unitBlockReach <- function(variants, unit, blocks) { + v <- .locusRanges(variants) + list_rbind(map( + unique(blocks$fit), + .unitFitReach, + v = v, + unit = unit, + blocks = blocks + )) +} + +# @noRd +#' @importFrom dplyr count +.unitFitReach <- function(fit, v, unit, blocks) { + own <- which(blocks$fit == fit) + r <- blocks$ranges[own] + inside <- .overlapsOnShared(v, r) + if (!any(inside)) { + return(NULL) + } + chroms <- unique(as.character(seqnames(v))[inside]) + out <- v[!inside & is_in(as.character(seqnames(v)), chroms)] + if (length(out) == 0L) { + return(NULL) + } + onChroms <- which(is_in(as.character(seqnames(r)), chroms)) + hit <- own[onChroms][GenomicRanges::nearest( + .onSeqlevels(out, chroms), + .onSeqlevels(r[onChroms], chroms), + ignore.strand = TRUE + )] + count( + tibble( + unit = unit, + fit = fit, + block = blocks$label[hit], + given = blocks$given[hit], + side = if_else( + start(out) < start(blocks$ranges[hit]), + "start", + "end" + ) + ), + .data$unit, + .data$fit, + .data$block, + .data$given, + .data$side + ) +} + +# Internal: abort over variants past a given range, else warn over runs of +# more than one variant past a computed one. +# @noRd +.reportBlockReach <- function(issues, caller, what) { + if (is.null(issues) || nrow(issues) == 0L) { + return(invisible(NULL)) + } + given <- filter(issues, .data$given) + if (nrow(given) > 0L) { + abort(c( + glue( + "{caller}: {what} reach past the LD blocks loaded for a GWAS ", + "study they overlap. Those blocks' ranges were given, so the ", + "variants past them lie in blocks that were not loaded." + ), + .blockReachLines(given), + i = "Load the neighbouring LD blocks of those studies too." + )) + } + computed <- filter(issues, !.data$given, .data$n > 1L) + if (nrow(computed) > 0L) { + warn(c( + glue( + "{caller}: {what} reach past the variants of a GWAS study ", + "they overlap. Those blocks' ranges are the span of the GWAS ", + "variants, so the variants past them may only be ones the ", + "GWAS lacks, or a block may not have been loaded." + ), + .blockReachLines(computed), + i = str_c( + "Give the GWAS its windows as a `region` to have this ", + "checked strictly." + ) + )) + } + invisible(NULL) +} + +# @noRd +.blockReachLines <- function(issues) { + shown <- utils::head(issues, 5L) + lines <- glue( + "{shown$unit}: {shown$n} variant(s) past the {shown$side} of block ", + "{shown$block} of GWAS study {shown$fit}." + ) + more <- nrow(issues) - nrow(shown) + set_names( + c(lines, if (more > 0L) glue("... and {more} more.")), + rep("*", length(lines) + (more > 0L)) + ) +} + # Internal: trait-position provenance. One GRanges per trait carrying the # molecular feature's OWN genomic coordinates (gene/peak range; TSS = start()), # distinct from the fine-mapping `region`. The true trait position cannot be @@ -479,14 +910,13 @@ # and TwasWeights. Mirrors the `region` helpers above; absent for GWAS. # traitPos is optional provenance: always known for a QtlDataset, but only known # for a QtlSumStats when the caller supplied it (it cannot be inferred from -# summary statistics). When the column is absent we return a scalar NA rather -# than an empty GRanges, so traitPosition() reports "no trait position" -# honestly instead of a zero-length range. +# summary statistics). When the column is absent the answer is an empty +# GRanges -- no position, in the type every other answer has. .getTraitPosColumn <- function(x) { if (is_in("traitPos", .tupleColumnNames(x))) { .tupleColumn(x, "traitPos") } else { - NA + GenomicRanges::GRanges() } } @@ -500,7 +930,7 @@ if (length(traitPos) != n) { abort("`traitPos` must have the same length as `study`.") } - c(cols, list(traitPos = traitPos)) + c(cols, list(traitPos = .ucscRanges(traitPos))) } #' @importFrom checkmate checkClass @@ -521,13 +951,16 @@ # Internal: a length-n "unknown" column matching the type of `exemplar`, used # to pad a collection that lacks an optional column before a union row-bind. -# Character -> NA; GRanges -> a 0-width chrUn sentinel range; else NA. +# Character -> NA; GRanges -> placeholder ranges; else NA. .naLikeColumn <- function(exemplar, n) { if (methods::is(exemplar, "GRanges")) { - return(GenomicRanges::GRanges( - rep("chrUn", n), - IRanges::IRanges(start = 1L, width = 0L) - )) + return(.placeholderRanges(n)) + } + if (methods::is(exemplar, "CharacterList")) { + return(IRanges::CharacterList(rep(list(character(0)), n))) + } + if (methods::is(exemplar, "List")) { + return(S4Vectors::SimpleList(rep(list(NULL), n))) } if (is.character(exemplar)) { return(rep(NA_character_, n)) @@ -561,7 +994,7 @@ # with the rebase onto GRangesList. # # `slots` carries the collection-level state a concrete subclass adds beyond -# `ldReference` (SumStatsBase's `genome` / `qcInfo`). It is passed in rather +# `ldReference` (SumStatsBase's `genome` / `qcOptions`). It is passed in rather # than read off `parts[[1L]]` because those slots describe the WHOLE collection, # so merging them is the caller's decision -- first-wins would silently drop the # other parts' QC audit. @@ -604,32 +1037,23 @@ context = NULL, trait = NULL, method = NULL, - region = NULL, + blockId = NULL, perEntry, onSingle = perEntry, viewArgs = list() ) { - single <- .fmrTrySingle( - x, - studyName, - context, - trait, - method, - region, - onSingle, - viewArgs - ) - if (single$done) { - return(single$result) - } - idx <- .fmrRowsMatching( - x, + sel <- list( studyName = studyName, context = context, trait = trait, method = method, - region = region + blockId = blockId ) + single <- .fmrTrySingle(x, sel, onSingle, viewArgs) + if (single$done) { + return(single$result) + } + idx <- exec(.fmrRowsMatching, x, !!!sel) meta <- .fmrRowMetadata(x) if (length(idx) == 0L) { return(.fmrEmptyOrError(single, meta)) @@ -659,38 +1083,18 @@ slice(meta, integer(0)) } -# Attempt the single-entry fast path when any selector is supplied. Returns -# list(done, result) on a successful single-select, else list(done = FALSE, sel) -# carrying the selection error (or NULL when no selector was given). +# Attempt the single-entry fast path when any of `selectors` -- the named row +# selectors -- is supplied. Returns list(done, result) on a successful +# single-select, else list(done = FALSE, sel) carrying the selection error +# (or NULL when no selector was given). # @noRd #' @importFrom rlang try_fetch -.fmrTrySingle <- function( - x, - studyName, - context, - trait, - method, - region, - onSingle, - viewArgs -) { - anySelector <- !is.null(studyName) || - !is.null(context) || - !is.null(trait) || - !is.null(method) || - !is.null(region) - if (!anySelector) { +.fmrTrySingle <- function(x, selectors, onSingle, viewArgs) { + if (length(compact(selectors)) == 0L) { return(list(done = FALSE, sel = NULL)) } sel <- try_fetch( - .fmrSelectEntry( - x, - studyName = studyName, - context = context, - trait = trait, - method = method, - region = region - ), + exec(.fmrSelectEntry, x, !!!selectors), error = function(cnd) cnd ) if (!inherits(sel, "error")) { @@ -762,25 +1166,13 @@ S4Vectors::DataFrame, !!!c(combined, list(check.names = FALSE)) ) - elements <- list_flatten(map(parts, as.list)) - # Rebuilding from as.list() merges each part's seqinfo, so a part whose - # elements never had a build set would leave the result carrying both the - # real build and NA. The agreed build is written back explicitly to keep + # Joining the parts merges each part's seqinfo, so a part whose elements + # never had a build set would leave the result carrying both the real + # build and NA. The agreed build is written back explicitly to keep # seqinfo single-valued, which validity requires. - built <- .withGenomeBuild( - GenomicRanges::GRangesList(elements), - !is.null(genome), - genome - ) - grl <- S4Vectors::`mcols<-`(built, value = md) - out <- exec( - methods::new, - cls, - grl, - !!!c(list(ldReference = dict$refs), slots) - ) - validObject(out) - out + built <- .withGenomeBuild(.rtlJoinParts(parts), !is.null(genome), genome) + grl <- .rtlNamed(S4Vectors::`mcols<-`(built, value = md)) + exec(methods::new, cls, grl, !!!c(list(ldReference = dict$refs), slots)) } # Concatenate column `cn` across all parts (NA-filling parts that lack it). @@ -819,10 +1211,23 @@ "FineMappingRow", variants = .rtlGatherElements(x, idx), susieFit = md$susieFit[[first]], - cvResult = md$cvResult[[first]] + cvResult = md$cvResult[[first]], + fitVariants = .mdFitVariants(md, idx) ) } +# The variants the fit of rows `idx` was made with, in its order: the first +# row's, as the fit payload is, since rows split from one entry repeat both. +# None for a collection saved before rows recorded them. +# @noRd +.mdFitVariants <- function(md, idx) { + fv <- md$fitVariants + if (is.null(fv)) { + return(character(0)) + } + as.character(fv[[idx[[1L]]]]) +} + # @noRd .fmrPartsVariantIds <- function(parts) { variantIds(.asFmRowPayload(parts)) @@ -876,18 +1281,8 @@ } # @noRd -.fmrRowMarginalEffects <- function(parts, maxPval = NULL) { - tl <- .fmrPartsTopLoci(parts) - if (nrow(tl) == 0L) { - return(.projectMarginalView(tl)) - } - allRows <- .projectMarginalView(tl) - out <- if (is.null(maxPval) || nrow(allRows) == 0L) { - allRows - } else { - filter(allRows, !is.na(.data$p) & .data$p <= maxPval) - } - out +.fmrRowMarginalEffects <- function(parts) { + .projectMarginalView(.fmrPartsTopLoci(parts)) } # @noRd @@ -927,15 +1322,27 @@ } # @noRd +# The fit's own log Bayes factors of the variants the row still holds, each +# found in the fit by id; a row narrowed since the fit loses the columns of +# the variants it dropped, and nothing is rescaled. .fmrRowLbf <- function(parts) { lbf <- .asLbfMatrix(susieFit(parts)) - vids <- .fmrPartsVariantIds(parts) - if (is.null(lbf) || ncol(lbf) != length(vids)) { + if (is.null(lbf)) { return(tibble(variant_id = character(0))) } - wide <- as_tibble(t(as.matrix(lbf)), .name_repair = "minimal") + fitted <- .partsFitIds(parts, lbf) + if (ncol(lbf) != length(fitted)) { + return(tibble(variant_id = character(0))) + } + vids <- .fmrPartsVariantIds(parts) + col <- .fitColumnOf(vids, fitted) + held <- !is.na(col) + wide <- as_tibble( + t(as.matrix(lbf)[, col[held], drop = FALSE]), + .name_repair = "minimal" + ) w <- `names<-`(wide, str_c("lbf_L", seq_len(ncol(wide)))) - bind_cols(tibble(variant_id = as.character(vids)), w) + bind_cols(tibble(variant_id = as.character(vids[held])), w) } # @noRd @@ -993,7 +1400,8 @@ methodFits = md$fits[[first]], cvResult = md$cvResult[[first]], weightStandardized = isTRUE(md$standardized[[first]]), - weightsDataType = md$dataType[[first]] + weightsDataType = md$dataType[[first]], + fitVariants = .mdFitVariants(md, idx) ) } @@ -1023,15 +1431,173 @@ list(variantIds = vids[ok], weights = w[ok]) } -# Class-aware row payload: the TwasWeights and fine-mapping shapes differ -# (weights vs a susie fit), so callers that accept either weight source route -# through here. Replaces the old .collectionEntry bridge. +# ---- fit coverage ------------------------------------------------------------ +# A row keeps the fit it was built with when its variants are narrowed (to +# those a GWAS also carries, say). The fit, and everything read off it, still +# describes the run on all of its variants, so reading it from a row that +# holds fewer warns. Nothing is rescaled: intersectVariants() is the explicit +# way to restrict a fit. + +# The variants a row's stored fit was made with. # @noRd -.rowParts <- function(x, i) { - if (methods::is(x, "TwasWeights")) { - return(.twrRowParts(x, i)) +.rowFitVariants <- function(parts) { + if (methods::is(parts, "TwasWeightsRow")) { + return(.twRowFitVariants(parts)) + } + .fmRowFitVariants(parts) +} + +# The fit's variables in its own order: the ids the row recorded when it was +# built, else the names the fit's matrix `mat` carries, else -- an unnamed fit +# of a row saved before rows recorded them -- the row's variants as they are. +# @noRd +.partsFitIds <- function(parts, mat = NULL) { + recorded <- .rowFitVariants(parts) + if (length(recorded) > 0L) { + return(recorded) } - .fmrRowParts(x, i) + colnames(mat) %||% variantIds(parts) +} + +# How many of `fitted` are gone from `held`. A variant whose alleles +# harmonization swapped is held under another id, so ids that do not match +# exactly are matched allele-aware before they count as gone. +# @noRd +.lostFitVariantCount <- function(fitted, held) { + gone <- fitted[!is_in(fitted, held)] + if (length(gone) == 0L) { + return(0L) + } + matched <- matchVariants(gone, held, removeStrandAmbiguous = FALSE) + length(gone) - length(unique(matched$idxA)) +} + +# For each of `held`, its column in a fit made on `fitted` (NA when the fit +# has none), matched the same allele-aware way. +# @noRd +.fitColumnOf <- function(held, fitted) { + col <- match(held, fitted) + miss <- which(is.na(col)) + if (length(miss) == 0L) { + return(col) + } + m <- matchVariants(held[miss], fitted, removeStrandAmbiguous = FALSE) + replace(col, miss[m$idxA], m$idxB) +} + +# `parts` unchanged, after warning when its row holds fewer variants than its +# stored fit was made with. +# @noRd +.fitCoverageChecked <- function(parts, caller) { + fitted <- .rowFitVariants(parts) + lost <- .lostFitVariantCount(fitted, variantIds(parts)) + if (lost > 0L) { + warn( + c( + glue( + "{caller}: the stored fit was made with ", + "{length(fitted)} variants, {lost} of which this row no ", + "longer holds." + ), + i = .fitCoverageHint(parts) + ), + class = "pecotmrFitCoverage" + ) + } + parts +} + +# `x` unchanged, after warning once about every row that holds fewer variants +# than its stored fit was made with. +# @noRd +.fitCoverageCheckedRows <- function(x, caller) { + .fitCoverageCheckedAll(list(x), caller) + invisible(x) +} + +# Warn once about the narrowed rows of every collection in `xs`, so a +# pipeline reading the fits of two inputs names all of them in one warning. +# @noRd +.fitCoverageCheckedAll <- function(xs, caller) { + labels <- map(xs, .narrowedRowLabels) + rows <- list_c(labels, ptype = character()) + if (length(rows) == 0L) { + return(invisible(NULL)) + } + warn( + c( + glue( + "{caller}: {length(rows)} row(s) hold fewer variants than ", + "their stored fit was made with." + ), + set_names(utils::head(rows, 5L), rep("*", min(5L, length(rows)))), + i = .fitCoverageHint(xs[[which(lengths(labels) > 0L)[[1L]]]]) + ), + class = "pecotmrFitCoverage" + ) + invisible(NULL) +} + +# The labels of the rows of `x` that hold fewer variants than their stored +# fit was made with. None when `x` records no fit variants, or is not a +# collection at all: an optional input left NULL, or one the caller has yet +# to validate, which this advisory check must not pre-empt. +# @noRd +.narrowedRowLabels <- function(x) { + if (!methods::is(x, "RangedTupleList")) { + return(character(0)) + } + fv <- mcols(x, use.names = FALSE)$fitVariants + if (is.null(fv) || length(x) == 0L) { + return(character(0)) + } + lost <- map_int(seq_along(x), .rowLostFitVariants, x = x, fv = fv) + short <- which(lost > 0L) + if (length(short) == 0L) { + return(character(0)) + } + .pubRowLabels(x, short) +} + +# @noRd +.rowLostFitVariants <- function(i, x, fv) { + .lostFitVariantCount(as.character(fv[[i]]), .grVariantIds(x[[i]])) +} + +# `expr` with its fit-coverage warnings muffled, for a caller that has +# already warned about the rows `expr` reads -- a pipeline that runs itself +# once per study, say. +# @noRd +.muffleFitCoverage <- function(expr) { + withCallingHandlers( + expr, + pecotmrFitCoverage = function(cnd) invokeRestart("muffleWarning") + ) +} + +# What to do about a narrowed row of `x`. Only fine-mapping results have a +# way to restrict their fits, intersectVariants(); weights are refitted. +# @noRd +.fitCoverageHint <- function(x) { + restrict <- if (.isFineMappingPayload(x)) { + str_c( + "intersectVariants() restricts a fit to the variants two results ", + "share; otherwise refit on the variants kept." + ) + } else { + "Refit on the variants kept to have fits that describe them." + } + str_c( + "The fit, and the values read from it, describe the original run on ", + "all of its variants, unchanged. ", + restrict + ) +} + +# @noRd +.isFineMappingPayload <- function(x) { + methods::is(x, "FineMappingRow") || + methods::is(x, "FineMappingResultBase") } # The per-variant weight vector of one row, whichever weight source it came @@ -1116,6 +1682,19 @@ abort(msg) } +# The `entry` elements whose variants lie on more than one chromosome. A +# collection element spans exactly one, so such an entry would be split into +# one row per chromosome, each repeating the entry's identity and payload. +# @noRd +.multiChromosomeEntries <- function(entry) { + which(map_int(entry, .fmRowSeqnameCount) > 1L) +} + +# @noRd +.fmRowSeqnameCount <- function(e) { + n_distinct(as.character(seqnames(variants(e)))) +} + # Shape-tolerant readers for values that may still be a legacy entry object # while the flip is in progress. Delete the entry branch (and these) once # nothing produces entries. @@ -1142,7 +1721,8 @@ fits = S4Vectors::SimpleList(map(entry, methodFits)), cvResult = S4Vectors::SimpleList(map(entry, cvResult)), standardized = map_lgl(entry, .twPayloadStandardized), - dataType = S4Vectors::SimpleList(map(entry, weightsDataType)) + dataType = S4Vectors::SimpleList(map(entry, weightsDataType)), + fitVariants = IRanges::CharacterList(map(entry, .twRowFitVariants)) ) } @@ -1150,15 +1730,14 @@ # Combining summary-statistics collections # ----------------------------------------------------------------------------- # A SumStatsBase subclass carries three COLLECTION-level slots -- ldReference, -# genome and qcInfo -- on top of the elements and their mcols, so row-binding +# genome and qcOptions -- on top of the elements and their mcols, so row-binding # per-block pieces back into one collection has to say what happens to each. # The rules live here once, shared by combineGwasSumStats() and # combineQtlSumStats(), so the two cannot drift: # # genome must agree; a mismatch is an error -# qcInfo `entryAudit` concatenates in element order (it is indexed BY -# element); the rest is carried from the first part after checking -# the QC options agree +# qcOptions carried from the first part after checking the QC options +# agree; each row's audit is a column, so it binds with the rows # ldReference the panels union, read through the parts' shared GenotypeHandle # # The ldReference rule is the one that matters for correctness. A block-parallel @@ -1195,10 +1774,14 @@ .rtlExtraSlots <- function(parts, fn) { own <- setdiff(.rtlOwnSlots(parts[[1L]]), "ldReference") # discard(is.null), not compact(): parts no QC has run on merge to an - # empty qcInfo, which is a merged value -- compact() would drop it and + # empty qcOptions, which is a merged value -- compact() would drop it and # report the slot as having no merge rule. out <- discard( - list(qcInfo = if (is_in("qcInfo", own)) .ssCombineQcInfo(parts, fn)), + list( + qcOptions = if (is_in("qcOptions", own)) { + .ssCombineQcOptions(parts, fn) + } + ), is.null ) unknown <- setdiff(own, names(out)) @@ -1271,14 +1854,12 @@ genomes } -# qcInfo is collection-level EXCEPT `entryAudit`, which qcDiagnostics() -# addresses BY element index -- so the audit concatenates in element order -# while the rest is carried from the first part. Concatenation pads a part -# whose audit is absent or short, because an audit that slipped out of step -# with the elements would report another block's diagnostics. +# qcOptions describes the whole collection, so it is carried from the first +# part once every part is shown to have run the same QC. Each row's audit is +# a column of mcols(), so it binds with the rows it describes. # @noRd -.ssCombineQcInfo <- function(parts, fn) { - populated <- keep(parts, .ssHasQcInfo) +.ssCombineQcOptions <- function(parts, fn) { + populated <- keep(parts, .ssHasQcOptions) if (length(populated) == 0L) { return(list()) } @@ -1286,39 +1867,24 @@ msg <- glue( "{fn}: {length(parts) - length(populated)} of {length(parts)} ", "inputs carry no QC record. Run summaryStatsQc() on every input ", - "before combining, or the combined qcInfo would claim QC that ", - "only some elements went through." + "before combining, or the combined qcOptions would claim QC ", + "that only some elements went through." ) abort(msg) } .ssCheckQcOptions(populated, fn) - list_assign( - qcInfo(populated[[1L]]), - entryAudit = list_flatten(map(parts, .ssEntryAudit)) - ) + qcOptions(populated[[1L]]) } # @noRd -.ssHasQcInfo <- function(x) length(qcInfo(x)) > 0L - -# One part's per-element audit, padded to its element count so positions stay -# aligned with the elements they describe. -# @noRd -.ssEntryAudit <- function(x) { - audit <- qcInfo(x)$entryAudit %||% list() - n <- nrow(x) - if (length(audit) >= n) { - return(as.list(audit)[seq_len(n)]) - } - c(as.list(audit), vector("list", n - length(audit))) -} +.ssHasQcOptions <- function(x) length(qcOptions(x)) > 0L # The QC options must match: a collection stitched from blocks filtered at # different MAF / INFO cutoffs has no single honest answer for "what QC ran", # and every downstream consumer reads that answer off one record. # @noRd .ssCheckQcOptions <- function(parts, fn) { - first <- qcInfo(parts[[1L]])$options + first <- qcOptions(parts[[1L]])$options same <- map_lgl(parts, .ssSameQcOptions, first = first) if (all(same)) { return(invisible(NULL)) @@ -1333,7 +1899,7 @@ # @noRd .ssSameQcOptions <- function(x, first) { - identical(qcInfo(x)$options, first) + identical(qcOptions(x)$options, first) } # The LD references of `parts`, row-bound: each row keeps the reference it @@ -1483,7 +2049,7 @@ ) kept <- which(!duplicated(names(rr))) ord <- kept[order( - canonChrom(as.character(seqnames(rr)[kept])), + as.character(seqnames(rr)[kept]), start(rr)[kept] )] md <- S4Vectors::metadata(stacked) @@ -1589,7 +2155,7 @@ si <- if (nrow(combined) > 0L && keyed) { deduped <- combined[!duplicated(combined$SNP), , drop = FALSE] deduped[ - order(canonChrom(deduped$CHR), as.integer(deduped$BP)), + order(deduped$CHR, as.integer(deduped$BP)), , drop = FALSE ] diff --git a/R/twasWeights.R b/R/twasWeights.R index a7249b61..5a202e52 100644 --- a/R/twasWeights.R +++ b/R/twasWeights.R @@ -23,11 +23,13 @@ # ============================================================================= # TwasWeights S4 class # ----------------------------------------------------------------------------- -# DFrame-subclass collection keyed by the identity tuple (study, context, -# trait, method). Each row holds a TwasWeightsRow payload (variant ids -# + per-variant weight vector/matrix). Class-level slots: -# * ldReference GenotypeHandle (NULL for individual-level fits, the -# LD-sketch handle for RSS-derived weights). +# RangedTupleList collection keyed by the identity tuple (study, context, +# trait, method). Each element is one row's variants, with their weights as +# its `weight` mcols column; the fits, cross-validation and scale are columns +# of the collection's own mcols. Class-level slots: +# * ldReference the LD references RSS-derived weights used, each stored +# once; the ldReference mcols column names each row's (NA +# for weights learned from individual-level data). # Constructor + accessors below. The twasWeights pipeline helpers # (learnTwasWeights, CV, ensemble, etc.) follow at the bottom. # ============================================================================= @@ -36,14 +38,16 @@ NULL #' @title TWAS Weights Collection -#' @description S4 collection of TWAS weights keyed by the identity tuple -#' \code{(study, context, trait, method)}. Each entry is a -#' \code{TwasWeightsRow} carrying one method's weights for one -#' trait/context/study. Implements the \code{DFrame}-subclass collection -#' pattern. +#' @description S4 collection of TWAS weights, one row per +#' \code{(study, context, trait, method)}: one method's weights for one +#' trait, context and study. Each element is a row's variants: a +#' \code{GRanges} whose \code{weight} column holds the weights. #' -#' Required columns: \code{study}, \code{context}, \code{trait}, \code{method}, -#' \code{entry}. Each \code{entry} is a \code{TwasWeightsRow}. +#' Required \code{mcols()} columns: the identity tuple \code{study}, +#' \code{context}, \code{trait} and \code{method}, and each row's payload: +#' its stored fits (\code{fits}), \code{cvResult}, \code{standardized} and +#' \code{dataType}. The constructor also records \code{fitVariants}, the +#' variants the weights were fitted on. #' #' Optional columns \code{jointStudies}, \code{jointContexts}, #' \code{jointTraits} appear when the collection contains rows produced by a @@ -58,6 +62,16 @@ NULL #' \code{mcols} names the entry each row used (\code{NA} for weights #' learned from individual-level data). Used downstream to check that the #' rows a pipeline combines share an LD reference. +#' @section Narrowed rows: Each row records in its \code{fitVariants} column +#' the ids of the variants its weights were fitted on (none for a row +#' without a fit payload). A row narrowed since keeps its fits as they +#' were, so \code{cvResult()} and \code{methodFits()} warn, with condition +#' class \code{pecotmrFitCoverage}, when a row holds fewer variants than +#' they describe. So do the pipelines that read them: +#' \code{causalInferencePipeline()} when it selects weights by their +#' cross-validation, and \code{ctwasPipeline()} for rows whose SuSiE fit +#' renormalizes their weights. The weights themselves are narrowed with +#' the row and do not warn. #' @export setClass( "TwasWeights", @@ -134,10 +148,7 @@ setClass( # @noRd .twasValidateKeyUniqueness <- function(object, jointCols) { keyCols <- c("study", "context", "trait", "method", jointCols) - # Extract key columns directly rather than via `object[, keyCols]`: - # column-subsetting preserves the TwasWeights class while dropping the - # required `entry` column, and older S4Vectors revalidates that - # intermediate, spuriously failing with "missing columns: entry". + # Read column by column: `[` takes no column index on a collection. keyTbl <- as_tibble(set_names( map(keyCols, .twasColumn, object = object), keyCols @@ -155,9 +166,8 @@ setClass( # ============================================================================= #' @title Create a TwasWeights Collection Object -#' @description Construct a \code{TwasWeights} DFrame-subclass collection from -#' per-tuple vectors and a list of \code{TwasWeightsRow} payloads (one per -#' tuple). +#' @description Construct a \code{TwasWeights} collection from per-tuple +#' vectors and a list of \code{TwasWeightsRow} payloads (one per tuple). #' @param studyName Character vector of study identifiers. Use the sentinel #' \code{"joint"} for rows produced by a cross-study joint fit. #' @param context Character vector of context labels. Use \code{"joint"} for @@ -187,9 +197,12 @@ setClass( #' forward as provenance; not part of the identity key. \code{NULL} #' (default) omits the column, and \code{\link{genomicRegion}} then #' derives the window from the span of the variants present. +#' @param metadata A list of free-form metadata about the collection, +#' as \code{metadata()} holds on any Bioconductor vector. Default +#' \code{list()}. #' @return A \code{TwasWeights} object. #' @examples -#' twe <- twasWeightsRow(variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), +#' twe <- TwasWeightsRow(variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), #' weights = rep(0.1, 4), cvResult = list(rsq = 0.5), #' weightStandardized = FALSE) #' tw <- TwasWeights(studyName = "s1", context = "brain", trait = "gene1", @@ -209,7 +222,8 @@ TwasWeights <- function( jointTraits = NULL, traitPos = NULL, region = NULL, - ldReference = NULL + ldReference = NULL, + metadata = list() ) { .twasAssertArgs( studyName, @@ -237,7 +251,10 @@ TwasWeights <- function( region, n ) - .rtlNewValidated("TwasWeights", entry, cols, ldReference) + .withMetadata( + .rtlNewValidated("TwasWeights", entry, cols, ldReference), + metadata + ) } # The identity and joint-axis arguments, checked. Mirrors @@ -319,7 +336,7 @@ TwasWeights <- function( length(entry) != n ) { msg <- glue( - "`study`, `context`, `trait`, `method`, and `entry` must all ", + "`studyName`, `context`, `trait`, `method`, and `entry` must all ", "have the same length." ) abort(msg) @@ -355,11 +372,6 @@ TwasWeights <- function( abort(msg) } -#' @rdname genomicRegion -#' @export -setMethod("genomicRegion", "TwasWeights", function(x) .getRegionColumn(x)) - - #' @rdname traitPosition #' @export setMethod("traitPosition", "TwasWeights", function(x) { @@ -380,7 +392,7 @@ setMethod("traitPosition", "TwasWeights", function(x) { #' collection has a single row. #' @return A \code{TwasWeightsRow} object. #' @examples -#' twe <- twasWeightsRow( +#' twe <- TwasWeightsRow( #' variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), weights = rep(0.1, 4), #' cvResult = list(rsq = 0.5), weightStandardized = FALSE) #' tw <- TwasWeights(studyName = "s1", context = "brain", trait = "g1", @@ -391,7 +403,13 @@ setMethod("traitPosition", "TwasWeights", function(x) { #' @export setGeneric( "twasWeights", - function(x, studyName = NULL, context = NULL, trait = NULL, method = NULL) { + function( + x, + studyName = NULL, + context = NULL, + trait = NULL, + method = NULL + ) { standardGeneric("twasWeights") } ) @@ -401,16 +419,14 @@ setGeneric( setMethod( "twasWeights", "TwasWeights", - function(x, studyName = NULL, context = NULL, trait = NULL, method = NULL) { - idx <- .tupleSelectRow( - x, - studyName, - context, - trait, - method, - cls = "TwasWeights" - ) - x[idx] + function( + x, + studyName = NULL, + context = NULL, + trait = NULL, + method = NULL + ) { + x[.twrSelectRowIndex(x, studyName, context, trait, method)] } ) @@ -420,14 +436,10 @@ setMethod( mcols(x[[i]])$weight } -# The row payload a (study, context, trait, method) selector pins. -# -# Read directly rather than via twasWeights(): that accessor returns a -# single-row collection, so routing the per-field accessors through it would -# dispatch straight back into them. +# The row a (study, context, trait, method) selector pins. # @noRd -.twrSelectRowParts <- function(x, studyName, context, trait, method) { - idx <- .tupleSelectRow( +.twrSelectRowIndex <- function(x, studyName, context, trait, method) { + .tupleSelectRow( x, studyName, context, @@ -435,7 +447,19 @@ setMethod( method, cls = "TwasWeights" ) - .twrRowParts(x, idx) +} + +# The row payload that selector pins. +# +# Read directly rather than via twasWeights(): that accessor returns a +# single-row collection, so routing the per-field accessors through it would +# dispatch straight back into them. +# @noRd +.twrSelectRowParts <- function(x, studyName, context, trait, method) { + .twrRowParts( + x, + .twrSelectRowIndex(x, studyName, context, trait, method) + ) } #' @rdname resolveWeights @@ -475,7 +499,7 @@ setMethod( #' this fine-mapping / weight method; \code{NULL} matches all methods. #' @return A numeric vector or matrix of weights. #' @examples -#' twe <- twasWeightsRow(variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), +#' twe <- TwasWeightsRow(variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), #' weights = rep(0.1, 4), cvResult = list(rsq = 0.5), #' weightStandardized = FALSE) #' weights(twe) @@ -495,7 +519,13 @@ setMethod( ... ) { weights( - .twrSelectRowParts(object, studyName, context, trait, method) + .twrSelectRowParts( + object, + studyName, + context, + trait, + method + ) ) } ) @@ -512,7 +542,8 @@ setMethod( trait = NULL, method = NULL ) { - cvResult(.twrSelectRowParts(x, studyName, context, trait, method)) + parts <- .twrSelectRowParts(x, studyName, context, trait, method) + cvResult(.fitCoverageChecked(parts, "cvResult()")) } ) @@ -528,24 +559,56 @@ setMethod( trait = NULL, method = NULL ) { - methodFits(.twrSelectRowParts(x, studyName, context, trait, method)) + parts <- .twrSelectRowParts(x, studyName, context, trait, method) + methodFits(.fitCoverageChecked(parts, "methodFits()")) + } +) + +# Before rows recorded the variants their weights were fitted on, a +# collection had no `fitVariants` column; a row saved then records the +# variants it holds, and a row with no fit payload records none. +#' @rdname updateObject-methods +#' @export +setMethod( + "updateObject", + "TwasWeights", + function(object, ..., verbose = FALSE) { + if (isTRUE(verbose)) { + message("updateObject(object = 'TwasWeights')") + } + if (is_in("fitVariants", .tupleColumnNames(object))) { + return(methods::callNextMethod(object, ..., verbose = verbose)) + } + held <- map(seq_along(object), .twrBackfillFitVariants, x = object) + `$<-`(object, "fitVariants", IRanges::CharacterList(held)) } ) +# @noRd +.twrBackfillFitVariants <- function(i, x) { + md <- mcols(x, use.names = FALSE) + if (length(md$fits[[i]]) == 0L && is.null(md$cvResult[[i]])) { + return(character(0)) + } + .grVariantIds(x[[i]]) +} + #' @rdname weightStandardized #' @export setMethod( "weightStandardized", "TwasWeights", - function(x, studyName = NULL, context = NULL, trait = NULL, method = NULL) { + function( + x, + studyName = NULL, + context = NULL, + trait = NULL, + method = NULL + ) { isTRUE( - weightStandardized(.twrSelectRowParts( - x, - studyName, - context, - trait, - method - )) + weightStandardized( + .twrSelectRowParts(x, studyName, context, trait, method) + ) ) } ) @@ -555,14 +618,16 @@ setMethod( setMethod( "weightsDataType", "TwasWeights", - function(x, studyName = NULL, context = NULL, trait = NULL, method = NULL) { - weightsDataType(.twrSelectRowParts( - x, - studyName, - context, - trait, - method - )) + function( + x, + studyName = NULL, + context = NULL, + trait = NULL, + method = NULL + ) { + weightsDataType( + .twrSelectRowParts(x, studyName, context, trait, method) + ) } ) @@ -612,7 +677,6 @@ setMethod("methodNames", "TwasWeights", function(x) { unique(as.character(x$method)) }) - #' @rdname show-methods #' @export setMethod("show", "TwasWeights", function(object) { @@ -633,7 +697,6 @@ setMethod("show", "TwasWeights", function(object) { cat(glue(" LD reference: {ldSrc}\n", .trim = FALSE)) }) - # ============================================================================= # TwasWeights pipeline helpers (learnTwasWeights + CV + ensemble + # Mvsusie/Mrmash) @@ -698,6 +761,7 @@ setMethod("show", "TwasWeights", function(object) { args = list(max.iter = 100) ), enet = list(fn = "enet_weights", impl = "enetWeights", args = list()), + ridge = list(fn = "ridge_weights", impl = "ridgeWeights", args = list()), lasso = list( fn = "lasso_weights", impl = "lassoWeights", @@ -856,6 +920,7 @@ setMethod("show", "TwasWeights", function(object) { list( lasso = c("lassoWeights", "glmnetWeights", "glmnet::cv.glmnet"), enet = c("enetWeights", "glmnetWeights", "glmnet::cv.glmnet"), + ridge = c("ridgeWeights", "glmnetWeights", "glmnet::cv.glmnet"), scad = c("scadWeights", "ncvregWeights", "ncvreg::cv.ncvreg"), mcp = c("mcpWeights", "ncvregWeights", "ncvreg::cv.ncvreg"), l0learn = c("l0learnWeights", "L0Learn::L0Learn.cvfit"), @@ -891,10 +956,12 @@ setMethod("show", "TwasWeights", function(object) { # Summary statistics: each chain ends in pecotmr's own RSS solver or an # upstream *.rss entry point, never the individual-level engine. pecotmr's # solvers are reached through their LD-source paths (.penalizedRssPath(), -# .lassosumRssPath(), .prsCsRun(), .sdprRun()), which take the options of -# penalizedRss(), lassosumRss(), prsCs() and sdpr() under the same names, so +# .prsCsRun(), .sdprRun()), which take the options of penalizedRss() -- +# lassosumRss()'s are a subset -- prsCs() and sdpr() under the same names, so # a genotype reference can be used through its factor without forming the LD -# matrix. +# matrix. Every penalized method's path is .penalizedRssPath(): the penalty +# reaches it as one record its wrapper built, so only the path's own options +# (lambda, thr, maxiter) count as the method's. # @noRd .twasMethodChainsSumstat <- function() { list( @@ -918,7 +985,19 @@ setMethod("show", "TwasWeights", function(object) { lasso = c( "lassosumRssWeights", ".rssShrinkGridWeights", - ".lassosumRssPath" + ".penalizedRssPath" + ), + enet = c( + "enetRssWeights", + ".penalizedRssWeights", + ".rssShrinkGridWeights", + ".penalizedRssPath" + ), + ridge = c( + "ridgeRssWeights", + ".penalizedRssWeights", + ".rssShrinkGridWeights", + ".penalizedRssPath" ), prsCs = c("prsCsWeights", ".prsCsRun"), dprGibbs = c("sdprWeights", ".sdprRun"), @@ -967,6 +1046,8 @@ setMethod("show", "TwasWeights", function(object) { "solverInput", "LDs", "config", + "spec", + "label", "bInit", "vInit", "K" @@ -1014,7 +1095,6 @@ setMethod("show", "TwasWeights", function(object) { (length(fm) == 1L && is.na(fm[[1L]])) || is_in("...", fm) } - # The implementation that runs one method on one input path. # @noRd .twasMethodImplFor <- function(token, inputKind) { @@ -1739,10 +1819,11 @@ setMethod("show", "TwasWeights", function(object) { #' maximum number of variants to use for CV purpose, to save computing time. #' @param variantsToKeep An optional integer to ensure that the listed variants #' are kept in the CV when there is a limit on the maxNumVariants to use. -#' @param numThreads The number of threads to use for parallel processing. If -#' set to -1, the function uses all available cores. If set to 0 or 1, no -#' parallel processing is performed. If set to 2 or more, parallel processing -#' is enabled with that many threads. +#' @param BPPARAM A \code{BiocParallelParam} the folds run on; +#' \code{SerialParam()} (default) runs them one at a time. Each draws from +#' its own random-number stream, seeded by \code{seed}, else by the param's +#' own \code{RNGseed}, else by one draw from the session RNG, so a run +#' gives the same numbers however many workers it has. #' @param verbose Integer controlling verbosity level: 0 = suppress all #' messages, 1 = suppress external package messages (default), 2 = show all #' messages including those from external packages. @@ -1753,11 +1834,9 @@ setMethod("show", "TwasWeights", function(object) { #' for every other method the two behave alike. #' @param seed Integer or \code{NULL}. When supplied, seeds both the #' main-process RNG (fold partitioning, variant sub-sampling) and the -#' parallel fold-fitting RNG via the \code{BiocParallel} \code{RNGseed}, so -#' results are reproducible even under multi-threading. The main-process -#' seed is scoped to the call, so the session RNG is left as it was found. -#' \code{NULL} (default) does not seed at all and uses the historical -#' parallel default. +#' streams the folds draw from (see \code{BPPARAM}). The main-process seed +#' is scoped to the call, so the session RNG is left as it was found. +#' \code{NULL} (default) seeds neither. #' @param fittedModelsCv Optional per-fold fine-mapping fits, as #' \code{method -> fold_ -> fit}, from a \code{fineMappingPipeline()} #' run with \code{cvFolds > 1}. SuSiE-family weight wrappers extract from a @@ -1793,7 +1872,7 @@ setMethod("show", "TwasWeights", function(object) { #' process. #' } #' @importFrom purrr map -#' @importFrom BiocParallel bplapply multicoreWorkers MulticoreParam +#' @importFrom BiocParallel SerialParam #' @importFrom quadprog solve.QP #' @examples #' data(multiTraitData) @@ -1815,7 +1894,7 @@ twasWeightsCv <- function( weightMethods = NULL, maxNumVariants = NULL, variantsToKeep = NULL, - numThreads = 1, + BPPARAM = SerialParam(), verbose = 1, fitRetention = c("none", "slim", "full"), seed = NULL, @@ -1831,7 +1910,7 @@ twasWeightsCv <- function( # .cvSubsampleVariants relies on `ncol(X) <= maxNumVariants` being FALSE # for it. assertNumber(maxNumVariants, lower = 1, null.ok = TRUE) - assertInt(numThreads) + .assertBpparam(BPPARAM) assertCount(verbose) fitRetention <- arg_match(fitRetention) assertInt(seed, null.ok = TRUE) @@ -1843,7 +1922,7 @@ twasWeightsCv <- function( weightMethods = weightMethods, maxNumVariants = maxNumVariants, variantsToKeep = variantsToKeep, - numThreads = numThreads, + BPPARAM = BPPARAM, verbose = verbose, fitRetention = fitRetention, seed = seed, @@ -1946,7 +2025,7 @@ twasWeightsCv <- function( weightMethods, maxNumVariants, variantsToKeep, - numThreads, + BPPARAM, verbose, fitRetention, seed, @@ -1978,7 +2057,7 @@ twasWeightsCv <- function( fitRetention, verbose ), - numThreads = numThreads, + BPPARAM = BPPARAM, maxNumVariants = maxNumVariants, variantsToKeep = variantsToKeep, fitRetention = fitRetention, @@ -2204,7 +2283,7 @@ twasWeightsCv <- function( # One TwasWeightsRow for a (variantIds, weights) pair with the shared flags. # @noRd .twasEntry <- function(variantIds, weights, fits, ctx) { - twasWeightsRow( + TwasWeightsRow( variantIds = variantIds, weights = weights, methodFits = fits, @@ -2272,10 +2351,11 @@ twasWeightsCv <- function( #' "enet_weights")) in which case default arguments will be used for all #' methods. methods in the list can be either univariate (applied to each #' column of Y) or multivariate (applied to the entire Y matrix). -#' @param numThreads The number of threads to use for parallel processing. If -#' set to -1, the function uses all available cores. If set to 0 or 1, no -#' parallel processing is performed. If set to 2 or more, parallel processing -#' is enabled with that many threads. +#' @param BPPARAM A \code{BiocParallelParam} the methods run on; +#' \code{SerialParam()} (default) runs them one at a time. Each draws from +#' its own random-number stream, seeded by \code{seed}, else by the param's +#' own \code{RNGseed}, else by one draw from the session RNG, so a run +#' gives the same numbers however many workers it has. #' @param fittedModels Named list of fitted SuSiE-family models, keyed by #' token (\code{susie}, \code{susieInf}, \code{mvsusie}, \code{fsusie}). #' Required whenever a SuSiE-family weight method is requested: those @@ -2304,10 +2384,9 @@ twasWeightsCv <- function( #' \code{\link{readGenotypes}}, a \code{GenotypeMixture} or an #' \code{LdMatrix}) to record on the weights, or \code{NULL}. #' @param seed Integer or \code{NULL}. When supplied, seeds the main-process -#' RNG and the parallel method-fitting RNG via the \code{BiocParallel} -#' \code{RNGseed}, for reproducibility under multi-threading. The +#' RNG and the streams the methods draw from (see \code{BPPARAM}). The #' main-process seed is scoped to the call, so the session RNG is left as it -#' was found. \code{NULL} (default) does not seed at all. +#' was found. \code{NULL} (default) seeds neither. #' @return A list where each element is named after a method and contains the #' weight matrix produced by that method. #' @@ -2335,7 +2414,7 @@ learnTwasWeights <- function( studyName = "", context = "", trait = "", - numThreads = 1, + BPPARAM = SerialParam(), fittedModels = NULL, fitRetention = c("none", "slim", "full"), weightStandardized = FALSE, @@ -2347,7 +2426,7 @@ learnTwasWeights <- function( assertString(studyName) assertString(context) assertString(trait) - assertInt(numThreads) + .assertBpparam(BPPARAM) fitRetention <- arg_match(fitRetention) assertFlag(weightStandardized) assertString(weightsDataType, null.ok = TRUE) @@ -2366,7 +2445,7 @@ learnTwasWeights <- function( studyName = studyName, context = context, trait = trait, - numThreads = numThreads, + BPPARAM = BPPARAM, fittedModels = fittedModels, fitRetention = fitRetention, weightStandardized = weightStandardized, @@ -2390,14 +2469,6 @@ learnTwasWeights <- function( Y } -# Number of BiocParallel workers to use: -1 means all available, otherwise the -# requested count capped at what is available. -# @noRd -.twasResolveCores <- function(numThreads) { - avail <- multicoreWorkers() - min(if (numThreads == -1) avail else numThreads, avail) -} - # Variant ids for the weight rows: colnames(X), or synthetic variant_i labels. # @noRd .twasVariantIds <- function(X) { @@ -2416,22 +2487,17 @@ learnTwasWeights <- function( colnames(X) } -# Fit every weight method (parallel when >= 2 cores, else serial map), keyed by -# method name. +# Fit every weight method on BPPARAM's workers, keyed by method name. # @noRd -.twasFitAllMethods <- function(weightMethods, ctx, numCores) { - weightsList <- if (numCores >= 2) { - bpParam <- .bpSeedParam(numCores, ctx$rngSeed) - bplapply( - names(weightMethods), - .computeMethodWeights, - weightMethods, - ctx, - BPPARAM = bpParam - ) - } else { - map(names(weightMethods), .computeMethodWeights, weightMethods, ctx) - } +.twasFitAllMethods <- function(weightMethods, ctx, BPPARAM) { + weightsList <- .bpMap( + names(weightMethods), + .computeMethodWeights, + weightMethods, + ctx, + BPPARAM = BPPARAM, + seed = ctx$rngSeed + ) set_names(weightsList, names(weightMethods)) } @@ -2478,7 +2544,7 @@ learnTwasWeights <- function( studyName, context, trait, - numThreads, + BPPARAM, fittedModels, fitRetention, weightStandardized, @@ -2510,11 +2576,7 @@ learnTwasWeights <- function( verbose = verbose, rngSeed = seed ) - weightsList <- .twasFitAllMethods( - prepared, - ctx, - .twasResolveCores(numThreads) - ) |> + weightsList <- .twasFitAllMethods(prepared, ctx, BPPARAM) |> .twasApplyRownames(X) rows <- .buildTwasWeightEntries(weightsList, .twasVariantIds(X), ctx) .twasLearnResult(rows, ldReference) @@ -2571,7 +2633,7 @@ learnTwasWeights <- function( #' data(multiTraitData) #' X <- multiTraitData$X[, 1:4] #' colnames(X) <- sprintf("chr1:%d:A:G", 100L * (1:4)) -#' twe <- twasWeightsRow(variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), +#' twe <- TwasWeightsRow(variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), #' weights = rep(0.1, 4), cvResult = list(rsq = 0.5), #' weightStandardized = FALSE) #' tw <- TwasWeights(studyName = "s1", context = "brain", trait = "g1", @@ -2591,8 +2653,8 @@ twasPredict <- function(X, weightsList) { # for compatibility with the legacy snake_case "_predicted" # convention; ensembleWeights() rebinds the suffix. methodNames <- as.character(weightsList$method) - # The per-row weights live in each element's mcols now, so read them - # off the elements rather than a stored `entry` column. + # The per-row weights live in each element's mcols, so read them off + # the elements. wl <- set_names( map(seq_len(nrow(weightsList)), .twasRowWeights, x = weightsList), str_c(methodNames, "_weights") @@ -2690,8 +2752,7 @@ estimateSparsity <- function(weightResults) { ) } -# Column `cn` of `object`, extracted via `[[` (preserves the required `entry` -# column that `object[, cn]` would drop). +# Column `cn` of `object`'s mcols. # @noRd .twasColumn <- function(cn, object) { .tupleColumn(object, cn) diff --git a/R/twasWeightsPipeline.R b/R/twasWeightsPipeline.R index cac12f46..a603e345 100644 --- a/R/twasWeightsPipeline.R +++ b/R/twasWeightsPipeline.R @@ -58,7 +58,7 @@ #' @return A single combined \code{TwasWeights}. #' @seealso \code{\link{combineFineMappingResults}} #' @examples -#' twe <- twasWeightsRow( +#' twe <- TwasWeightsRow( #' variantIds = sprintf("chr1:%d:A:G", 100L * (1:4)), weights = rep(0.1, 4), #' cvResult = list(rsq = 0.5), weightStandardized = FALSE) #' tw1 <- TwasWeights(studyName = "s1", context = "brain", trait = "g1", @@ -134,7 +134,7 @@ combineTwasWeights <- function(..., ldReference = NULL) { } else { unname(list_c(wList)) } - twasWeightsRow( + TwasWeightsRow( variantIds = unname(list_c(map(payloads, .twrPartsVariantIds))), weights = stacked, methodFits = set_names(map(payloads, methodFits), fittedLabels), @@ -184,10 +184,11 @@ combineTwasWeights <- function(..., ldReference = NULL) { # Per the design: BGLR / qgg "Bayes alphabet" methods (bayes_a/b/c/l/n/r, # b_lasso) are individual-only until the qgg CRAN release adds qBayes # sumstat support. dpr_gibbs has the SDPR sumstat counterpart; -# dpr_vb / dpr_adaptive_gibbs remain individual-only. enet has no cpp11 -# sumstat solver yet (lassosumRssCpp is pure L1, no alpha mixing) and is -# documented as individual-only for now. prsCs has no individual-level -# counterpart (it is a sumstat-only Bayesian shrinkage method). +# dpr_vb / dpr_adaptive_gibbs remain individual-only. lasso, enet and ridge +# are glmnet on individual data and the penalized RSS solver on summary +# statistics, at alpha = 1, 0.5 (or the caller's) and 0. prsCs has no +# individual-level counterpart (it is a sumstat-only Bayesian shrinkage +# method). # @noRd .twasMethodCapabilities <- list( # NOTE: fine-mapping methods (susie / susieInf / susieAsh / mvsusie / @@ -230,10 +231,14 @@ combineTwasWeights <- function(..., ldReference = NULL) { sumstatImpl = "sdprWeights", multivariate = FALSE ), - # Individual-only -- no cpp11 sumstat solver yet. enet = list( individualImpl = "enetWeights", - sumstatImpl = NULL, + sumstatImpl = "enetRssWeights", + multivariate = FALSE + ), + ridge = list( + individualImpl = "ridgeWeights", + sumstatImpl = "ridgeRssWeights", multivariate = FALSE ), # Individual-only DPR variants (sumstat counterparts not implemented). @@ -400,6 +405,7 @@ combineTwasWeights <- function(..., ldReference = NULL) { "susieInf", "mrash", "enet", + "ridge", "lasso", "bayesR", "bayesL", @@ -432,6 +438,7 @@ combineTwasWeights <- function(..., ldReference = NULL) { susie_ash_inf = "susieAsh", mrash = "mrash", enet = "enet", + ridge = "ridge", lasso = "lasso", bayesR = "bayesR", bayesL = "bayesL", @@ -818,7 +825,7 @@ combineTwasWeights <- function(..., ldReference = NULL) { if (length(mv) == 0L) { return(invisible(NULL)) } - components <- qtlDatasets(data) + components <- as.list(data) if (length(components) == 0L) { return(invisible(NULL)) } @@ -877,11 +884,11 @@ combineTwasWeights <- function(..., ldReference = NULL) { # set is a subset of the ldReference panel. # @noRd .twasAssertQcd <- function(sumstats) { - if (length(qcInfo(sumstats)) == 0L) { + if (length(qcOptions(sumstats)) == 0L) { cls <- class(sumstats)[[1L]] msg <- glue( "twasWeightsPipeline: the supplied {cls} has no QC record ", - "(qcInfo is empty). Call summaryStatsQc() first and pass the ", + "(qcOptions() is empty). Call summaryStatsQc() first and pass the ", "QC-applied result." ) abort(msg) @@ -933,7 +940,7 @@ combineTwasWeights <- function(..., ldReference = NULL) { tokens, .twasFitForToken, fineMappingResult = fineMappingResult, - study = studyName, + studyName = studyName, context = context, trait = trait ), @@ -1084,11 +1091,16 @@ combineTwasWeights <- function(..., ldReference = NULL) { #' (require at least two traits OR at least two contexts). #' \item \code{prsCs} runs only on summary statistics, so it is rejected #' on \code{QtlDataset} input. -#' \item \code{enet}, \code{dprVb}, \code{dprAdaptiveGibbs} and the -#' Bayesian alphabet (\code{bayesA}, \code{bayesB}, \code{bayesC}, -#' \code{bayesL}, \code{bayesN}, \code{bayesR}, \code{bLasso}) run -#' only on individual-level data, so they are rejected on -#' \code{QtlSumStats} input. +#' \item \code{dprVb}, \code{dprAdaptiveGibbs} and the Bayesian alphabet +#' (\code{bayesA}, \code{bayesB}, \code{bayesC}, \code{bayesL}, +#' \code{bayesN}, \code{bayesR}, \code{bLasso}) run only on +#' individual-level data, so they are rejected on \code{QtlSumStats} +#' input. +#' \item \code{lasso}, \code{enet} and \code{ridge} are glmnet on +#' individual-level data and the penalized RSS solver on summary +#' statistics. \code{enet} mixes the two penalties at +#' \code{alpha = 0.5} unless the method's options set it, on either +#' input: \code{methods = list(enet = list(alpha = 0.3))}. #' } #' #' A \code{QtlSumStats} input must have been QC'd via @@ -1124,9 +1136,9 @@ combineTwasWeights <- function(..., ldReference = NULL) { #' default is \code{c("lasso", "prsCs", "dprGibbs")}, which there run #' lassosum, PRS-CS and SDPR; the fine-mapping methods are not in it, and #' are requested by name together with a \code{fineMappingResult}. -#' @param contexts Optional context selection; \code{NULL} (the default) uses -#' every context. A character vector applies to every study: a context no -#' study has is an error, and one only some studies lack is skipped for +#' @param contexts Optional context selection; \code{NULL} (the default) +#' uses every context. A character vector applies to every study: a context +#' no study has is an error, and one only some studies lack is skipped for #' those, with a warning. A list keyed by study name picks each study's #' contexts separately (\code{list(A = "liver")}); studies it does not name #' keep all of theirs. @@ -1138,14 +1150,19 @@ combineTwasWeights <- function(..., ldReference = NULL) { #' (\code{list(A = list(brain = "ENSG1"))}). Studies and contexts the list #' does not name keep all of their traits. A joint fit spanning a study's #' contexts uses every trait selected in any of them, minus the (context, -#' trait) pairs a per-context entry leaves out. +#' trait) pairs a per-context entry leaves out. In a MultiStudyQtlDataset +#' a study left with no trait selected sits out; the run is refused only +#' when no study or summary-statistics row has one. #' @param region Optional variant window for QtlDataset trait selection: a -#' \code{GRanges}, a \code{"chr:start-end"} string, or a one-row data.frame -#' with \code{chrom}/\code{start}/\code{end}. Mutually exclusive with -#' \code{traitId}. +#' \code{GRanges}. Mutually exclusive with \code{traitId}. #' @param cisWindow For QtlDataset: cis-window (bp) around each trait's genomic #' position when extracting variants. Required when \code{traitId} is -#' supplied. Mutually exclusive with \code{region}. +#' supplied. Mutually exclusive with \code{region}. For QtlSumStats: +#' optional; each selected tuple is analysed over its \code{traitPos} +#' \eqn{\pm} \code{cisWindow}, within its \code{region}, which is then +#' the window its result records. Every selected tuple needs a +#' \code{traitPos}. A MultiStudyQtlDataset applies it to each of its +#' studies, individual-level or summary-statistics, as above. #' @section Panel filters on the RSS path: On \code{QtlSumStats} input there #' is no genotype matrix to filter, so \code{panelFilterParam}'s #' \code{mafCutoff} / \code{macCutoff} / \code{imissCutoff} are measured @@ -1160,12 +1177,11 @@ combineTwasWeights <- function(..., ldReference = NULL) { #' \code{summaryStatsQc(raissParam = ...)}, which only bounds which variants #' RAISS will impute. #' -#' @param genotypeFilterParam For QtlDataset: per-call genotype-filter -#' overrides, built with \code{\link{GenotypeFilterParam}}. Each field that is -#' set replaces the corresponding construct-time \code{\link{QtlDataset}} slot -#' for this call only (applied to a validated copy); a field left unset -#' leaves the stored value in place. Variant QC is a property of the data, -#' so these are applied identically here and in +#' @param genotypeFilterParam For QtlDataset: which variants and samples the +#' run keeps, built with \code{\link{GenotypeFilterParam}}: its +#' \code{keepSamples} narrows the dataset once, and its other settings +#' apply to each extracted block. A field left unset filters nothing. +#' These are applied identically here and in #' \code{\link{fineMappingPipeline}} --- there is deliberately no #' TWAS-specific variant filter. #' @param panelFilterParam For QtlSumStats: LD-reference-panel filters, @@ -1196,7 +1212,9 @@ combineTwasWeights <- function(..., ldReference = NULL) { #' its SuSiE / SuSiE-inf / SuSiE-ash trimmed fits for the matching (study, #' context, trait) tuples are injected into \code{learnTwasWeights} via #' \code{fittedModels} so SuSiE-family weight methods reuse the prior fit -#' instead of refitting. +#' instead of refitting. Its fits and cross-validation are reused whole, +#' so a row narrowed since its fit warns (condition class +#' \code{pecotmrFitCoverage}). #' @param twasWeights Optional \code{\link{TwasWeights}} resume cache. For each #' requested \code{(study, context, trait, method)} tuple already present in #' this collection, the cached \code{TwasWeightsRow} is copied through and @@ -1228,13 +1246,17 @@ combineTwasWeights <- function(..., ldReference = NULL) { #' of the returned object's contract. #' #' \code{"full"} is honoured by the mr.mash engines and, on summary -#' statistics, by \code{lasso}, \code{scad}, \code{mcp} and -#' \code{l0learn}, whose full fit also keeps every candidate's +#' statistics, by \code{lasso}, \code{enet}, \code{ridge}, \code{scad}, +#' \code{mcp} and \code{l0learn}, whose full fit also keeps every candidate's #' coefficients; every other method keeps its fit whole or not at all. #' Requesting \code{"full"} for a run where no method can honour it is an #' error, and a mixed run warns rather than dropping it in silence. -#' @param naAction Character. How to handle missing values in the extracted -#' data. +#' @param phenotypeFilterParam The run's phenotype QC, built with +#' \code{\link{PhenotypeFilterParam}}: how missing phenotype values are +#' handled (unset drops the affected samples; \code{"impute"} fills each +#' trait's mean; a fit cannot take \code{"keep"}) and whether outlier +#' samples are dropped. Every fit of the run, joint ones included, reads +#' its phenotypes under it. #' @param crossValidationParam Cross-validation settings, built with #' \code{\link{CrossValidationParam}}: \code{folds} (default \code{0}, no #' CV), \code{threads}, \code{samplePartition}, \code{maxVariants} (cap @@ -1281,11 +1303,10 @@ combineTwasWeights <- function(..., ldReference = NULL) { #' @section The genotype scale: #' Individual-level genotypes reach every method centred and scaled to unit #' variance, so all the weights are on one scale and the recorded -#' \code{weight_standardized} says so. The scaling belongs to the -#' \code{QtlDataset} accessors rather than to this pipeline: -#' \code{\link{residualizedGenotypes}} applies it, governed by -#' \code{ResidualizationParam(scaleResiduals = )} per call with the -#' dataset's own \code{\link{scaleResiduals}} slot as the default. +#' \code{weight_standardized} says so. The residualization +#' (\code{\link{residualizedGenotypes}}) applies it, governed by +#' \code{ResidualizationParam(scaleResiduals = )}, which defaults to +#' \code{TRUE}. #' #' It is not cosmetic: measured through pecotmr's own entry points, every #' method returns coefficients on the scale of the \code{X} it was given @@ -1312,6 +1333,8 @@ combineTwasWeights <- function(..., ldReference = NULL) { #' @return A \code{\link{TwasWeights}} collection keyed by \code{(study, #' context, trait, method)}. Each row's LD reference is none for #' individual-level fits and that of the input row(s) for RSS-derived fits. +#' Its \code{seqinfo()} names the genome build the inputs name; inputs +#' naming different builds are refused. #' @examples #' data(qtlDatasetExample) #' twasWeightsPipeline(qtlDatasetExample, methods = "lasso", cisWindow = 1e6) @@ -1383,6 +1406,7 @@ setGeneric("twasWeightsPipeline", function(data, ...) { dataDrivenPriorMatricesCv, cisWindow, residualizationParam, + genotypeFilter, verbose ) { # A per-context selection goes in whole: the joint scope then takes each @@ -1401,6 +1425,7 @@ setGeneric("twasWeightsPipeline", function(data, ...) { dataDrivenPriorMatricesCv = dataDrivenPriorMatricesCv, cisWindow = cisWindow, residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter, verbose = verbose ) ) @@ -1420,8 +1445,9 @@ setGeneric("twasWeightsPipeline", function(data, ...) { twasWeights, dataDrivenPriorMatricesCv, cisWindow, - naAction, + phenotypeFilter, residualizationParam, + genotypeFilter, usePCA, nPCs, verbose @@ -1437,14 +1463,12 @@ setGeneric("twasWeightsPipeline", function(data, ...) { dataDrivenPriorMatricesCv = dataDrivenPriorMatricesCv, cisWindow = cisWindow, residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter, verbose = verbose )) } .twasQdsUnivariateEngine( - studyName = grid$study, - useCtx = grid$useCtx, - allTraits = grid$allTraits, - traitSelection = grid$traitSelection, + grid, marker = marker, data = data, xRegions = xRegions, @@ -1453,8 +1477,9 @@ setGeneric("twasWeightsPipeline", function(data, ...) { twasWeights = twasWeights, dataDrivenPriorMatricesCv = dataDrivenPriorMatricesCv, cisWindow = cisWindow, - naAction = naAction, + phenotypeFilter = phenotypeFilter, residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter, usePCA = usePCA, nPCs = nPCs, verbose = verbose @@ -1509,12 +1534,17 @@ setGeneric("twasWeightsPipeline", function(data, ...) { fitRetention = c("slim", "none", "full"), residualizationParam = ResidualizationParam(), weightsDataType = NULL, - naAction = c("drop", "impute"), + phenotypeFilterParam = PhenotypeFilterParam(), verbose = 1, seed = NULL ) { - naAction <- arg_match(naAction) + phenotypeFilter <- .twasResolvePhenotypeFilter(phenotypeFilterParam) fitRetention <- arg_match(fitRetention) + build <- .inputsBuild( + list(data, region, fineMappingResult, twasWeights), + "twasWeightsPipeline" + ) + .fitCoverageCheckedRows(fineMappingResult, "twasWeightsPipeline()") contexts <- parseContexts(contexts, data) traitId <- parseTraitIds(traitId, data) .twasQdsAssertParams( @@ -1532,6 +1562,8 @@ setGeneric("twasWeightsPipeline", function(data, ...) { ) data <- resolved$data cfg <- .twasJointCfg( + genotypeFilter = resolved$genotypeFilter, + phenotypeFilter = phenotypeFilter, contexts = contexts, traitId = traitId, cisWindow = cisWindow, @@ -1563,7 +1595,7 @@ setGeneric("twasWeightsPipeline", function(data, ...) { traitId ) if (joint$done) { - return(joint$result) + return(.withGenome(joint$result, build)) } grid <- .twasQdsResolveGrid( data, @@ -1582,13 +1614,14 @@ setGeneric("twasWeightsPipeline", function(data, ...) { twasWeights = twasWeights, dataDrivenPriorMatricesCv = setup$ctx$dataDrivenPriorMatricesCv, cisWindow = cisWindow, - naAction = naAction, + phenotypeFilter = phenotypeFilter, residualizationParam = residualizationParam, + genotypeFilter = resolved$genotypeFilter, usePCA = usePCA, nPCs = nPCs, verbose = verbose ) - .twasQdsAssemble(tw, joint$result) + .withGenome(.twasQdsAssemble(tw, joint$result), build) } #' @rdname twasWeightsPipeline @@ -1645,10 +1678,10 @@ setMethod( ) } -# Reject the region + cisWindow combination, derive the X windows, and apply -# the per-call filter overrides to a validated copy of the dataset. Mirrors -# .fmQdsResolveInputs; variant QC is a data property applied identically to -# fine-mapping and TWAS, so there is no TWAS-specific variant filter. +# Reject the region + cisWindow combination, derive the X windows, resolve the +# run's genotype filter and narrow the dataset to its samples. Mirrors +# .fmQdsResolveInputs; variant QC is applied identically to fine-mapping and +# TWAS, so there is no TWAS-specific variant filter. # @noRd .twasQdsResolveInputs <- function( data, @@ -1662,9 +1695,11 @@ setMethod( cisWindow, "twasWeightsPipeline(QtlDataset)" ) + genotypeFilter <- .qtlResolveFilter(genotypeFilterParam) list( - data = .qtlApplyFilterOverrides(data, genotypeFilterParam), - xRegions = .makeXRegions(region, jointRegions) + data = .qtlRestrictSamples(data, genotypeFilter$keepSamples), + xRegions = .makeXRegions(region, jointRegions), + genotypeFilter = genotypeFilter ) } @@ -1748,11 +1783,25 @@ setMethod( list(parsedJointSpec = parsedJointSpec, norm = norm) } +# TWAS's phenotype QC: a weight fit cannot take a missing phenotype, so an +# unset naAction drops the affected samples and "keep" is refused. +# @noRd +.twasResolvePhenotypeFilter <- function(phenotypeFilterParam) { + .qtlResolvePhenotypeFilter( + phenotypeFilterParam, + naDefault = "drop", + naAllowed = c("drop", "impute"), + caller = "twasWeightsPipeline" + ) +} + # The individual-level settings a TWAS run fits under, as one record: built # once by the QtlDataset method and once by the MultiStudyQtlDataset method, # with the same builder, so a setting added for one reaches the other. # @noRd .twasJointCfg <- function( + genotypeFilter, + phenotypeFilter, contexts, traitId, cisWindow, @@ -1769,6 +1818,8 @@ setMethod( seed ) { list( + genotypeFilter = genotypeFilter, + phenotypeFilter = phenotypeFilter, contexts = contexts, traitId = traitId, cisWindow = cisWindow, @@ -1801,7 +1852,7 @@ setMethod( ), ensembleParam = .ensembleResolve(cfg$ensembleParam), weightsDataType = cfg$weightsDataType, - standardized = .qtlScaleResiduals(data, cfg$residualizationParam), + standardized = .qtlScaleResiduals(cfg$residualizationParam), fitRetention = cfg$fitRetention, estimatePi = cfg$estimatePi, verbose = cfg$verbose, @@ -1817,6 +1868,8 @@ setMethod( dataDrivenPriorMatricesCv = mash$dataDrivenPriorMatricesCv, cisWindow = cfg$cisWindow, residualizationParam = cfg$residualizationParam, + genotypeFilter = cfg$genotypeFilter, + phenotypeFilter = cfg$phenotypeFilter, verbose = cfg$verbose ) ) @@ -1860,8 +1913,8 @@ setMethod( .twasQdsResolveTraits <- function(data, useCtx, traitId, region) { perCtxTraits <- map( useCtx, - .twasQdsCtxTraits, - data = data, + .contextSelectedTraits, + qd = data, traitId = traitId, region = region ) @@ -1896,9 +1949,8 @@ setMethod( fitRetention = fitRetention, # DERIVED from what the accessors actually do: genotypes reach # the fitter scaled to unit variance unless - # `ResidualizationParam(scaleResiduals = FALSE)` or the dataset's - # own slot says otherwise. Resolved by the caller, which is where - # the dataset and the bundle are both in scope. + # `ResidualizationParam(scaleResiduals = FALSE)` says otherwise. + # Resolved by the caller, which holds the bundle. standardized = standardized, estimatePi = estimatePi, verbose = verbose, @@ -1938,12 +1990,10 @@ setMethod( # Univariate methods ROUTED THROUGH THE ENGINE: one 1-condition group per # (context, trait), per region -> the SAME per-method fitter (+ ensemble layer # for >= 2 methods + resume cache) as the joint paths, merged across regions. +# `grid` is the dispatch row naming the study, contexts and traits. # @noRd .twasQdsUnivariateEngine <- function( - studyName, - useCtx, - allTraits, - traitSelection, + grid, marker, data, xRegions, @@ -1952,18 +2002,19 @@ setMethod( twasWeights, dataDrivenPriorMatricesCv, cisWindow, - naAction, + phenotypeFilter, residualizationParam, + genotypeFilter, usePCA, nPCs, verbose ) { plan <- .twasQdsUnivPlan( usePCA, - studyName, - useCtx, - allTraits, - traitSelection + grid$study, + grid$useCtx, + grid$allTraits, + grid$traitSelection ) cells <- plan$cells scope <- plan$scope @@ -1981,8 +2032,9 @@ setMethod( twasWeights = twasWeights, dataDrivenPriorMatricesCv = dataDrivenPriorMatricesCv, cisWindow = cisWindow, - naAction = naAction, + phenotypeFilter = phenotypeFilter, residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter, nPCs = nPCs, verbose = verbose ) @@ -2000,8 +2052,9 @@ setMethod( twasWeights, dataDrivenPriorMatricesCv, cisWindow, - naAction, + phenotypeFilter, residualizationParam, + genotypeFilter, nPCs, verbose ) { @@ -2014,8 +2067,9 @@ setMethod( region = xRegions[[bi]], regionIndex = bi, nRegions = length(xRegions), - naAction = naAction, + phenotypeFilter = phenotypeFilter, residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter, nPCs = nPCs, verbose = verbose ) @@ -2062,6 +2116,7 @@ setMethod( methods = NULL, contexts = NULL, traitId = NULL, + cisWindow = NULL, jointSpecification = NULL, fineMappingResult = NULL, twasWeights = NULL, @@ -2078,11 +2133,17 @@ setMethod( "twasWeightsPipeline", "QtlSumStats" ) - .twasPipelineQtlSumStats( + build <- .inputsBuild( + list(data, fineMappingResult, twasWeights), + "twasWeightsPipeline" + ) + .fitCoverageCheckedRows(fineMappingResult, "twasWeightsPipeline()") + res <- .twasPipelineQtlSumStats( data = data, methods = methods, contexts = contexts, traitId = traitId, + cisWindow = cisWindow, jointSpecification = jointSpecification, fineMappingResult = fineMappingResult, twasWeights = twasWeights, @@ -2091,6 +2152,7 @@ setMethod( verbose = verbose, panelFilterParam = panelFilterParam ) + .withGenome(res, build) } ) @@ -2138,11 +2200,21 @@ setMethod( ) } +# A QtlSumStats TWAS-weights run's inputs: its data, checked for a QC +# record, and its selection parsed once, with `cisWindow` laid on the tuples +# selected. +# @noRd +.twasQssInputs <- function(data, contexts, traitId, cisWindow) { + .twasAssertQcd(data) + .qssSelection(data, contexts, traitId, cisWindow, "twasWeightsPipeline") +} + .twasPipelineQtlSumStats <- function( data, methods, contexts, traitId, + cisWindow, jointSpecification, fineMappingResult, twasWeights, @@ -2151,15 +2223,13 @@ setMethod( verbose, panelFilterParam ) { - .twasAssertQcd(data) - contexts <- parseContexts(contexts, data) - traitId <- parseTraitIds(traitId, data) + inputs <- .twasQssInputs(data, contexts, traitId, cisWindow) # One record of the settings the joint phase and the shared dispatcher # both need, so each names them once. jointCfg <- list( - data = data, - contexts = contexts, - traitId = traitId, + data = inputs$data, + contexts = inputs$contexts, + traitId = inputs$traitId, weightsDataType = weightsDataType, verbose = verbose, fitRetention = fitRetention, @@ -2175,10 +2245,10 @@ setMethod( return(joint$result) } .twasQssAfterJoint( - data, + inputs$data, joint = joint, - contexts = contexts, - traitId = traitId, + contexts = inputs$contexts, + traitId = inputs$traitId, twasWeights = twasWeights, weightsDataType = weightsDataType, fineMappingResult = fineMappingResult, @@ -2220,7 +2290,7 @@ setMethod( panelFilterParam = panelFilterParam ) ) - .twasQssAssemble(rows, joint$result) + .twasQssAssemble(rows, joint$result, data) } # Normalize the methods argument into (tokens, methodArgs). The default set @@ -2404,18 +2474,25 @@ setMethod( } # Assemble a TwasWeights collection from a flat list of row records, each row -# on the LD reference its record carries (none for an individual-level fit). +# on the LD reference its record carries (none for an individual-level fit), +# and on the trait position and window `data` holds for its (study, context, +# trait) -- the window a cisWindow laid, which the result promises to record. # @noRd -.twasRowsToWeights <- function(rows) { +.twasRowsToWeights <- function(rows, data) { if (length(rows) == 0L) { return(NULL) } + studies <- map_chr(rows, "study") + contexts <- map_chr(rows, "context") + traits <- map_chr(rows, "trait") TwasWeights( - studyName = map_chr(rows, "study"), - context = map_chr(rows, "context"), - trait = map_chr(rows, "trait"), + studyName = studies, + context = contexts, + trait = traits, method = map_chr(rows, "method"), entry = map(rows, "entry"), + traitPos = .anchorVector(data, studies, contexts, traits, "traitPos"), + region = .anchorVector(data, studies, contexts, traits, "region"), ldReference = map(rows, "ldReference") ) } @@ -2661,7 +2738,7 @@ setMethod( ldReference, cutoffs = NULL ) { - allDf <- as.data.frame( + allDf <- .sumStatsDf( data, studyName = st, context = ctx, @@ -2791,7 +2868,7 @@ setMethod( ctx, tr, tk, - twasWeightsRow( + TwasWeightsRow( variantIds = fitCtx$variantIds, weights = as.numeric(`attr<-`(weights, "fit", NULL)), methodFits = attr(weights, "fit"), @@ -2961,7 +3038,7 @@ setMethod( ldReference = NULL, cutoffs = NULL ) { - allDf <- as.data.frame( + allDf <- .sumStatsDf( data, studyName = st, context = ctxNames[[1L]], @@ -2993,7 +3070,7 @@ setMethod( # One context's z column and median N, checked against the shared SNP order. # @noRd .twasQssContextStats <- function(ctx, data, st, tr, variantIds) { - d <- as.data.frame( + d <- .sumStatsDf( data, studyName = st, context = ctx, @@ -3246,8 +3323,8 @@ setMethod( # Combine the per-tuple result with any joint result (error if both empty). # @noRd -.twasQssAssemble <- function(rows, jointResult) { - perTupleResult <- .twasRowsToWeights(rows) +.twasQssAssemble <- function(rows, jointResult, data) { + perTupleResult <- .twasRowsToWeights(rows, data) if (is.null(jointResult)) { if (is.null(perTupleResult)) { msg <- glue( @@ -3285,25 +3362,25 @@ setMethod( # @noRd .twasPerStudy <- function(qd, cfg) { # `cfg` carries the parsed selection for every study; this study gets its - # own share, and a study with none of its contexts selected sits out. - s <- studyName(qd) - contexts <- .selectedContexts(cfg$contexts, s) - if (!is.null(contexts) && length(contexts) == 0L) { + # own share, and a study left with no trait selected in its selected + # contexts -- none of its contexts, none of the traits -- sits out. + if (!.studyHasSelectedTraits(qd, cfg$contexts, cfg$traitId, cfg$region)) { return(NULL) } - twasWeightsPipeline( + s <- studyName(qd) + .muffleFitCoverage(twasWeightsPipeline( data = qd, jointSpecification = NULL, fitRetention = cfg$fitRetention, methods = cfg$methods, - contexts = contexts, + contexts = .selectedContexts(cfg$contexts, s), traitId = .studyTraitIdArg(cfg$traitId, s), region = cfg$region, cisWindow = cfg$cisWindow, jointRegions = cfg$jointRegions, fineMappingResult = cfg$fineMappingResult, twasWeights = cfg$twasWeights, - naAction = cfg$naAction, + phenotypeFilterParam = cfg$phenotypeFilterParam, verbose = cfg$verbose, crossValidationParam = cfg$crossValidationParam, ensembleParam = cfg$ensembleParam, @@ -3315,16 +3392,17 @@ setMethod( nPCs = cfg$nPCs, weightsDataType = cfg$weightsDataType, residualizationParam = cfg$residualizationParam - ) + )) } # Embedded-sumstats TWAS-weights worker for .multiStudyPipelineDriver. # @noRd .twasSumStats <- function(ss, cfg) { - # Summary statistics carry no genotypes: nothing to select a region - # from, residualize, cross-validate, stack or fit on full data. `cfg` - # carries those for the individual-level sibling and they are not - # forwarded here. + # Summary statistics carry no genotypes: each tuple's window is in the + # input, narrowed by `cisWindow` around its trait position as on the + # QtlDataset side, and there is nothing to residualize, cross-validate, + # stack or fit on full data. `cfg` carries those for the individual-level + # sibling and they are not forwarded here. # # The parsed selection is applied here, to the rows, so the recursion runs # on what it keeps with nothing left to filter -- and rows it leaves out @@ -3333,19 +3411,20 @@ setMethod( if (!any(keepRows)) { return(NULL) } - twasWeightsPipeline( + .muffleFitCoverage(twasWeightsPipeline( data = if (all(keepRows)) ss else ss[which(keepRows)], jointSpecification = NULL, fitRetention = cfg$fitRetention, methods = cfg$methods, contexts = NULL, traitId = NULL, + cisWindow = cfg$cisWindow, fineMappingResult = cfg$fineMappingResult, twasWeights = cfg$twasWeights, verbose = cfg$verbose, panelFilterParam = cfg$panelFilterParam, weightsDataType = cfg$weightsDataType - ) + )) } # Few methods distinguish the retention levels (.twasFullDetailTokens()); @@ -3389,7 +3468,7 @@ setMethod( # @noRd .twasFullDetailTokens <- function(inputKind) { if (identical(inputKind, "QtlSumStats")) { - return(c("mrmash", "lasso", "scad", "mcp", "l0learn")) + return(c("mrmash", "lasso", "enet", "ridge", "scad", "mcp", "l0learn")) } "mrmash" } @@ -3472,7 +3551,7 @@ setMethod( nPCs = 10L, fitRetention = c("slim", "none", "full"), weightsDataType = NULL, - naAction = c("drop", "impute"), + phenotypeFilterParam = PhenotypeFilterParam(), verbose = 1, residualizationParam = ResidualizationParam(), crossValidationParam = CrossValidationParam(), @@ -3483,14 +3562,21 @@ setMethod( # Every collection holds individual-level studies, so their rule applies # here; a summary-statistic study is checked again by its own route. .twasWarnUnretainableDetail(fitRetention, methods, "QtlDataset") + # Resolved once here so a bad choice fails before any study runs; the + # record carries the bundle itself, as each component resolves its own. + .twasResolvePhenotypeFilter(phenotypeFilterParam) + build <- .inputsBuild( + list(data, region, fineMappingResult, twasWeights), + "twasWeightsPipeline(MultiStudyQtlDataset)" + ) + # Once here; each study's run below reads the same rows and is muffled. + .fitCoverageCheckedRows(fineMappingResult, "twasWeightsPipeline()") inputs <- .msResolveInputs( - naAction, region, cisWindow, jointRegions, "twasWeightsPipeline(MultiStudyQtlDataset)" ) - naAction <- inputs$naAction cfg <- .twasMsCfg( methods = methods, contexts = parseContexts(contexts, data), @@ -3500,7 +3586,7 @@ setMethod( jointRegions = jointRegions, fineMappingResult = fineMappingResult, twasWeights = twasWeights, - naAction = naAction, + phenotypeFilterParam = phenotypeFilterParam, verbose = verbose, crossValidationParam = crossValidationParam, ensembleParam = ensembleParam, @@ -3515,6 +3601,7 @@ setMethod( weightsDataType = weightsDataType, residualizationParam = residualizationParam ) + .msAssertTraitsSelected(data, cfg, "twasWeightsPipeline") jointCfg <- .twasMsJointCfg(cfg, data, inputs$xRegions) joint <- .twasMsResolveTokens( jointSpecification, @@ -3523,9 +3610,16 @@ setMethod( jointCfg ) if (joint$done) { - return(joint$result) + return(.withGenome(joint$result, build)) } - .twasMsDriver(data, joint$result, list_assign(cfg, methods = joint$methods)) + .withGenome( + .twasMsDriver( + data, + joint$result, + list_assign(cfg, methods = joint$methods) + ), + build + ) } # The MultiStudyQtlDataset joint record, derived from the record the @@ -3538,6 +3632,10 @@ setMethod( .twasMsJointCfg <- function(cfg, data, xRegions) { list_assign( .twasJointCfg( + genotypeFilter = .qtlResolveFilter(cfg$genotypeFilterParam), + phenotypeFilter = .twasResolvePhenotypeFilter( + cfg$phenotypeFilterParam + ), contexts = cfg$contexts, traitId = cfg$traitId, cisWindow = cfg$cisWindow, @@ -3668,7 +3766,7 @@ setMethod( jointRegions, fineMappingResult, twasWeights, - naAction, + phenotypeFilterParam, verbose, crossValidationParam, ensembleParam, @@ -3692,7 +3790,7 @@ setMethod( jointRegions = jointRegions, fineMappingResult = fineMappingResult, twasWeights = twasWeights, - naAction = naAction, + phenotypeFilterParam = phenotypeFilterParam, verbose = verbose, crossValidationParam = crossValidationParam, ensembleParam = ensembleParam, @@ -4564,28 +4662,12 @@ ensembleWeights <- function( regionIndex = bi, nRegions = length(ctx$xRegions), residualizationParam = ctx$residualizationParam, + genotypeFilter = ctx$genotypeFilter, + phenotypeFilter = ctx$phenotypeFilter, verbose = ctx$verbose ) } -# The traits of one context: those traitId selects there, else region -# overlap, else every trait in the context. A traitId that leaves this -# context out keeps all of its traits -- region picks traits only when no -# traitId is given at all. -# @noRd -.twasQdsCtxTraits <- function(ctx, data, traitId, region) { - se <- molecularTraits(data, contexts = ctx) - ids <- rownames(se) - if (!is.null(traitId)) { - intersect(ids, .selectedTraits(traitId, studyName(data), ctx) %||% ids) - } else if (!is.null(region)) { - rr <- SummarizedExperiment::rowRanges(se) - ids[IRanges::overlapsAny(rr, region)] - } else { - ids - } -} - # One region's univariate joint-cell fit (region `bi` of `xRegions`). # @noRd .twasQdsUnivRegion <- function( @@ -4600,8 +4682,9 @@ ensembleWeights <- function( twasWeights, dataDrivenPriorMatricesCv, cisWindow, - naAction, + phenotypeFilter, residualizationParam, + genotypeFilter, nPCs, verbose ) { @@ -4615,8 +4698,9 @@ ensembleWeights <- function( twasWeights = twasWeights, dataDrivenPriorMatricesCv = dataDrivenPriorMatricesCv, cisWindow = cisWindow, - naAction = naAction, + phenotypeFilter = phenotypeFilter, residualizationParam = residualizationParam, + genotypeFilter = genotypeFilter, nPCs = nPCs, verbose = verbose ) @@ -4694,7 +4778,7 @@ ensembleWeights <- function( ctxNames[[kk]], tr, tk, - twasWeightsRow( + TwasWeightsRow( variantIds = mvStat$variantIds, weights = as.numeric(weights[, kk]), methodFits = if (kk == 1L) fitAttr else NULL, diff --git a/R/twasWeightsRow.R b/R/twasWeightsRow.R index 0c01ede2..ca37ac5e 100644 --- a/R/twasWeightsRow.R +++ b/R/twasWeightsRow.R @@ -11,7 +11,7 @@ NULL #' @title TWAS Weights Row #' @description One row's worth of TWAS weights. Build one with -#' \code{\link{twasWeightsRow}} and pass a list of them as +#' \code{\link{TwasWeightsRow}} and pass a list of them as #' \code{\link{TwasWeights}}' \code{entry} argument. #' @slot variants A \code{GRanges} of the weighted variants. #' @slot weights Per-variant weights, aligned to \code{variants}. @@ -19,7 +19,14 @@ NULL #' @slot cvResult Cross-validation payload, or \code{NULL}. #' @slot weightStandardized Whether the weights are on the standardized scale. #' @slot weightsDataType Optional data-type label. -#' @seealso \code{\link{twasWeightsRow}}, +#' @slot fitVariants The ids of the variants the weights were fitted on, in +#' the fit's own order, recorded when the row is built; empty for a row with +#' no fit payload. A row narrowed to fewer variants keeps them, which is how +#' reading its fits can tell they describe more variants than the row now +#' holds. +#' @section Coercion: \code{as(x, "GRanges")} gives the row's variants with +#' their \code{weight} column: the element a collection stores for it. +#' @seealso \code{\link{TwasWeightsRow}}, #' \code{\linkS4class{FineMappingRow}} #' @export setClass( @@ -30,14 +37,16 @@ setClass( methodFits = "ANY", cvResult = "ANY", weightStandardized = "logical", - weightsDataType = "ANY" + weightsDataType = "ANY", + fitVariants = "character" ), prototype( weights = NULL, methodFits = NULL, cvResult = NULL, weightStandardized = FALSE, - weightsDataType = NULL + weightsDataType = NULL, + fitVariants = character(0) ) ) @@ -80,9 +89,9 @@ methods::setValidity("TwasWeightsRow", function(object) { #' scale. #' @param weightsDataType Optional data-type label. #' @return A \code{\linkS4class{TwasWeightsRow}}. -#' @seealso \code{\link{fineMappingRow}} +#' @seealso \code{\link{FineMappingRow}} #' @examples -#' row <- twasWeightsRow( +#' row <- TwasWeightsRow( #' variantIds = c("chr1:100:A:G", "chr1:200:C:T"), #' weights = c(0.4, -0.2) #' ) @@ -91,7 +100,7 @@ methods::setValidity("TwasWeightsRow", function(object) { #' entry = list(row) #' ) #' @export -twasWeightsRow <- function( +TwasWeightsRow <- function( variantIds, weights, methodFits = NULL, @@ -120,17 +129,17 @@ twasWeightsRow <- function( gr, value = `[[<-`(mcols(gr, use.names = FALSE), "weight", value = w) ) - obj <- new( + fitted <- length(methodFits) > 0L || !is.null(cvResult) + new( "TwasWeightsRow", variants = withWeight, weights = w, methodFits = methodFits, cvResult = cvResult, weightStandardized = isTRUE(weightStandardized), - weightsDataType = weightsDataType + weightsDataType = weightsDataType, + fitVariants = if (fitted) .grVariantIds(gr) else character(0) ) - validObject(obj) - obj } @@ -154,6 +163,9 @@ setMethod("methodFits", "TwasWeightsRow", function(x) x@methodFits) #' @export setMethod("cvResult", "TwasWeightsRow", function(x) x@cvResult) +# @noRd +.twRowFitVariants <- function(x) x@fitVariants + #' @rdname weightStandardized #' @export setMethod("weightStandardized", "TwasWeightsRow", function(x) { @@ -167,6 +179,13 @@ setMethod("weightsDataType", "TwasWeightsRow", function(x) x@weightsDataType) # @noRd setMethod("variants", "TwasWeightsRow", function(x) x@variants) +#' @rdname TwasWeightsRow-class +#' @name coerce,TwasWeightsRow,GRanges-method +#' @aliases coerce,TwasWeightsRow,GRanges-method +#' @usage NULL +#' @exportMethod coerce +setAs("TwasWeightsRow", "GRanges", function(from) variants(from)) + #' @rdname show-methods #' @export setMethod("show", "TwasWeightsRow", function(object) { diff --git a/R/variantId.R b/R/variantId.R index 42970a79..0a585bfe 100644 --- a/R/variantId.R +++ b/R/variantId.R @@ -12,12 +12,6 @@ #' @importFrom magrittr is_in NULL -#' Strip "chr" prefix from chromosome identifiers. -#' @param x Character vector of chromosome identifiers (e.g., "chr1", "chrX"). -#' @return Character vector with "chr" prefix removed (e.g., "1", "X"). -#' @noRd -stripChrPrefix <- function(x) str_remove(x, "^chr") - #' Canonicalize chromosome identifiers to a normalized string. #' #' Strips a leading "chr"/"ch" prefix (case-insensitive), uppercases, drops @@ -52,16 +46,84 @@ canonChromLabel <- function(x) { replace(ok & x == "M", "MT") } -#' Ensure a leading chr prefix on a chromosome identifier. +#' Chromosome identifiers in the UCSC style. #' -#' Case-insensitive additive companion to \code{canonChrom} (which strips the -#' prefix): \code{"1"}, \code{"chr1"}, \code{"CHR1"} all become \code{"chr1"}. -#' Does not remap 23/24/M. +#' The style \code{seqlevelsStyle(x) <- "UCSC"} gives, and the only one pecotmr +#' holds: every chromosome label that enters -- read from a file, parsed from a +#' variant id, or passed to a constructor or as a range argument -- goes +#' through here once, so comparisons inside the package are exact. +#' \code{"1"}, \code{"chr1"}, +#' \code{"CHR1"} and \code{"01"} all become \code{"chr1"}; the numeric codes +#' fold as in \code{canonChrom} (\code{23 -> chrX}, \code{24 -> chrY}); and +#' the mitochondrion, \code{"M"} or \code{"MT"}, becomes \code{"chrM"}. A +#' label outside the standard set keeps its spelling behind the prefix. #' @param x Character or numeric vector of chromosome identifiers. -#' @return Character vector with a lowercase \code{"chr"} prefix. +#' @return Character vector of UCSC-style chromosome names. #' @noRd withChrPrefix <- function(x) { - str_c("chr", str_remove(as.character(x), regex("^chr", ignore_case = TRUE))) + bare <- str_remove(as.character(x), regex("^chr", ignore_case = TRUE)) + canon <- canonChrom(bare) + standard <- is_in(canon, .STANDARD_CHROMS) + str_c("chr", if_else(standard, str_replace(canon, "^MT$", "M"), bare)) +} + +# The chromosomes withChrPrefix() spells as UCSC does, in canonChrom() form. +# @noRd +.STANDARD_CHROMS <- c(as.character(seq_len(22L)), "X", "Y", "MT") + +# `gr` with its chromosomes in UCSC style, for ranges entering from outside: +# a constructor's ranges, a range argument. Strand, metadata columns and the +# genome build are kept, and ranges already in UCSC style come back as they +# are. Anything but ranges (NULL, a stray value a constructor is about to +# refuse) passes through untouched. +# @noRd +.ucscRanges <- function(gr) { + if (!methods::is(gr, "GenomicRanges") && !methods::is(gr, "GRangesList")) { + return(gr) + } + old <- GenomeInfoDb::seqlevels(gr) + new <- withChrPrefix(old) + if (identical(old, new)) { + return(gr) + } + if (!anyDuplicated(new)) { + return(GenomeInfoDb::renameSeqlevels(gr, set_names(new, old))) + } + # Two spellings of one chromosome ("1" and "chr1") cannot both be + # renamed onto one name, so the ranges are rebuilt on the merged names. + out <- S4Vectors::`mcols<-`( + GenomicRanges::GRanges( + withChrPrefix(as.character(GenomicRanges::seqnames(gr))), + IRanges::ranges(gr), + strand = GenomicRanges::strand(gr) + ), + value = S4Vectors::mcols(gr) + ) + .withGenome(out, .oneBuild(gr)) +} + +# A collection constructor's `entry` list with every element's chromosomes in +# UCSC style; a NULL element stays NULL. +# @noRd +.ucscEntries <- function(entry) { + map(as.list(entry), .ucscRanges) +} + +# A context or genotype experiment with its rowRanges in UCSC style, so a +# dataset compares them exactly with every other range pecotmr holds. +# @noRd +.ucscExperiment <- function(se) { + if (!methods::is(se, "RangedSummarizedExperiment")) { + return(se) + } + old <- GenomeInfoDb::seqlevels(se) + if (identical(withChrPrefix(old), old)) { + return(se) + } + SummarizedExperiment::`rowRanges<-`( + se, + value = .ucscRanges(SummarizedExperiment::rowRanges(se)) + ) } #' Order key for chromosome identifiers. @@ -81,16 +143,12 @@ chromOrder <- function(x) { factor(x, levels = c(standard, extra), ordered = TRUE) } -# Backwards-compat alias - #' Strip build suffix from variant IDs (e.g., ":b38" or "_b38"). #' @param x Character vector of variant IDs. #' @return Character vector with build suffix removed. #' @noRd stripBuildSuffix <- function(x) str_remove(x, "(:|_)b[0-9]+$") -# Backwards-compat alias - #' Test whether allele pairs are single-nucleotide (SNP, not indel). #' #' Returns TRUE for each pair where both alleles are exactly one of A, T, C, G. @@ -162,8 +220,6 @@ isSnpAlleles <- function(a1, a2) { ) } -# Backwards-compat alias - #' Detect the naming convention of variant IDs #' #' Examines variant ID strings to detect their format: whether they have a "chr" @@ -220,22 +276,21 @@ detectVariantConvention <- function(ids) { ) } -# Backwards-compat alias for external callers - #' Parse variant IDs into a data frame #' #' Converts variant IDs from any supported string format or data.frame into a -#' standardized data.frame with a normalized character chrom, integer pos, and -#' character allele columns (A2, A1). The chrom is canonicalized (chr stripped, -#' uppercased, 23 -> X / 24 -> Y / M -> MT) but kept as a string so X/Y/MT -#' survive. Supports colon-separated ("chr1:100:A:G"), underscore-separated -#' ("1_100_A_G"), with or without "chr" prefix, and with optional build suffix -#' (":b38" or "_b38"). The detected input convention is stored as an attribute. +#' standardized data.frame with a character chrom, integer pos, and character +#' allele columns (A2, A1). The chrom is spelled in UCSC style, as every +#' chromosome pecotmr holds is ("chr1", "chrX", "chrM"; 23 -> chrX, +#' 24 -> chrY). Supports colon-separated ("chr1:100:A:G"), +#' underscore-separated ("1_100_A_G"), with or without "chr" prefix, and with +#' optional build suffix (":b38" or "_b38"). The detected input convention is +#' stored as an attribute. #' #' @param ids A character vector of variant IDs, or a data.frame with columns #' "chrom", "pos", and allele columns (A2/A1 or ref/alt or any 4-column #' layout). -#' @return A tibble with columns "chrom" (character, normalized), "pos" +#' @return A tibble with columns "chrom" (character, UCSC style), "pos" #' (integer), "A2" (character), "A1" (character). The detected convention is #' stored as \code{attr(result, "convention")}. #' @examples @@ -259,7 +314,7 @@ parseVariantId <- function(ids) { # non-matching id yields an all-NA capture row (mirrors strcapture). m <- str_match(normalized, "^([^:]+):([^:]+):([^:]+):([^:]+)") data <- tibble( - chrom = canonChrom(m[, 2L]), + chrom = withChrPrefix(m[, 2L]), pos = as.integer(m[, 3L]), A2 = m[, 4L], A1 = m[, 5L] @@ -274,7 +329,7 @@ parseVariantId <- function(ids) { .withCanonicalCoords <- function(ids) { # `value =` named: tibble's `[[<-` method carries an extra `j` formal, so a # third POSITIONAL argument binds to `j` and the write silently misfires. - coerced <- `[[<-`(ids, "chrom", value = canonChrom(ids$chrom)) + coerced <- `[[<-`(ids, "chrom", value = withChrPrefix(ids$chrom)) `[[<-`(coerced, "pos", value = as.integer(ids$pos)) } @@ -323,8 +378,10 @@ parseVariantId <- function(ids) { #' @param pos Integer position. #' @param A2 Character reference allele. #' @param A1 Character alternate/effect allele. -#' @param chrPrefix Logical, whether to add "chr" prefix. Default TRUE. Ignored -#' if \code{convention} is provided. +#' @param chrPrefix Logical. \code{TRUE} (default) spells the chromosome in UCSC +#' style (\code{chr1}, \code{chrX}, \code{chrM}); \code{FALSE} writes it +#' bare (\code{1}, \code{X}, \code{MT}). Ignored if \code{convention} is +#' provided. #' @param alleleSep Character, separator between pos/A2 and A2/A1 fields. #' Default \code{":"} produces canonical \code{"chr1:100:A:G"}; \code{"_"} #' produces mixed \code{"chr1:100_A_G"}. Ignored if \code{convention} is @@ -353,18 +410,12 @@ formatVariantId <- function( ":" } } - # Normalize the chromosome (strip prefix, uppercase, map synonyms) then - # re-add the "chr" prefix if requested. canonChrom keeps X/Y/MT as strings. - chromClean <- canonChrom(chrom) - if (chrPrefix) { - str_c("chr", chromClean, ":", pos, alleleSep, A2, alleleSep, A1) - } else { - str_c(chromClean, ":", pos, alleleSep, A2, alleleSep, A1) - } + # UCSC style is pecotmr's own; the bare form is for a consumer that wants + # it (canonChrom keeps X/Y/MT as strings). + chromOut <- if (chrPrefix) withChrPrefix(chrom) else canonChrom(chrom) + str_c(chromOut, ":", pos, alleleSep, A2, alleleSep, A1) } -# Backwards-compat alias for external callers - #' Re-format variant IDs to a chosen output convention #' #' Output-only convenience: parses variant IDs and re-emits them in a single @@ -380,8 +431,10 @@ formatVariantId <- function( #' name-based downstream consumers. #' #' @param ids A character vector of variant IDs in any supported format. -#' @param chrPrefix Logical, whether to include "chr" prefix. Default TRUE. -#' Ignored if \code{convention} is provided. +#' @param chrPrefix Logical. \code{TRUE} (default) writes the chromosome in +#' UCSC style (\code{chr1}, \code{chrM}), the style pecotmr uses +#' throughout; \code{FALSE} writes it bare. Ignored if \code{convention} is +#' provided. #' @param convention Optional list from \code{detectVariantConvention} or #' \code{attr(parseVariantId(ids), "convention")}. When provided, the output #' format is driven automatically by the detected convention. @@ -1180,122 +1233,6 @@ matchVariants <- function( ) } -# Backwards-compat alias for external callers - -#' Parse a region string into its components -#' -#' Split a region identifier (e.g. \code{"chr1:100-200"} or -#' \code{"chr1_100_200"}) into chromosome, start and end. Non-character or -#' non-scalar input is returned unchanged. -#' -#' @param region A single region string. -#' @return A vector/list with the chromosome, start and end, or the input -#' unchanged when it is not a scalar string. -#' @importFrom stringr str_split -#' @examples -#' parseRegion("chr1:1000000-2000000") -#' parseRegion("chr1_1000000_2000000") -#' @export -parseRegion <- function(region) { - if (!is.character(region) || length(region) != 1) { - return(region) - } - - # Both documented spellings: "chr1:100-200" and the underscore form - # "chr1_100_200" that LD-block / region ids use. MT and M are accepted - # alongside X/Y -- canonChrom() below exists precisely to normalize them, - # and rejecting them here made that unreachable. - pattern <- "^chr[0-9XYMTm]+(:[0-9]+-[0-9]+|_[0-9]+_[0-9]+)$" - if (!str_detect(region, pattern)) { - abort( - "Input string format must be 'chr:start-end' or 'chr_start_end'." - ) - } - parts <- str_split_1(region, "[:_-]") - tibble( - chrom = canonChrom(parts[1]), - start = as.integer(parts[2]), - end = as.integer(parts[3]) - ) -} - -#' Utility function to convert LD region_ids to `region of interest` dataframe -#' -#' The first field is treated as the chromosome and kept as a normalized string -#' (via \code{canonChrom}) so X/Y/MT survive; the remaining fields are genomic -#' positions and are returned as integers. -#' @param ldRegionId A string of region in the format of chrom_start_end. -#' @param colnames Character vector of length 3 giving output column names for -#' chromosome, start and end. Default \code{c("chrom", "start", "end")}. -#' @return A tibble with one row per input region and columns named by -#' \code{colnames}: a normalized character chromosome plus integer start/end. -#' @examples -#' regionToDf(c("1_100_200", "2_300_400")) -#' @importFrom checkmate assertCharacter -#' @export -regionToDf <- function(ldRegionId, colnames = c("chrom", "start", "end")) { - # @param says "A string", but the function is vectorised and callers pass - # a character vector -- assert what it actually accepts, not the prose. - assertCharacter(ldRegionId, any.missing = FALSE) - assertCharacter(colnames, len = 3L, any.missing = FALSE) - parts <- str_split(ldRegionId, "[_:-]", simplify = TRUE) - regionOfInterest <- `colnames<-`( - as_tibble(parts, .name_repair = "minimal"), - colnames - ) - regionOfInterest |> - mutate( - across(all_of(colnames[1]), canonChrom), - across(all_of(colnames[-1]), as.integer) - ) -} - -# Backwards-compat alias for external callers - -#' Convert region specifications to a GRanges object -#' -#' Accepts region strings ("chr1:100-200", "1_100_200"), character vectors of -#' such strings, or data.frames with chrom/start/end columns. Returns a -#' \code{\link[GenomicRanges]{GRanges}} object. -#' -#' @param regions A region string, character vector, or data.frame with -#' chrom/start/end columns. -#' @return A \code{GRanges} object. -#' @examples -#' regions <- c("chr1:100-200", "chr1:300-400") -#' asGranges(regions = regions) -#' @export -asGranges <- function(regions) { - if (is.character(regions)) { - df <- regionToDf(regions) - } else if (is.data.frame(regions)) { - if (!all(is_in(c("chrom", "start", "end"), names(regions)))) { - abort("data.frame must have columns: chrom, start, end") - } - df <- regions - } else { - msg <- glue( - "regions must be a character vector or data.frame with ", - "chrom/start/end columns" - ) - abort(msg) - } - # GRanges expects character seqnames; prefix with "chr" if numeric - rawChrom <- as.character(df$chrom) - seqnames <- if (any(str_detect(rawChrom, "^chr"))) { - rawChrom - } else { - str_c("chr", rawChrom) - } - GenomicRanges::GRanges( - seqnames = seqnames, - ranges = IRanges::IRanges( - start = as.integer(df$start), - end = as.integer(df$end) - ) - ) -} - #' Classify variant type from allele strings #' #' Determines whether each variant is a SNP, insertion, deletion, or @@ -1360,8 +1297,8 @@ classifyVariantType <- function(ids) { # Build the element GRanges for a set of variant ids. # # Ids that do not encode coordinates are a CONSTRUCTION ERROR. Substituting a -# synthetic range would make range() lie, and range() is the block identity that -# subsetRegion() and the (tuple, range) uniqueness key are both built on -- a +# synthetic range would make range() lie, and range() is the block identity the +# (tuple, range) uniqueness key is built on -- a # fabricated coordinate corrupts both silently. # @noRd .variantIdsToGRanges <- function(ids, what = "variant ids") { @@ -1391,7 +1328,7 @@ classifyVariantType <- function(ids) { } gr <- S4Vectors::`mcols<-`( GenomicRanges::GRanges( - withChrPrefix(parsed$chrom), + parsed$chrom, IRanges::IRanges(start = parsed$pos, width = 1L) ), value = S4Vectors::DataFrame( diff --git a/_pkgdown.yml b/_pkgdown.yml index 6d37ecd6..ebf5f9e3 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -153,7 +153,7 @@ reference: - ColocResult - CtwasResult - CtwasResultEntry - - fineMappingRow + - FineMappingRow - GenotypeMixture - GwasFineMappingResult - GwasSumStats @@ -169,7 +169,7 @@ reference: - qtlSumStatsFromZMatrix - SldscData - TwasWeights - - twasWeightsRow + - TwasWeightsRow - title: "Engine options and method parameters" desc: > @@ -238,6 +238,7 @@ reference: - EnsembleParam - FineMappingMethodsParam - GenotypeFilterParam + - PhenotypeFilterParam - GwasFineMappingParam - MashComponentParam - MashPriorParam @@ -292,7 +293,6 @@ reference: - flattenTupleRanges - nestTupleRanges - RangedTupleList-methods - - subsetRegion - updateObject-methods - subtitle: "FineMappingResultBase" @@ -316,8 +316,8 @@ reference: - variantIds - intersectVariants - resolveWeights - - exportToVcf - - exportToBed + - writeGwasVcf + - writeBed - readFineMappingResult - blockId @@ -344,8 +344,6 @@ reference: - subtitle: "ColocResultBase / ColocResult / ColocBoostResult" contents: - - "as.data.frame,ColocBoostResult-method" - - "as.data.frame,ColocResult-method" - colocViews - colocBoostOutcomes - computingTime @@ -359,31 +357,31 @@ reference: - ldReference - maf - nSamples + - sampleSize - variantColumnReplace + - fillFromReference - pval - qcDiagnostics - qcInfo + - qcOptions - se - studyName - variantIds - z - nSnps - - subsetChr - subtitle: "GwasSumStats" contents: - combineGwasSumStats - - sumStatsDataFrame - "sumStats,GwasSumStats-method" - varY - - exportToVcf + - writeGwasVcf - subtitle: "QtlSumStats" contents: - combineQtlSumStats - contexts - significantQtls - - sumStatsDataFrame - sumStats - traitPosition - traitNames @@ -407,8 +405,8 @@ reference: - variantIds - weights-methods - resolveWeights - - exportToVcf - - exportToBed + - writeGwasVcf + - writeBed - readTwasWeights - subtitle: "TwasWeightsRow" @@ -479,7 +477,6 @@ reference: - subtitle: "MultiStudyQtlDataset" contents: - - qtlDatasets - studyName - sumStats @@ -493,10 +490,8 @@ reference: - molecularTraits - residualizedGenotypes - residualizedPhenotypes - - scaleResiduals - studyName - traitPosition - - qtlDatasetFilters - subtitle: "SldscData" contents: @@ -589,9 +584,6 @@ reference: - parseVariantId - normalizeVariantId - classifyVariantType - - parseRegion - - regionToDf - - asGranges - genomicOrder - title: "Fine-mapping" @@ -644,7 +636,10 @@ reference: - glmnetWeights - lassoWeights - enetWeights + - ridgeWeights - lassosumRssWeights + - enetRssWeights + - ridgeRssWeights - mcpWeights - mcpRssWeights - scadWeights diff --git a/data/colocboostResultExample.rda b/data/colocboostResultExample.rda index e99140d5f29393d27e0f25c1d92a010ebc21de0a..7341fe87bbb2814270ac3bbf9959f985599f9bb6 100644 GIT binary patch delta 85 zcmbOszC?V2B#WCUciKi-CvMje-T4mJdXEH1Dy*A4>sN49!`|fD2gj{cdGe3{+j#ES oA-22cnEx;ULGTu>PYjIz#HRHyGI%d8%Ca-y?PdZ=Fh)iJ0J2LT@c;k- delta 73 zcmZ1?K0|zhB#Y}8?&yuOPTZEU66Y6j`@4B&ya_Lo$ad-MRax}*@Y+YO+H4pY7{t%5 dk78i_EcUgVk>T$@gI{(AyxmMdaR$c7C;$d{8s7i_ diff --git a/data/ctwasEstExample.rda b/data/ctwasEstExample.rda index 18d676b9984a5167c5c06bcee576781f566498b8..d4c11e0626129bd1ee97e35a63b43591bc20d82d 100644 GIT binary patch delta 244598 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

    xMQDpf%hngR-qHM{ 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 literal 211696 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

    ooiXB7Zol| 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ɤX} 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