Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
^.*\.Rproj$
^\.Rproj\.user$
^doc$
^docker$
^Meta$
^validation$
^CLAUDE\.md$
^CLAUDE_CHANGELOG\.md$
^\.positai$
^\.claude$
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@
CoSIA.Rproj
/doc/
/Meta/
.positai
14 changes: 8 additions & 6 deletions R/CoSIA-plots-method.R
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ setMethod(
filter_gex <- filter_gex[
filter_gex$Anatomical_entity_name %in% single_tissue,
]
filter_gex <- tidyr::separate_rows(filter_gex, VST)
filter_gex <- tidyr::unnest(filter_gex, VST)
filter_gex$VST <- as.numeric(filter_gex$VST)
filter_gex <- as.data.frame(filter_gex)
brewer.pal.info <- RColorBrewer::brewer.pal.info
Expand Down Expand Up @@ -102,6 +102,7 @@ setMethod(
fig <- fig %>%
plotly::add_trace(
type = "violin",
mode = NULL,
spanmode = "hard",
showlegend = FALSE
)
Expand Down Expand Up @@ -212,7 +213,7 @@ setMethod(
ids <- as.character(ids)
filter_gex <- gex_dataframe[gex_dataframe$Ensembl_ID %in% ids, ]
filter_gex <- filter_gex[filter_gex$Species %in% single_species, ]
filter_gex <- tidyr::separate_rows(filter_gex, VST)
filter_gex <- tidyr::unnest(filter_gex, VST)
filter_gex$VST <- as.numeric(filter_gex$VST)

brewer.pal.info <- RColorBrewer::brewer.pal.info
Expand Down Expand Up @@ -242,6 +243,7 @@ setMethod(
fig <- fig %>%
plotly::add_trace(
type = "violin",
mode = NULL,
spanmode = "hard",
showlegend = FALSE
)
Expand Down Expand Up @@ -403,7 +405,7 @@ setMethod("plotDSGEx", signature(object = "CoSIAn"), function(object) {
#' "h_sapiens", "r_norvegicus"
#' ), output_ids = c("Ensembl_id", "Symbol"),
#' mapping_tool = "annotationDBI", ortholog_database = "HomoloGene",
#' map_tissues = c("adult mammalian kidney","heart"),
#' map_tissues = c("adult mammalian kidney","heart"),
#' map_species = c("h_sapiens", "r_norvegicus"),
#' metric_type = "CV_Tissue"
#' )
Expand All @@ -429,15 +431,15 @@ setGeneric("plotCVGEx", function(object) standardGeneric("plotCVGEx"))
#' "h_sapiens", "r_norvegicus"
#' ), output_ids = c("Ensembl_id", "Symbol"),
#' mapping_tool = "annotationDBI", ortholog_database = "HomoloGene",
#' map_tissues = c("adult mammalian kidney","heart"),
#' map_tissues = c("adult mammalian kidney","heart"),
#' map_species = c("h_sapiens", "r_norvegicus"),
#' metric_type = "CV_Tissue"
#' )
#' Kidney_gene_conversion <- CoSIA::getConversion(Kidney_Genes)
#' Kidney_gene_metric <- getGExMetrics(Kidney_gene_conversion)
#' plot <- plotCVGEx(Kidney_gene_metric)
#' @references Dot plot in R with the dotchart function [with examples].
#' R CODER. (2020, November 20). Retrieved from https://r-coder.com/dot-plot-r/
#' @references Dot plot in R with the dotchart function [with examples].
#' R CODER. (2020, November 20). Retrieved from https://r-coder.com/dot-plot-r/
setMethod("plotCVGEx", signature(object = "CoSIAn"), function(object) {
# set object slots into variables
metric_type <- object@metric_type
Expand Down
83 changes: 83 additions & 0 deletions docker/Dockerfile_1.10.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
FROM bioconductor/bioconductor:devel-r-4.6.0
# includes: BIOCONDUCTOR_DOCKER_VERSION=3.23.22

##----------------------------------------------------------------------------##
## SYSTEM PACKAGES
##----------------------------------------------------------------------------##

RUN apt-get update --yes && \
apt-get upgrade --yes

RUN apt-get install --yes \
python3-pip \
python3-dev \
python3-pip \
python3-tk


RUN apt-get install --yes \
libcurl4-openssl-dev \
libssl-dev \
libcairo2-dev libxt-dev \
libxml2-dev \
libudunits2-dev \
libhdf5-dev \
libv8-dev \
libgdal-dev \
xorg libx11-dev libglu1-mesa-dev \
samtools libboost-all-dev \
libgsl-dev

RUN apt-get install -y \
wget \
unzip \
git


##----------------------------------------------------------------------------##
## R PACKAGES
##----------------------------------------------------------------------------##

#### Leave the top line the same for each new project. Uncomment lines to add ####
RUN R -e 'install.packages(c("tidyverse", "remotes", "BiocManager", "devtools", "knitr", "lintr", "styler", "here", "markdown", "rmarkdown", "reticulate"))' \
# && R -e 'install.packages(c("< insert CRAN repos here >"))' \
# && R -e 'devtools::install_github("< insert GitHub repos here >")' \
# && R -e 'remotes::install_github("< insert GitHub repos here >")' \
&& R -e 'BiocManager::install(c("BiocFileCache", "BiocGenerics", "AnnotationHub", "ExperimentHub", "CoSIA", "CoSIAdata"))'


##----------------------------------------------------------------------------##
## PYTHON PACKAGES
##----------------------------------------------------------------------------##


RUN pip3 install kaleido plotly --break-system-packages
RUN wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list \
&& apt-get update --yes \
&& apt-get install --yes google-chrome-stable

##----------------------------------------------------------------------------##
## 3RD PARTY PROGRAMS
##----------------------------------------------------------------------------##

#### Uncomment these lines if you need a conda env in your docker ####

# Install miniconda
# ENV CONDA_DIR /opt/conda
# RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh && \
# /bin/bash ~/miniconda.sh -b -p /opt/conda
# ENV PATH=$CONDA_DIR/bin:$PATH


##----------------------------------------------------------------------------##
## CONDA ENV
##----------------------------------------------------------------------------##

#### Uncomment these lines if you need a conda env in your docker ####

#RUN conda config --set channel_priority false && \
# conda env create -f opt/BLAZE-1.1.0/conda_env/environment.yml

#SHELL ["conda", "run", "-n", "blaze", "/bin/bash", "-c"]

8 changes: 3 additions & 5 deletions tests/test.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#!/usr/bin/env bash
set -euo pipefail

PROJECT_PATH="/data/user/$USER/CoSIA"
DEV_PATH="/data/user/$USER/CoSIA"
PROJECT_PATH="$(pwd)"
CONTAINER_PATH="$PROJECT_PATH/bin/container"
SIF="${CONTAINER_PATH}/bioc_cosia_1.10.0.sif"
SIF_URI="${COSIA_SIF_URI:-docker://lizzyr/bioc_cosia:1.10.0}"
SIF="${CONTAINER_PATH}/bioc_cosia_1.10.1.sif"
SIF_URI="${COSIA_SIF_URI:-docker://lasseignelab/bioc_cosia:1.10.1}"

ensure_sif() {
mkdir -p "$CONTAINER_PATH"
Expand Down Expand Up @@ -33,7 +32,6 @@ mkdir -p \
singularity exec --cleanenv \
--containall \
--home "${CACHE_BASE}/home:/home/${USER}" \
-B "${DEV_PATH}" \
-B "${PROJECT_PATH}" \
-B "${CACHE_BASE}:${CACHE_BASE}" \
-B "${TMP_BASE}:/tmp" \
Expand Down
97 changes: 97 additions & 0 deletions tests/testthat/test-plots.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# plotSpeciesGEx and plotTissueGEx tests
# These run offline — VST data is injected as a list column to match the real
# ExperimentHub format and catch the separate_rows vs unnest regression.

make_plot_cosian <- function() {
obj <- make_cosian(map_species = "m_musculus", map_tissues = "heart")

mock_gex <- data.frame(
Anatomical_entity_name = c("heart", "heart"),
Ensembl_ID = c("ENSG00000008710", "ENSMUSG00000032855"),
Sample_size = c(3L, 3L),
Experiment_ID = c("EXP1", "EXP2"),
Anatomical_entity_ID = c("UBERON:0000948", "UBERON:0000948"),
Species = c("Homo_sapiens", "Mus_musculus"),
Scaled_Median_VST = c(1.0, 1.0),
mad = c(0.1, 0.1),
stringsAsFactors = FALSE
)
mock_gex$VST <- list(c(10.5, 11.0, 12.0), c(11.0, 11.5, 11.8))

obj@gex <- mock_gex
obj@converted_id <- data.frame(
h_sapiens_ensembl_id = "ENSG00000008710",
h_sapiens_symbol = "PKD1",
m_musculus_ensembl_id = "ENSMUSG00000032855",
m_musculus_symbol = "Pkd1",
stringsAsFactors = FALSE
)
obj
}

# --- plotSpeciesGEx ---

test_that("plotSpeciesGEx returns a plotly object", {
obj <- make_plot_cosian()
fig <- plotSpeciesGEx(obj, "heart", "ENSG00000008710")
expect_true(inherits(fig, "plotly"))
})

test_that("plotSpeciesGEx VST values are non-NA (list-column unnest)", {
obj <- make_plot_cosian()
fig <- plotly::plotly_build(plotSpeciesGEx(obj, "heart", "ENSG00000008710"))

all_y <- unlist(lapply(fig$x$data, function(tr) tr$y))
expect_false(
all(is.na(all_y)),
label = "all VST values are NA — separate_rows regression likely"
)
expect_true(all(all_y > 0, na.rm = TRUE))
})


# --- plotTissueGEx ---

make_tissue_cosian <- function() {
obj <- make_cosian(map_species = "h_sapiens", map_tissues = c("heart", "brain"))

mock_gex <- data.frame(
Anatomical_entity_name = c("heart", "brain"),
Ensembl_ID = c("ENSG00000008710", "ENSG00000008710"),
Sample_size = c(3L, 4L),
Experiment_ID = c("EXP1", "EXP2"),
Anatomical_entity_ID = c("UBERON:0000948", "UBERON:0000955"),
Species = c("Homo_sapiens", "Homo_sapiens"),
Scaled_Median_VST = c(1.0, 1.0),
mad = c(0.1, 0.1),
stringsAsFactors = FALSE
)
mock_gex$VST <- list(c(10.5, 11.0, 12.0), c(9.5, 10.0, 10.5, 11.0))

obj@gex <- mock_gex
obj@converted_id <- data.frame(
h_sapiens_ensembl_id = "ENSG00000008710",
h_sapiens_symbol = "PKD1",
stringsAsFactors = FALSE
)
obj
}

test_that("plotTissueGEx returns a plotly object", {
obj <- make_tissue_cosian()
fig <- plotTissueGEx(obj, "h_sapiens", "ENSG00000008710")
expect_true(inherits(fig, "plotly"))
})

test_that("plotTissueGEx VST values are non-NA (list-column unnest)", {
obj <- make_tissue_cosian()
fig <- plotly::plotly_build(plotTissueGEx(obj, "h_sapiens", "ENSG00000008710"))

all_y <- unlist(lapply(fig$x$data, function(tr) tr$y))
expect_false(
all(is.na(all_y)),
label = "all VST values are NA — separate_rows regression likely"
)
expect_true(all(all_y > 0, na.rm = TRUE))
})

69 changes: 69 additions & 0 deletions validation/gene_expression.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# validation/gene_expression.R
#
# Creates the gene expression plot that was not working after updating CoSIA.
#
# Usage (from repo root):
# Run the script in RStudio.
#
# Output: Gene expression plot in the RStudio Viewer window

devtools::load_all(".")

loaded_version <- as.character(packageVersion("CoSIA"))
loaded_path <- find.package("CoSIA")

cat("CoSIA version :", loaded_version, "\n")
cat("CoSIA path :", loaded_path, "\n\n")

GENE_SET <- c("ENSG00000008710", "ENSG00000118762")
I_SPECIES <- "h_sapiens"
INPUT_ID <- "Ensembl_id"
OUTPUT_IDS <- c("Ensembl_id")
TOOL <- "annotationDBI"
ORTHO_DB <- "HomoloGene"
TISSUE <- "brain"
MULTI_SPECIES <- c("h_sapiens", "m_musculus")

make_obj <- function(map_species, map_tissues, metric_type,
o_species = map_species) {
obj <- CoSIAn(
gene_set = GENE_SET,
i_species = I_SPECIES,
input_id = INPUT_ID,
o_species = o_species,
output_ids = OUTPUT_IDS,
mapping_tool = TOOL,
ortholog_database = ORTHO_DB,
map_tissues = map_tissues,
map_species = map_species,
metric_type = metric_type
)
getConversion(obj)
}

run_metric <- function(label, ...) {
cat("---", label, "---\n")
tryCatch({
obj <- make_obj(...)
obj <- getGEx(obj)
cat(" SUCCESS \n")
obj
}, error = function(e) {
cat(" ERROR:", conditionMessage(e), "\n\n")
NULL
})
}

gex_species_multi = run_metric(
"DS_Gene multi-species",
map_species = MULTI_SPECIES,
map_tissues = TISSUE,
metric_type = "DS_Gene",
o_species = MULTI_SPECIES
)

# print(CoSIA::plotSpeciesGEx(gex_species_multi, "brain", "ENSG00000008710"))

dir.create("validation/output", showWarnings = FALSE, recursive = TRUE)
p <- CoSIA::plotSpeciesGEx(gex_species_multi, "brain", "ENSG00000008710")
plotly::save_image(p, "validation/output/gex_plot.png", width = 800, height = 600, scale = 2)
Loading
Loading