Skip to content
Open
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
95 changes: 51 additions & 44 deletions .codeocean/app-panel.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,56 +12,73 @@
}
],
"categories": [
{
"id": "7Rr6IxOMDucKMImp",
"name": "Input Data Parameters",
"description": "Options for defining input data",
"icon": "📁"
},
{
"id": "EzTg1ivlFDHEy9PI",
"name": "Basic",
"icon": "📂"
"icon": "\ud83d\udcc2"
},
{
"id": "FvI4Z2eb9sjL47Jt",
"name": "Visualization",
"description": "Visualization and plotting options",
"icon": "📊"
"icon": "\ud83d\udcca"
},
{
"id": "7Rr6IxOMDucKMImp",
"name": "Advanced",
"description": "Advanced input data options",
"icon": "\ud83d\udcc1"
}
],
"parameters": [
{
"id": "count_type_id",
"category": "FvI4Z2eb9sjL47Jt",
"category": "EzTg1ivlFDHEy9PI",
"name": "Count type",
"param_name": "count_type",
"description": "Type of counts to use (e.g., filt, norm)",
"type": "list",
"value_type": "string",
"default_value": "filt",
"extra_data": [
"raw",
"clean",
"filt",
"norm"
]
},
{
"id": "group_colname_id",
"category": "EzTg1ivlFDHEy9PI",
"name": "Group column name",
"param_name": "group_colname",
"description": "Column name for sample groups",
"type": "text",
"value_type": "string",
"default_value": "Group"
},
{
"id": "label_colname_id",
"category": "EzTg1ivlFDHEy9PI",
"name": "Label column name",
"param_name": "label_colname",
"description": "Column name for sample labels",
"type": "text",
"value_type": "string",
"default_value": "filt"
"default_value": "Label"
},
{
"id": "sub_count_type_id",
"category": "FvI4Z2eb9sjL47Jt",
"category": "7Rr6IxOMDucKMImp",
"name": "Sub count type",
"param_name": "sub_count_type",
"description": "Sub count type if count_type is a list",
"type": "text",
"value_type": "string"
},
{
"id": "feature_id_colname_id",
"category": "FvI4Z2eb9sjL47Jt",
"name": "Feature ID column name",
"param_name": "feature_id_colname",
"description": "Column name for feature IDs",
"type": "text",
"value_type": "string"
},
{
"id": "sample_id_colname_id",
"category": "FvI4Z2eb9sjL47Jt",
"category": "EzTg1ivlFDHEy9PI",
"name": "Sample ID column name",
"param_name": "sample_id_colname",
"description": "Column name for sample IDs",
Expand All @@ -77,36 +94,25 @@
"type": "text",
"value_type": "string"
},
{
"id": "group_colname_id",
"category": "7Rr6IxOMDucKMImp",
"name": "Group column name",
"param_name": "group_colname",
"description": "Column name for sample groups",
"type": "text",
"value_type": "string",
"default_value": "Group"
},
{
"id": "label_colname_id",
"category": "7Rr6IxOMDucKMImp",
"name": "Label column name",
"param_name": "label_colname",
"description": "Column name for sample labels",
"type": "text",
"value_type": "string",
"default_value": "Label"
},
{
"id": "principal_components_id",
"category": "EzTg1ivlFDHEy9PI",
"category": "7Rr6IxOMDucKMImp",
"name": "Principal components",
"param_name": "principal_components",
"description": "Principal components to plot (comma-separated, e.g., 1,2,3)",
"type": "text",
"value_type": "string",
"default_value": "1,2,3"
},
{
"id": "feature_id_colname_id",
"category": "7Rr6IxOMDucKMImp",
"name": "Feature ID column name",
"param_name": "feature_id_colname",
"description": "Column name for feature IDs",
"type": "text",
"value_type": "string"
},
{
"id": "point_size_id",
"category": "FvI4Z2eb9sjL47Jt",
Expand All @@ -132,7 +138,8 @@
"category": "FvI4Z2eb9sjL47Jt",
"name": "Color values",
"param_name": "color_values",
"description": "Comma-separated color values for groups",
"description": "Comma-separated group colors. Defaults to the MOSuite palette.",
"help_text": "Use color names or hex codes. Supplied colors are used first; if there are more groups than colors, additional colors are generated from the MOSuite palette, with random colors only if that palette is too short.",
"type": "text",
"value_type": "string",
"default_value": "#5954d6,#e1562c,#b80058,#00c6f8,#d163e6,#00a76c,#ff9287,#008cf9,#006e00,#796880,#FFA500,#878500"
Expand All @@ -153,4 +160,4 @@
"file_name": "figures/pca/pca_3D.html"
}
]
}
}
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Code Ocean capsule - MOSuite - plot 3D PCA

