diff --git a/.github/workflows/check-standard.yaml b/.github/workflows/check-standard.yaml index c33c512..3f5a748 100644 --- a/.github/workflows/check-standard.yaml +++ b/.github/workflows/check-standard.yaml @@ -31,6 +31,11 @@ jobs: steps: - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 17 + - uses: r-lib/actions/setup-pandoc@v2 - uses: r-lib/actions/setup-r@v2 diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 62da705..ae03aef 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -17,6 +17,11 @@ jobs: steps: - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 17 + - uses: r-lib/actions/setup-r@v2 with: use-public-rspm: true diff --git a/DESCRIPTION b/DESCRIPTION index 14b2477..d1e2d9c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,10 +1,10 @@ Package: rPHG2 Title: R interface to PHGv2 -Version: 0.1 +Version: 0.2 Authors@R: person( given = "Brandon", - family = "Last", + family = "Monier", email = "bm646@cornell.edu", role = c("aut", "cre"), comment = c(ORCID = "0000-0001-6797-1221") @@ -23,12 +23,16 @@ License: Apache License (>= 2) | file LICENSE Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.3.1 +Depends: + R (>= 4.1.0) Imports: cli, curl, + GenomicRanges, httr, jsonlite, methods, + rJava, tibble Suggests: testthat (>= 3.0.0) diff --git a/NAMESPACE b/NAMESPACE index a1dce58..60594c9 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,23 +1,48 @@ # Generated by roxygen2: do not edit by hand +export(PHGLocalCon) export(PHGServerCon) export(brapiURL) export(brapiVersion) +export(buildHaplotypeGraph) +export(hVcfFiles) export(host) export(httProtocol) +export(initPhg) +export(javaMemoryAddress) +export(javaRefObj) +export(numberOfChromosomes) +export(numberOfRefRanges) +export(numberOfTaxa) export(phgType) export(port) +export(readHapIdMetaData) +export(readHapIdPosMetaData) +export(readHapIds) export(readRefRanges) export(readSamples) export(serverInfo) +exportClasses(HaplotypeGraph) exportClasses(PHGCon) +exportClasses(PHGLocalCon) exportClasses(PHGServerCon) exportMethods(brapiURL) exportMethods(brapiVersion) +exportMethods(hVcfFiles) exportMethods(host) exportMethods(httProtocol) +exportMethods(javaMemoryAddress) +exportMethods(javaRefObj) +exportMethods(numberOfChromosomes) +exportMethods(numberOfRefRanges) +exportMethods(numberOfTaxa) exportMethods(phgType) exportMethods(port) +exportMethods(readHapIdMetaData) +exportMethods(readHapIdPosMetaData) +exportMethods(readHapIds) +exportMethods(readRefRanges) exportMethods(readSamples) exportMethods(serverInfo) importFrom(curl,has_internet) +importFrom(methods,is) diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..17d2b57 --- /dev/null +++ b/NEWS @@ -0,0 +1,22 @@ +## CHANGES IN 0.2 +* Added JVM connections via `rJava` interface +* Added new class, `HaplotypeGraph` + + Wrapper for PHGv2 API Java graph object +* Added new class, `PHGLocalCon` + + Interface to local hVCF database and file connections +* Added new function `initPHG()` + + Initializes JVM and adds PHGv2 Java JARs to classpath +* Added new function `readHapIds()` + + Reads haplotype IDs as a `character` matrix from a connection object +* Added new function `readHapIdMetaData()` + + Reads ALT header metadata for each haplotype ID from a connection object +* Added new function `readHapIdPosMetaData()` + + Reads ALT header positional metadata for each haplotype ID from a + connection object +* Added new function `readSamples()` + + Reads sample IDs from a connection object +* Added new function `readRefRanges()` + + Read reference range positional information as a `GRanges` object from a + connection object + + diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..b16061b --- /dev/null +++ b/NEWS.md @@ -0,0 +1,22 @@ +## rPHG2 0.2 +* Added JVM connections via `rJava` interface +* Added new class, `HaplotypeGraph` + + Wrapper for PHGv2 API Java graph object +* Added new class, `PHGLocalCon` + + Interface to local hVCF database and file connections +* Added new function `initPHG()` + + Initializes JVM and adds PHGv2 Java JARs to classpath +* Added new function `readHapIds()` + + Reads haplotype IDs as a `character` matrix from a connection object +* Added new function `readHapIdMetaData()` + + Reads ALT header metadata for each haplotype ID from a connection object +* Added new function `readHapIdPosMetaData()` + + Reads ALT header positional metadata for each haplotype ID from a + connection object +* Added new function `readSamples()` + + Reads sample IDs from a connection object +* Added new function `readRefRanges()` + + Read reference range positional information as a `GRanges` object from a + connection object + + diff --git a/R/class_all_generics.R b/R/class_all_generics.R index 0c278b3..191afb8 100644 --- a/R/class_all_generics.R +++ b/R/class_all_generics.R @@ -54,6 +54,90 @@ setGeneric("host", function(object, ...) standardGeneric("host")) setGeneric("httProtocol", function(object, ...) standardGeneric("httProtocol")) +## ---- +#' @title Return hVCF files +#' +#' @description +#' Returns a list of hVCF files. +#' +#' @param object an \code{rPHG} local connection object +#' @param ... Additional arguments, for use in specific methods +#' +#' @rdname hVcfFiles +#' @export +setGeneric("hVcfFiles", function(object, ...) standardGeneric("hVcfFiles")) + + +## ---- +#' @title Return \code{rJava} reference object +#' +#' @description +#' Returns the \code{rJava} memory reference for a given \code{rPHG} object +#' +#' @param object an \code{rPHG} local or server connection object +#' @param ... Additional arguments, for use in specific methods +#' +#' @rdname javaMemoryAddress +#' @export +setGeneric("javaMemoryAddress", function(object, ...) standardGeneric("javaMemoryAddress")) + + +## ---- +#' @title Return \code{rJava} reference object +#' +#' @description +#' Returns the \code{rJava} memory reference for a given \code{rPHG} object +#' +#' @param object an \code{rPHG} local or server connection object +#' @param ... Additional arguments, for use in specific methods +#' +#' @rdname javaRefObj +#' @export +setGeneric("javaRefObj", function(object, ...) standardGeneric("javaRefObj")) + + +## ---- +#' @title Return number of chromosomes +#' +#' @description +#' Returns the number of chromosomes for a given object +#' +#' @param object an \code{rPHG} local or server connection object +#' @param ... Additional arguments, for use in specific methods +#' +#' @rdname numberOfChromosomes +#' @export +setGeneric("numberOfChromosomes", function(object, ...) standardGeneric("numberOfChromosomes")) + + +## ---- +#' @title Return number of reference ranges +#' +#' @description +#' Returns the number of reference ranges for a given object +#' +#' @param object an \code{rPHG} local or server connection object +#' @param ... Additional arguments, for use in specific methods +#' +#' @rdname numberOfRefRanges +#' @export +setGeneric("numberOfRefRanges", function(object, ...) standardGeneric("numberOfRefRanges")) + + +## ---- +#' @title Return number of taxa +#' +#' @description +#' Returns the number of taxa for a given object +#' +#' @param object an \code{rPHG} local or server connection object +#' @param ... Additional arguments, for use in specific methods +#' +#' @rdname numberOfTaxa +#' @export +setGeneric("numberOfTaxa", function(object, ...) standardGeneric("numberOfTaxa")) + + ## ---- #' @title Return type of PHG connection #' @@ -82,11 +166,57 @@ setGeneric("phgType", function(object, ...) standardGeneric("phgType")) setGeneric("port", function(object, ...) standardGeneric("port")) +## ---- +#' @title Return haplotype IDs +#' +#' @description +#' Gets haplotype ID for given samples and reference ranges from a +#' \code{HaplotypeGraph} +#' +#' @param object an \code{rPHG} local or server connection object +#' @param nThreads Number of threads to use when evaluating haplotype IDs +#' @param ... Additional arguments, for use in specific methods +#' +#' @rdname readHapIds +#' @export +setGeneric("readHapIds", function(object, nThreads, ...) standardGeneric("readHapIds")) + + +## ---- +#' @title Return haplotype ID metadata +#' +#' @description +#' Gets haplotype ID metadata for given samples and reference ranges from a +#' \code{HaplotypeGraph} +#' +#' @param object an \code{rPHG} local or server connection object +#' @param ... Additional arguments, for use in specific methods +#' +#' @rdname readHapIdMetaData +#' @export +setGeneric("readHapIdMetaData", function(object, ...) standardGeneric("readHapIdMetaData")) + + +## ---- +#' @title Return haplotype ID positional metadata +#' +#' @description +#' Gets haplotype ID positional metadata for given samples and reference ranges +#' from a \code{HaplotypeGraph} +#' +#' @param object an \code{rPHG} local or server connection object +#' @param ... Additional arguments, for use in specific methods +#' +#' @rdname readHapIdPosMetaData +#' @export +setGeneric("readHapIdPosMetaData", function(object, ...) standardGeneric("readHapIdPosMetaData")) + + ## ---- #' @title Return reference ranges #' #' @description -#' Get reference range data for a given PHG method +#' Get reference range data from a \code{HaplotypeGraph} #' #' @param object an \code{rPHG} local or server connection object #' @param ... Additional arguments, for use in specific methods @@ -100,7 +230,7 @@ setGeneric("readRefRanges", function(object, ...) standardGeneric("readRefRanges #' @title Return samples IDs #' #' @description -#' Gets sample ID data for a given PHG method +#' Gets sample ID data from a \code{HaplotypeGraph} #' #' @param object an \code{rPHG} local or server connection object #' @param ... Additional arguments, for use in specific methods diff --git a/R/class_haplotype_graph.R b/R/class_haplotype_graph.R new file mode 100644 index 0000000..369bb6d --- /dev/null +++ b/R/class_haplotype_graph.R @@ -0,0 +1,264 @@ +## ---- +#' @title A HaplotypeGraph Class +#' +#' @description +#' Class \code{HaplotypeGraph} defines a \code{rPHG} Class for storing +#' a \code{HaplotypeGraph} object defined in the PHG API +#' +#' @slot nChrom Number of chromosomes +#' @slot nRefRanges Number of reference ranges +#' @slot nTaxa Number of taxa +#' @slot jHapGraph An \code{rJava} \code{jobjRef} object representing a +#' \code{HaplotypeGraph} class in the PHG API +#' @slot jMemAddress An identifier string to the JVM memory space +#' +#' @name HaplotypeGraph-class +#' @rdname HaplotypeGraph-class +#' @exportClass HaplotypeGraph +setClass( + Class = "HaplotypeGraph", + slots = c( + nChrom = "integer", + nRefRanges = "integer", + nTaxa = "integer", + jHapGraph = "jobjRef", + jMemAddress = "character" + ), + prototype = list( + nChrom = NA_integer_, + nRefRanges = NA_integer_, + nTaxa = NA_integer_, + jHapGraph = rJava::.jnull(), + jMemAddress = NA_character_ + ) +) + + +## ---- +#' @title HaplotypeGraph validation +#' +#' @name HaplotypeGraph-validity +#' +#' @description Checks if \code{HaplotypeGraph} class objects are valid. +#' +#' @param object A \code{HaplotypeGraph} object. +#' +#' @importFrom curl has_internet +setValidity("HaplotypeGraph", function(object) { + errors <- character() + + jObjRef <- javaRefObj(object) + + if (!any(names(jObjRef) == "getClass()")) { + msg <- "Could not find `getClass()` getter from reference object" + errors <- c(errors, msg) + } + + jObjRefClass <- jObjRef$getClass()$getName() + if (jObjRefClass != PHG_JVM$HAP_GRAPH) { + msg <- "Reference object is not of type `HaplotypeGraph`" + errors <- c(errors, msg) + } + + if (length(errors) == 0) TRUE else errors +}) + + +## ---- +#' @title Helper function to build HaplotypeGraph object +#' +#' @description +#' Creates a \code{\linkS4class{HaplotypeGraph}} object to be used to build and store +#' an \code{rJava} reference object pointing to a \code{HaplotypeGraph} object +#' from the PHG API. +#' +#' @param phgLocalCon A \code{\linkS4class{PHGLocalCon}} object. +#' +#' @importFrom methods is +#' +#' @export +buildHaplotypeGraph <- function( + phgLocalCon +) { + if (!is(phgLocalCon, "PHGLocalCon")) { + stop("phgLocalCon object is not of type PHGLocalCon") + } + + if (!is.na(host(phgLocalCon))) { + stop("TileDB retrieval methods currently not implemented") + } else { + jvmGraph <- hapGraphConstructor(hVcfFiles(phgLocalCon)) + } + + pointer <- gsub(".*@", "", rJava::.jstrVal(jvmGraph)) + + methods::new( + Class = "HaplotypeGraph", + nChrom = jvmGraph$getContigs()$size(), + nRefRanges = jvmGraph$numberOfRanges(), + nTaxa = jvmGraph$numberOfSamples(), + jHapGraph = jvmGraph, + jMemAddress = pointer + ) +} + + + +# /// Methods (show) //////////////////////////////////////////////// + +## ---- +#' @title Show methods for HaplotypeGraph objects +#' +#' @description +#' Prints out information regarding properties from the \code{HaplotypeGraph} +#' class to the console +#' +#' @param object A \code{\linkS4class{HaplotypeGraph}} object +#' +#' @docType methods +#' @rdname HaplotypeGraph-class +#' @aliases show,HaplotypeGraph-method +setMethod( + f = "show", + signature = "HaplotypeGraph", + definition = function(object) { + pointerSymbol <- cli::col_green(cli::symbol$pointer) + + msg <- c( + paste0( + "A ", cli::style_bold("HaplotypeGraph"), " object @ ", + cli::style_bold(cli::col_blue(javaMemoryAddress(object))) + ), + paste0(" ", pointerSymbol, " # of ref ranges....: ", numberOfRefRanges(object)), + paste0(" ", pointerSymbol, " # of taxa..........: ", numberOfTaxa(object)), + paste0(" ", pointerSymbol, " # of chromosomes...: ", numberOfChromosomes(object)) + ) + + cat(msg, sep = "\n") + } +) + + + +# /// Methods (general) ///////////////////////////////////////////// + +## ---- +#' @rdname javaMemoryAddress +#' @export +setMethod( + f = "javaMemoryAddress", + signature = signature(object = "HaplotypeGraph"), + definition = function(object) { + return(object@jMemAddress) + } +) + + +## ---- +#' @rdname javaRefObj +#' @export +setMethod( + f = "javaRefObj", + signature = signature(object = "HaplotypeGraph"), + definition = function(object) { + return(object@jHapGraph) + } +) + + +## ---- +#' @rdname numberOfChromosomes +#' @export +setMethod( + f = "numberOfChromosomes", + signature = signature(object = "HaplotypeGraph"), + definition = function(object) { + return(object@nChrom) + } +) + + +## ---- +#' @rdname numberOfRefRanges +#' @export +setMethod( + f = "numberOfRefRanges", + signature = signature(object = "HaplotypeGraph"), + definition = function(object) { + return(object@nRefRanges) + } +) + + +## ---- +#' @rdname numberOfTaxa +#' @export +setMethod( + f = "numberOfTaxa", + signature = signature(object = "HaplotypeGraph"), + definition = function(object) { + return(object@nTaxa) + } +) + + +## ---- +#' @rdname readHapIds +#' @export +setMethod( + f = "readHapIds", + signature = signature(object = "HaplotypeGraph"), + definition = function(object, nThreads = 1) { + return(hapIdsFromJvmGraph(javaRefObj(object), nThreads)) + } +) + + +## ---- +#' @rdname readHapIdMetaData +#' @export +setMethod( + f = "readHapIdMetaData", + signature = signature(object = "HaplotypeGraph"), + definition = function(object) { + return(hapIdMetaDataFromJvmGraph(javaRefObj(object))) + } +) + + +## ---- +#' @rdname readHapIdPosMetaData +#' @export +setMethod( + f = "readHapIdPosMetaData", + signature = signature(object = "HaplotypeGraph"), + definition = function(object) { + return(hapIdPosMetaDataFromJvmGraph(javaRefObj(object))) + } +) + + +## ---- +#' @rdname readRefRanges +#' @export +setMethod( + f = "readRefRanges", + signature = signature(object = "HaplotypeGraph"), + definition = function(object) { + return(refRangesFromJvmGraph(javaRefObj(object))) + } +) + + +## ---- +#' @rdname readSamples +#' @export +setMethod( + f = "readSamples", + signature = signature(object = "HaplotypeGraph"), + definition = function(object) { + return(samplesFromJvmGraph(javaRefObj(object))) + } +) + + diff --git a/R/class_phg_con_local.R b/R/class_phg_con_local.R new file mode 100644 index 0000000..ec415f3 --- /dev/null +++ b/R/class_phg_con_local.R @@ -0,0 +1,129 @@ +## ---- +#' @title A PHGLocalCon Class +#' +#' @description +#' A \code{PHGLocalCon} class defines a \code{rPHG} class for storing +#' local config file data. +#' +#' @slot hVcfFiles A list of hVCF files +#' +#' @name PHGLocalCon-class +#' @rdname PHGLocalCon-class +#' @exportClass PHGLocalCon +setClass( + Class = "PHGLocalCon", + contains = "PHGCon", + representation = representation( + hVcfFiles = "character" + ), + prototype = prototype( + hVcfFiles = NA_character_ + ) +) + + +## ---- +#' @title PHGLocalCon validation +#' +#' @name PHGLocalCon-validity +#' +#' @description +#' Checks for correct data entry into \code{PHGLocalCon} class +#' +#' @param object A \code{\linkS4class{PHGLocalCon}} object +setValidity("PHGLocalCon", function(object) { + errors <- character() + + if (!dir.exists(host(object)) && !is.na(host(object))) { + errors <- c("TileDB URI path does not exist", errors) + } + + if (length(errors) == 0) { + return(TRUE) + } else { + return(errors) + } +}) + + +## ---- +#' @title Helper function to construct a \code{PHGLocalCon} object +#' +#' @description +#' Creates a \code{\linkS4class{PHGLocalCon}} object to be used to read PHG +#' DB data for a given set of PHG-related methods. +#' +#' @param hVcfFiles +#' A list of \href{https://github.com/maize-genetics/phg_v2/blob/main/docs/hvcf_specifications.md}{hVCF} +#' files as a \code{character} vector +#' +#' @export +PHGLocalCon <- function(hVcfFiles) { + # This is probably overkill right now, but will revisit once the TileDB + # C API is better integrated in PHGv2... + methods::new( + Class = "PHGLocalCon", + phgType = "local", + host = NA_character_, # making this NA for now + hVcfFiles = normalizePath(hVcfFiles) + ) +} + + + +# /// Methods (show) //////////////////////////////////////////////// + +## ---- +#' @title Show methods for PHGLocalCon objects +#' +#' @description +#' Prints out information regarding properties from the \code{PHGLocalCon} +#' class to the console +#' +#' @param object A \code{\linkS4class{PHGLocalCon}} object +#' +#' @docType methods +#' @rdname PHGLocalCon-class +#' @aliases show,PHGLocalCon-method +setMethod( + f = "show", + signature = "PHGLocalCon", + definition = function(object) { + pointerSymbol <- cli::col_green(cli::symbol$pointer) + present <- cli::col_green(cli::symbol$radio_on) + absent <- cli::col_grey(cli::symbol$radio_off) + + dbUriStatus <- ifelse(is.na(object@host), absent, present) + + if (any(is.na(object@hVcfFiles))) { + hVcfStatus <- absent + } else { + hVcfStatus <- present + } + + msg <- c( + paste0("A ", cli::style_bold("PHGLocalCon"), " connection object"), + paste0(" ", pointerSymbol, " DB URI.... : ", dbUriStatus), + paste0(" ", pointerSymbol, " hVCF Files...: ", hVcfStatus) + ) + + cat(msg, sep = "\n") + } +) + + + +# /// Methods (general) ///////////////////////////////////////////// + +## ---- +#' @rdname hVcfFiles +#' @export +setMethod( + f = "hVcfFiles", + signature = signature(object = "PHGLocalCon"), + definition = function(object) { + return(object@hVcfFiles) + } +) + + diff --git a/R/constants.R b/R/constants.R index 26cdfeb..dd56f87 100644 --- a/R/constants.R +++ b/R/constants.R @@ -31,3 +31,13 @@ BRAPI_PARAMS <- list( ) +## ---- +# Commonly used JVM and PHG API classes +PHG_JVM <- list( + "ARRAY_LIST" = "java.util.ArrayList", + "HAP_GRAPH" = "net.maizegenetics.phgv2.api.HaplotypeGraph", + "LIST" = "java/util/List", + "R_METHODS" = "net.maizegenetics.phgv2.rphg.RMethods" +) + + diff --git a/R/read_hap_id_metadata.R b/R/read_hap_id_metadata.R new file mode 100644 index 0000000..77fea05 --- /dev/null +++ b/R/read_hap_id_metadata.R @@ -0,0 +1,13 @@ +## ---- +# Get alt headers (hap ID metadata) from JVM graph object +# +# @param jvmGraph A JVM graph object +hapIdMetaDataFromJvmGraph <- function(jvmGraph) { + interface <- createRMethodInterface() + + ahDf <- interface$getAltHeadersFromGraph(jvmGraph) |> kotlinListToRDataFrame() + + return(ahDf) +} + + diff --git a/R/read_hap_id_pos_metadata.R b/R/read_hap_id_pos_metadata.R new file mode 100644 index 0000000..b91aa98 --- /dev/null +++ b/R/read_hap_id_pos_metadata.R @@ -0,0 +1,14 @@ +## ---- +# Get positional data from alt headers (hap ID metadata) from JVM graph object +# +# @param jvmGraph A JVM graph object +hapIdPosMetaDataFromJvmGraph <- function(jvmGraph) { + interface <- createRMethodInterface() + + ahPosDf <- interface$getAltHeaderPositionsFromGraph(jvmGraph) |> kotlinListToRDataFrame() + + return(ahPosDf) +} + + + diff --git a/R/read_hap_ids.R b/R/read_hap_ids.R new file mode 100644 index 0000000..f6c57fc --- /dev/null +++ b/R/read_hap_ids.R @@ -0,0 +1,19 @@ +## ---- +# Get haplotype IDs from JVM graph object +# +# @param jvmGraph A JVM graph object +# @param nThreads Number of threads to use during evaluation +# +# @return A matrix of character elements +hapIdsFromJvmGraph <- function(jvmGraph, nThreads) { + # Ensure integer type + nThreads <- as.integer(nThreads) + + interface <- createRMethodInterface() + jm <- interface$getHapIdMatrixFromGraph(jvmGraph, nThreads) + rm <- jm |> kotlin2DArrayToRMatrix() + + return(rm) +} + + diff --git a/R/read_ref_ranges.R b/R/read_ref_ranges.R new file mode 100644 index 0000000..feb428b --- /dev/null +++ b/R/read_ref_ranges.R @@ -0,0 +1,17 @@ +## ---- +# Get ref ranges from JVM graph object +# +# @param jvmGraph A JVM graph object +refRangesFromJvmGraph <- function(jvmGraph) { + interface <- createRMethodInterface() + + jrr <- interface$getRefRangesFromGraph(jvmGraph) + + rrr <- jrr |> + kotlinListToRDataFrame() |> + GenomicRanges::makeGRangesFromDataFrame() + + return(rrr) +} + + diff --git a/R/read_samples.R b/R/read_samples.R index 9b89a4f..9cf4321 100644 --- a/R/read_samples.R +++ b/R/read_samples.R @@ -16,3 +16,16 @@ samplesFromServer <- function(conObj, conMethod, conDemo) { } +## ---- +# Get samples from JVM graph object +# +# @param jvmGraph A JVM graph object +samplesFromJvmGraph <- function(jvmGraph) { + jvmGraph$samples()$toArray() |> + rJava::.jevalArray() |> + vapply(\(it) { + it$toString() + }, "character") +} + + diff --git a/R/utilities_api_brapi.R b/R/utils_api_brapi.R similarity index 100% rename from R/utilities_api_brapi.R rename to R/utils_api_brapi.R diff --git a/R/utils_jvm.R b/R/utils_jvm.R new file mode 100644 index 0000000..8f50de7 --- /dev/null +++ b/R/utils_jvm.R @@ -0,0 +1,76 @@ +## ---- +# Create connection to RMethods class in PHGv2 +createRMethodInterface <- function() { + jrc <- PHG_JVM$R_METHODS + interface <- rJava::.jnew(jrc) + + return(interface) +} + + +## ---- +# Constructor for instantiating a PHGv2 HaplotypeGraph object +# +# @param l A list of hVCF files +hapGraphConstructor <- function(l) { + hvcfJList <- rJava::.jnew(PHG_JVM$ARRAY_LIST) + lapply(l, function(i) hvcfJList$add(i)) + hvcfJList <- rJava::.jcast(hvcfJList, PHG_JVM$LIST) + + jvmGraph <- rJava::.jnew(PHG_JVM$HAP_GRAPH, hvcfJList) + + return(jvmGraph) +} + + +## ---- +#' Initialize JVM and add class path (for R&D purposes only) +#' +#' @param phgPath path to PHGv2 lib folder +#' @param verbose Display all JARs added classpath? Defaults to FALSE. +#' +#' @export +initPhg <- function(phgPath, verbose = TRUE) { + rJava::.jinit() + rJava::.jaddClassPath(dir(phgPath, full.names = TRUE)) + + if (verbose) message("PHG JARs added to class path") +} + + +## ---- +# Convert a PHG/Kotlin RList object into an R data frame +# +# @param kl A PHG/Kotlin RList object +kotlinListToRDataFrame <- function(kl) { + if (!grepl("phgv2_r_list", kl$toString())) { + stop("Object does not have a 'RList' signature") + } + + rdf <- kl$getMatrixData() |> + as.list() |> + lapply(rJava::.jevalArray, simplify = TRUE) + + names(rdf) <- kl$getColNames() + + return(tibble::as_tibble(rdf)) +} + + +## ----- +# Convert a PHG/Kotlin (Int|Dbl|String)Matrix into an R matrix +# +# @param kmat A PHG/Kotlin (Int|Dbl|String)Matrix object +kotlin2DArrayToRMatrix <- function(kmat) { + if (!grepl("MatrixWithNames", kmat$getClass()$toString())) { + stop("Object does not have a 'MatrixWithNames' signature") + } + + rmat <- kmat$getMatrixData() |> rJava::.jevalArray(simplify = TRUE) + colnames(rmat) <- kmat$getColNames() + rownames(rmat) <- kmat$getRowNames() + + return(rmat) +} + + diff --git a/inst/extdata/LineA.h.vcf b/inst/extdata/LineA.h.vcf new file mode 100644 index 0000000..f5cf1f7 --- /dev/null +++ b/inst/extdata/LineA.h.vcf @@ -0,0 +1,94 @@ +##fileformat=VCFv4.2 +##FILTER= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##contig= +##contig= +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT LineA +1 1 . G <12f0cec9102e84a161866e37072443b7> . . END=1000 GT:AD:DP 1:0,2,0:2 +1 1001 . A <3149b3144f93134eb29661bade697fc6> . . END=5500 GT:AD:DP 1:0,2,0:2 +1 5501 . A <1b568197f6f329ec5b71f66e49a732fb> . . END=6500 GT:AD:DP 1:0,2,0:2 +1 6501 . C <369464a8743d2e40ad83d1375c196bdd> . . END=11000 GT:AD:DP 1:0,2,0:2 +1 11001 . A . . END=12000 GT:AD:DP 1:0,2,0:2 +1 12001 . A . . END=16500 GT:AD:DP 1:0,2,0:2 +1 16501 . A <18498579d89483ac270e8cca57f34752> . . END=17500 GT:AD:DP 1:0,2,0:2 +1 17501 . C <8e5dbf7df5b265ba5daf35c4dfdf8a39> . . END=22000 GT:AD:DP 1:0,2,0:2 +1 22001 . C . . END=23000 GT:AD:DP 1:0,2,0:2 +1 23001 . G . . END=27500 GT:AD:DP 1:0,2,0:2 +1 27501 . G <64747625066ac7d3477cca8ecfa46ed1> . . END=28500 GT:AD:DP 1:0,2,0:2 +1 28501 . C . . END=33000 GT:AD:DP 1:0,2,0:2 +1 33001 . C <5a2ff3fb844d5647987da5c194d1c728> . . END=34000 GT:AD:DP 1:0,2,0:2 +1 34001 . A . . END=38500 GT:AD:DP 1:0,2,0:2 +1 38501 . C . . END=39500 GT:AD:DP 1:0,2,0:2 +1 39501 . G . . END=44000 GT:AD:DP 1:0,2,0:2 +1 44001 . G . . END=45000 GT:AD:DP 1:0,2,0:2 +1 45001 . G <5ae13475e95253ee352dda4875dc9f7c> . . END=49500 GT:AD:DP 1:0,2,0:2 +1 49501 . G <5be0e52ccfe573a6e42e4dd1e8658105> . . END=50500 GT:AD:DP 1:0,2,0:2 +2 1 . C <13417ecbb38b9a159e3ca8c9dade7088> . . END=1000 GT:AD:DP 1:0,2,0:2 +2 1001 . A . . END=5500 GT:AD:DP 1:0,2,0:2 +2 5501 . G <50044914d5111c5b5ec58c9d720e3b2d> . . END=6500 GT:AD:DP 1:0,2,0:2 +2 6501 . A . . END=11000 GT:AD:DP 1:0,2,0:2 +2 11001 . A <3ec680649615da0685b8c245e0f196e2> . . END=12000 GT:AD:DP 1:0,2,0:2 +2 12001 . A <184a72815a2ba5949635cc38769cedd0> . . END=16500 GT:AD:DP 1:0,2,0:2 +2 16501 . A <1e38bd82670c3f10982f70390c599a8d> . . END=17500 GT:AD:DP 1:0,2,0:2 +2 17501 . G . . END=22000 GT:AD:DP 1:0,2,0:2 +2 22001 . A . . END=23000 GT:AD:DP 1:0,2,0:2 +2 23001 . C <74ffef78af08b12ba1c7876206570e26> . . END=27500 GT:AD:DP 1:0,2,0:2 +2 27501 . G . . END=28500 GT:AD:DP 1:0,2,0:2 +2 28501 . A . . END=33000 GT:AD:DP 1:0,2,0:2 +2 33001 . G <90248144d7173c1f1481008c43e65129> . . END=34000 GT:AD:DP 1:0,2,0:2 +2 34001 . A . . END=38500 GT:AD:DP 1:0,2,0:2 +2 38501 . A <539d334104090326aa72b38e4b353cc0> . . END=39500 GT:AD:DP 1:0,2,0:2 +2 39501 . A <51a185c08bf7fac70a60abfeaefc2c90> . . END=44000 GT:AD:DP 1:0,2,0:2 +2 44001 . G . . END=45000 GT:AD:DP 1:0,2,0:2 +2 45001 . A <565c967a46f12cd0bf458fe366cdc6db> . . END=49500 GT:AD:DP 1:0,2,0:2 +2 49501 . G <0eb9029f3896313aebc69c8489923141> . . END=50500 GT:AD:DP 1:0,2,0:2 diff --git a/inst/extdata/LineB.h.vcf b/inst/extdata/LineB.h.vcf new file mode 100644 index 0000000..ff0604b --- /dev/null +++ b/inst/extdata/LineB.h.vcf @@ -0,0 +1,93 @@ +##fileformat=VCFv4.2 +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##contig= +##contig= +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT LineB +1 1 . G <4fc7b8af32ddd74e07cb49d147ef1938> . . END=1000 GT:AD:DP 1:0,2,0:2 +1 1001 . A <8967fabf10e55d881caa6fe192e7d4ca> . . END=5500 GT:AD:DP 1:0,2,0:2 +1 5501 . A <05efe15d97db33185b64821791b01b0f> . . END=6500 GT:AD:DP 1:0,2,0:2 +1 6501 . C <8f7de1a693aa15fb8fb7b85e7a8b5e95> . . END=11000 GT:AD:DP 1:0,2,0:2 +1 11001 . A <6b5f46bd5c31917af3ab6c3ccc8668cd> . . END=12000 GT:AD:DP 1:0,2,0:2 +1 12001 . A . . END=16500 GT:AD:DP 1:0,2,0:2 +1 16501 . A . . END=17500 GT:AD:DP 1:0,2,0:2 +1 17501 . C . . END=22000 GT:AD:DP 1:0,2,0:2 +1 22001 . C . . END=23000 GT:AD:DP 1:0,2,0:2 +1 23001 . G <39c0c13208f7990489337408cf980b79> . . END=27500 GT:AD:DP 1:0,2,0:2 +1 27501 . G . . END=28500 GT:AD:DP 1:0,2,0:2 +1 28501 . C <00f297caa4a0fa5a6f8e76d388393fa7> . . END=33000 GT:AD:DP 1:0,2,0:2 +1 33001 . C <79146831745c85d26117f13b5873935f> . . END=34000 GT:AD:DP 1:0,2,0:2 +1 34001 . A <25413a93cd7622fa44d015d6914f344d> . . END=38500 GT:AD:DP 1:0,2,0:2 +1 38501 . C <5d5381ccc68ac93826334f634578672e> . . END=39500 GT:AD:DP 1:0,2,0:2 +1 39501 . G <18dcf42d7b02fd603e05e3714fa71e95> . . END=44000 GT:AD:DP 1:0,2,0:2 +1 44001 . G . . END=45000 GT:AD:DP 1:0,2,0:2 +1 45001 . G <7e388530fa03aa2ab21b3cd10a438f5a> . . END=49500 GT:AD:DP 1:0,2,0:2 +1 49501 . G . . END=50500 GT:AD:DP 1:0,2,0:2 +2 1 . C <180417a01edbfed525d7c238910e0ff4> . . END=1000 GT:AD:DP 1:0,2,0:2 +2 1001 . A <8bcf66e8c49da2d9ad8cbafa0bb7a93d> . . END=5500 GT:AD:DP 1:0,2,0:2 +2 5501 . G <45b121547c7ae517a181fdd2621495c4> . . END=6500 GT:AD:DP 1:0,2,0:2 +2 6501 . A . . END=11000 GT:AD:DP 1:0,2,0:2 +2 11001 . A . . END=12000 GT:AD:DP 1:0,2,0:2 +2 12001 . A <6fb2de47c835bd9ab026c02d62f49807> . . END=16500 GT:AD:DP 1:0,2,0:2 +2 16501 . A . . END=17500 GT:AD:DP 1:0,2,0:2 +2 17501 . G . . END=22000 GT:AD:DP 1:0,2,0:2 +2 22001 . A . . END=23000 GT:AD:DP 1:0,2,0:2 +2 23001 . C <261f7e63beed04e2500a9d8ae867e4ab> . . END=27500 GT:AD:DP 1:0,2,0:2 +2 27501 . G . . END=28500 GT:AD:DP 1:0,2,0:2 +2 28501 . A <8f2731708b30e1c402c6d6a69a983fe4> . . END=33000 GT:AD:DP 1:0,2,0:2 +2 33001 . G . . END=34000 GT:AD:DP 1:0,2,0:2 +2 34001 . A . . END=38500 GT:AD:DP 1:0,2,0:2 +2 38501 . A <4df3ac835af83a9b5bf80d4e4850627d> . . END=39500 GT:AD:DP 1:0,2,0:2 +2 39501 . A . . END=44000 GT:AD:DP 1:0,2,0:2 +2 44001 . G <12ea83315f749ee2f2b38b631d8115f0> . . END=45000 GT:AD:DP 1:0,2,0:2 +2 45001 . A . . END=49500 GT:AD:DP 1:0,2,0:2 +2 49501 . G <5031218d4ac709dd51a946acd0550356> . . END=50500 GT:AD:DP 1:0,2,0:2 diff --git a/man/HaplotypeGraph-class.Rd b/man/HaplotypeGraph-class.Rd new file mode 100644 index 0000000..e0dd04e --- /dev/null +++ b/man/HaplotypeGraph-class.Rd @@ -0,0 +1,35 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_haplotype_graph.R +\docType{class} +\name{HaplotypeGraph-class} +\alias{HaplotypeGraph-class} +\alias{show,HaplotypeGraph-method} +\title{A HaplotypeGraph Class} +\usage{ +\S4method{show}{HaplotypeGraph}(object) +} +\arguments{ +\item{object}{A \code{\linkS4class{HaplotypeGraph}} object} +} +\description{ +Class \code{HaplotypeGraph} defines a \code{rPHG} Class for storing +a \code{HaplotypeGraph} object defined in the PHG API + +Prints out information regarding properties from the \code{HaplotypeGraph} +class to the console +} +\section{Slots}{ + +\describe{ +\item{\code{nChrom}}{Number of chromosomes} + +\item{\code{nRefRanges}}{Number of reference ranges} + +\item{\code{nTaxa}}{Number of taxa} + +\item{\code{jHapGraph}}{An \code{rJava} \code{jobjRef} object representing a +\code{HaplotypeGraph} class in the PHG API} + +\item{\code{jMemAddress}}{An identifier string to the JVM memory space} +}} + diff --git a/man/HaplotypeGraph-validity.Rd b/man/HaplotypeGraph-validity.Rd new file mode 100644 index 0000000..ba19bef --- /dev/null +++ b/man/HaplotypeGraph-validity.Rd @@ -0,0 +1,11 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_haplotype_graph.R +\name{HaplotypeGraph-validity} +\alias{HaplotypeGraph-validity} +\title{HaplotypeGraph validation} +\arguments{ +\item{object}{A \code{HaplotypeGraph} object.} +} +\description{ +Checks if \code{HaplotypeGraph} class objects are valid. +} diff --git a/man/PHGLocalCon-class.Rd b/man/PHGLocalCon-class.Rd new file mode 100644 index 0000000..b3c8910 --- /dev/null +++ b/man/PHGLocalCon-class.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_phg_con_local.R +\docType{class} +\name{PHGLocalCon-class} +\alias{PHGLocalCon-class} +\alias{show,PHGLocalCon-method} +\title{A PHGLocalCon Class} +\usage{ +\S4method{show}{PHGLocalCon}(object) +} +\arguments{ +\item{object}{A \code{\linkS4class{PHGLocalCon}} object} +} +\description{ +A \code{PHGLocalCon} class defines a \code{rPHG} class for storing +local config file data. + +Prints out information regarding properties from the \code{PHGLocalCon} +class to the console +} +\section{Slots}{ + +\describe{ +\item{\code{hVcfFiles}}{A list of hVCF files} +}} + diff --git a/man/PHGLocalCon-validity.Rd b/man/PHGLocalCon-validity.Rd new file mode 100644 index 0000000..839485d --- /dev/null +++ b/man/PHGLocalCon-validity.Rd @@ -0,0 +1,11 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_phg_con_local.R +\name{PHGLocalCon-validity} +\alias{PHGLocalCon-validity} +\title{PHGLocalCon validation} +\arguments{ +\item{object}{A \code{\linkS4class{PHGLocalCon}} object} +} +\description{ +Checks for correct data entry into \code{PHGLocalCon} class +} diff --git a/man/PHGLocalCon.Rd b/man/PHGLocalCon.Rd new file mode 100644 index 0000000..63df54a --- /dev/null +++ b/man/PHGLocalCon.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_phg_con_local.R +\name{PHGLocalCon} +\alias{PHGLocalCon} +\title{Helper function to construct a \code{PHGLocalCon} object} +\usage{ +PHGLocalCon(hVcfFiles) +} +\arguments{ +\item{hVcfFiles}{A list of \href{https://github.com/maize-genetics/phg_v2/blob/main/docs/hvcf_specifications.md}{hVCF} +files as a \code{character} vector} +} +\description{ +Creates a \code{\linkS4class{PHGLocalCon}} object to be used to read PHG +DB data for a given set of PHG-related methods. +} diff --git a/man/buildHaplotypeGraph.Rd b/man/buildHaplotypeGraph.Rd new file mode 100644 index 0000000..460ab8b --- /dev/null +++ b/man/buildHaplotypeGraph.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_haplotype_graph.R +\name{buildHaplotypeGraph} +\alias{buildHaplotypeGraph} +\title{Helper function to build HaplotypeGraph object} +\usage{ +buildHaplotypeGraph(phgLocalCon) +} +\arguments{ +\item{phgLocalCon}{A \code{\linkS4class{PHGLocalCon}} object.} +} +\description{ +Creates a \code{\linkS4class{HaplotypeGraph}} object to be used to build and store +an \code{rJava} reference object pointing to a \code{HaplotypeGraph} object +from the PHG API. +} diff --git a/man/hVcfFiles.Rd b/man/hVcfFiles.Rd new file mode 100644 index 0000000..c4da008 --- /dev/null +++ b/man/hVcfFiles.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_all_generics.R, R/class_phg_con_local.R +\name{hVcfFiles} +\alias{hVcfFiles} +\alias{hVcfFiles,PHGLocalCon-method} +\title{Return hVCF files} +\usage{ +hVcfFiles(object, ...) + +\S4method{hVcfFiles}{PHGLocalCon}(object) +} +\arguments{ +\item{object}{an \code{rPHG} local connection object} + +\item{...}{Additional arguments, for use in specific methods} +} +\description{ +Returns a list of hVCF files. +} diff --git a/man/initPhg.Rd b/man/initPhg.Rd new file mode 100644 index 0000000..d73ea8e --- /dev/null +++ b/man/initPhg.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils_jvm.R +\name{initPhg} +\alias{initPhg} +\title{Initialize JVM and add class path (for R&D purposes only)} +\usage{ +initPhg(phgPath, verbose = TRUE) +} +\arguments{ +\item{phgPath}{path to PHGv2 lib folder} + +\item{verbose}{Display all JARs added classpath? Defaults to FALSE.} +} +\description{ +Initialize JVM and add class path (for R&D purposes only) +} diff --git a/man/javaMemoryAddress.Rd b/man/javaMemoryAddress.Rd new file mode 100644 index 0000000..655b983 --- /dev/null +++ b/man/javaMemoryAddress.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_all_generics.R, R/class_haplotype_graph.R +\name{javaMemoryAddress} +\alias{javaMemoryAddress} +\alias{javaMemoryAddress,HaplotypeGraph-method} +\title{Return \code{rJava} reference object} +\usage{ +javaMemoryAddress(object, ...) + +\S4method{javaMemoryAddress}{HaplotypeGraph}(object) +} +\arguments{ +\item{object}{an \code{rPHG} local or server connection object} + +\item{...}{Additional arguments, for use in specific methods} +} +\description{ +Returns the \code{rJava} memory reference for a given \code{rPHG} object +} diff --git a/man/javaRefObj.Rd b/man/javaRefObj.Rd new file mode 100644 index 0000000..1cd3584 --- /dev/null +++ b/man/javaRefObj.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_all_generics.R, R/class_haplotype_graph.R +\name{javaRefObj} +\alias{javaRefObj} +\alias{javaRefObj,HaplotypeGraph-method} +\title{Return \code{rJava} reference object} +\usage{ +javaRefObj(object, ...) + +\S4method{javaRefObj}{HaplotypeGraph}(object) +} +\arguments{ +\item{object}{an \code{rPHG} local or server connection object} + +\item{...}{Additional arguments, for use in specific methods} +} +\description{ +Returns the \code{rJava} memory reference for a given \code{rPHG} object +} diff --git a/man/numberOfChromosomes.Rd b/man/numberOfChromosomes.Rd new file mode 100644 index 0000000..189d293 --- /dev/null +++ b/man/numberOfChromosomes.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_all_generics.R, R/class_haplotype_graph.R +\name{numberOfChromosomes} +\alias{numberOfChromosomes} +\alias{numberOfChromosomes,HaplotypeGraph-method} +\title{Return number of chromosomes} +\usage{ +numberOfChromosomes(object, ...) + +\S4method{numberOfChromosomes}{HaplotypeGraph}(object) +} +\arguments{ +\item{object}{an \code{rPHG} local or server connection object} + +\item{...}{Additional arguments, for use in specific methods} +} +\description{ +Returns the number of chromosomes for a given object +} diff --git a/man/numberOfRefRanges.Rd b/man/numberOfRefRanges.Rd new file mode 100644 index 0000000..a5e8f5b --- /dev/null +++ b/man/numberOfRefRanges.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_all_generics.R, R/class_haplotype_graph.R +\name{numberOfRefRanges} +\alias{numberOfRefRanges} +\alias{numberOfRefRanges,HaplotypeGraph-method} +\title{Return number of reference ranges} +\usage{ +numberOfRefRanges(object, ...) + +\S4method{numberOfRefRanges}{HaplotypeGraph}(object) +} +\arguments{ +\item{object}{an \code{rPHG} local or server connection object} + +\item{...}{Additional arguments, for use in specific methods} +} +\description{ +Returns the number of reference ranges for a given object +} diff --git a/man/numberOfTaxa.Rd b/man/numberOfTaxa.Rd new file mode 100644 index 0000000..f0fff4b --- /dev/null +++ b/man/numberOfTaxa.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_all_generics.R, R/class_haplotype_graph.R +\name{numberOfTaxa} +\alias{numberOfTaxa} +\alias{numberOfTaxa,HaplotypeGraph-method} +\title{Return number of taxa} +\usage{ +numberOfTaxa(object, ...) + +\S4method{numberOfTaxa}{HaplotypeGraph}(object) +} +\arguments{ +\item{object}{an \code{rPHG} local or server connection object} + +\item{...}{Additional arguments, for use in specific methods} +} +\description{ +Returns the number of taxa for a given object +} diff --git a/man/readHapIdMetaData.Rd b/man/readHapIdMetaData.Rd new file mode 100644 index 0000000..b6c03bc --- /dev/null +++ b/man/readHapIdMetaData.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_all_generics.R, R/class_haplotype_graph.R +\name{readHapIdMetaData} +\alias{readHapIdMetaData} +\alias{readHapIdMetaData,HaplotypeGraph-method} +\title{Return haplotype ID metadata} +\usage{ +readHapIdMetaData(object, ...) + +\S4method{readHapIdMetaData}{HaplotypeGraph}(object) +} +\arguments{ +\item{object}{an \code{rPHG} local or server connection object} + +\item{...}{Additional arguments, for use in specific methods} +} +\description{ +Gets haplotype ID metadata for given samples and reference ranges from a +\code{HaplotypeGraph} +} diff --git a/man/readHapIdPosMetaData.Rd b/man/readHapIdPosMetaData.Rd new file mode 100644 index 0000000..b30763d --- /dev/null +++ b/man/readHapIdPosMetaData.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_all_generics.R, R/class_haplotype_graph.R +\name{readHapIdPosMetaData} +\alias{readHapIdPosMetaData} +\alias{readHapIdPosMetaData,HaplotypeGraph-method} +\title{Return haplotype ID positional metadata} +\usage{ +readHapIdPosMetaData(object, ...) + +\S4method{readHapIdPosMetaData}{HaplotypeGraph}(object) +} +\arguments{ +\item{object}{an \code{rPHG} local or server connection object} + +\item{...}{Additional arguments, for use in specific methods} +} +\description{ +Gets haplotype ID positional metadata for given samples and reference ranges +from a \code{HaplotypeGraph} +} diff --git a/man/readHapIds.Rd b/man/readHapIds.Rd new file mode 100644 index 0000000..9cd2738 --- /dev/null +++ b/man/readHapIds.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class_all_generics.R, R/class_haplotype_graph.R +\name{readHapIds} +\alias{readHapIds} +\alias{readHapIds,HaplotypeGraph-method} +\title{Return haplotype IDs} +\usage{ +readHapIds(object, nThreads, ...) + +\S4method{readHapIds}{HaplotypeGraph}(object, nThreads = 1) +} +\arguments{ +\item{object}{an \code{rPHG} local or server connection object} + +\item{nThreads}{Number of threads to use when evaluating haplotype IDs} + +\item{...}{Additional arguments, for use in specific methods} +} +\description{ +Gets haplotype ID for given samples and reference ranges from a +\code{HaplotypeGraph} +} diff --git a/man/readRefRanges.Rd b/man/readRefRanges.Rd index 9784e36..5a6878e 100644 --- a/man/readRefRanges.Rd +++ b/man/readRefRanges.Rd @@ -1,10 +1,13 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/class_all_generics.R +% Please edit documentation in R/class_all_generics.R, R/class_haplotype_graph.R \name{readRefRanges} \alias{readRefRanges} +\alias{readRefRanges,HaplotypeGraph-method} \title{Return reference ranges} \usage{ readRefRanges(object, ...) + +\S4method{readRefRanges}{HaplotypeGraph}(object) } \arguments{ \item{object}{an \code{rPHG} local or server connection object} @@ -12,5 +15,5 @@ readRefRanges(object, ...) \item{...}{Additional arguments, for use in specific methods} } \description{ -Get reference range data for a given PHG method +Get reference range data from a \code{HaplotypeGraph} } diff --git a/man/readSamples.Rd b/man/readSamples.Rd index ee70efe..7448fa0 100644 --- a/man/readSamples.Rd +++ b/man/readSamples.Rd @@ -1,12 +1,16 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/class_all_generics.R, R/class_phg_con_server.R +% Please edit documentation in R/class_all_generics.R, +% R/class_haplotype_graph.R, R/class_phg_con_server.R \name{readSamples} \alias{readSamples} +\alias{readSamples,HaplotypeGraph-method} \alias{readSamples,PHGServerCon-method} \title{Return samples IDs} \usage{ readSamples(object, ...) +\S4method{readSamples}{HaplotypeGraph}(object) + \S4method{readSamples}{PHGServerCon}(object) } \arguments{ @@ -15,5 +19,5 @@ readSamples(object, ...) \item{...}{Additional arguments, for use in specific methods} } \description{ -Gets sample ID data for a given PHG method +Gets sample ID data from a \code{HaplotypeGraph} } diff --git a/tests/testthat/setup.R b/tests/testthat/setup.R new file mode 100644 index 0000000..6f980a2 --- /dev/null +++ b/tests/testthat/setup.R @@ -0,0 +1,93 @@ +# rPHG2 setup and initialization for local and GitHub actions +# +# This script will perform the following actions: +# 1. Download and decompress the latest version of PHGv2 JARs +# 2. Initialize the JVM and add PHGv2 libraries to class path + + +# --- Functions ----------------------------------------------------- + +## ---- +# Get latest PHGv2 release URL +# +# @param repo A GitHub repository +# +# @export A URL string of type `character` +getLatestReleaseUrl <- function(repo) { + apiUrl <- sprintf("https://api.github.com/repos/%s/releases/latest", repo) + + response <- httr::GET(apiUrl) + + # Check if the request was successful + if (httr::http_status(response)$category != "Success") { + stop( + sprintf( + "Failed to fetch the latest release info for '%s'. HTTP status code: %s", + repo, + httr::http_status(response)$reason + ) + ) + } + + responseContent <- httr::content(response, "text") + parsed <- jsonlite::fromJSON(responseContent) + + # Check if the asset URL is available + if (length(parsed$assets) == 0 || is.null(parsed$assets$browser_download_url)) { + stop(sprintf("No assets found in the latest release for '%s'.", repo)) + } + + assetUrl <- parsed$assets$browser_download_url + + return(assetUrl) +} + + +## ---- +# Download PHGv2 JARs +# +# @param dir Destination directory for Java JARs +# @param repo Organization and repository endpoint for API +downloadJavaLibraries <- function(dir, repo = "maize-genetics/phg_v2") { + + # Attempt to get the latest release URL with error handling + libraryUrl <- tryCatch({ + getLatestReleaseUrl(repo) + }, error = function(e) { + stop(sprintf("Error fetching latest release URL: %s", e$message)) + }) + + destFile <- file.path(dir, "phg_java_libs.tar.gz") + + # Attempt to download the file with error handling + tryCatch({ + utils::download.file(libraryUrl, destFile, mode = "wb") + }, error = function(e) { + stop(sprintf("Error downloading the Java library from '%s': %s", libraryUrl, e$message)) + }) + + # Attempt to decompress the file with error handling + tryCatch({ + utils::untar(destFile, exdir = dir) + }, error = function(e) { + stop(sprintf("Error decompressing the Java library archive: %s", e$message)) + }) +} + + + +# --- "Main" entry point -------------------------------------------- + +## Set up temporary directories ---- +phgLibDir <- tempdir() +phgLibPath <- file.path(phgLibDir, "phg", "lib") + + +## Download and decompress ---- +downloadJavaLibraries(phgLibDir) + + +## Initialize JVM and add PHGv2 JARs to classpath ---- +initPhg(phgLibPath) + + diff --git a/tests/testthat/test_class_all_generics.R b/tests/testthat/test_class_all_generics.R index 4e01fcd..0d00e49 100644 --- a/tests/testthat/test_class_all_generics.R +++ b/tests/testthat/test_class_all_generics.R @@ -1,4 +1,4 @@ -test_that("Generic methods for classes tests", { +test_that("Generic methods for classes tests from BrAPI/Ktor server", { brapiUrl <- "https://test-server.brapi.org" phgSrvCon <- PHGServerCon(brapiUrl) @@ -14,3 +14,18 @@ test_that("Generic methods for classes tests", { }) +test_that("Generic methods for classes tests from JVM", { + hVcfFileDir <- system.file("extdata", package = "rPHG2") + hVcfFiles <- list.files(hVcfFileDir, pattern = ".h.vcf$", full.names = TRUE) + locCon <- PHGLocalCon(hVcfFiles) + graph <- buildHaplotypeGraph(locCon) + + + expect_true(is(javaMemoryAddress(graph), "character")) + expect_true(is(numberOfChromosomes(graph), "numeric")) + expect_true(is(numberOfRefRanges(graph), "numeric")) + expect_equal(numberOfRefRanges(graph), 38) + expect_true(is(numberOfTaxa(graph), "numeric")) + expect_equal(numberOfTaxa(graph), 2) + +}) diff --git a/tests/testthat/test_class_haplotype_graph.R b/tests/testthat/test_class_haplotype_graph.R new file mode 100644 index 0000000..6e4d28e --- /dev/null +++ b/tests/testthat/test_class_haplotype_graph.R @@ -0,0 +1,30 @@ +test_that("HaplotypeGraph class construction tests", { + hVcfFileDir <- system.file("extdata", package = "rPHG2") + hVcfFiles <- list.files(hVcfFileDir, pattern = ".h.vcf$", full.names = TRUE) + locCon <- PHGLocalCon(hVcfFiles) + testUrl <- "test-server.brapi.org" + srvCon <- PHGServerCon(testUrl) + + expect_error( + buildHaplotypeGraph(mtcars), + regexp = "phgLocalCon object is not of type PHGLocalCon" + ) + + expect_error( + buildHaplotypeGraph(srvCon), + regexp = "phgLocalCon object is not of type PHGLocalCon" + ) + + locConBad <- locCon + locConBad@host <- "1" + + expect_error(buildHaplotypeGraph(locConBad)) + + + graph <- buildHaplotypeGraph(locCon) + locConOutput <- utils::capture.output(graph) + + expect_equal(length(locConOutput), 4) + +}) + diff --git a/tests/testthat/test_class_phg_con_local.R b/tests/testthat/test_class_phg_con_local.R new file mode 100644 index 0000000..b5ba341 --- /dev/null +++ b/tests/testthat/test_class_phg_con_local.R @@ -0,0 +1,11 @@ +test_that("Local connection tests", { + hVcfFileDir <- system.file("extdata", package = "rPHG2") + hVcfFiles <- list.files(hVcfFileDir, pattern = ".h.vcf$", full.names = TRUE) + locCon <- PHGLocalCon(hVcfFiles) + + locConOutput <- utils::capture.output(locCon) + + expect_equal(length(locConOutput), 3) + +}) + diff --git a/tests/testthat/test_read_hap_id_metadata.R b/tests/testthat/test_read_hap_id_metadata.R new file mode 100644 index 0000000..c66d86f --- /dev/null +++ b/tests/testthat/test_read_hap_id_metadata.R @@ -0,0 +1,16 @@ +test_that("Hap ID metadata reading tests from JVM", { + hVcfFileDir <- system.file("extdata", package = "rPHG2") + hVcfFiles <- list.files(hVcfFileDir, pattern = ".h.vcf$", full.names = TRUE) + locCon <- PHGLocalCon(hVcfFiles) + graph <- buildHaplotypeGraph(locCon) + + obsHapIdMetaData <- readHapIdMetaData(graph) + + expect_error(readHapIdMetaData(mtcars)) + expect_true(is(obsHapIdMetaData, "data.frame")) + expect_equal(dim(obsHapIdMetaData), c(76, 6)) + expect_equal( + colnames(obsHapIdMetaData), + c("hap_id", "sample_name", "description", "source", "checksum", "ref_range_hash") + ) +}) diff --git a/tests/testthat/test_read_hap_id_pos_metadata.R b/tests/testthat/test_read_hap_id_pos_metadata.R new file mode 100644 index 0000000..7a946a7 --- /dev/null +++ b/tests/testthat/test_read_hap_id_pos_metadata.R @@ -0,0 +1,16 @@ +test_that("Hap ID positional metadata reading tests from JVM", { + hVcfFileDir <- system.file("extdata", package = "rPHG2") + hVcfFiles <- list.files(hVcfFileDir, pattern = ".h.vcf$", full.names = TRUE) + locCon <- PHGLocalCon(hVcfFiles) + graph <- buildHaplotypeGraph(locCon) + + obsHapIdPosMetaData <- readHapIdPosMetaData(graph) + + expect_error(readHapIdPosMetaData(mtcars)) + expect_true(is(obsHapIdPosMetaData, "data.frame")) + expect_equal(dim(obsHapIdPosMetaData), c(76, 5)) + expect_equal( + colnames(obsHapIdPosMetaData), + c("hap_id", "contig_start", "contig_end", "start", "end") + ) +}) diff --git a/tests/testthat/test_read_hap_ids.R b/tests/testthat/test_read_hap_ids.R new file mode 100644 index 0000000..3695919 --- /dev/null +++ b/tests/testthat/test_read_hap_ids.R @@ -0,0 +1,14 @@ +test_that("Hap ID matrix reading tests from JVM", { + hVcfFileDir <- system.file("extdata", package = "rPHG2") + hVcfFiles <- list.files(hVcfFileDir, pattern = ".h.vcf$", full.names = TRUE) + locCon <- PHGLocalCon(hVcfFiles) + graph <- buildHaplotypeGraph(locCon) + + obsHapIds <- readHapIds(graph, 2) + + expect_true(is(obsHapIds, "matrix")) + expect_true(is(obsHapIds[1, 1], "character")) + expect_equal(dim(obsHapIds), c(2, 38)) +}) + + diff --git a/tests/testthat/test_read_ref_ranges.R b/tests/testthat/test_read_ref_ranges.R new file mode 100644 index 0000000..ab71788 --- /dev/null +++ b/tests/testthat/test_read_ref_ranges.R @@ -0,0 +1,19 @@ +test_that("Ref range reading tests from JVM object", { + hVcfFileDir <- system.file("extdata", package = "rPHG2") + hVcfFiles <- list.files(hVcfFileDir, pattern = ".h.vcf$", full.names = TRUE) + locCon <- PHGLocalCon(hVcfFiles) + graph <- buildHaplotypeGraph(locCon) + + obsRefRanges <- readRefRanges(graph) + obsRefRangesDf <- as.data.frame(obsRefRanges, char) + + expect_true(is(obsRefRanges, "GRanges")) + expect_equal(nrow(obsRefRangesDf), 38) + expect_equal(levels(obsRefRangesDf$seqnames), c("1", "2")) + expect_equal( + colnames(obsRefRangesDf), + c("seqnames", "start", "end", "width", "strand") + ) +}) + + diff --git a/tests/testthat/test_read_samples.R b/tests/testthat/test_read_samples.R index 6955364..9c11e6f 100644 --- a/tests/testthat/test_read_samples.R +++ b/tests/testthat/test_read_samples.R @@ -1,4 +1,4 @@ -test_that("Sample reading tests", { +test_that("Sample reading tests from BrAPI/Ktor server", { testUrl <- "test-server.brapi.org" phgSrvCon <- PHGServerCon(testUrl) @@ -12,3 +12,15 @@ test_that("Sample reading tests", { }) +test_that("Sample reading tests from JVM object", { + hVcfFileDir <- system.file("extdata", package = "rPHG2") + hVcfFiles <- list.files(hVcfFileDir, pattern = ".h.vcf$", full.names = TRUE) + locCon <- PHGLocalCon(hVcfFiles) + graph <- buildHaplotypeGraph(locCon) + + obsSamples <- readSamples(graph) + + expect_true(is(obsSamples, "character")) + expect_equal(length(obsSamples), 2) + expect_equal(obsSamples, c("LineA", "LineB")) +}) diff --git a/tests/testthat/test_utilities_api_brapi.R b/tests/testthat/test_utils_api_brapi.R similarity index 99% rename from tests/testthat/test_utilities_api_brapi.R rename to tests/testthat/test_utils_api_brapi.R index e8563a0..cd2f792 100644 --- a/tests/testthat/test_utilities_api_brapi.R +++ b/tests/testthat/test_utils_api_brapi.R @@ -44,7 +44,6 @@ test_that("BrAPI utitlity tests", { expect_error(parseJSON(negControl2)) expect_true(is(parseJSON(posControl3), "list")) expect_message(parseJSON(posControl3, verbose = TRUE)) - }) diff --git a/tests/testthat/test_utils_jvm.R b/tests/testthat/test_utils_jvm.R new file mode 100644 index 0000000..c4409b4 --- /dev/null +++ b/tests/testthat/test_utils_jvm.R @@ -0,0 +1,15 @@ +test_that("JVM utility tests", { + negControl1 <- rJava::.jarray(c(1, 2, 3)) + expect_error( + kotlinListToRDataFrame(negControl1), + regexp = "Object does not have a \'RList\' signature" + ) + expect_error( + kotlin2DArrayToRMatrix(negControl1), + regexp = "Object does not have a \'MatrixWithNames\' signature" + ) + + expect_silent(initPhg(phgLibPath, verbose = FALSE)) +}) + +