Skip to content

Commit

Permalink
Merge pull request #191 from KrishnaswamyLab/dev
Browse files Browse the repository at this point in the history
MAGIC v2.0.4
  • Loading branch information
scottgigante committed Nov 2, 2020
2 parents b462b38 + a3e728f commit 0a4f0c6
Show file tree
Hide file tree
Showing 17 changed files with 203 additions and 78 deletions.
12 changes: 12 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Expand Up @@ -65,5 +65,17 @@ You can do this with `R -e 'reticulate::py_discover_config(required_module = "ma

</details>

Output of `Rmagic::check_pymagic_version()`:

<details>

```
If you are running MAGIC in R, please run `Rmagic::check_pymagic_version()` and paste the results here.
You can do this with `R -e 'Rmagic::check_pymagic_version()'`
```

</details>

**Additional context**
Add any other context about the problem here.
5 changes: 3 additions & 2 deletions .travis.yml
Expand Up @@ -20,7 +20,7 @@ addons:
- deadsnakes
packages:
- libhdf5-dev
- python3.6
- python3.6-dev

cache:
- packages
Expand All @@ -40,6 +40,7 @@ before_install:
install:
- cd python; pip install --user -q .
- cd ../Rmagic; R -e 'install.packages("devtools", repos="http://cloud.r-project.org")'
- R -e 'install.packages("BiocManager", repos="http://cloud.r-project.org"); BiocManager::install("multtest")'
- R -e 'devtools::install_deps(dep = T, upgrade="always")'
- cd ..

Expand All @@ -48,7 +49,7 @@ script:
- cd Rmagic; R CMD build .
- R CMD check *tar.gz
- cd ../python; pip install --user -q .[test]
- if [ "$TRAVIS_PYTHON_VERSION" != "3.5" ]; then black . --check --diff; fi
- if [ "$TRAVIS_PYTHON_VERSION" != "3.5" ]; then black . --check --diff -t py35; fi
- python setup.py test
- pip install --user -q .[doc]
- cd doc; make html; cd ..
Expand Down
4 changes: 2 additions & 2 deletions Rmagic/DESCRIPTION
@@ -1,7 +1,7 @@
Package: Rmagic
Type: Package
Title: MAGIC - Markov Affinity-Based Graph Imputation of Cells
Version: 2.0.3
Version: 2.0.3.999
Authors@R: c(person(given = "David", family = "van Dijk", email = "davidvandijk@gmail.com", role = c("aut")),
person(given = 'Scott', family = 'Gigante', email = 'scott.gigante@yale.edu', role = 'cre',
comment = c(ORCID = '0000-0002-4544-2764')))
Expand All @@ -22,5 +22,5 @@ Suggests:
phateR
License: GPL-2 | file LICENSE
LazyData: true
RoxygenNote: 6.1.1
RoxygenNote: 7.0.2
Encoding: UTF-8
2 changes: 2 additions & 0 deletions Rmagic/NAMESPACE
Expand Up @@ -8,9 +8,11 @@ S3method(magic,default)
S3method(magic,seurat)
S3method(print,magic)
S3method(summary,magic)
export(check_pymagic_version)
export(install.magic)
export(library.size.normalize)
export(magic)
export(pymagic_is_available)
import(Matrix)
importFrom(ggplot2,ggplot)
importFrom(utils,packageVersion)
64 changes: 33 additions & 31 deletions Rmagic/R/magic.R
Expand Up @@ -21,6 +21,11 @@
#' sets the level of diffusion. If 'auto', t is selected according to the
#' Procrustes disparity of the diffused data.'
#' @param npca number of PCA components that should be used; default: 100.
#' @param solver str, optional, default: 'exact'
#' Which solver to use. "exact" uses the implementation described
#' in van Dijk et al. (2018). "approximate" uses a faster implementation
#' that performs imputation in the PCA space and then projects back to the
#' gene space. Note, the "approximate" solver may return negative values.
#' @param init magic object, optional
#' object to use for initialization. Avoids recomputing
#' intermediate steps if parameters are the same.
Expand Down Expand Up @@ -113,6 +118,7 @@ magic.default <- function(
decay = 1,
t = 3,
npca = 100,
solver = 'exact',
init = NULL,
t.max = 20,
knn.dist.method = 'euclidean',
Expand All @@ -134,32 +140,16 @@ magic.default <- function(
message("Argument alpha is deprecated. Using decay instead.")
decay <- alpha
}
knn <- as.integer(x = knn)
t.max <- as.integer(x = t.max)
n.jobs <- as.integer(x = n.jobs)
if (is.numeric(x = npca)) {
npca <- as.integer(x = npca)
} else if (!is.null(x = npca) && is.na(x = npca)) {
npca <- NULL
}
if (is.numeric(x = decay)) {
decay <- as.double(x = decay)
} else if (!is.null(x = decay) && is.na(x = decay)) {
decay <- NULL
}
if (is.numeric(x = t)) {
t <- as.integer(x = t)
} else if (is.null(x = t) || is.na(x = t)) {
t <- 'auto'
}
if (is.numeric(x = seed)) {
seed <- as.integer(x = seed)
} else if (!is.null(x = seed) && is.na(x = seed)) {
seed <- NULL
}
if (is.numeric(x = verbose)) {
verbose <- as.integer(x = verbose)
}
# validate parameters
knn <- check.int(x = knn)
t.max <- check.int(x = t.max)
n.jobs <- check.int(x = n.jobs)
npca <- check.int.or.null(npca)
knn.max <- check.int.or.null(knn.max)
seed <- check.int.or.null(seed)
verbose <- check.int.or.null(verbose)
decay <- check.double.or.null(decay)
t <- check.int.or.string(t, 'auto')
if (!methods::is(object = data, "Matrix")) {
data <- as.matrix(x = data)
}
Expand Down Expand Up @@ -190,6 +180,7 @@ magic.default <- function(
"decay" = decay,
"t" = t,
"npca" = npca,
"solver" = solver,
"knn.dist.method" = knn.dist.method
)
# use pre-initialized values if given
Expand All @@ -205,10 +196,12 @@ magic.default <- function(
decay = decay,
t = t,
n_pca = npca,
solver = solver,
knn_dist = knn.dist.method,
n_jobs = n.jobs,
random_state = seed,
verbose = verbose
verbose = verbose,
...
)
}
}
Expand All @@ -219,10 +212,12 @@ magic.default <- function(
decay = decay,
t = t,
n_pca = npca,
solver = solver,
knn_dist = knn.dist.method,
n_jobs = n.jobs,
random_state = seed,
verbose = verbose
verbose = verbose,
...
)
}
result <- operator$fit_transform(
Expand Down Expand Up @@ -254,6 +249,7 @@ magic.seurat <- function(
decay = 1,
t = 3,
npca = 100,
solver = "exact",
init = NULL,
t.max = 20,
knn.dist.method = 'euclidean',
Expand All @@ -271,12 +267,14 @@ magic.seurat <- function(
decay = decay,
t = t,
npca = npca,
solver = solver,
init = init,
t.max = t.max,
knn.dist.method = knn.dist.method,
verbose = verbose,
n.jobs = n.jobs,
seed = seed
seed = seed,
...
)
data@data <- t(x = as.matrix(x = results$result))
return(data)
Expand All @@ -290,6 +288,7 @@ magic.seurat <- function(
decay = decay,
t = t,
npca = npca,
solver = solver,
init = init,
t.max = t.max,
knn.dist.method = knn.dist.method,
Expand All @@ -316,6 +315,7 @@ magic.Seurat <- function(
decay = 1,
t = 3,
npca = 100,
solver = 'exact',
init = NULL,
t.max = 20,
knn.dist.method = 'euclidean',
Expand All @@ -336,17 +336,19 @@ magic.Seurat <- function(
decay = decay,
t = t,
npca = npca,
solver = solver,
init = init,
t.max = t.max,
knn.dist.method = knn.dist.method,
verbose = verbose,
n.jobs = n.jobs,
seed = seed
seed = seed,
...
)
assay_name <- paste0('MAGIC_', assay)
data[[assay_name]] <- Seurat::CreateAssayObject(data = t(x = as.matrix(x = results$result)))
print(paste0("Added MAGIC output to ", assay_name, ". To use it, pass assay='", assay_name,
"' to downstream methods or set seurat_object@active.assay <- '", assay_name, "'."))
"' to downstream methods or set DefaultAssay(seurat_object) <- '", assay_name, "'."))
Seurat::Tool(object = data) <- results[c('operator', 'params')]
return(data)
} else {
Expand Down
45 changes: 42 additions & 3 deletions Rmagic/R/utils.R
Expand Up @@ -9,6 +9,10 @@ null_equal <- function(x, y) {
}
}

#' Check that the current MAGIC version in Python is up to date.
#'
#' @importFrom utils packageVersion
#' @export
check_pymagic_version <- function() {
pyversion <- strsplit(pymagic$`__version__`, '\\.')[[1]]
rversion <- strsplit(as.character(packageVersion("Rmagic")), '\\.')[[1]]
Expand All @@ -17,12 +21,12 @@ check_pymagic_version <- function() {
if (as.integer(pyversion[1]) < major_version) {
warning(paste0("Python MAGIC version ", pymagic$`__version__`, " is out of date (recommended: ",
major_version, ".", minor_version, "). Please update with pip ",
"(e.g. pip install --upgrade magic-impute) or Rmagic::install.magic()."))
"(e.g. ", reticulate::py_config()$python, " -m pip install --upgrade magic-impute) or Rmagic::install.magic()."))
return(FALSE)
} else if (as.integer(pyversion[2]) < minor_version) {
warning(paste0("Python MAGIC version ", pymagic$`__version__`, " is out of date (recommended: ",
major_version, ".", minor_version, "). Consider updating with pip ",
"(e.g. pip install --upgrade magic-impute) or Rmagic::install.magic()."))
"(e.g. ", reticulate::py_config()$python, " -m pip install --upgrade magic-impute) or Rmagic::install.magic()."))
return(FALSE)
}
return(TRUE)
Expand Down Expand Up @@ -112,7 +116,7 @@ install.magic <- function(envname = "r-reticulate", method = "auto",
error = function(e) {
stop(paste0(
"Cannot locate MAGIC Python package, please install through pip ",
"(e.g. pip install magic-impute) and then restart R."
"(e.g. ", reticulate::py_config()$python, " -m pip install magic-impute) and then restart R."
))
}
)
Expand All @@ -124,3 +128,38 @@ pymagic <- NULL
py_config <- reticulate::py_discover_config(required_module = "magic")
load_pymagic()
}

######
# Parameter validation
######

check.int <- function(x) {
as.integer(x)
}

check.int.or.null <- function(x) {
if (is.numeric(x = x)) {
x <- as.integer(x = x)
} else if (!is.null(x = x) && is.na(x = x)) {
x <- NULL
}
x
}

check.double.or.null <- function(x) {
if (is.numeric(x = x)) {
x <- as.integer(x = x)
} else if (!is.null(x = x) && is.na(x = x)) {
x <- NULL
}
x
}

check.int.or.string <- function(x, str) {
if (is.numeric(x = x)) {
x <- as.integer(x = x)
} else if (is.null(x = x) || is.na(x = x)) {
x <- str
}
x
}
11 changes: 11 additions & 0 deletions Rmagic/man/check_pymagic_version.Rd

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

9 changes: 7 additions & 2 deletions Rmagic/man/install.magic.Rd

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

0 comments on commit 0a4f0c6

Please sign in to comment.