## Development version

- Align the PCA color and point size defaults with MOSuite package defaults.
- Document that color palettes fall back to random colors only when too few colors are provided.
- Added tests for the plot pca 3D capsule Code Ocean panel and CLI contract (#1, @phoman14).
- Improved the Code Ocean parameter UI for the plot pca 3D capsule (#1, @phoman14).

## v2.0

- Use MOSuite v0.3.0.
Expand All @@ -9,4 +16,4 @@

Initial release

<https://poc-nci.codeocean.io/capsule/3313117/tree/v1>
<https://poc-nci.codeocean.io/capsule/3313117/tree/v1>
107 changes: 82 additions & 25 deletions code/main.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,73 @@ setup_capsule_environment()
# parse CLI arguments
parser <- ArgumentParser()

parser$add_argument("--count_type", type="character", default="filt")
parser$add_argument("--sub_count_type", type="character", default=NULL, help="Sub count type if count_type is a list")
parser$add_argument("--feature_id_colname", type="character", default=NULL, help="Column name for feature IDs")
parser$add_argument("--sample_id_colname", type="character", default=NULL, help="Column name for sample IDs")
parser$add_argument("--samples_to_rename", type="character", default="", help="Samples to rename in format old:new,old2:new2")
parser$add_argument("--group_colname", type="character", default="Group", help="Column name for sample groups")
parser$add_argument("--label_colname", type="character", default="Label", help="Column name for sample labels")
parser$add_argument("--principal_components", type="character", default="1,2,3", help="Principal components to plot (comma-separated)")
parser$add_argument("--point_size", type="integer", default=8, help="Size of points in plot")
parser$add_argument("--label_font_size", type="integer", default=24, help="Font size for labels")
parser$add_argument("--color_values", type="character", default="#5954d6,#e1562c,#b80058,#00c6f8,#d163e6,#00a76c,#ff9287,#008cf9,#006e00,#796880,#FFA500,#878500", help="Comma-separated color values")
parser$add_argument("--plot_title", type="character", default="PCA 3D", help="Title for the plot")
parser$add_argument("--count_type", type = "character", default = "filt")
parser$add_argument(
"--sub_count_type",
type = "character",
default = NULL,
help = "Sub count type if count_type is a list"
)
parser$add_argument(
"--feature_id_colname",
type = "character",
default = NULL,
help = "Column name for feature IDs"
)
parser$add_argument(
"--sample_id_colname",
type = "character",
default = NULL,
help = "Column name for sample IDs"
)
parser$add_argument(
"--samples_to_rename",
type = "character",
default = "",
help = "Samples to rename in format old:new,old2:new2"
)
parser$add_argument(
"--group_colname",
type = "character",
default = "Group",
help = "Column name for sample groups"
)
parser$add_argument(
"--label_colname",
type = "character",
default = "Label",
help = "Column name for sample labels"
)
parser$add_argument(
"--principal_components",
type = "character",
default = "1,2,3",
help = "Principal components to plot (comma-separated)"
)
parser$add_argument(
"--point_size",
type = "integer",
default = 8,
help = "Size of points in plot"
)
parser$add_argument(
"--label_font_size",
type = "integer",
default = 24,
help = "Font size for labels"
)
parser$add_argument(
"--color_values",
type = "character",
default = "#5954d6,#e1562c,#b80058,#00c6f8,#d163e6,#00a76c,#ff9287,#008cf9,#006e00,#796880,#FFA500,#878500",
help = "Comma-separated group colors. Defaults to the MOSuite palette. Extra group colors are generated when needed."
)
parser$add_argument(
"--plot_title",
type = "character",
default = "PCA 3D",
help = "Title for the plot"
)

args <- parser$parse_args()

Expand All @@ -33,17 +88,19 @@ moo <- load_moo_from_data_dir()

# run MOSuite
plot_pca(
moo,
count_type = args$count_type,
sub_count_type = args$sub_count_type,
principal_components = as.integer(parse_optional_vector(args$principal_components)),
feature_id_colname = args$feature_id_colname,
sample_id_colname = args$sample_id_colname,
samples_to_rename = parse_samples_to_rename(args$samples_to_rename),
group_colname = args$group_colname,
label_colname = args$label_colname,
point_size = args$point_size,
label_font_size = args$label_font_size,
color_values = parse_optional_vector(args$color_values),
plot_title = args$plot_title
moo,
count_type = args$count_type,
sub_count_type = args$sub_count_type,
principal_components = as.integer(parse_optional_vector(
args$principal_components
)),
feature_id_colname = args$feature_id_colname,
sample_id_colname = args$sample_id_colname,
samples_to_rename = parse_samples_to_rename(args$samples_to_rename),
group_colname = args$group_colname,
label_colname = args$label_colname,
point_size = args$point_size,
label_font_size = args$label_font_size,
color_values = parse_optional_vector(args$color_values),
plot_title = args$plot_title
)
11 changes: 11 additions & 0 deletions tests/test-setup.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
testthat::test_that("test setup has expected capsule files", {
repo_root <- normalizePath(file.path(testthat::test_path(), "..", ".."))

testthat::expect_true(file.exists(file.path(repo_root, "code", "main.R")))
testthat::expect_true(file.exists(file.path(repo_root, "code", "run")))
testthat::expect_true(file.exists(file.path(
repo_root,
".codeocean",
"app-panel.json"
)))
})
3 changes: 3 additions & 0 deletions tests/testthat.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
library(testthat)

test_dir(file.path("tests", "testthat"))
76 changes: 76 additions & 0 deletions tests/testthat/helper-panel.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
repo_path <- function(...) {
file.path(normalizePath(file.path(testthat::test_path(), "..", "..")), ...)
}

read_repo_file <- function(...) {
readLines(repo_path(...), warn = FALSE)
}

extract_main_arguments <- function(main_lines) {
main_text <- paste(main_lines, collapse = "\n")
matches <- regmatches(
main_text,
gregexpr(
'parser\\$add_argument\\(\\s*"--([[:alnum:]_]+)"',
main_text,
perl = TRUE
)
)[[1]]

sub('.*"--([[:alnum:]_]+)".*', "\\1", matches)
}

extract_panel_param_names <- function(panel_lines) {
matches <- regmatches(
panel_lines,
gregexpr(
'"param_name"[[:space:]]*:[[:space:]]*"([[:alnum:]_]+)"',
panel_lines
)
)
matches <- unlist(matches, use.names = FALSE)

sub(
'.*"param_name"[[:space:]]*:[[:space:]]*"([[:alnum:]_]+)".*',
"\\1",
matches
)
}

extract_panel_default <- function(panel_lines, param_name) {
param_line <- grep(
sprintf('"param_name"[[:space:]]*:[[:space:]]*"%s"', param_name),
panel_lines
)
if (length(param_line) != 1) {
return(NA_character_)
}

next_param <- grep('"param_name"[[:space:]]*:', panel_lines)
next_param <- next_param[next_param > param_line]
end_line <- if (length(next_param) > 0) {
next_param[[1]] - 1
} else {
length(panel_lines)
}
block <- panel_lines[param_line:end_line]
default_line <- grep('"default_value"[[:space:]]*:', block, value = TRUE)
if (length(default_line) != 1) {
return(NA_character_)
}

sub(
'.*"default_value"[[:space:]]*:[[:space:]]*"([^"]*)".*',
"\\1",
default_line
)
}

expect_same_values <- function(actual, expected, info = NULL) {
testthat::expect_setequal(actual, expected)
testthat::expect_equal(
length(actual),
length(unique(actual)),
info = "Values should not be duplicated"
)
}
Loading
Loading