From 8387dab3eb1fec399bb366dcb5740363a7b59216 Mon Sep 17 00:00:00 2001 From: phoman14 Date: Fri, 17 Jul 2026 11:50:25 -0400 Subject: [PATCH 01/11] Update syncweaver ref to FigOutSync --- .syncweaver-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.syncweaver-lock.json b/.syncweaver-lock.json index e770d45..94dcc04 100644 --- a/.syncweaver-lock.json +++ b/.syncweaver-lock.json @@ -5,7 +5,7 @@ "sources": { "code/MOSuite": { "repo_url": "https://github.com/CCBR/MOSuite", - "ref": "v0.3.2", + "ref": "FigOutSync", "git_sha": "f4465c58a7d04f5feb41d4455a019ca4946a4ca8" } } From 4aff3c6f32a78c4ab73585129ff4bbffff96e4f9 Mon Sep 17 00:00:00 2001 From: phoman14 Date: Fri, 17 Jul 2026 12:50:43 -0400 Subject: [PATCH 02/11] Restore syncweaver source ref --- .syncweaver-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.syncweaver-lock.json b/.syncweaver-lock.json index 94dcc04..e770d45 100644 --- a/.syncweaver-lock.json +++ b/.syncweaver-lock.json @@ -5,7 +5,7 @@ "sources": { "code/MOSuite": { "repo_url": "https://github.com/CCBR/MOSuite", - "ref": "FigOutSync", + "ref": "v0.3.2", "git_sha": "f4465c58a7d04f5feb41d4455a019ca4946a4ca8" } } From 7966134932bbd22312604ee281e3ca8d26e7fe87 Mon Sep 17 00:00:00 2001 From: phoman14 Date: Fri, 17 Jul 2026 20:45:22 +0000 Subject: [PATCH 03/11] Parameter defaults --- .codeocean/app-panel.json | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.codeocean/app-panel.json b/.codeocean/app-panel.json index 4d81488..5e4585f 100644 --- a/.codeocean/app-panel.json +++ b/.codeocean/app-panel.json @@ -16,18 +16,18 @@ "id": "7Rr6IxOMDucKMImp", "name": "Input Data Parameters", "description": "Options for defining input data", - "icon": "\ud83d\udcc1" + "icon": "📁" }, { "id": "EzTg1ivlFDHEy9PI", "name": "Basic", - "icon": "\ud83d\udcc2" + "icon": "📂" }, { "id": "FvI4Z2eb9sjL47Jt", "name": "Advanced", "description": "Advanced parameters", - "icon": "\ud83d\udcc2" + "icon": "📂" } ], "parameters": [ @@ -66,7 +66,7 @@ "help_text": "These values must be in the contrasts column", "type": "text", "value_type": "string", - "default_value": "B-A,B-C,C-A", + "default_value": "B-A, B-C, C-A", "required": true }, { @@ -77,8 +77,7 @@ "description": "Comma-separated list of columns to be used as covariates in linear modeling; must include the contrast column", "type": "text", "value_type": "string", - "default_value": "Group,Batch", - "required": true + "default_value": "Batch" }, { "id": "WoZUI91NYysibcVj", @@ -170,4 +169,4 @@ "file_name": "figures/diff/mean-variance.png" } ] -} +} \ No newline at end of file From da748887a32dd5e70c5f52bc20144c5bc0d6632b Mon Sep 17 00:00:00 2001 From: phoman14 Date: Thu, 30 Jul 2026 21:38:17 -0400 Subject: [PATCH 04/11] chore(syncweaver): update MOSuite source to main _commit message is ai-generated_ --- .syncweaver-lock.json | 4 +- code/MOSuite/.Rbuildignore | 30 +- code/MOSuite/.github/CODEOWNERS | 1 + .../.github/workflows/R-CMD-check.yaml | 7 +- .../MOSuite/.github/workflows/auto-format.yml | 11 +- .../workflows/syncweaver-source-dispatch.yml | 92 + code/MOSuite/.gitignore | 29 +- code/MOSuite/.lintr | 1 + code/MOSuite/.pre-commit-config.yaml | 7 +- code/MOSuite/.vscode/extensions.json | 5 - code/MOSuite/.vscode/settings.json | 13 - code/MOSuite/AGENTS.md | 58 + code/MOSuite/CITATION.cff | 101 +- code/MOSuite/DESCRIPTION | 9 +- code/MOSuite/NAMESPACE | 6 + code/MOSuite/NEWS.md | 19 +- code/MOSuite/R/batch-correction.R | 124 +- code/MOSuite/R/clean.R | 60 +- code/MOSuite/R/colors.R | 323 +- code/MOSuite/R/counts.R | 70 + code/MOSuite/R/data.R | 14 + code/MOSuite/R/differential.R | 4 +- code/MOSuite/R/filter.R | 243 +- code/MOSuite/R/normalize.R | 63 +- code/MOSuite/R/plot_heatmap.R | 377 +- code/MOSuite/R/plot_histogram.R | 264 +- code/MOSuite/R/plot_pca.R | 310 +- code/MOSuite/R/plot_read_depth.R | 79 +- code/MOSuite/R/plot_volcano_enhanced.R | 447 +- code/MOSuite/R/plot_volcano_summary.R | 445 +- code/MOSuite/R/plots.R | 182 + code/MOSuite/R/reexports.R | 5 + code/MOSuite/R/render_report.R | 64 + code/MOSuite/R/volcano.R | 55 + code/MOSuite/SECURITY.md | 18 + code/MOSuite/_pkgdown.yml | 5 +- code/MOSuite/codemeta.json | 2 +- code/MOSuite/data-raw/mosuite_palette.R | 26 + code/MOSuite/data/mosuite_palette.rda | Bin 0 -> 174 bytes code/MOSuite/docker/Dockerfile | 4 - code/MOSuite/inst/extdata/example_script.sh | 19 - .../Batch_Correction_CCBR_.code-template.json | 381 -- .../Clean_Raw_Counts_CCBR_.code-template.json | 119 - .../DEG_Analysis_CCBR_.code-template.json | 153 - .../DEG_Gene_List_CCBR_.code-template.json | 316 - ...xpression_Heatmap_CCBR_.code-template.json | 571 -- ...Filter_Low_Counts_CCBR_.code-template.json | 419 -- ...lkTemplate_parameterTo_MOSuiteMapping.json | 350 -- .../Normalization_CCBR_.code-template.json | 378 -- .../PCA_3D_CCBR_.code-template.json | 229 - .../Venn_Diagram_CCBR_.code-template.json | 1087 ---- ...ano_Plot_Enhanced_CCBR_.code-template.json | 310 - ...cano_Plot_Summary_CCBR_.code-template.json | 5126 ---------------- .../galaxy/0_nidap-1.0/missing_parameters.csv | 12 - .../batch_correct_counts.json | 167 - .../1_mosuite-templates/clean_raw_counts.json | 159 - .../create_multiOmicDataSet_from_files.json | 89 - .../1_mosuite-templates/diff_counts.json | 189 - .../1_mosuite-templates/filter_counts.json | 433 -- .../1_mosuite-templates/filter_diff.json | 357 -- .../initialize-templates.py | 57 - .../1_mosuite-templates/normalize_counts.json | 414 -- .../plot_expr_heatmap.json | 567 -- .../1_mosuite-templates/plot_pca_2d.json | 296 - .../1_mosuite-templates/plot_pca_3d.json | 217 - .../plot_venn_diagram.json | 1106 ---- .../plot_volcano_enhanced.json | 331 -- .../plot_volcano_summary.json | 5125 ---------------- .../write_multiOmicDataSet_properties.json | 53 - .../2_blueprints/batch_correct_counts.json | 161 - .../galaxy/2_blueprints/clean_raw_counts.json | 156 - .../create_multiOmicDataSet_from_files.json | 83 - .../galaxy/2_blueprints/diff_counts.json | 181 - .../galaxy/2_blueprints/filter_counts.json | 427 -- .../galaxy/2_blueprints/filter_diff.json | 345 -- .../galaxy/2_blueprints/normalize_counts.json | 408 -- .../2_blueprints/plot_expr_heatmap.json | 558 -- .../galaxy/2_blueprints/plot_pca_2d.json | 275 - .../galaxy/2_blueprints/plot_pca_3d.json | 212 - .../2_blueprints/plot_venn_diagram.json | 1100 ---- .../2_blueprints/plot_volcano_enhanced.json | 329 -- .../2_blueprints/plot_volcano_summary.json | 5129 ----------------- .../write_multiOmicDataSet_properties.json | 52 - code/MOSuite/inst/extdata/galaxy/galaxy.R | 261 - .../common/batch_correct_counts.json | 16 - .../json_args/common/clean_raw_counts.json | 14 - .../create_multiOmicDataSet_from_files.json | 5 - .../extdata/json_args/common/diff_counts.json | 25 - .../json_args/common/filter_counts.json | 48 - .../extdata/json_args/common/filter_diff.json | 38 - .../json_args/common/normalize_counts.json | 33 - .../json_args/common/plot_expr_heatmap.json | 80 - .../extdata/json_args/common/plot_pca_2d.json | 36 - .../extdata/json_args/common/plot_pca_3d.json | 31 - .../json_args/common/plot_venn_diagram.json | 40 - .../common/plot_volcano_enhanced.json | 33 - .../common/plot_volcano_summary.json | 52 - .../write_multiOmicDataSet_properties.json | 6 - .../defaults/batch_correct_counts.json | 16 - .../json_args/defaults/clean_raw_counts.json | 15 - .../create_multiOmicDataSet_from_files.json | 8 - .../json_args/defaults/diff_counts.json | 18 - .../json_args/defaults/filter_counts.json | 37 - .../json_args/defaults/filter_diff.json | 29 - .../json_args/defaults/normalize_counts.json | 35 - .../json_args/defaults/plot_expr_heatmap.json | 51 - .../json_args/defaults/plot_pca_2d.json | 25 - .../json_args/defaults/plot_pca_3d.json | 21 - .../json_args/defaults/plot_venn_diagram.json | 35 - .../defaults/plot_volcano_enhanced.json | 33 - .../defaults/plot_volcano_summary.json | 47 - .../write_multiOmicDataSet_properties.json | 5 - code/MOSuite/inst/quarto/report.qmd | 165 + code/MOSuite/man/batch_correct_counts.Rd | 87 +- code/MOSuite/man/clean_raw_counts.Rd | 10 + code/MOSuite/man/diff_counts.Rd | 2 +- code/MOSuite/man/display_colors.Rd | 24 + code/MOSuite/man/display_palette.Rd | 24 + code/MOSuite/man/filter_counts.Rd | 45 +- code/MOSuite/man/get_colors_lst.Rd | 15 +- code/MOSuite/man/get_colors_vctr.Rd | 22 +- code/MOSuite/man/get_observed_values.Rd | 22 + code/MOSuite/man/get_random_colors.Rd | 5 +- code/MOSuite/man/log_transform_counts.Rd | 35 + code/MOSuite/man/mosuite_palette.Rd | 25 + code/MOSuite/man/normalize_counts.Rd | 32 +- .../man/plot_corr_heatmap-data.frame.Rd | 4 +- .../man/plot_corr_heatmap-multiOmicDataSet.Rd | 9 + code/MOSuite/man/plot_corr_heatmap.Rd | 5 +- code/MOSuite/man/plot_expr_heatmap.Rd | 33 +- code/MOSuite/man/plot_histogram.data.frame.Rd | 13 +- .../man/plot_histogram.multiOmicDataSet.Rd | 9 + code/MOSuite/man/plot_palette.Rd | 21 + code/MOSuite/man/plot_pca.Rd | 6 + code/MOSuite/man/plot_pca_2d.Rd | 88 +- code/MOSuite/man/plot_pca_3d.Rd | 44 +- .../MOSuite/man/plot_read_depth.data.frame.Rd | 10 + .../man/plot_read_depth.multiOmicDataSet.Rd | 9 + code/MOSuite/man/plot_venn_diagram.Rd | 3 +- code/MOSuite/man/plot_volcano_enhanced.Rd | 172 +- code/MOSuite/man/plot_volcano_summary.Rd | 163 +- code/MOSuite/man/reexports.Rd | 3 +- code/MOSuite/man/remove_low_count_genes.Rd | 16 +- code/MOSuite/man/render_report.Rd | 54 + code/MOSuite/man/resolve_plot_colors.Rd | 33 + code/MOSuite/man/resolve_volcano_colnames.Rd | 32 + code/MOSuite/man/select_mosuite_colors.Rd | 22 + code/MOSuite/man/set_color_pal.Rd | 12 +- code/MOSuite/tests/testthat/_snaps/E2E.md | 2 - .../testthat/_snaps/plot_volcano_enhanced.md | 16 + .../testthat/_snaps/plot_volcano_summary.md | 32 +- .../tests/testthat/_snaps/plots/heatmap.png | Bin 0 -> 23016 bytes .../testthat/_snaps/plots/read_depth.png | Bin 0 -> 154535 bytes .../testthat/data/example_args.json} | 0 .../MOSuite/tests/testthat/helper-functions.R | 54 + .../tests/testthat/test-batch-correction.R | 389 +- code/MOSuite/tests/testthat/test-clean.R | 187 + code/MOSuite/tests/testthat/test-cli.R | 75 +- code/MOSuite/tests/testthat/test-colors.R | 368 +- code/MOSuite/tests/testthat/test-filter.R | 639 ++ code/MOSuite/tests/testthat/test-normalize.R | 343 ++ .../tests/testthat/test-plot_heatmap.R | 321 ++ .../tests/testthat/test-plot_histogram.R | 296 + code/MOSuite/tests/testthat/test-plot_pca.R | 451 +- .../tests/testthat/test-plot_read_depth.R | 60 + .../testthat/test-plot_volcano_enhanced.R | 586 +- .../testthat/test-plot_volcano_summary.R | 549 +- code/MOSuite/tests/testthat/test-plots.R | 15 +- .../tests/testthat/test-render_report.R | 37 + code/MOSuite/tests/testthat/test-volcano.R | 87 + code/MOSuite/vignettes/cli.Rmd | 218 - code/MOSuite/vignettes/visualization.Rmd | 186 +- 172 files changed, 7953 insertions(+), 31348 deletions(-) create mode 100644 code/MOSuite/.github/CODEOWNERS create mode 100644 code/MOSuite/.github/workflows/syncweaver-source-dispatch.yml delete mode 100644 code/MOSuite/.vscode/extensions.json delete mode 100644 code/MOSuite/.vscode/settings.json create mode 100644 code/MOSuite/AGENTS.md create mode 100644 code/MOSuite/R/render_report.R create mode 100644 code/MOSuite/R/volcano.R create mode 100644 code/MOSuite/SECURITY.md create mode 100644 code/MOSuite/data-raw/mosuite_palette.R create mode 100644 code/MOSuite/data/mosuite_palette.rda delete mode 100644 code/MOSuite/inst/extdata/example_script.sh delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Batch_Correction_CCBR_.code-template.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Clean_Raw_Counts_CCBR_.code-template.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/DEG_Analysis_CCBR_.code-template.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/DEG_Gene_List_CCBR_.code-template.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Expression_Heatmap_CCBR_.code-template.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Filter_Low_Counts_CCBR_.code-template.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/NIDAPBulkTemplate_parameterTo_MOSuiteMapping.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Normalization_CCBR_.code-template.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/PCA_3D_CCBR_.code-template.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Venn_Diagram_CCBR_.code-template.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Volcano_Plot_Enhanced_CCBR_.code-template.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Volcano_Plot_Summary_CCBR_.code-template.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/missing_parameters.csv delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/batch_correct_counts.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/clean_raw_counts.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/create_multiOmicDataSet_from_files.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/diff_counts.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/filter_counts.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/filter_diff.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/initialize-templates.py delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/normalize_counts.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_expr_heatmap.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_pca_2d.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_pca_3d.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_venn_diagram.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_volcano_enhanced.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_volcano_summary.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/write_multiOmicDataSet_properties.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/batch_correct_counts.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/clean_raw_counts.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/create_multiOmicDataSet_from_files.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/diff_counts.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/filter_counts.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/filter_diff.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/normalize_counts.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_expr_heatmap.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_pca_2d.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_pca_3d.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_venn_diagram.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_volcano_enhanced.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_volcano_summary.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/2_blueprints/write_multiOmicDataSet_properties.json delete mode 100644 code/MOSuite/inst/extdata/galaxy/galaxy.R delete mode 100644 code/MOSuite/inst/extdata/json_args/common/batch_correct_counts.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/clean_raw_counts.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/create_multiOmicDataSet_from_files.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/diff_counts.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/filter_counts.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/filter_diff.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/normalize_counts.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/plot_expr_heatmap.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/plot_pca_2d.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/plot_pca_3d.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/plot_venn_diagram.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/plot_volcano_enhanced.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/plot_volcano_summary.json delete mode 100644 code/MOSuite/inst/extdata/json_args/common/write_multiOmicDataSet_properties.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/batch_correct_counts.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/clean_raw_counts.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/create_multiOmicDataSet_from_files.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/diff_counts.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/filter_counts.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/filter_diff.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/normalize_counts.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/plot_expr_heatmap.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/plot_pca_2d.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/plot_pca_3d.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/plot_venn_diagram.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/plot_volcano_enhanced.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/plot_volcano_summary.json delete mode 100644 code/MOSuite/inst/extdata/json_args/defaults/write_multiOmicDataSet_properties.json create mode 100644 code/MOSuite/inst/quarto/report.qmd create mode 100644 code/MOSuite/man/display_colors.Rd create mode 100644 code/MOSuite/man/display_palette.Rd create mode 100644 code/MOSuite/man/get_observed_values.Rd create mode 100644 code/MOSuite/man/log_transform_counts.Rd create mode 100644 code/MOSuite/man/mosuite_palette.Rd create mode 100644 code/MOSuite/man/plot_palette.Rd create mode 100644 code/MOSuite/man/render_report.Rd create mode 100644 code/MOSuite/man/resolve_plot_colors.Rd create mode 100644 code/MOSuite/man/resolve_volcano_colnames.Rd create mode 100644 code/MOSuite/man/select_mosuite_colors.Rd create mode 100644 code/MOSuite/tests/testthat/_snaps/plots/heatmap.png create mode 100644 code/MOSuite/tests/testthat/_snaps/plots/read_depth.png rename code/MOSuite/{inst/extdata/example.json => tests/testthat/data/example_args.json} (100%) create mode 100644 code/MOSuite/tests/testthat/test-render_report.R create mode 100644 code/MOSuite/tests/testthat/test-volcano.R delete mode 100644 code/MOSuite/vignettes/cli.Rmd diff --git a/.syncweaver-lock.json b/.syncweaver-lock.json index e770d45..dd6fdbe 100644 --- a/.syncweaver-lock.json +++ b/.syncweaver-lock.json @@ -5,8 +5,8 @@ "sources": { "code/MOSuite": { "repo_url": "https://github.com/CCBR/MOSuite", - "ref": "v0.3.2", - "git_sha": "f4465c58a7d04f5feb41d4455a019ca4946a4ca8" + "ref": "main", + "git_sha": "c5840edd0b81696208363c7d5b402116392f8f97" } } } diff --git a/code/MOSuite/.Rbuildignore b/code/MOSuite/.Rbuildignore index 7ee19e0..c302c77 100644 --- a/code/MOSuite/.Rbuildignore +++ b/code/MOSuite/.Rbuildignore @@ -1,37 +1,39 @@ -^renv$ -^renv\.lock$ ^_pkgdown\.yml$ +^[.]?air[.]toml$ ^\.github$ ^\.lintr$ +^\.posit$ ^\.pre-commit-config\.yaml$ ^\.prettierignore$ ^\.prettierrc$ ^\.Rproj\.user$ +^\.vscode$ ^CITATION\.cff$ ^codemeta\.json$ ^data-raw$ ^doc$ -^Dockerfile$ ^docker$ +^Dockerfile$ ^docs$ ^figures$ +^inst/quarto/report_files$ ^LICENSE\.md$ ^Meta$ +^moo_input\.rds$ ^MOSuite\.Rproj$ ^pkgdown$ -^README\.Rmd$ -^README\.html$ -^README_files$ -^Rplots\.pdf$ -^moo_input\.rds$ ^plot-volc-enh\.json$ -^volc-sum-params\.json$ -^report_files$ -^inst/quarto/report_files$ +^README.*$ +^renv\.lock$ +^renv$ +^report +^Rplots\.pdf$ +^SECURITY\.md$ ^tests/figures$ +^vignettes/cli\.Rmd$ ^vignettes/figures/$ ^vignettes/memory\.Rmd$ -^vignettes/cli\.Rmd$ +^volc-sum-params\.json$ VennDiagram.*\.log -^[.]?air[.]toml$ -^\.vscode$ +^\.posit/assistant$ +^AGENTS\.md$ diff --git a/code/MOSuite/.github/CODEOWNERS b/code/MOSuite/.github/CODEOWNERS new file mode 100644 index 0000000..672346f --- /dev/null +++ b/code/MOSuite/.github/CODEOWNERS @@ -0,0 +1 @@ +* @kelly-sovacool diff --git a/code/MOSuite/.github/workflows/R-CMD-check.yaml b/code/MOSuite/.github/workflows/R-CMD-check.yaml index e4a69e6..d2449c3 100644 --- a/code/MOSuite/.github/workflows/R-CMD-check.yaml +++ b/code/MOSuite/.github/workflows/R-CMD-check.yaml @@ -6,7 +6,6 @@ on: push: branches: [main, master] pull_request: - branches: [main, master] workflow_dispatch: concurrency: @@ -23,8 +22,8 @@ jobs: fail-fast: false matrix: config: - - { os: ubuntu-latest, r: 'release' } - - { os: ubuntu-latest, r: 'oldrel-1' } + - { os: ubuntu-latest, r: "release" } + - { os: ubuntu-latest, r: "oldrel-1" } runs-on: ${{ matrix.config.os }} name: ${{ matrix.config.os }} (${{ matrix.config.r }}) env: @@ -51,7 +50,7 @@ jobs: - uses: actions/checkout@v6 - uses: r-lib/actions/setup-r@v2 with: - r-version: '4.5' + r-version: "4.5" use-public-rspm: true - uses: r-lib/actions/setup-r-dependencies@v2 with: diff --git a/code/MOSuite/.github/workflows/auto-format.yml b/code/MOSuite/.github/workflows/auto-format.yml index 758c5ba..9be747c 100644 --- a/code/MOSuite/.github/workflows/auto-format.yml +++ b/code/MOSuite/.github/workflows/auto-format.yml @@ -3,7 +3,6 @@ name: auto-format on: workflow_dispatch: pull_request: - branches: [ main, master ] permissions: contents: write @@ -26,7 +25,7 @@ jobs: private-key: ${{ secrets.CCBR_BOT_PRIVATE_KEY }} owner: ${{ github.repository_owner }} - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: token: ${{ steps.generate-token.outputs.token }} fetch-depth: 0 @@ -40,7 +39,7 @@ jobs: - uses: r-lib/actions/setup-r@v2 with: - r-version: '4.5' + r-version: "4.5" use-public-rspm: true - uses: r-lib/actions/setup-r-dependencies@v2 @@ -48,12 +47,6 @@ jobs: extra-packages: local::. needs: dev - - name: update Galaxy blueprints - shell: Rscript {0} - run: | - source('inst/extdata/galaxy/galaxy.R') - write_package_json_blueprints() - - name: render README.Rmd & docs shell: Rscript {0} run: | diff --git a/code/MOSuite/.github/workflows/syncweaver-source-dispatch.yml b/code/MOSuite/.github/workflows/syncweaver-source-dispatch.yml new file mode 100644 index 0000000..74a4450 --- /dev/null +++ b/code/MOSuite/.github/workflows/syncweaver-source-dispatch.yml @@ -0,0 +1,92 @@ +name: syncweaver-source-dispatch + +on: + release: + types: [published] + workflow_dispatch: + inputs: + source_ref: + description: Optional source ref to dispatch (defaults to release tag for release events, or current ref for manual runs). + required: false + type: string + source_repo: + description: Optional source repository override in OWNER/REPO format (defaults to current repository). + required: false + type: string + orchestrator-repo: + description: Optional orchestrator repository override in OWNER/REPO format. + required: false + default: NIDAP-Community/syncweaver-orchestrator + type: string + +permissions: + contents: read + +jobs: + notify-syncweaver: + runs-on: ubuntu-latest + env: + SOURCE_REPOSITORY: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.source_repo || github.repository }} + SOURCE_REF: ${{ github.event_name == 'release' && github.event.release.tag_name || github.event.inputs.source_ref || github.ref_name }} + ORCHESTRATOR_REPO: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs['orchestrator-repo'] || vars['orchestrator-repo'] || 'NIDAP-Community/syncweaver-orchestrator' }} + steps: + - name: Validate dispatch payload + shell: bash + run: | + set -euo pipefail + if [[ -z "${SOURCE_REPOSITORY//[[:space:]]/}" ]]; then + echo "Error: source repository cannot be empty." >&2 + exit 1 + fi + if [[ -z "${SOURCE_REF//[[:space:]]/}" ]]; then + echo "Error: source ref cannot be empty." >&2 + exit 1 + fi + if [[ -z "${ORCHESTRATOR_REPO//[[:space:]]/}" ]]; then + echo "Error: orchestrator repository cannot be empty." >&2 + exit 1 + fi + if [[ "${ORCHESTRATOR_REPO}" != */* ]]; then + echo "Error: orchestrator repository must be in OWNER/REPO format." >&2 + exit 1 + fi + if [[ -z "${{ vars.CCBR_BOT_APP_ID }}" ]]; then + echo "Error: vars.CCBR_BOT_APP_ID is required to generate a dispatch token." >&2 + exit 1 + fi + if [[ -z "${{ secrets.CCBR_BOT_PRIVATE_KEY }}" ]]; then + echo "Error: secrets.CCBR_BOT_PRIVATE_KEY is required to generate a dispatch token." >&2 + exit 1 + fi + + - name: Resolve orchestrator repository owner and name + id: orchestrator_repo + shell: bash + run: | + set -euo pipefail + owner="${ORCHESTRATOR_REPO%%/*}" + repo="${ORCHESTRATOR_REPO#*/}" + if [[ -z "${owner}" || -z "${repo}" ]]; then + echo "Error: failed to parse orchestrator repository '${ORCHESTRATOR_REPO}'." >&2 + exit 1 + fi + echo "owner=${owner}" >> "$GITHUB_OUTPUT" + echo "repository=${repo}" >> "$GITHUB_OUTPUT" + + - name: Generate CCBR-bot token + id: ccbr_bot + uses: actions/create-github-app-token@v3 + with: + client-id: ${{ vars.CCBR_BOT_APP_ID }} + private-key: ${{ secrets.CCBR_BOT_PRIVATE_KEY }} + owner: ${{ steps.orchestrator_repo.outputs.owner }} + repositories: ${{ steps.orchestrator_repo.outputs.repository }} + + - name: Dispatch syncweaver-update-hosts workflow in orchestrator repo + uses: peter-evans/repository-dispatch@v4 + with: + token: ${{ steps.ccbr_bot.outputs.token }} + repository: ${{ env.ORCHESTRATOR_REPO }} + event-type: syncweaver-update-hosts + client-payload: >- + {"source_repository": ${{ toJson(env.SOURCE_REPOSITORY) }}, "ref": ${{ toJson(env.SOURCE_REF) }}} diff --git a/code/MOSuite/.gitignore b/code/MOSuite/.gitignore index a7f1be5..4d2ccac 100644 --- a/code/MOSuite/.gitignore +++ b/code/MOSuite/.gitignore @@ -1,21 +1,24 @@ -.Rproj.user -.Rhistory -.Rdata -.httr-oauth .DS_Store -.quarto -docs -inst/doc +*_files/ +**/figures/ +/.github/plans/ +/.httr-oauth +/.posit/ +/.quarto +/.Rdata +/.Rhistory +/.Rproj.user +/.vscode/ /doc/ +/docs +/inst/doc /Meta/ /README.html -**/figures/ -VennDiagram.*.log -*_files/ -tests/testthat/Rplots.pdf +/tests/testthat/Rplots.pdf /tmp -vignettes/args*.json -Rplots.pdf +/vignettes/args*.json moo_input.rds plot-volc-enh.json +Rplots.pdf +VennDiagram.*.log volc-sum-params.json diff --git a/code/MOSuite/.lintr b/code/MOSuite/.lintr index e636784..4250828 100644 --- a/code/MOSuite/.lintr +++ b/code/MOSuite/.lintr @@ -3,6 +3,7 @@ linters: linters_with_defaults( commented_code_linter = NULL, object_name_linter = NULL, object_length_linter = object_length_linter(60L), + object_usage_linter = NULL, return_linter = return_linter( return_style = "explicit" ), diff --git a/code/MOSuite/.pre-commit-config.yaml b/code/MOSuite/.pre-commit-config.yaml index a09d9f3..6910bb6 100644 --- a/code/MOSuite/.pre-commit-config.yaml +++ b/code/MOSuite/.pre-commit-config.yaml @@ -20,20 +20,19 @@ repos: - id: trailing-whitespace # spell check - repo: https://github.com/codespell-project/codespell - rev: v2.4.2 + rev: v2.4.3 hooks: - id: codespell args: ["-I=.github/WORDLIST.txt"] # R formatting - repo: https://github.com/posit-dev/air-pre-commit - rev: 0.9.0 + rev: 0.11.0 hooks: - id: air-format - repo: https://github.com/lorenzwalthert/precommit - rev: v0.4.3.9025 + rev: v0.4.3.9029 hooks: - id: parsable-R - - id: readme-rmd-rendered - id: use-tidy-description - id: lintr args: [--warn_only] diff --git a/code/MOSuite/.vscode/extensions.json b/code/MOSuite/.vscode/extensions.json deleted file mode 100644 index 344f76e..0000000 --- a/code/MOSuite/.vscode/extensions.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "recommendations": [ - "Posit.air-vscode" - ] -} diff --git a/code/MOSuite/.vscode/settings.json b/code/MOSuite/.vscode/settings.json deleted file mode 100644 index 61ac215..0000000 --- a/code/MOSuite/.vscode/settings.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "[r]": { - "editor.formatOnSave": true, - "editor.defaultFormatter": "Posit.air-vscode" - }, - "[quarto]": { - "editor.formatOnSave": true, - "editor.defaultFormatter": "quarto.quarto" - }, - "chat.tools.terminal.autoApprove": { - "timeout": true - } -} diff --git a/code/MOSuite/AGENTS.md b/code/MOSuite/AGENTS.md new file mode 100644 index 0000000..f0a7ede --- /dev/null +++ b/code/MOSuite/AGENTS.md @@ -0,0 +1,58 @@ +# multiOmicsSuite + +## Description + +multiOmicsSuite (`MOSuite`) is an R package for differential multi-omic analysis. +It defines an S7 class called `multiOmicDataSet` to store data and analyses from +multi-omic experiments. + +Development of MOSuite follows the R packages 2nd edition (https://r-pkgs.org/), +with a few minor exceptions noted below. +Helper functions from `usethis` and `devtools` are used extensively for development tasks. + +## Package conventions + +- **Internal functions should have roxygen2 documentation** (with `@keywords internal`). Do not strip roxygen docs from internal functions. +- R code should pass `lintr` and `air format` (run `air format .` from the package root). +- Tests should be written with `testthat`. +- The package must pass `devtools::check()`. +- R code should adhere to the tidyverse style guide. https://style.tidyverse.org/ +- Only include one return statement at the end of a function. Explicit returns are preferred but not required for R functions. + +## Commit messages + +- Commit messages must follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) (as enforced in `CONTRIBUTING.md`). +- Generate messages from staged changes only (`git diff --staged`); do not include unrelated work. +- Commits should be atomic: one logical change per commit. +- If mixed changes are present, split into multiple logical commits; the number of commits does not need to equal the number of files changed. +- Subject format must be: `(optional-scope): short imperative summary` (<=72 chars), e.g., `fix(profile): update release table parser`. +- Add a body only when needed to explain **why** and notable impact; never include secrets, tokens, PHI, or large diffs. +- For AI-assisted commits, add this final italicized footer line in the commit message body: _commit message is ai-generated_ + +## Pull request (PR) process + +- When opening a PR, use the request template (`.github/PULL_REQUEST_TEMPLATE.md`) and fill out all sections of the template in the PR description. +- Do not allow the developer to proceed with opening a PR if it does not fill out all sections of the template. +- Before a PR can be moved from draft to "ready for review", all of the relevant checklist items must be checked, and any +irrelevant checklist items should be crossed out. +- If code is AI-generated, the PR should be labeled `generated-by-AI`. There should be a brief, concise statement in the PR description of how AI was used in creating the PR (model used, high-level prompt intent, manual review confirmation). +- When new features, bug fixes, or other behavioral changes are introduced to the code, +unit tests must be added or updated to cover the new or changed functionality. +- If there are any API or other user-facing changes, the documentation must be updated both inline via roxygen comments and long-form docs in the `vignettes/` directory as R Markdown files. +- The `R-CMD-check` github actions workflow must pass before the PR can be approved. + +### Changelog + +The changelog for the repository is maintained in `NEWS.md` at the root of the repository. +Each pull request that introduces user-facing changes must include a concise +entry with the PR number and author username tagged. +Developer-only changes (i.e. updates to CI workflows, development notes, etc.) +should never be included in the changelog. + +Example: + +``` +## development version + +- Fix bug in `detect_absolute_paths()` to ignore comments. (#123, @username) +``` diff --git a/code/MOSuite/CITATION.cff b/code/MOSuite/CITATION.cff index 9768535..d08f0fc 100644 --- a/code/MOSuite/CITATION.cff +++ b/code/MOSuite/CITATION.cff @@ -8,7 +8,7 @@ message: 'To cite package "MOSuite" in publications use:' type: software license: MIT title: 'MOSuite: R package for differential multi-omics analysis' -version: 0.3.2 +version: 0.4.0.9000 doi: 10.5281/zenodo.16371580 identifiers: - description: Archived snapshots of all versions @@ -71,14 +71,11 @@ references: url: https://www.R-project.org/ authors: - name: R Core Team - website: https://ror.org/02zz1nj61 institution: name: R Foundation for Statistical Computing - website: https://ror.org/05qewa988 address: Vienna, Austria year: '2026' - doi: 10.32614/R.manuals - version: '>= 4.0.0' + version: '>= 4.1.0' - type: software title: assertthat abstract: 'assertthat: Easy Pre and Post Assertions' @@ -90,6 +87,18 @@ references: email: hadley@rstudio.com year: '2026' doi: 10.32614/CRAN.package.assertthat +- type: software + title: cli + abstract: 'cli: Helpers for Developing Command Line Interfaces' + notes: Imports + url: https://cli.r-lib.org + repository: https://CRAN.R-project.org/package=cli + authors: + - family-names: Csárdi + given-names: Gábor + email: gabor@posit.co + year: '2026' + doi: 10.32614/CRAN.package.cli - type: software title: dendextend abstract: 'dendextend: Extending ''dendrogram'' Functionality in R' @@ -234,6 +243,16 @@ references: orcid: https://orcid.org/0000-0002-6983-2759 year: '2026' doi: 10.32614/CRAN.package.glue +- type: software + title: grid + abstract: 'R: A Language and Environment for Statistical Computing' + notes: Imports + authors: + - name: R Core Team + institution: + name: R Foundation for Statistical Computing + address: Vienna, Austria + year: '2026' - type: software title: htmlwidgets abstract: 'htmlwidgets: HTML Widgets for R' @@ -280,8 +299,51 @@ references: authors: - family-names: Smyth given-names: Gordon - email: smyth@wehi.edu.au - orcid: https://orcid.org/0000-0001-9221-2892 + - family-names: Hu + given-names: Yifang + - family-names: Ritchie + given-names: Matthew + - family-names: Silver + given-names: Jeremy + - family-names: Wettenhall + given-names: James + - family-names: McCarthy + given-names: Davis + - family-names: Wu + given-names: Di + - family-names: Shi + given-names: Wei + - family-names: Phipson + given-names: Belinda + - family-names: Lun + given-names: Aaron + - family-names: Thorne + given-names: Natalie + - family-names: Oshlack + given-names: Alicia + - family-names: Graaf + given-names: Carolyn + name-particle: de + - family-names: Chen + given-names: Yunshun + - family-names: Giner + given-names: Goknur + - family-names: Langaas + given-names: Mette + - family-names: Ferkingstad + given-names: Egil + - family-names: Davy + given-names: Marcus + - family-names: Pepin + given-names: Francois + - family-names: Choi + given-names: Dongseok + - family-names: Law + given-names: Charity + - family-names: Li + given-names: Mengbo + - family-names: Chen + given-names: Lizhong year: '2026' doi: 10.18129/B9.bioc.limma - type: software @@ -303,13 +365,10 @@ references: notes: Imports authors: - name: R Core Team - website: https://ror.org/02zz1nj61 institution: name: R Foundation for Statistical Computing - website: https://ror.org/05qewa988 address: Vienna, Austria year: '2026' - doi: 10.32614/R.manuals - type: software title: options abstract: 'options: Simple, Consistent Package Options' @@ -432,13 +491,10 @@ references: notes: Imports authors: - name: R Core Team - website: https://ror.org/02zz1nj61 institution: name: R Foundation for Statistical Computing - website: https://ror.org/05qewa988 address: Vienna, Austria year: '2026' - doi: 10.32614/R.manuals - type: software title: stringr abstract: 'stringr: Simple, Consistent Wrappers for Common String Operations' @@ -679,7 +735,7 @@ references: authors: - family-names: Auguie given-names: Baptiste - email: baptiste.auguie@gmail.com + email: baptiste.auguie@vuw.ac.nz year: '2026' doi: 10.32614/CRAN.package.gridExtra - type: software @@ -731,6 +787,23 @@ references: given-names: Jim year: '2026' doi: 10.32614/CRAN.package.plotrix +- type: software + title: quarto + abstract: 'quarto: R Interface to ''Quarto'' Markdown Publishing System' + notes: Suggests + url: https://quarto-dev.github.io/quarto-r/ + repository: https://CRAN.R-project.org/package=quarto + authors: + - family-names: Allaire + given-names: JJ + email: jj@posit.co + orcid: https://orcid.org/0000-0003-0174-9868 + - family-names: Dervieux + given-names: Christophe + email: cderv@posit.co + orcid: https://orcid.org/0000-0003-4474-2498 + year: '2026' + doi: 10.32614/CRAN.package.quarto - type: software title: RColorBrewer abstract: 'RColorBrewer: ColorBrewer Palettes' diff --git a/code/MOSuite/DESCRIPTION b/code/MOSuite/DESCRIPTION index 8f728ed..c7a926b 100644 --- a/code/MOSuite/DESCRIPTION +++ b/code/MOSuite/DESCRIPTION @@ -1,6 +1,6 @@ Package: MOSuite Title: R package for differential multi-omics analysis -Version: 0.3.2 +Version: 0.4.0.9000 Authors@R: c( person("Kelly", "Sovacool", , "kelly.sovacool@nih.gov", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-3283-829X")), @@ -22,15 +22,17 @@ License: MIT + file LICENSE URL: https://github.com/CCBR/MOSuite, https://ccbr.github.io/MOSuite/ BugReports: https://github.com/CCBR/MOSuite/issues Depends: - R (>= 4.0.0) + R (>= 4.1.0) Imports: assertthat, + cli, dendextend, DESeq2, dplyr, edgeR, ggplot2, glue, + grid, htmlwidgets, jsonlite, limma, @@ -63,6 +65,7 @@ Suggests: lobstr, patchwork, plotrix, + quarto, RColorBrewer, Rd2md, readr, @@ -82,11 +85,11 @@ VignetteBuilder: biocViews: Config/Needs/dev: cffr, covr, here, lintr, pkgdown, rcmdcheck, xml2 +Config/roxygen2/version: 8.0.0 Config/testthat/edition: 3 Config/testthat/parallel: true Encoding: UTF-8 LazyData: true LazyDataCompression: xz Roxygen: list(markdown = TRUE) -Config/roxygen2/version: 8.0.0 RoxygenNote: 8.0.0 diff --git a/code/MOSuite/NAMESPACE b/code/MOSuite/NAMESPACE index dcdf57a..7a4ba1f 100644 --- a/code/MOSuite/NAMESPACE +++ b/code/MOSuite/NAMESPACE @@ -1,6 +1,7 @@ # Generated by roxygen2: do not edit by hand export("!!") +export("%||%") export(":=") export(.data) export(batch_correct_counts) @@ -13,6 +14,8 @@ export(cli_from_json) export(create_multiOmicDataSet_from_dataframes) export(create_multiOmicDataSet_from_files) export(diff_counts) +export(display_colors) +export(display_palette) export(do_math) export(extract_counts) export(filter_counts) @@ -38,6 +41,8 @@ export(plot_volcano_enhanced) export(plot_volcano_summary) export(print_or_save_plot) export(read_multiOmicDataSet) +export(render_report) +export(select_mosuite_colors) export(set_color_pal) export(setup_capsule_environment) export(write_multiOmicDataSet) @@ -47,5 +52,6 @@ importFrom(DESeq2,DESeq) importFrom(dendextend,rotate) importFrom(matrixStats,rowVars) importFrom(rlang,"!!") +importFrom(rlang,"%||%") importFrom(rlang,":=") importFrom(rlang,.data) diff --git a/code/MOSuite/NEWS.md b/code/MOSuite/NEWS.md index a1c1f01..524603d 100644 --- a/code/MOSuite/NEWS.md +++ b/code/MOSuite/NEWS.md @@ -1,4 +1,21 @@ -## 0.3.2 +## MOSuite development version + +## MOSuite 0.4.0 + +- Fix how `plot_volcano_summary()` & `plot_volcano_enhanced` handle detecting column names for features, significance, and fold-change. `plot_volcano_summary()` plot now uses `plot_volcano_enhanced()` for rendering. (#239, @phoman14) +- Update PCA label, point-size, and histogram behavior. (#230, @phoman14) +- Add optional count log-transform controls for PCA plots. (#234, @phoman14) +- Add a post-clean CPM histogram output in `clean_raw_counts()`. (#234, @phoman14) +- Improvements to plot colors: (#223, @phoman14) + - Align plot color defaults with the MOSuite Code Ocean capsule defaults while preserving fallback random colors when a requested palette is too short. + - Improve top and bottom legend wrapping and automatic legend text sizing for PCA and histogram plots with many or long labels. + - Add optional group coloring to `plot_read_depth()` and the `clean_raw_counts()` read-depth output while preserving the single-color default when no group is selected. +- New function `display_colors()` shows a multiOmicDataSet's chosen color palettes, and `get_colors_lst()` now takes a palette vector rather than function for simplicity. (#236, @kelly-sovacool) +- New report template & helper function: `render_report()`. (#120, @kelly-sovacool) +- Fix ggplot2 size deprecation warning in `plot_volcano_summary()`. (#228, @kelly-sovacool) +- docs: show how to set `output_dir` in `render_report()`. (#235, @kelly-sovacool) + +## MOSuite 0.3.2 - Support ggplot2 v4.0.0 for correlation heatmap plots in `filter_counts()`, `normalize_counts()`, and `batch_correct_counts()`. (#205, @copilot, @kelly-sovacool) diff --git a/code/MOSuite/R/batch-correction.R b/code/MOSuite/R/batch-correction.R index bcbf63e..d0aaac0 100644 --- a/code/MOSuite/R/batch-correction.R +++ b/code/MOSuite/R/batch-correction.R @@ -54,10 +54,28 @@ batch_correct_counts <- function( samples_to_include = NULL, covariates_colnames = "Group", batch_colname = "Batch", - label_colname = NULL, + label_colname = "Label", + samples_to_rename = c(""), + add_label_to_pca = TRUE, + principal_component_on_x_axis = 1, + principal_component_on_y_axis = 2, + legend_position_for_pca = "top", + label_offset_x_ = 2, + label_offset_y_ = 2, + label_font_size = 3, + point_size_for_pca = 5, + color_histogram_by_group = TRUE, + set_min_max_for_x_axis_for_histogram = FALSE, + minimum_for_x_axis_for_histogram = -1, + maximum_for_x_axis_for_histogram = 1, + legend_font_size_for_histogram = NULL, + legend_position_for_histogram = "top", + number_of_histogram_legend_columns = 6, + plot_corr_matrix_heatmap = TRUE, colors_for_plots = NULL, print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), + interactive_plots = FALSE, plots_subdir = "batch" ) { abort_packages_not_installed("sva") @@ -103,6 +121,7 @@ batch_correct_counts <- function( if (is.null(samples_to_include)) { samples_to_include <- sample_metadata |> dplyr::pull(sample_id_colname) } + pca_label_colname <- if (isTRUE(add_label_to_pca)) label_colname else NULL if (is.null(label_colname)) { label_colname <- sample_id_colname } @@ -147,8 +166,13 @@ batch_correct_counts <- function( } if (isTRUE(print_plots) || isTRUE(save_plots)) { - if (is.null(colors_for_plots)) { - colors_for_plots <- moo@analyses[["colors"]][[batch_colname]] + colors_for_plots <- colors_for_plots %||% + moo@analyses$colors[[batch_colname]] + + if (isTRUE(color_histogram_by_group)) { + colors_for_histogram <- colors_for_plots + } else { + colors_for_histogram <- moo@analyses$colors[[label_colname]] } pca_plot <- plot_pca( combat_edata, @@ -156,8 +180,19 @@ batch_correct_counts <- function( sample_id_colname = sample_id_colname, feature_id_colname = feature_id_colname, group_colname = batch_colname, - label_colname = label_colname, + label_colname = pca_label_colname, + samples_to_rename = samples_to_rename, color_values = colors_for_plots, + principal_components = c( + principal_component_on_x_axis, + principal_component_on_y_axis + ), + legend_position = legend_position_for_pca, + point_size = point_size_for_pca, + label_font_size = label_font_size, + label_offset_y_ = label_offset_y_, + label_offset_x_ = label_offset_x_, + log_transform = FALSE, print_plots = FALSE, save_plots = FALSE ) + @@ -170,39 +205,68 @@ batch_correct_counts <- function( feature_id_colname = feature_id_colname, group_colname = batch_colname, label_colname = label_colname, - color_values = colors_for_plots, - color_by_group = TRUE - ) + - ggplot2::labs(caption = "batch-corrected counts") - corHM_plot <- plot_corr_heatmap( - combat_edata, - sample_metadata = sample_metadata, - sample_id_colname = sample_id_colname, - feature_id_colname = feature_id_colname, - group_colname = batch_colname, - label_colname = label_colname, - color_values = colors_for_plots + color_values = colors_for_histogram, + color_by_group = color_histogram_by_group, + set_min_max_for_x_axis = set_min_max_for_x_axis_for_histogram, + minimum_for_x_axis = minimum_for_x_axis_for_histogram, + maximum_for_x_axis = maximum_for_x_axis_for_histogram, + x_axis_label = "Batch Corrected Counts", + legend_position = legend_position_for_histogram, + legend_font_size = legend_font_size_for_histogram, + number_of_legend_columns = number_of_histogram_legend_columns, + interactive_plots = interactive_plots ) + if (!isTRUE(interactive_plots)) { + hist_plot <- hist_plot + ggplot2::labs(caption = "batch-corrected counts") + } + if (isTRUE(plot_corr_matrix_heatmap)) { + corHM_plot <- plot_corr_heatmap( + combat_edata, + sample_metadata = sample_metadata, + sample_id_colname = sample_id_colname, + feature_id_colname = feature_id_colname, + group_colname = batch_colname, + label_colname = label_colname, + color_values = colors_for_plots + ) + print_or_save_plot( + corHM_plot, + filename = file.path(plots_subdir, "corr_heatmap.png"), + print_plots = print_plots, + save_plots = save_plots, + caption = "batch-corrected counts" + ) + } - print_or_save_plot( - pca_plot, - filename = file.path(plots_subdir, "pca.png"), - print_plots = print_plots, - save_plots = save_plots - ) + plot_ext <- "png" + if (isTRUE(interactive_plots)) { + pca_plot <- pca_plot |> plotly::ggplotly(tooltip = "text") + plot_ext <- "html" + } + if (identical(plot_ext, "png")) { + print_or_save_plot( + pca_plot, + filename = file.path(plots_subdir, glue::glue("pca.{plot_ext}")), + print_plots = print_plots, + save_plots = save_plots, + width = 7, + height = 7, + units = "in" + ) + } else { + print_or_save_plot( + pca_plot, + filename = file.path(plots_subdir, glue::glue("pca.{plot_ext}")), + print_plots = print_plots, + save_plots = save_plots + ) + } print_or_save_plot( hist_plot, - filename = file.path(plots_subdir, "histogram.png"), + filename = file.path(plots_subdir, glue::glue("histogram.{plot_ext}")), print_plots = print_plots, save_plots = save_plots ) - print_or_save_plot( - corHM_plot, - filename = file.path(plots_subdir, "corr_heatmap.png"), - print_plots = print_plots, - save_plots = save_plots, - caption = "batch-corrected counts" - ) } message(glue::glue( diff --git a/code/MOSuite/R/clean.R b/code/MOSuite/R/clean.R index d14b2ca..0ee08c1 100644 --- a/code/MOSuite/R/clean.R +++ b/code/MOSuite/R/clean.R @@ -9,6 +9,12 @@ #' @inheritParams filter_counts #' @inheritParams option_params #' +#' @param group_colname sample metadata column used to color the read-depth plot. Leave blank to use the current +#' single-color bar fill. +#' @param colors_for_plots optional colors used when `group_colname` is supplied. If `NULL`, colors are taken from +#' `moo@analyses$colors[[group_colname]]`. +#' Named vectors are matched to group values; +#' unnamed vectors follow group order and are extended with MOSuite colors when too few colors are supplied. #' @param cleanup_column_names Invalid raw counts column names can cause errors #' in the downstream analysis. If this is `TRUE`, any invalid column names #' will be automatically altered to a correct format. These format changes @@ -55,6 +61,8 @@ clean_raw_counts <- function( sample_id_colname = NULL, feature_id_colname = NULL, samples_to_rename = "", + group_colname = "", + colors_for_plots = NULL, cleanup_column_names = TRUE, split_gene_name = TRUE, aggregate_rows_with_duplicate_gene_names = TRUE, @@ -74,7 +82,13 @@ clean_raw_counts <- function( } # Sample Read Counts Plot if (isTRUE(print_plots) || isTRUE(save_plots)) { - read_plot <- plot_read_depth(counts_dat) + read_plot <- plot_read_depth( + counts_dat, + sample_metadata = sample_metadata, + sample_id_colname = sample_id_colname, + group_colname = group_colname, + color_values = colors_for_plots + ) print_or_save_plot( read_plot, filename = file.path(plots_subdir, "read_depth.png"), @@ -162,6 +176,50 @@ clean_raw_counts <- function( ) moo@counts[["clean"]] <- counts_dat + if (isTRUE(print_plots) || isTRUE(save_plots)) { + # CPM histogram after cleaning + # + # This QC plot is built from the cleaned count table after sample renaming, + # column cleanup, gene-name splitting, and duplicate aggregation. CPM is + # calculated first so library-size differences are accounted for, then genes + # with zero counts in every sample are removed from the plotted CPM table. + # When group_colname is supplied, the histogram is colored by that sample + # metadata group. The CPM calculation is plot-only here; it does not replace + # the raw or cleaned count slots used by downstream workflow steps. + cpm_feature_id_colname <- colnames(counts_dat)[1] + sample_colnames <- colnames(counts_dat)[ + vapply(counts_dat, is.numeric, logical(1)) + ] + color_cpm_histogram_by_group <- !is.null(group_colname) && + nzchar(trimws(group_colname)) + cpm_counts_dat <- calc_cpm_df( + counts_dat[, c(cpm_feature_id_colname, sample_colnames), drop = FALSE], + feature_id_colname = cpm_feature_id_colname + ) + cpm_counts_dat <- cpm_counts_dat[ + rowSums(cpm_counts_dat[, sample_colnames, drop = FALSE] != 0) > 0, + , + drop = FALSE + ] + cpm_hist_plot <- plot_histogram( + cpm_counts_dat, + sample_metadata = sample_metadata, + sample_id_colname = sample_id_colname, + feature_id_colname = cpm_feature_id_colname, + group_colname = group_colname, + color_values = colors_for_plots, + color_by_group = color_cpm_histogram_by_group, + x_axis_label = "CPM", + use_log2_x_axis = TRUE + ) + + ggplot2::labs(caption = "CPM counts") + print_or_save_plot( + cpm_hist_plot, + filename = file.path(plots_subdir, "cpm_histogram.png"), + print_plots = print_plots, + save_plots = save_plots + ) + } return(moo) } diff --git a/code/MOSuite/R/colors.R b/code/MOSuite/R/colors.R index 291901f..97c6cd3 100644 --- a/code/MOSuite/R/colors.R +++ b/code/MOSuite/R/colors.R @@ -1,7 +1,10 @@ +utils::globalVariables("mosuite_palette") + #' Get random colors. #' -#' Note: this function is not guaranteed to create a color blind friendly palette. -#' Consider using other palettes such as `RColorBrewer::display.brewer.all(colorblindFriendly = TRUE)`. +#' Note: this function is not guaranteed to create a color blind friendly +#' palette. Consider using other palettes such as +#' `RColorBrewer::display.brewer.all(colorblindFriendly = TRUE)`. #' #' @param num_colors number of colors to select. #' @param n number of random RGB values to generate in the color space. @@ -32,90 +35,302 @@ get_random_colors <- function(num_colors, n = 2e3) { return(unname(colorspace::hex(colorspace::LAB(km$centers)))) } +#' Select colors from MOSuite's default palette +#' +#' @param n number of colors to select. +#' @param ... additional arguments (ignored). +#' +#' @returns vector of colors in hex format. +#' @export +#' +#' @examples +#' select_mosuite_colors(5) +select_mosuite_colors <- function(n, ...) { + return(mosuite_palette[seq_len(min(n, length(mosuite_palette)))]) +} + +#' Get observed values from a column +#' +#' Returns non-missing values from `dat[[colname]]`. For factor columns, values +#' are returned in factor-level order; otherwise, values keep first-observed +#' order. +#' +#' @param dat data frame +#' @param colname column name in `dat` +#' @returns character vector of observed values +#' @keywords internal +get_observed_values <- function(dat, colname) { + values <- dplyr::pull(dat, colname) + observed_values <- stats::na.omit(as.character(values)) + + if (is.factor(values)) { + return(levels(values)[levels(values) %in% observed_values]) + } + + return(unique(observed_values)) +} + #' Create named list of default colors for plotting #' #' @inheritParams create_multiOmicDataSet_from_dataframes #' -#' @param palette_fun Function for selecting colors. Assumed to contain `n` for the number of colors. Default: -#' `grDevices::palette.colors()` -#' @param ... additional arguments forwarded to `palette_fun` +#' @param palette Character vector of colors to assign. Defaults to +#' `mosuite_palette`. #' -#' @returns named list, with each column in `sample_metadata` containing entry with a named vector of colors +#' @returns named list, with each column in `sample_metadata` containing a corresponding entry with a named vector of +#' colors #' @export #' #' @examples #' get_colors_lst(nidap_sample_metadata) -#' \dontrun{ -#' get_colors_lst(nidap_sample_metadata, palette_fun = RColorBrewer::brewer.pal, name = "Set3") -#' } +#' get_colors_lst(nidap_sample_metadata, palette = RColorBrewer::brewer.pal(12, "Set3")) get_colors_lst <- function( sample_metadata, - palette_fun = grDevices::palette.colors, - ... + palette = mosuite_palette ) { dat_colnames <- colnames(sample_metadata) - color_lists <- dat_colnames |> - purrr::map( - .f = get_colors_vctr, + n_palette <- length(palette) + + color_offset <- 0L + color_lists <- vector("list", length(dat_colnames)) + for (i in seq_along(dat_colnames)) { + colname <- dat_colnames[[i]] + n_obs <- length(get_observed_values(sample_metadata, colname)) + # Only offset when the column is small enough that unique colors are available + use_offset <- n_obs <= n_palette / 2 && color_offset + n_obs <= n_palette + vctr <- get_colors_vctr( dat = sample_metadata, - palette_fun = palette_fun, - ... + colname = colname, + palette = palette, + color_offset = if (use_offset) color_offset else 0L ) + if (use_offset) { + color_offset <- color_offset + n_obs + } + color_lists[[i]] <- vctr + } names(color_lists) <- dat_colnames return(color_lists) } #' Get vector of colors for observations in one column of a data frame #' +#' Assigns one color per unique observed value in `dat[[colname]]`, drawn from +#' `palette` starting at `color_offset`. If the palette is too short, +#' falls back to `get_random_colors()`. Factor columns use factor-level order; +#' other columns use first-observed order. +#' #' @inheritParams get_colors_lst #' @param dat data frame #' @param colname column name in `dat` -#' @returns named vector of colors for each unique observation in `dat$colname` +#' @param color_offset integer; number of palette colors to skip before +#' assigning colors to this column's values. Used by [get_colors_lst()] to +#' avoid repeating colors across columns with few unique values. +#' @returns Named character vector of hex colors, one per unique observed value +#' in `dat[[colname]]`. #' @export #' +#' @examples +#' get_colors_vctr(nidap_sample_metadata, "Group") +#' get_colors_vctr(nidap_sample_metadata, "Group", color_offset = 3L) get_colors_vctr <- function( dat, colname, - palette_fun = grDevices::palette.colors, - ... + palette = mosuite_palette, + color_offset = 0L ) { - obs <- dat |> - dplyr::pull(colname) |> - unique() + obs <- get_observed_values(dat, colname) n_obs <- length(obs) - warned_cnd <- NULL - colors_vctr <- withCallingHandlers( - warning = function(cnd) { - warned_cnd <<- cnd - invokeRestart("muffleWarning") - }, - palette_fun(n = n_obs, ...) - ) + if (n_obs == 0) { + colors_vctr <- character(0) + } else { + # if fewer colors are available than needed, handle gracefully + if (length(palette) < n_obs + color_offset) { + # If an offset pushed us past the palette end but n_obs alone would fit, + # retry from the start of the palette before falling back to random colors. + if (color_offset > 0L && length(palette) >= n_obs) { + color_offset <- 0L + } + } + # If still not enough colors, fall back to random + if (length(palette) < n_obs) { + message(glue::glue( + "Number of unique values ({n_obs}) in column \"{colname}\" ", + "exceeds the palette maximum. Falling back to random colors." + )) + colors_vctr <- get_random_colors(n_obs) + } else { + colors_vctr <- palette[seq.int(color_offset + 1L, color_offset + n_obs)] + } + names(colors_vctr) <- obs + } - # if fewer colors were returned than needed (e.g. when n exceeds the palette maximum, - # such as Okabe-Ito's maximum of 9), fall back to random colors - if (length(colors_vctr) < n_obs) { - message(glue::glue( - 'Number of unique values ({n_obs}) in column "{colname}" exceeds the palette maximum. Falling back to random colors.' - )) - colors_vctr <- get_random_colors(n_obs) - } else if (!is.null(warned_cnd)) { - # warning was raised but we still have enough colors (e.g. brewer.pal warns when n < 3 - # but returns 3 colors); convert to a message and re-raise the original warning + return(colors_vctr) +} + + +#' Resolve plotting colors for one column +#' +#' Uses `color_values` when supplied; otherwise generates colors with +#' [get_colors_vctr()]. If `color_values` is named and covers all observed +#' values, it is returned as-is. If too few colors are provided, missing colors +#' are generated and appended. +#' +#' @param dat data frame +#' @param colname column name in `dat` +#' @param color_values optional named or unnamed character vector of colors +#' @param palette character vector of colors used to generate defaults +#' @returns named character vector of colors matching observed values in +#' `dat[[colname]]` +#' @keywords internal +resolve_plot_colors <- function( + dat, + colname, + color_values = NULL, + palette = mosuite_palette +) { + obs <- get_observed_values(dat, colname) + + if (length(obs) == 0) { + return(color_values) + } + + if (is.null(color_values)) { + return(get_colors_vctr(dat, colname, palette = palette)) + } + + if (!is.null(names(color_values))) { + if (all(obs %in% names(color_values))) { + return(color_values) + } + } + + if (length(color_values) < length(obs)) { + n_missing <- length(obs) - length(color_values) message(glue::glue( - 'Warning raised in get_color_vctr() for column "{colname}"' + "color_values contains {length(color_values)} colors for ", + "{length(obs)} values in column {colname}. Generating ", + "{n_missing} additional colors." )) - warning(conditionMessage(warned_cnd)) + generated_colors <- get_colors_vctr( + dat, + colname, + palette = palette + ) + color_values <- c( + unname(color_values), + unname(generated_colors)[seq.int(length(color_values) + 1, length(obs))] + ) } - # if more colors are returned than are in the observations, truncate the vector. - # this occurs when using RColorBrewer::brewer.pal with n < 3 - colors_vctr <- colors_vctr[seq_len(n_obs)] + return(stats::setNames(unname(color_values)[seq_along(obs)], obs)) +} - names(colors_vctr) <- obs - return(colors_vctr) +#' Display the mosuite color palette +#' +#' Plots each color in `mosuite_palette` as a labeled tile with its hex code +#' displayed below. The plot is rendered at a width proportional to the number +#' of colors so labels remain horizontal and legible. +#' +#' @param palette Character vector of hex color codes. Defaults to +#' `mosuite_palette`. +#' +#' @returns Invisibly returns the underlying [ggplot2::ggplot] object. +#' @export +#' +#' @examples +#' display_palette() +#' display_palette(c("#FF0000", "#00FF00", "#0000FF")) +display_palette <- function(palette = mosuite_palette) { + n <- length(palette) + + df <- data.frame( + hex = palette, + idx = factor(seq_len(n)) + ) + + p <- plot_palette(df) + + ggplot2::labs(title = "mosuite_palette") + + return(p) +} + +#' Display colors for a multiOmicDataSet object +#' +#' Plots a palette strip for each group column stored in `moo@analyses$colors`, +#' stacked vertically. Each strip shows the assigned hex colors and their codes. +#' +#' @param moo A `multiOmicDataSet` object (see +#' [create_multiOmicDataSet_from_dataframes()]). +#' @returns A [patchwork][patchwork::wrap_plots] of [ggplot2::ggplot] objects, +#' one per group column in `moo@analyses$colors`. +#' @export +#' @examples +#' moo <- create_multiOmicDataSet_from_dataframes(nidap_sample_metadata, nidap_raw_counts) +#' display_colors(moo) +display_colors <- function(moo) { + abort_packages_not_installed("patchwork") + colors_lst <- moo@analyses$colors + plots_lst <- lapply(names(colors_lst), function(colname) { + palette <- colors_lst[[colname]] + n <- length(palette) + df <- data.frame( + hex = palette, + idx = factor(seq_len(n)) + ) + return( + p <- plot_palette(df) + + ggplot2::labs(title = colname) + ) + }) + return(patchwork::wrap_plots(plots_lst, ncol = 1)) +} + +#' Plot a palette tile strip +#' +#' Renders a data frame with columns `hex` and `idx` as a row of colored tiles, +#' each labeled with its hex code. Used internally by [display_palette()] and +#' [display_colors()]. +#' +#' @param dat data frame with columns `hex` (hex color codes) and `idx` +#' (factor, used for faceting) +#' @returns a [ggplot2::ggplot] object +#' @keywords internal +plot_palette <- function(dat) { + p <- ggplot2::ggplot(dat) + + ggplot2::geom_rect( + ggplot2::aes(fill = .data$hex), + xmin = 0, + xmax = 1, + ymin = 0.25, + ymax = 1 + ) + + ggplot2::geom_text( + ggplot2::aes(label = .data$hex), + x = 0.5, + y = 0.12, + size = 2.8, + family = "mono", + vjust = 1 + ) + + ggplot2::scale_fill_identity() + + ggplot2::facet_wrap(~idx, nrow = 1) + + ggplot2::theme_void() + + ggplot2::theme( + strip.text = ggplot2::element_text( + size = 9, + margin = ggplot2::margin(b = 3) + ), + panel.spacing = ggplot2::unit(3, "pt"), + plot.title = ggplot2::element_text( + size = 12, + margin = ggplot2::margin(b = 8) + ), + plot.margin = ggplot2::margin(4, 4, 4, 4) + ) + return(p) } #' Set color palette for a single group/column @@ -127,7 +342,7 @@ get_colors_vctr <- function( #' @param moo `multiOmicDataSet` object (see `create_multiOmicDataSet_from_dataframes()`) #' @param colname group column name to set the palette for #' -#' @returns `moo` with colors updated at `moo@analyses$colors$colname` +#' @returns `moo` with colors updated at `moo@analyses$colors[[colname]]` #' @export #' #' @examples @@ -136,14 +351,14 @@ get_colors_vctr <- function( #' counts_dat = as.data.frame(nidap_raw_counts) #' ) #' moo@analyses$colors$Group -#' moo <- moo |> set_color_pal("Group", palette_fun = RColorBrewer::brewer.pal, name = "Set2") +#' moo <- moo |> set_color_pal("Group", palette = RColorBrewer::brewer.pal(3, "Set2")) #' moo@analyses$colors$Group #' #' @family moo methods set_color_pal <- S7::new_generic( "set_color_pal", "moo", - function(moo, colname, palette_fun = grDevices::palette.colors, ...) { + function(moo, colname, palette = mosuite_palette) { return(S7::S7_dispatch()) } ) @@ -151,14 +366,12 @@ set_color_pal <- S7::new_generic( S7::method(set_color_pal, multiOmicDataSet) <- function( moo, colname, - palette_fun = grDevices::palette.colors, - ... + palette = mosuite_palette ) { - moo@analyses[["colors"]][[colname]] <- get_colors_vctr( + moo@analyses$colors[[colname]] <- get_colors_vctr( dat = moo@sample_meta, colname = colname, - palette_fun = palette_fun, - ... + palette = palette ) return(moo) } diff --git a/code/MOSuite/R/counts.R b/code/MOSuite/R/counts.R index 039bded..37e708e 100644 --- a/code/MOSuite/R/counts.R +++ b/code/MOSuite/R/counts.R @@ -59,6 +59,76 @@ calc_cpm_df <- function(dat, feature_id_colname = "gene_id", ...) { return(dat_cpm |> dplyr::relocate(tidyselect::all_of(feature_id_colname))) } +#' Log-transform count columns in a data frame +#' +#' @inheritParams create_multiOmicDataSet_from_dataframes +#' @param counts_dat data frame of feature counts. +#' @param sample_colnames optional vector of sample columns to transform. If `NULL`, all columns except +#' `feature_id_colname` are transformed. +#' @param pseudocount value added before log transformation. +#' @param base logarithm base to use for the transformation. Use a numeric value, or `"e"`, `"ln"`, or `"natural"` +#' for natural log. Default is `"ln"`. +#' +#' @return count data frame with selected count columns transformed as `log(x + pseudocount, base)`. +#' @keywords internal +log_transform_counts <- function( + counts_dat, + feature_id_colname = NULL, + sample_colnames = NULL, + pseudocount = 0.5, + base = "ln" +) { + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(counts_dat)[1] + } + if (is.null(sample_colnames)) { + sample_colnames <- setdiff(colnames(counts_dat), feature_id_colname) + } + if (!is.numeric(pseudocount) || length(pseudocount) != 1) { + stop("pseudocount must be a single numeric value") + } + if (pseudocount < 0) { + stop("pseudocount cannot be negative") + } + base <- resolve_log_transform_base(base) + if ( + any( + as.matrix(counts_dat[, sample_colnames, drop = FALSE]) + pseudocount <= 0, + na.rm = TRUE + ) + ) { + stop( + "log_transform_counts requires all count values plus pseudocount to be greater than 0" + ) + } + counts_dat |> + dplyr::mutate(dplyr::across( + tidyselect::all_of(sample_colnames), + ~ log(.x + pseudocount, base = base) + )) +} + +resolve_log_transform_base <- function(base) { + if (is.character(base) && length(base) == 1) { + base <- tolower(base) + if (base %in% c("e", "ln", "natural")) { + return(exp(1)) + } + stop( + "base must be a single numeric value or one of 'e', 'ln', or 'natural'" + ) + } + if (!is.numeric(base) || length(base) != 1) { + stop( + "base must be a single numeric value or one of 'e', 'ln', or 'natural'" + ) + } + if (base <= 0 || base == 1) { + stop("base must be greater than 0 and cannot equal 1") + } + return(base) +} + #' Convert a data frame of gene counts to a matrix #' #' @inheritParams create_multiOmicDataSet_from_dataframes diff --git a/code/MOSuite/R/data.R b/code/MOSuite/R/data.R index f27fb3b..23f2561 100644 --- a/code/MOSuite/R/data.R +++ b/code/MOSuite/R/data.R @@ -64,3 +64,17 @@ #' The result of running `plot_venn_diagram()` on `nidap_volcano_summary_dat` #' @keywords data "nidap_venn_diagram_dat" + +#' Default MOSuite color palette +#' +#' A character vector of 12 hex color codes used as the default palette throughout MOSuite plots. +#' Colors are assigned to groups in the order they appear (or by factor level order). +#' Use [set_color_pal()] to override the palette for a specific metadata column. +#' +#' @format A character vector of length 12. +#' @seealso [select_mosuite_colors()], [set_color_pal()] +#' @keywords data +#' @examples +#' mosuite_palette +#' scales::show_col(mosuite_palette) +"mosuite_palette" diff --git a/code/MOSuite/R/differential.R b/code/MOSuite/R/differential.R index 3adf34c..fd16d21 100644 --- a/code/MOSuite/R/differential.R +++ b/code/MOSuite/R/differential.R @@ -15,7 +15,7 @@ #' @param return_mean_and_sd if TRUE, return Mean and Standard Deviation of groups in addition to DEG estimates for #' contrast(s) #' -#' @returns `multiOmicDataSet` with `diff` added to the `analyses` slot (i.e. `moo@analyses$diff`) +#' @returns `multiOmicDataSet` with `diff` added to the `analyses` slot (i.e. `moo@analyses[["diff"]]`) #' @export #' #' @family moo methods @@ -485,7 +485,7 @@ get_gene_lists <- function( ) { upreg_genes <- list() downreg_genes <- list() - for (i in seq_len(length(contrasts))) { + for (i in seq_along(contrasts)) { if (pval == "pval") { upreg_genes[[i]] <- finalres |> dplyr::filter( diff --git a/code/MOSuite/R/filter.R b/code/MOSuite/R/filter.R index b520ef1..5bddf68 100644 --- a/code/MOSuite/R/filter.R +++ b/code/MOSuite/R/filter.R @@ -33,10 +33,10 @@ #' column showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal, #' Before, After, etc.). #' @param label_colname The column from the sample metadata containing the sample labels as you wish them to appear in -#' the plots produced by this template. This can be the same Sample Names Column. However, you may desire different -#' labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the -#' column with your preferred Labels here. The selected column should contain unique names for each sample. (Default: -#' `NULL` -- `sample_id_colname` will be used.) +#' heatmap and PCA figures. This can be the same Sample Names Column. However, you may desire different labels to +#' display on your figures (e.g. shorter labels are sometimes preferred on plots). In that case, select the column with +#' your preferred Labels here. The selected column should contain unique names for each sample. Use `add_label_to_pca` +#' to control whether these labels are displayed on the PCA plot. #' @param samples_to_include Which samples would you like to include? Usually, you will choose all sample columns, or #' you could choose to remove certain samples. Samples excluded here will be removed in this step and from further #' analysis downstream of this step. (Default: `NULL` - all sample IDs in `moo@sample_meta` will be used.) @@ -45,19 +45,23 @@ #' been transformed (eg log2, CPM, FPKM or some form of Normalization) set to FALSE. If FALSE no further #' transformation will be applied and features will be filtered as is. For RNAseq data RAW counts should be #' transformed to CPM in order to properly filter. -#' @param minimum_count_value_to_be_considered_nonzero Minimum count value to be considered non-zero for a sample -#' @param minimum_number_of_samples_with_nonzero_counts_in_total Minimum number of samples (total) with non-zero counts +#' @param minimum_count_value_to_be_considered_nonzero Minimum value in the selected filtering table required for a +#' sample to be considered nonzero. If `use_cpm_counts_to_filter` is `TRUE`, this threshold is applied to CPM values. +#' If `use_cpm_counts_to_filter` is `FALSE`, this threshold is applied directly to the selected `count_type` table. +#' @param minimum_number_of_samples_with_nonzero_counts_in_total Minimum number of samples in total that must meet the +#' `minimum_count_value_to_be_considered_nonzero` threshold for a feature to be kept. #' @param use_group_based_filtering If TRUE, only keeps features (e.g. genes) that have at least a certain number of -#' samples with nonzero CPM counts in at least one group +#' samples passing the threshold in at least one group #' @param minimum_number_of_samples_with_nonzero_counts_in_a_group Only keeps genes that have at least this number of -#' samples with nonzero CPM counts in at least one group +#' samples meeting the threshold in at least one group #' @param principal_component_on_x_axis The principal component to plot on the x-axis for the PCA plot. Choices include #' 1, 2, 3, ... (default: 1) #' @param principal_component_on_y_axis The principal component to plot on the y-axis for the PCA plot. Choices include #' 1, 2, 3, ... (default: 2) #' @param legend_position_for_pca legend position for the PCA plot #' @param point_size_for_pca geom point size for the PCA plot -#' @param add_label_to_pca label points on the PCA plot +#' @param add_label_to_pca If `TRUE`, display labels from `label_colname` on PCA points. If `FALSE`, the PCA plot uses +#' unlabeled points while heatmap labels still use `label_colname`. #' @param label_font_size label font size for the PCA plot #' @param label_offset_y_ label offset y for the PCA plot #' @param label_offset_x_ label offset x for the PCA plot @@ -66,16 +70,23 @@ #' renaming. Use the following format to describe which old name (in your sample metadata table) you want to rename to #' which new name: old_name: new_name #' @param color_histogram_by_group Set to FALSE to label histogram by Sample Names, or set to TRUE to label histogram by -#' the column you select in the "Group Column Used to Color Histogram" parameter (below). Default is FALSE. +#' the column you select in the "Group Column Used to Color Histogram" parameter (below). Default is TRUE. #' @param set_min_max_for_x_axis_for_histogram whether to set min/max value for histogram x-axis #' @param minimum_for_x_axis_for_histogram x-axis minimum for histogram plot #' @param maximum_for_x_axis_for_histogram x-axis maximum for histogram plot #' @param legend_position_for_histogram legend position for the histogram plot. consider setting to 'none' for a large #' number of samples. -#' @param legend_font_size_for_histogram legend font size for the histogram plot +#' @param legend_font_size_for_histogram legend font size for the histogram plot. +#' If `NULL`, the size is scaled automatically. #' @param number_of_histogram_legend_columns number of columns for the histogram legend -#' @param colors_for_plots Colors for the PCA and histogram will be picked, in order, from this list. +#' @param colors_for_plots Optional colors for PCA/histogram/heatmap plots. If `NULL`, colors are taken from +#' `moo@analyses$colors[[group_colname]]`. #' Colors must either be names in `grDevices::colors()` or valid hex codes. +#' Unnamed colors are assigned by factor level order when the grouping column is a factor; +#' otherwise, they follow the order in which groups first appear in the metadata column. If more groups are present +#' than colors provided, +#' supplied colors are used first and additional colors are generated from the selected palette for the remaining +#' groups; random colors are used only if that palette returns fewer colors than the number of groups. #' @param plot_corr_matrix_heatmap Datasets with a large number of samples may be too large to create a correlation #' matrix heatmap. If this function takes longer than 5 minutes to run, Set to `FALSE` and the correlation matrix will #' not be be created. Default is `TRUE`. @@ -106,7 +117,7 @@ filter_counts <- function( feature_id_colname = NULL, sample_id_colname = NULL, group_colname = "Group", - label_colname = NULL, + label_colname = "Label", samples_to_include = NULL, minimum_count_value_to_be_considered_nonzero = 8, minimum_number_of_samples_with_nonzero_counts_in_total = 7, @@ -116,18 +127,18 @@ filter_counts <- function( principal_component_on_x_axis = 1, principal_component_on_y_axis = 2, legend_position_for_pca = "top", - point_size_for_pca = 1, + point_size_for_pca = 5, add_label_to_pca = TRUE, label_font_size = 3, label_offset_y_ = 2, label_offset_x_ = 2, samples_to_rename = c(""), - color_histogram_by_group = FALSE, + color_histogram_by_group = TRUE, set_min_max_for_x_axis_for_histogram = FALSE, minimum_for_x_axis_for_histogram = -1, maximum_for_x_axis_for_histogram = 1, legend_position_for_histogram = "top", - legend_font_size_for_histogram = 10, + legend_font_size_for_histogram = NULL, number_of_histogram_legend_columns = 6, colors_for_plots = NULL, plot_corr_matrix_heatmap = TRUE, @@ -151,6 +162,7 @@ filter_counts <- function( if (is.null(samples_to_include)) { samples_to_include <- sample_metadata |> dplyr::pull(sample_id_colname) } + pca_label_colname <- if (isTRUE(add_label_to_pca)) label_colname else NULL if (is.null(label_colname)) { label_colname <- sample_id_colname } @@ -168,6 +180,7 @@ filter_counts <- function( df_filt <- remove_low_count_genes( counts_dat = df, sample_metadata = sample_metadata, + sample_id_colname = sample_id_colname, feature_id_colname = feature_id_colname, group_colname = group_colname, use_cpm_counts_to_filter = use_cpm_counts_to_filter, @@ -176,35 +189,38 @@ filter_counts <- function( minimum_number_of_samples_with_nonzero_counts_in_total = minimum_number_of_samples_with_nonzero_counts_in_total, minimum_number_of_samples_with_nonzero_counts_in_a_group = minimum_number_of_samples_with_nonzero_counts_in_a_group ) - message(glue::glue("colors_for_plots {class(colors_for_plots)}")) + if (nrow(df_filt) == 0) { + warning( + "No features remain after filtering. ", + "Consider relaxing the filtering thresholds ", + "(e.g. minimum_count_value_to_be_considered_nonzero, ", + "minimum_number_of_samples_with_nonzero_counts_in_total, or ", + "minimum_number_of_samples_with_nonzero_counts_in_a_group). ", + "Skipping QC plots." + ) + moo@counts[["filt"]] <- df[0, ] + return(moo) + } + if (isTRUE(print_plots) || isTRUE(save_plots)) { # use consistent colors - if (is.null(colors_for_plots)) { - colors_for_plots <- moo@analyses[["colors"]][[group_colname]] - } else { - colors_for_plots <- as.vector(colors_for_plots) - } + colors_for_plots <- colors_for_plots %||% + moo@analyses$colors[[group_colname]] + if (isTRUE(color_histogram_by_group)) { colors_for_histogram <- colors_for_plots } else { - colors_for_histogram <- moo@analyses[["colors"]][[label_colname]] + colors_for_histogram <- moo@analyses$colors[[label_colname]] } - message(glue::glue("colors_for_plots {class(colors_for_plots)}")) - - log_counts <- df_filt |> - dplyr::mutate(dplyr::across( - tidyselect::all_of(samples_to_include), - ~ log(.x + 0.5) - )) pca_plot <- plot_pca( - log_counts, + df_filt, sample_metadata = sample_metadata, sample_id_colname = sample_id_colname, feature_id_colname = feature_id_colname, samples_to_rename = samples_to_rename, group_colname = group_colname, - label_colname = label_colname, + label_colname = pca_label_colname, color_values = colors_for_plots, principal_components = c( principal_component_on_x_axis, @@ -212,17 +228,30 @@ filter_counts <- function( ), legend_position = legend_position_for_pca, point_size = point_size_for_pca, - add_label = add_label_to_pca, label_font_size = label_font_size, label_offset_y_ = label_offset_y_, label_offset_x_ = label_offset_x_, + log_transform = TRUE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", print_plots = FALSE, save_plots = FALSE ) + ggplot2::labs(caption = "filtered counts") + # Histogram data and axis setup + histogram_x_axis_label <- if (isTRUE(use_cpm_counts_to_filter)) { + "CPM" + } else { + "Count" + } + log2_axis_pseudocount <- 0.5 + histogram_threshold_x <- minimum_count_value_to_be_considered_nonzero + + log2_axis_pseudocount + + # Base histogram plot hist_plot <- plot_histogram( - log_counts, + df_filt, sample_metadata, sample_id_colname = sample_id_colname, feature_id_colname = feature_id_colname, @@ -233,11 +262,38 @@ filter_counts <- function( set_min_max_for_x_axis = set_min_max_for_x_axis_for_histogram, minimum_for_x_axis = minimum_for_x_axis_for_histogram, maximum_for_x_axis = maximum_for_x_axis_for_histogram, + x_axis_label = histogram_x_axis_label, legend_position = legend_position_for_histogram, legend_font_size = legend_font_size_for_histogram, - number_of_legend_columns = number_of_histogram_legend_columns + number_of_legend_columns = number_of_histogram_legend_columns, + interactive_plots = interactive_plots, + return_ggplot = TRUE, + use_log2_x_axis = TRUE ) + ggplot2::labs(caption = "filtered counts") + + # Filtering threshold marker + hist_plot <- hist_plot + + ggplot2::geom_vline( + xintercept = histogram_threshold_x, + linetype = 2, + linewidth = 1 + ) + + ggplot2::annotate( + "text", + x = histogram_threshold_x, + y = Inf, + label = if (isTRUE(use_cpm_counts_to_filter)) { + glue::glue("CPM: {minimum_count_value_to_be_considered_nonzero}") + } else { + glue::glue("Count: {minimum_count_value_to_be_considered_nonzero}") + }, + hjust = -0.05, + vjust = 1.5, + size = 3 + ) + + # Correlation heatmap plot if (isTRUE(plot_corr_matrix_heatmap)) { corHM <- plot_corr_heatmap( df_filt[, samples_to_include], @@ -257,19 +313,33 @@ filter_counts <- function( ) } + # Interactive plot conversion plot_ext <- "png" if (isTRUE(interactive_plots)) { - pca_plot <- pca_plot |> plotly::ggplotly(tooltip = c("sample", "group")) - hist_plot <- (hist_plot + ggplot2::theme(legend.position = "none")) |> - plotly::ggplotly(tooltip = c("sample")) + pca_plot <- pca_plot |> plotly::ggplotly(tooltip = "text") + hist_plot <- hist_plot |> plotly::ggplotly(tooltip = "text") plot_ext <- "html" } - print_or_save_plot( - pca_plot, - filename = file.path(plots_subdir, glue::glue("pca.{plot_ext}")), - print_plots = print_plots, - save_plots = save_plots - ) + + # Save or print PCA and histogram plots + if (identical(plot_ext, "png")) { + print_or_save_plot( + pca_plot, + filename = file.path(plots_subdir, glue::glue("pca.{plot_ext}")), + print_plots = print_plots, + save_plots = save_plots, + width = 7, + height = 7, + units = "in" + ) + } else { + print_or_save_plot( + pca_plot, + filename = file.path(plots_subdir, glue::glue("pca.{plot_ext}")), + print_plots = print_plots, + save_plots = save_plots + ) + } print_or_save_plot( hist_plot, filename = file.path(plots_subdir, glue::glue("histogram.{plot_ext}")), @@ -300,6 +370,7 @@ filter_counts <- function( remove_low_count_genes <- function( counts_dat, sample_metadata, + sample_id_colname = NULL, feature_id_colname, group_colname, use_cpm_counts_to_filter = TRUE, @@ -308,52 +379,78 @@ remove_low_count_genes <- function( minimum_number_of_samples_with_nonzero_counts_in_total = 7, minimum_number_of_samples_with_nonzero_counts_in_a_group = 3 ) { - # TODO refactor with tidyverse - value <- isexpr1 <- NULL df <- counts_dat df <- df[stats::complete.cases(df), ] + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } + sample_colnames <- setdiff(colnames(df), feature_id_colname) + sample_colnames <- sample_colnames[vapply( + df[sample_colnames], + is.numeric, + logical(1) + )] # USE CPM Transformation trans_df <- df if (use_cpm_counts_to_filter == TRUE) { - trans_df[, -1] <- edgeR::cpm(as.matrix(df[, -1])) + trans_df[, sample_colnames] <- edgeR::cpm(as.matrix(df[, sample_colnames])) } + passing_counts <- as.matrix(trans_df[, sample_colnames, drop = FALSE]) >= + minimum_count_value_to_be_considered_nonzero if (use_group_based_filtering == TRUE) { - rownames(trans_df) <- trans_df[, feature_id_colname] - trans_df[, feature_id_colname] <- NULL - - counts <- trans_df >= minimum_count_value_to_be_considered_nonzero # boolean matrix - - tcounts <- as.data.frame(t(counts)) - colnum <- dim(counts)[1] # number of genes - tcounts <- merge(sample_metadata[group_colname], tcounts, by = "row.names") - tcounts$Row.names <- NULL - melted <- reshape2::melt(tcounts, id.vars = group_colname) - tcounts.tot <- dplyr::summarise( - dplyr::group_by_at(melted, c(group_colname, "variable")), - sum = sum(value) + if (!(sample_id_colname %in% colnames(sample_metadata))) { + stop(glue::glue( + "sample_id_colname {sample_id_colname} not in sample_metadata" + )) + } + if (!(group_colname %in% colnames(sample_metadata))) { + stop(glue::glue("group_colname {group_colname} not in sample_metadata")) + } + sample_match <- match( + sample_colnames, + as.character(sample_metadata[[sample_id_colname]]) ) - tcounts.group <- tcounts.tot |> - tidyr::pivot_wider(names_from = "variable", values_from = "sum") |> - as.data.frame() - tcounts.keep <- colSums( - tcounts.group[(1:colnum + 1)] >= + if (anyNA(sample_match)) { + missing_samples <- sample_colnames[is.na(sample_match)] + stop(glue::glue( + "sample_metadata is missing sample IDs: ", + "{glue::glue_collapse(missing_samples, sep = ', ')}" + )) + } + sample_groups <- as.character(sample_metadata[[group_colname]][ + sample_match + ]) + groups <- unique(stats::na.omit(sample_groups)) + if (length(groups) == 0) { + stop(glue::glue( + "group_colname {group_colname} has no non-missing values for selected samples" + )) + } + passing_samples_by_group <- vapply( + groups, + function(group) { + group_sample_colnames <- sample_colnames[ + !is.na(sample_groups) & sample_groups == group + ] + rowSums(passing_counts[, group_sample_colnames, drop = FALSE]) + }, + numeric(nrow(passing_counts)) + ) + keep_rows <- rowSums( + passing_samples_by_group >= minimum_number_of_samples_with_nonzero_counts_in_a_group ) >= 1 - df_filt <- trans_df[tcounts.keep, ] |> - tibble::rownames_to_column(feature_id_colname) + df_filt <- trans_df[keep_rows, , drop = FALSE] } else { - trans_df$isexpr1 <- (rowSums( - as.matrix(trans_df[, -1]) > minimum_count_value_to_be_considered_nonzero - ) >= + keep_rows <- (rowSums(passing_counts) >= minimum_number_of_samples_with_nonzero_counts_in_total) - df_filt <- trans_df |> - dplyr::filter(isexpr1) |> - dplyr::select(-isexpr1) + df_filt <- trans_df[keep_rows, , drop = FALSE] } + rownames(df_filt) <- NULL message(paste0("Number of features after filtering: ", nrow(df_filt))) return(df_filt) diff --git a/code/MOSuite/R/normalize.R b/code/MOSuite/R/normalize.R index 4823217..4daf5f0 100644 --- a/code/MOSuite/R/normalize.R +++ b/code/MOSuite/R/normalize.R @@ -34,7 +34,7 @@ normalize_counts <- function( samples_to_include = NULL, sample_id_colname = NULL, group_colname = "Group", - label_colname = NULL, + label_colname = "Label", input_in_log_counts = FALSE, voom_normalization_method = "quantile", samples_to_rename = c(""), @@ -45,12 +45,12 @@ normalize_counts <- function( label_offset_x_ = 2, label_offset_y_ = 2, label_font_size = 3, - point_size_for_pca = 8, + point_size_for_pca = 5, color_histogram_by_group = TRUE, set_min_max_for_x_axis_for_histogram = FALSE, minimum_for_x_axis_for_histogram = -1, maximum_for_x_axis_for_histogram = 1, - legend_font_size_for_histogram = 10, + legend_font_size_for_histogram = NULL, legend_position_for_histogram = "top", number_of_histogram_legend_columns = 6, plot_corr_matrix_heatmap = TRUE, @@ -72,6 +72,7 @@ normalize_counts <- function( if (is.null(samples_to_include)) { samples_to_include <- sample_metadata |> dplyr::pull(sample_id_colname) } + pca_label_colname <- if (isTRUE(add_label_to_pca)) label_colname else NULL if (is.null(label_colname)) { label_colname <- sample_id_colname } @@ -103,13 +104,13 @@ normalize_counts <- function( message(paste0("Total number of features included: ", nrow(df.voom))) ### PH: END Limma Normalization if (isTRUE(print_plots) || isTRUE(save_plots)) { - if (is.null(colors_for_plots)) { - colors_for_plots <- moo@analyses[["colors"]][[group_colname]] - } + colors_for_plots <- colors_for_plots %||% + moo@analyses$colors[[group_colname]] + if (isTRUE(color_histogram_by_group)) { colors_for_histogram <- colors_for_plots } else { - colors_for_histogram <- moo@analyses[["colors"]][[label_colname]] + colors_for_histogram <- moo@analyses$colors[[label_colname]] } pca_plot <- plot_pca( df.voom, @@ -117,7 +118,7 @@ normalize_counts <- function( sample_id_colname = sample_id_colname, samples_to_rename = samples_to_rename, group_colname = group_colname, - label_colname = label_colname, + label_colname = pca_label_colname, color_values = colors_for_plots, principal_components = c( principal_component_on_x_axis, @@ -125,10 +126,10 @@ normalize_counts <- function( ), legend_position = legend_position_for_pca, point_size = point_size_for_pca, - add_label = add_label_to_pca, label_font_size = label_font_size, label_offset_y_ = label_offset_y_, label_offset_x_ = label_offset_x_, + log_transform = FALSE, print_plots = FALSE, save_plots = FALSE ) + @@ -143,11 +144,17 @@ normalize_counts <- function( color_values = colors_for_histogram, color_by_group = color_histogram_by_group, x_axis_label = "Normalized Counts", + set_min_max_for_x_axis = set_min_max_for_x_axis_for_histogram, + minimum_for_x_axis = minimum_for_x_axis_for_histogram, + maximum_for_x_axis = maximum_for_x_axis_for_histogram, legend_position = legend_position_for_histogram, legend_font_size = legend_font_size_for_histogram, - number_of_legend_columns = number_of_histogram_legend_columns - ) + - ggplot2::labs(caption = "normalized counts") + number_of_legend_columns = number_of_histogram_legend_columns, + interactive_plots = interactive_plots + ) + if (!isTRUE(interactive_plots)) { + hist_plot <- hist_plot + ggplot2::labs(caption = "normalized counts") + } if (isTRUE(plot_corr_matrix_heatmap)) { corHM_plot <- plot_corr_heatmap( df.filt, @@ -166,16 +173,32 @@ normalize_counts <- function( caption = "normalized counts" ) } - - print_or_save_plot( - pca_plot, - filename = file.path(plots_subdir, "pca.png"), - print_plots = print_plots, - save_plots = save_plots - ) + plot_ext <- "png" + if (isTRUE(interactive_plots)) { + pca_plot <- pca_plot |> plotly::ggplotly(tooltip = "text") + plot_ext <- "html" + } + if (identical(plot_ext, "png")) { + print_or_save_plot( + pca_plot, + filename = file.path(plots_subdir, glue::glue("pca.{plot_ext}")), + print_plots = print_plots, + save_plots = save_plots, + width = 7, + height = 7, + units = "in" + ) + } else { + print_or_save_plot( + pca_plot, + filename = file.path(plots_subdir, glue::glue("pca.{plot_ext}")), + print_plots = print_plots, + save_plots = save_plots + ) + } print_or_save_plot( hist_plot, - filename = file.path(plots_subdir, "histogram.png"), + filename = file.path(plots_subdir, glue::glue("histogram.{plot_ext}")), print_plots = print_plots, save_plots = save_plots ) diff --git a/code/MOSuite/R/plot_heatmap.R b/code/MOSuite/R/plot_heatmap.R index 879f0ee..e3dea29 100644 --- a/code/MOSuite/R/plot_heatmap.R +++ b/code/MOSuite/R/plot_heatmap.R @@ -42,10 +42,7 @@ #' feature_id_colname = NULL, #' group_colname = "Group", #' label_colname = "Label", -#' color_values = c( -#' "#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", -#' "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500" -#' )) +#' color_values = mosuite_palette) #' ``` #' #' @seealso @@ -64,6 +61,13 @@ plot_corr_heatmap <- S7::new_generic("plot_corr_heatmap", "moo_counts") #' @param count_type the type of counts to use. Must be a name in the counts slot (`names(moo@counts)`). #' @param sub_count_type used if `count_type` is a list in the counts slot: specify the sub count type within the list. #' Must be a name in `names(moo@counts[[count_type]])`. +#' @param group_colname The column from the sample metadata containing the sample group information. This is usually a +#' column showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal, +#' Before, After, etc.). +#' @param color_values vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +#' level order when the grouping column is a factor; otherwise, they are assigned in the order groups first appear in +#' the metadata column. Defaults to `NULL`; when `NULL`, `mosuite_palette` is used for `data.frame` dispatch and +#' stored colors are used for `multiOmicDataSet` dispatch. #' @param ... additional arguments forwarded to [plot_corr_heatmap()] for `data.frame` #' #' @rdname plot_corr_heatmap-multiOmicDataSet @@ -76,12 +80,17 @@ S7::method(plot_corr_heatmap, multiOmicDataSet) <- function( moo_counts, count_type, sub_count_type = NULL, + group_colname = "Group", + color_values = NULL, ... ) { counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) + color_values <- color_values %||% moo_counts@analyses$colors[group_colname] return(plot_corr_heatmap( counts_dat, sample_metadata = moo_counts@sample_meta, + group_colname = group_colname, + color_values = color_values, ... )) } @@ -105,7 +114,9 @@ S7::method(plot_corr_heatmap, multiOmicDataSet) <- function( #' labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the #' column with your preferred Labels here. The selected column should contain unique names for each sample. (Default: #' `NULL` -- `sample_id_colname` will be used.) -#' @param color_values vector of colors as hex values or names recognized by R +#' @param color_values vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +#' level order when the grouping column is a factor; otherwise, they are assigned in the order groups first appear in +#' the metadata column. Defaults to `NULL`; when `NULL`, `mosuite_palette` is used. #' #' @rdname plot_corr_heatmap-data.frame #' @aliases plot_corr_heatmap.data.frame @@ -120,22 +131,10 @@ S7::method(plot_corr_heatmap, S7::class_data.frame) <- function( feature_id_colname = NULL, group_colname = "Group", label_colname = "Label", - color_values = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ) + color_values = NULL ) { abort_packages_not_installed("amap", "ComplexHeatmap", "dendsort") + color_values <- color_values %||% mosuite_palette counts_dat <- moo_counts if (is.null(sample_id_colname)) { sample_id_colname <- colnames(sample_metadata)[1] @@ -154,20 +153,15 @@ S7::method(plot_corr_heatmap, S7::class_data.frame) <- function( # cannot set rownames on a tibble sample_metadata <- sample_metadata |> as.data.frame() rownames(sample_metadata) <- sample_metadata[[label_colname]] - annoVal <- lapply(group_colname, function(x) { - # TODO this only works on dataframes, not tibbles - out <- as.factor(sample_metadata |> dplyr::pull(x)) |> levels() - # names(out)=x - return(out) - }) |> - unlist() - col <- color_values[seq_along(annoVal)] - names(col) <- annoVal - + # normalize color_values to a named list so each column can have its own colors + if (!is.list(color_values)) { + color_values <- stats::setNames( + rep(list(color_values), length(group_colname)), + group_colname + ) + } cols <- lapply(group_colname, function(x) { - ax <- as.factor(sample_metadata |> dplyr::pull(x)) |> levels() - out <- col[ax] - return(out) + return(resolve_plot_colors(sample_metadata, x, color_values[[x]])) }) names(cols) <- (group_colname) @@ -255,7 +249,10 @@ S7::method(plot_corr_heatmap, S7::class_data.frame) <- function( #' labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the #' column with your preferred Labels here. The selected column should contain unique names for each sample. (Default: #' `NULL` -- `sample_id_colname` will be used.) -#' @param color_values vector of colors as hex values or names recognized by R +#' @param color_values vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +#' level order when the grouping column is a factor; otherwise, they are assigned in the order groups first appear in +#' the metadata column. Defaults to `NULL`; when `NULL`, `mosuite_palette` is used for `data.frame` dispatch and +#' stored colors are used for `multiOmicDataSet` dispatch. #' @param samples_to_include Which samples would you like to include? Usually, you will choose all sample columns, or #' you could choose to remove certain samples. Samples excluded here will be removed in this step and from further #' analysis downstream of this step. (Default: `NULL` - all sample IDs in `moo@sample_meta` will be used.) @@ -295,7 +292,6 @@ S7::method(plot_corr_heatmap, S7::class_data.frame) <- function( #' @param assign_group_colors If TRUE, set the groups assigned colors (below) #' @param assign_color_to_sample_groups Enter each sample to color in the format: group_name: color This parameter is #' ignored if "Assign Colors" is set to FALSE. -#' @param group_colors Set group annotation colors. #' @param heatmap_color_scheme color scheme (TODO document options) #' @param autoscale_heatmap_color Set to TRUE to autoscale the heatmap colors between the maximum and minimum heatmap #' color parameters. If FALSE, set the heatmap colors between "Set max heatmap color" and "Set min heatmap color" @@ -312,6 +308,7 @@ S7::method(plot_corr_heatmap, S7::class_data.frame) <- function( #' @param display_numbers Setting to FALSE (default) will not display numerical value of heat on heatmap. Set to TRUE if #' you want to see these numbers on the plot. #' @param plot_filename plot output filename - only used if save_plots is TRUE +#' @param ... additional arguments passed to methods #' #' @export #' @returns heatmap from `ComplexHeatmap::Heatmap()` @@ -365,20 +362,7 @@ plot_expr_heatmap <- S7::new_generic( group_colname = "Group", label_colname = NULL, samples_to_include = NULL, - color_values = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), + color_values = NULL, include_all_genes = FALSE, filter_top_genes_by_variance = TRUE, top_genes_by_variance_to_include = 500, @@ -403,20 +387,6 @@ plot_expr_heatmap <- S7::new_generic( group_columns = c("Group", "Replicate", "Batch"), assign_group_colors = FALSE, assign_color_to_sample_groups = c(), - group_colors = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), heatmap_color_scheme = "Default", autoscale_heatmap_color = TRUE, set_min_heatmap_color = -2, @@ -429,7 +399,8 @@ plot_expr_heatmap <- S7::new_generic( plot_filename = "expr_heatmap.png", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), - plots_subdir = "heatmap" + plots_subdir = "heatmap", + ... ) { return(S7::S7_dispatch()) } @@ -447,20 +418,7 @@ S7::method(plot_expr_heatmap, multiOmicDataSet) <- function( group_colname = "Group", label_colname = NULL, samples_to_include = NULL, - color_values = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), + color_values = NULL, include_all_genes = FALSE, filter_top_genes_by_variance = TRUE, top_genes_by_variance_to_include = 500, @@ -485,20 +443,6 @@ S7::method(plot_expr_heatmap, multiOmicDataSet) <- function( group_columns = c("Group", "Replicate", "Batch"), assign_group_colors = FALSE, assign_color_to_sample_groups = c(), - group_colors = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), heatmap_color_scheme = "Default", autoscale_heatmap_color = TRUE, set_min_heatmap_color = -2, @@ -511,58 +455,59 @@ S7::method(plot_expr_heatmap, multiOmicDataSet) <- function( plot_filename = "expr_heatmap.png", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), - plots_subdir = "heatmap" + plots_subdir = "heatmap", + ... ) { counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) + color_values <- color_values %||% moo_counts@analyses$colors[group_columns] heatmap_plot <- plot_expr_heatmap( counts_dat, count_type = count_type, sub_count_type = sub_count_type, sample_metadata = moo_counts@sample_meta, sample_id_colname = NULL, - feature_id_colname, - group_colname, - label_colname, - samples_to_include, - color_values, - include_all_genes, - filter_top_genes_by_variance, - top_genes_by_variance_to_include, - specific_genes_to_include_in_heatmap, - cluster_genes, - gene_distance_metric, - gene_clustering_method, - display_gene_dendrograms, - display_gene_names, - center_and_rescale_expression, - cluster_samples, - arrange_sample_columns, - order_by_gene_expression, - gene_to_order_columns, - gene_expression_order, - smpl_distance_metric, - smpl_clustering_method, - display_smpl_dendrograms, - reorder_dendrogram, - reorder_dendrogram_order, - display_sample_names, - group_columns, - assign_group_colors, - assign_color_to_sample_groups, - group_colors, - heatmap_color_scheme, - autoscale_heatmap_color, - set_min_heatmap_color, - set_max_heatmap_color, - aspect_ratio, - legend_font_size, - gene_name_font_size, - sample_name_font_size, - display_numbers, + feature_id_colname = feature_id_colname, + group_colname = group_colname, + label_colname = label_colname, + samples_to_include = samples_to_include, + color_values = color_values, + include_all_genes = include_all_genes, + filter_top_genes_by_variance = filter_top_genes_by_variance, + top_genes_by_variance_to_include = top_genes_by_variance_to_include, + specific_genes_to_include_in_heatmap = specific_genes_to_include_in_heatmap, + cluster_genes = cluster_genes, + gene_distance_metric = gene_distance_metric, + gene_clustering_method = gene_clustering_method, + display_gene_dendrograms = display_gene_dendrograms, + display_gene_names = display_gene_names, + center_and_rescale_expression = center_and_rescale_expression, + cluster_samples = cluster_samples, + arrange_sample_columns = arrange_sample_columns, + order_by_gene_expression = order_by_gene_expression, + gene_to_order_columns = gene_to_order_columns, + gene_expression_order = gene_expression_order, + smpl_distance_metric = smpl_distance_metric, + smpl_clustering_method = smpl_clustering_method, + display_smpl_dendrograms = display_smpl_dendrograms, + reorder_dendrogram = reorder_dendrogram, + reorder_dendrogram_order = reorder_dendrogram_order, + display_sample_names = display_sample_names, + group_columns = group_columns, + assign_group_colors = assign_group_colors, + assign_color_to_sample_groups = assign_color_to_sample_groups, + heatmap_color_scheme = heatmap_color_scheme, + autoscale_heatmap_color = autoscale_heatmap_color, + set_min_heatmap_color = set_min_heatmap_color, + set_max_heatmap_color = set_max_heatmap_color, + aspect_ratio = aspect_ratio, + legend_font_size = legend_font_size, + gene_name_font_size = gene_name_font_size, + sample_name_font_size = sample_name_font_size, + display_numbers = display_numbers, plot_filename = plot_filename, - print_plots, - save_plots, - plots_subdir + print_plots = print_plots, + save_plots = save_plots, + plots_subdir = plots_subdir ) return(heatmap_plot) } @@ -578,20 +523,7 @@ S7::method(plot_expr_heatmap, S7::class_data.frame) <- function( group_colname = "Group", label_colname = NULL, samples_to_include = NULL, - color_values = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), + color_values = NULL, include_all_genes = FALSE, filter_top_genes_by_variance = TRUE, top_genes_by_variance_to_include = 500, @@ -616,20 +548,6 @@ S7::method(plot_expr_heatmap, S7::class_data.frame) <- function( group_columns = c("Group", "Replicate", "Batch"), assign_group_colors = FALSE, assign_color_to_sample_groups = c(), - group_colors = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), heatmap_color_scheme = "Default", autoscale_heatmap_color = TRUE, set_min_heatmap_color = -2, @@ -642,10 +560,12 @@ S7::method(plot_expr_heatmap, S7::class_data.frame) <- function( plot_filename = "expr_heatmap.png", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), - plots_subdir = "heatmap" + plots_subdir = "heatmap", + ... ) { ## This function uses pheatmap to draw a heatmap, scaling first by rows ## (with samples in columns and genes in rows) + color_values <- color_values %||% mosuite_palette Gene <- NULL # TODO support tibbles; currently these must be dataframes counts_dat <- as.data.frame(moo_counts) @@ -749,9 +669,6 @@ S7::method(plot_expr_heatmap, S7::class_data.frame) <- function( # if (=FALSE) { # col.pal = rev(col.pal) # } - # Define metrics for clustering - drows1 <- gene_distance_metric - dcols1 <- smpl_distance_metric minx <- min(dat) maxx <- max(dat) if (autoscale_heatmap_color) { @@ -763,31 +680,58 @@ S7::method(plot_expr_heatmap, S7::class_data.frame) <- function( } breaks <- sapply(breaks, signif, 4) legbreaks <- sapply(legbreaks, signif, 4) - # Run cluster method using - hcrow <- stats::hclust(stats::dist(dat), method = gene_clustering_method) - # hc <- stats::hclust(stats::dist(t(dat)), method = smpl_clustering_method) + # Build distance matrices explicitly before hclust() so user-selected + # distance metrics are used. Calling stats::dist(dat) directly would force + # Euclidean distance and ignore gene_distance_metric/smpl_distance_metric. + heatmap_dist <- function(x, metric) { + metric <- trimws(metric) + if (identical(metric, "correlation")) { + corr <- stats::cor(t(x), use = "pairwise.complete.obs") + corr[is.na(corr)] <- 0 + return(stats::as.dist(1 - corr)) + } + + return(stats::dist(x, method = metric)) + } - if (FALSE) { - sort_hclust <- function(...) { - return(stats::as.hclust(rev( - dendsort::dendsort(stats::as.dendrogram(...)) - ))) + sort_hclust <- function(hc, reverse = FALSE, rotation_order = NULL) { + dend <- dendsort::dendsort(stats::as.dendrogram(hc)) + if (reverse) { + dend <- rev(dend) } - } else { - sort_hclust <- function(...) { - return(stats::as.hclust(dendsort::dendsort(stats::as.dendrogram(...)))) + if (!is.null(rotation_order) && length(rotation_order) > 0) { + dend <- dendextend::rotate(dend, rotation_order) } + return(stats::as.hclust(dend)) } - # if (clus) { - # colclus <- sort_hclust(hc) - # } else { - # colclus <- FALSE - # } + if (clus2) { + hcrow <- stats::hclust( + heatmap_dist(dat, gene_distance_metric), + method = gene_clustering_method + ) rowclus <- sort_hclust(hcrow) } else { rowclus <- FALSE } + if (clus) { + sample_rotation <- NULL + if (reorder_dendrogram == TRUE) { + sample_rotation <- reorder_dendrogram_order + } + hccol <- stats::hclust( + heatmap_dist(t(dat), smpl_distance_metric), + method = smpl_clustering_method + ) + colclus <- sort_hclust( + hccol, + reverse = TRUE, + rotation_order = sample_rotation + ) + } else { + colclus <- FALSE + } + if (display_smpl_dendrograms) { smpl_treeheight <- 25 } else { @@ -819,32 +763,20 @@ S7::method(plot_expr_heatmap, S7::class_data.frame) <- function( show_rownames = rn, show_colnames = cn, cluster_rows = rowclus, - cluster_cols = clus, - clustering_distance_rows = drows1, - clustering_distance_cols = dcols1, + cluster_cols = colclus, annotation_col = annotation_col, annotation_colors = annot_col, labels_col = labels_col ) - # mat <- t(dat) - callback <- function(hc, mat) { - dend <- rev(dendsort::dendsort(stats::as.dendrogram(hc))) - if (reorder_dendrogram == TRUE) { - dend <- dend |> dendextend::rotate(reorder_dendrogram_order) - } else { - dend <- dend |> dendextend::rotate(c(1:stats::nobs(dend))) - } - return(stats::as.hclust(dend)) - } ### PH: END SET up heatmap function for do.call ## Make Heatmap + # Row and column clustering are handled above by heatmap_dist(), + # stats::hclust(), and sort_hclust(), then passed in via cluster_rows + # and cluster_cols. return(do.call( ComplexHeatmap::pheatmap, - c( - hm.parameters, - list(clustering_callback = callback) - ) + hm.parameters )) } # End doheatmap() function. @@ -1025,25 +957,40 @@ S7::method(plot_expr_heatmap, S7::class_data.frame) <- function( annotation_col <- as.data.frame(unclass(annotation_col)) annotation_col[] <- lapply(annotation_col, factor) x <- length(unlist(lapply(annotation_col, levels))) - if (x > length(group_colors)) { - k <- x - length(group_colors) - more_cols <- get_random_colors(k) - group_colors <- c(group_colors, more_cols) + if (!is.list(color_values) && x > length(color_values)) { + generated_group_colors <- get_colors_vctr( + data.frame(group_color_index = seq_len(x)), + "group_color_index" + ) + more_cols <- unname(generated_group_colors)[seq.int( + length(color_values) + 1, + x + )] + color_values <- c(color_values, more_cols) } rownames(annotation_col) <- annot[[label_colname]] annot_col <- list() - b <- 1 - i <- 1 - while (i <= length(group_columns)) { - cnam <- group_columns[i] - grp <- as.factor(annotation_col[, i]) - c <- b + length(levels(grp)) - 1 - col <- group_colors[b:c] - names(col) <- levels(grp) - assign(cnam, col) - annot_col <- append(annot_col, mget(cnam)) - b <- c + 1 - i <- i + 1 + next_color <- 1 + for (cnam in group_columns) { + group_levels <- stats::na.omit(unique(annot[[cnam]])) + + if (is.list(color_values) && cnam %in% names(color_values)) { + col <- resolve_plot_colors(annot, cnam, color_values[[cnam]]) + } else if ( + !is.null(names(color_values)) && + all(as.character(group_levels) %in% names(color_values)) + ) { + col <- resolve_plot_colors(annot, cnam, color_values) + } else { + color_slice <- color_values[ + next_color:(next_color + length(group_levels) - 1) + ] + col <- resolve_plot_colors(annot, cnam, color_slice) + } + + next_color <- next_color + length(group_levels) + + annot_col[[cnam]] <- col } if (assign_group_colors == TRUE) { diff --git a/code/MOSuite/R/plot_histogram.R b/code/MOSuite/R/plot_histogram.R index 8dd3087..37e62cf 100644 --- a/code/MOSuite/R/plot_histogram.R +++ b/code/MOSuite/R/plot_histogram.R @@ -54,6 +54,13 @@ plot_histogram <- S7::new_generic( #' the counts slot (`moo@counts`). #' @param sub_count_type Used if `moo_counts` is a `multiOmicDataSet` AND if `count_type` is a list, specify the sub #' count type within the list +#' @param group_colname The column from the sample metadata containing the sample group information. This is usually a +#' column showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal, +#' Before, After, etc.). +#' @param color_values vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +#' level order when the grouping column is a factor; otherwise, they follow the order in which groups first appear in +#' the metadata column. Defaults to `NULL`; when `NULL`, `mosuite_palette` is used for `data.frame` dispatch and +#' stored colors are used for `multiOmicDataSet` dispatch. #' @examples #' # plot histogram for a counts slot in a multiOmicDataset Object #' moo <- multiOmicDataSet( @@ -75,16 +82,35 @@ S7::method(plot_histogram, multiOmicDataSet) <- function( moo_counts, count_type, sub_count_type = NULL, + group_colname = "Group", + color_values = NULL, ... ) { counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) + color_values <- color_values %||% moo_counts@analyses$colors[[group_colname]] return(plot_histogram( counts_dat, sample_metadata = moo_counts@sample_meta, + group_colname = group_colname, + color_values = color_values, ... )) } +build_histogram_hover_text <- function( + histogram_data, + sample_id_colname, + group_colname = NULL +) { + return(format_hover_text( + histogram_data, + primary_colname = sample_id_colname, + secondary_colname = group_colname, + missing_col_context = "histogram", + require_secondary = FALSE + )) +} + #' Plot histogram for counts dataframe #' #' @rdname plot_histogram.data.frame @@ -107,7 +133,9 @@ S7::method(plot_histogram, multiOmicDataSet) <- function( #' labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the #' column with your preferred Labels here. The selected column should contain unique names for each sample. (Default: #' `NULL` -- `sample_id_colname` will be used.) -#' @param color_values vector of colors as hex values or names recognized by R +#' @param color_values vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +#' level order when the grouping column is a factor; otherwise, they follow the order in which groups first appear in +#' the metadata column. Defaults to `NULL`; when `NULL`, `mosuite_palette` is used. #' @param color_by_group Set to FALSE to label histogram by Sample Names, or set to TRUE to label histogram by the #' column you select in the "Group Column Used to Color Histogram" parameter (below). Default is FALSE. #' @param set_min_max_for_x_axis whether to override the default for `ggplot2::xlim()` (default: `FALSE`) @@ -116,11 +144,16 @@ S7::method(plot_histogram, multiOmicDataSet) <- function( #' @param x_axis_label text label for the x axis `ggplot2::xlab()` #' @param y_axis_label text label for the y axis `ggplot2::ylab()` #' @param legend_position passed to in `legend.position` `ggplot2::theme()` -#' @param legend_font_size passed to `ggplot2::element_text()` via `ggplot2::theme()` +#' @param legend_font_size passed to `ggplot2::element_text()` via `ggplot2::theme()`. If `NULL`, the size is scaled +#' automatically based on the number and length of legend labels. #' @param number_of_legend_columns passed to `ncol` in `ggplot2::guide_legend()` #' @param interactive_plots set to TRUE to make the plot interactive with `plotly`, allowing you to hover your mouse #' over a point or line to view sample information. The similarity heat map will not display if this toggle is set to #' TRUE. Default is FALSE. +#' @param return_ggplot If `TRUE`, return the ggplot object prepared for interactive hover text before converting it to +#' plotly. Used when callers need to add more ggplot layers first. Default is `FALSE`. +#' @param use_log2_x_axis If `TRUE`, add a display-only pseudocount to plotted values and use a log2 x-axis. Default is +#' `FALSE`. #' @param ... additional arguments (ignored; accepted for compatibility with the moo dispatch) #' @examples #' @@ -153,20 +186,7 @@ S7::method(plot_histogram, S7::class_data.frame) <- function( feature_id_colname = NULL, group_colname = "Group", label_colname = "Label", - color_values = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), + color_values = NULL, color_by_group = FALSE, set_min_max_for_x_axis = FALSE, minimum_for_x_axis = -1, @@ -174,12 +194,16 @@ S7::method(plot_histogram, S7::class_data.frame) <- function( x_axis_label = "Counts", y_axis_label = "Density", legend_position = "top", - legend_font_size = 10, + legend_font_size = NULL, number_of_legend_columns = 6, interactive_plots = FALSE, + return_ggplot = FALSE, + use_log2_x_axis = FALSE, ... ) { count <- NULL + log2_axis_pseudocount <- 0.5 + color_values <- color_values %||% mosuite_palette counts_dat <- moo_counts if (is.null(sample_id_colname)) { sample_id_colname <- colnames(sample_metadata)[1] @@ -196,50 +220,171 @@ S7::method(plot_histogram, S7::class_data.frame) <- function( ) |> dplyr::left_join(sample_metadata, by = sample_id_colname) + # For log2 histogram axes, add a display-only pseudocount after reshaping. + # The original count table is not modified; this only keeps zeros finite for ggplot's log transform. + if (isTRUE(use_log2_x_axis)) { + df_long <- df_long |> + dplyr::mutate(count = count + log2_axis_pseudocount) + } + + # Match user-supplied x-axis limits to the plotted scale. On the log2 path, + # limits need the same pseudocount offset as the displayed data. if (set_min_max_for_x_axis == TRUE) { - xmin <- minimum_for_x_axis - xmax <- maximum_for_x_axis + if (isTRUE(use_log2_x_axis)) { + xmin <- minimum_for_x_axis + log2_axis_pseudocount + xmax <- maximum_for_x_axis + log2_axis_pseudocount + } else { + xmin <- minimum_for_x_axis + xmax <- maximum_for_x_axis + } } else { xmin <- min(df_long |> dplyr::pull(count)) xmax <- max(df_long |> dplyr::pull(count)) } + # Guard the log2 axis against non-finite or nonpositive limits after the offset. + if (isTRUE(use_log2_x_axis)) { + if (set_min_max_for_x_axis == TRUE) { + xmin <- max(xmin, log2_axis_pseudocount) + } else { + # Automatic log2 histograms should display a raw minimum of 0. + xmin <- log2_axis_pseudocount + } + if (!is.finite(xmax) || xmax <= xmin) { + xmax <- max(xmin, log2_axis_pseudocount) + } + } if (color_by_group == TRUE) { + df_long <- df_long |> + dplyr::filter(!is.na(!!rlang::sym(group_colname))) + color_values <- resolve_plot_colors(df_long, group_colname, color_values) df_long <- df_long |> dplyr::mutate( - !!rlang::sym(group_colname) := as.factor(!!rlang::sym(group_colname)) - ) |> - dplyr::filter(!is.na(group_colname)) - n <- df_long |> - dplyr::pull(group_colname) |> - levels() |> - length() + !!rlang::sym(group_colname) := as.character(!!rlang::sym(group_colname)) + ) + if (isTRUE(interactive_plots)) { + df_long$histogram_hover_text <- build_histogram_hover_text( + df_long, + sample_id_colname, + group_colname + ) + } + histogram_mapping <- ggplot2::aes( + x = count, + group = !!rlang::sym(sample_id_colname) + ) + if (isTRUE(interactive_plots)) { + histogram_mapping <- ggplot2::aes( + x = count, + group = !!rlang::sym(sample_id_colname), + text = histogram_hover_text + ) + } + # The problem here is that static histograms should keep density curves in + # the plot while showing line-style legend keys instead of box-like keys. + # We build geom_density() args as a list so static output can add + # key_glyph, but the interactive ggplotly() path can skip that tweak. + # Passing the legend-key change into ggplotly() made interactive density + # traces misbehave, so we apply it only for non-interactive plots. + density_layer_args <- list( + mapping = ggplot2::aes(colour = !!rlang::sym(group_colname)), + linewidth = 1 + ) + if (!isTRUE(interactive_plots)) { + density_layer_args$key_glyph <- ggplot2::draw_key_path + } # plot Density hist_plot <- df_long |> - ggplot2::ggplot(ggplot2::aes( + ggplot2::ggplot(histogram_mapping) + + do.call(ggplot2::geom_density, density_layer_args) + } else { + color_values <- resolve_plot_colors( + df_long, + sample_id_colname, + color_values + ) + df_long <- df_long |> + dplyr::mutate( + !!rlang::sym(sample_id_colname) := as.character( + !!rlang::sym(sample_id_colname) + ) + ) + if (isTRUE(interactive_plots)) { + df_long$histogram_hover_text <- build_histogram_hover_text( + df_long, + sample_id_colname, + group_colname + ) + } + histogram_mapping <- ggplot2::aes( + x = count, + group = !!rlang::sym(sample_id_colname) + ) + if (isTRUE(interactive_plots)) { + histogram_mapping <- ggplot2::aes( x = count, - group = !!rlang::sym(sample_id_colname) - )) + - ggplot2::geom_density( - ggplot2::aes(colour = !!rlang::sym(group_colname)), - linewidth = 1 + group = !!rlang::sym(sample_id_colname), + text = histogram_hover_text ) - } else { - n <- df_long |> - dplyr::pull(sample_id_colname) |> - unique() |> - length() + } + # Use the same strategy for sample-colored histograms: solve the static + # legend-key problem without changing the interactive density conversion. + # Static output gets line-style legend keys, while interactive output + # avoids the key_glyph change that breaks ggplotly(). + density_layer_args <- list( + mapping = ggplot2::aes(colour = !!rlang::sym(sample_id_colname)), + linewidth = 1 + ) + if (!isTRUE(interactive_plots)) { + density_layer_args$key_glyph <- ggplot2::draw_key_path + } hist_plot <- df_long |> - ggplot2::ggplot(ggplot2::aes( - x = count, - group = !!rlang::sym(sample_id_colname) - )) + - ggplot2::geom_density( - ggplot2::aes(colour = !!rlang::sym(sample_id_colname)), - linewidth = 1 - ) + ggplot2::ggplot(histogram_mapping) + + do.call(ggplot2::geom_density, density_layer_args) + } + + legend_font_size <- get_legend_text_size( + names(color_values), + legend_font_size + ) + + # Keep the plain histogram default unchanged. When requested, use ggplot's log2 + # scale and label ticks back on the original count scale by subtracting the offset. + x_axis_scale <- if (isTRUE(use_log2_x_axis)) { + ggplot2::scale_x_continuous( + transform = "log2", + limits = c(xmin, xmax), + breaks = function(limits) { + # Breaks are chosen on the original count scale, then shifted by the + # display-only pseudocount so they align with the plotted/log2 values. + raw_upper_limit <- max(limits - log2_axis_pseudocount, na.rm = TRUE) + if (!is.finite(raw_upper_limit) || raw_upper_limit <= 0) { + return(log2_axis_pseudocount) + } + max_power <- floor(log2(raw_upper_limit)) + if (max_power < 0) { + raw_breaks <- c(0, raw_upper_limit) + } else { + # Use powers of two, thinning to about eight labels for wide ranges, + # and always include the highest power so the high end is labeled. + step <- max(1, ceiling((max_power + 1) / 8)) + exponents <- unique(c(seq(0, max_power, by = step), max_power)) + raw_breaks <- c(0, 2^exponents) + } + raw_breaks <- raw_breaks[ + raw_breaks >= 0 & raw_breaks <= raw_upper_limit + ] + return(unique(raw_breaks + log2_axis_pseudocount)) + }, + labels = function(x) { + return(scales::label_number(big.mark = "")(x - log2_axis_pseudocount)) + }, + name = x_axis_label + ) + } else { + ggplot2::xlim(xmin, xmax) } hist_plot <- hist_plot + @@ -248,6 +393,7 @@ S7::method(plot_histogram, S7::class_data.frame) <- function( ggplot2::theme_bw() + ggplot2::theme( legend.position = legend_position, + legend.key = ggplot2::element_blank(), legend.text = ggplot2::element_text(size = legend_font_size), legend.title = ggplot2::element_blank(), panel.background = ggplot2::element_blank(), @@ -262,16 +408,30 @@ S7::method(plot_histogram, S7::class_data.frame) <- function( axis.ticks = ggplot2::element_line(linewidth = 1) ) + ggplot2::ggtitle("Frequency Histogram") + - ggplot2::xlim(xmin, xmax) + + x_axis_scale + # scale_linetype_manual(values=rep(c('solid', 'dashed','dotted','twodash'),n)) + - ggplot2::scale_colour_manual(values = color_values[1:n]) + - ggplot2::guides( - linetype = ggplot2::guide_legend(ncol = number_of_legend_columns) - ) + ggplot2::scale_colour_manual(values = color_values) if (isTRUE(interactive_plots)) { - hist_plot <- (hist_plot + ggplot2::theme(legend.position = "none")) |> - plotly::ggplotly(tooltip = c(sample_id_colname)) + if (isTRUE(return_ggplot)) { + return(hist_plot) + } + hist_plot <- hist_plot |> + plotly::ggplotly(tooltip = "text") + } else { + hist_plot <- add_colour_legend_layout( + hist_plot, + labels = names(color_values), + legend_position = legend_position, + ncol = number_of_legend_columns, + legend_text_size = legend_font_size, + guide_override_aes = list( + linetype = 1, + linewidth = 2, + shape = NA, + fill = NA + ) + ) } return(hist_plot) } diff --git a/code/MOSuite/R/plot_pca.R b/code/MOSuite/R/plot_pca.R index d419b80..3e35982 100644 --- a/code/MOSuite/R/plot_pca.R +++ b/code/MOSuite/R/plot_pca.R @@ -29,6 +29,12 @@ #' #' @details #' +#' PCA is sensitive to feature scale. For raw, cleaned, filtered, or CPM-like count data, setting +#' `log_transform = TRUE` compresses high-count features before PCA so ordination is less dominated by abundance +#' differences. Do not enable this for already normalized/log-scale data, such as voom/logCPM `norm` counts or +#' batch-corrected normalized counts, because that would apply a second log transform. The default PCA transform uses +#' the original MOSuite PCA scaling, `log(x + 0.5)`. +#' #' See the low-level function docs for additional arguments #' depending on whether you're plotting 2 or 3 PCs: #' @@ -122,6 +128,27 @@ S7::method(plot_pca, S7::class_data.frame) <- function( ) } +build_pca_hover_text <- function( + pca_data, + sample_id_colname, + group_colname, + label_colname = NULL +) { + label_hover_colname <- if (is.null(label_colname)) { + sample_id_colname + } else { + label_colname + } + + return(format_hover_text( + pca_data, + primary_colname = label_hover_colname, + secondary_colname = group_colname, + missing_col_context = "PCA", + require_secondary = TRUE + )) +} + #' Perform and plot a 2D Principal Components Analysis #' #' @rdname plot_pca_2d @@ -140,32 +167,23 @@ plot_pca_2d <- S7::new_generic( group_colname = "Group", label_colname = "Label", samples_to_rename = NULL, - color_values = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), + color_values = NULL, principal_components = c(1, 2), legend_position = "top", - point_size = 1, - add_label = TRUE, + point_size = 5, + legend_font_size = NULL, label_font_size = 3, label_offset_x_ = 2, label_offset_y_ = 2, + log_transform = FALSE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", interactive_plots = FALSE, plots_subdir = "pca", plot_filename = "pca_2D.png", print_plots = options::opt("print_plots"), - save_plots = options::opt("save_plots") + save_plots = options::opt("save_plots"), + ... ) { return(S7::S7_dispatch()) } @@ -182,34 +200,26 @@ S7::method(plot_pca_2d, multiOmicDataSet) <- function( group_colname = "Group", label_colname = "Label", samples_to_rename = NULL, - color_values = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), + color_values = NULL, principal_components = c(1, 2), legend_position = "top", - point_size = 1, - add_label = TRUE, + point_size = 5, + legend_font_size = NULL, label_font_size = 3, label_offset_x_ = 2, label_offset_y_ = 2, + log_transform = FALSE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", interactive_plots = FALSE, plots_subdir = "pca", plot_filename = "pca_2D.png", print_plots = options::opt("print_plots"), - save_plots = options::opt("save_plots") + save_plots = options::opt("save_plots"), + ... ) { counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) + color_values <- color_values %||% moo_counts@analyses$colors[[group_colname]] return(plot_pca_2d( counts_dat, sample_metadata = moo_counts@sample_meta, @@ -222,10 +232,13 @@ S7::method(plot_pca_2d, multiOmicDataSet) <- function( principal_components = principal_components, legend_position = legend_position, point_size = point_size, - add_label = add_label, + legend_font_size = legend_font_size, label_font_size = label_font_size, label_offset_x_ = label_offset_x_, label_offset_y_ = label_offset_y_, + log_transform = log_transform, + log_transform_pseudocount = log_transform_pseudocount, + log_transform_base = log_transform_base, interactive_plots = interactive_plots, plots_subdir = plots_subdir, plot_filename = plot_filename, @@ -252,20 +265,39 @@ S7::method(plot_pca_2d, multiOmicDataSet) <- function( #' @param group_colname The column from the sample metadata containing the sample group information. This is usually a #' column showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal, #' Before, After, etc.). -#' @param label_colname The column from the sample metadata containing the sample labels as you wish them to appear in -#' the plots produced by this template. This can be the same Sample Names Column. However, you may desire different -#' labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the -#' column with your preferred Labels here. The selected column should contain unique names for each sample. (Default: -#' `NULL` -- `sample_id_colname` will be used.) +#' @param label_colname The column from the sample metadata containing the sample labels as you wish them to appear on +#' the PCA plot. If `NULL`, no labels are added to PCA points. This can be the same Sample Names Column. However, you +#' may desire different labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In +#' that case, select the column with your preferred Labels here. The selected column should contain unique names for +#' each sample. #' @param samples_to_rename If you do not have a Plot Labels Column in your sample metadata table, you can use this #' parameter to rename samples manually for display on the PCA plot. Use "Add item" to add each additional sample for #' renaming. Use the following format to describe which old name (in your sample metadata table) you want to rename to #' which new name: old_name: new_name -#' @param color_values vector of colors as hex values or names recognized by R +#' @param color_values vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +#' level order when the grouping column is a factor; otherwise, they follow the order in which groups first appear in +#' the metadata column. Defaults to `NULL`; when `NULL`, `mosuite_palette` is used for `data.frame` dispatch and +#' stored colors are used for `multiOmicDataSet` dispatch. #' @param principal_components vector with numbered principal components to plot #' @param legend_position passed to in `legend.position` `ggplot2::theme()` #' @param point_size size for `ggplot2::geom_point()` -#' @param add_label whether to add text labels for the points +#' @param legend_font_size font size for the PCA legend text. If `NULL`, the size is scaled automatically based on the +#' number and length of legend labels. +#' @param count_type the type of counts to use when `moo_counts` is a `multiOmicDataSet`; ignored for data frame input. +#' @param sub_count_type used when `count_type` refers to a list of count matrices; ignored for data frame input. +#' @param label_font_size font size for text labels on the PCA plot. +#' @param label_offset_x_ horizontal offset for text labels on the PCA plot. +#' @param label_offset_y_ vertical offset for text labels on the PCA plot. +#' @param log_transform If `TRUE`, apply `log(x + log_transform_pseudocount, base = log_transform_base)` to sample +#' count columns before PCA. Use this for count-like data such as raw, clean, filt, or CPM-like counts; leave it +#' `FALSE` for already normalized/log-scale or batch-corrected values to avoid double transformation. +#' @param log_transform_pseudocount Pseudocount added before log-transforming counts when `log_transform` is +#' `TRUE`. +#' @param log_transform_base Logarithm base to use when `log_transform` is `TRUE`. Use a numeric value, or `"e"`, +#' `"ln"`, or `"natural"` for natural log. Default is `"ln"` to match the original PCA transform. +#' @param interactive_plots set to TRUE to make the PCA plot interactive with `plotly`. +#' @param plots_subdir subdirectory in `figures/` where PCA plots are saved. +#' @param plot_filename output filename for the PCA plot image. #' #' @return ggplot object #' @@ -283,34 +315,26 @@ S7::method(plot_pca_2d, S7::class_data.frame) <- function( group_colname = "Group", label_colname = "Label", samples_to_rename = NULL, - color_values = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), + color_values = NULL, principal_components = c(1, 2), legend_position = "top", - point_size = 1, - add_label = TRUE, + point_size = 5, + legend_font_size = NULL, label_font_size = 3, label_offset_x_ = 2, label_offset_y_ = 2, + log_transform = FALSE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", interactive_plots = FALSE, plots_subdir = "pca", plot_filename = "pca_2D.png", print_plots = options::opt("print_plots"), - save_plots = options::opt("save_plots") + save_plots = options::opt("save_plots"), + ... ) { PC <- std.dev <- percent <- cumulative <- NULL + color_values <- color_values %||% mosuite_palette if (length(principal_components) != 2) { stop( glue::glue( @@ -325,6 +349,14 @@ S7::method(plot_pca_2d, S7::class_data.frame) <- function( if (is.null(feature_id_colname)) { feature_id_colname <- colnames(moo_counts)[1] } + if (isTRUE(log_transform)) { + moo_counts <- log_transform_counts( + moo_counts, + feature_id_colname = feature_id_colname, + pseudocount = log_transform_pseudocount, + base = log_transform_base + ) + } # calculate PCA pca_df <- calc_pca( @@ -344,8 +376,19 @@ S7::method(plot_pca_2d, S7::class_data.frame) <- function( names_prefix = "PC", values_from = "value" ) + pca_wide$pca_hover_text <- build_pca_hover_text( + pca_wide, + sample_id_colname, + group_colname, + label_colname + ) prin_comp_x <- principal_components[1] prin_comp_y <- principal_components[2] + color_values <- resolve_plot_colors(pca_wide, group_colname, color_values) + legend_font_size <- get_legend_text_size( + names(color_values), + legend_font_size + ) # plot PCA pca_plot <- pca_wide |> dplyr::mutate( @@ -354,7 +397,7 @@ S7::method(plot_pca_2d, S7::class_data.frame) <- function( ggplot2::ggplot(ggplot2::aes( x = !!rlang::sym(glue::glue("PC{prin_comp_x}")), y = !!rlang::sym(glue::glue("PC{prin_comp_y}")), - text = !!rlang::sym(sample_id_colname) + text = pca_hover_text )) + ggplot2::geom_point( ggplot2::aes(color = !!rlang::sym(group_colname)), @@ -375,14 +418,21 @@ S7::method(plot_pca_2d, S7::class_data.frame) <- function( linewidth = 1 ), axis.ticks = ggplot2::element_line(linewidth = 1), - legend.text = ggplot2::element_text(size = 18) + legend.text = ggplot2::element_text(size = legend_font_size), + aspect.ratio = 1 ) + - ggplot2::coord_fixed(ratio = 1.5) + ggplot2::scale_colour_manual(values = color_values) + ggplot2::xlab(get_pc_percent_lab(pca_df, prin_comp_x)) + ggplot2::ylab(get_pc_percent_lab(pca_df, prin_comp_y)) - if (add_label == TRUE) { + pca_plot <- add_colour_legend_layout( + pca_plot, + labels = names(color_values), + legend_position = legend_position, + legend_text_size = legend_font_size + ) + + if (!is.null(label_colname)) { abort_packages_not_installed("ggrepel") pca_plot <- pca_plot + ggrepel::geom_text_repel( @@ -398,15 +448,27 @@ S7::method(plot_pca_2d, S7::class_data.frame) <- function( } if (isTRUE(interactive_plots)) { pca_plot <- (pca_plot) |> - plotly::ggplotly(tooltip = c(sample_id_colname, group_colname)) + plotly::ggplotly(tooltip = "text") } - print_or_save_plot( - pca_plot, - filename = file.path(plots_subdir, plot_filename), - print_plots = print_plots, - save_plots = save_plots - ) + if (inherits(pca_plot, "ggplot")) { + print_or_save_plot( + pca_plot, + filename = file.path(plots_subdir, plot_filename), + print_plots = print_plots, + save_plots = save_plots, + width = 7, + height = 7, + units = "in" + ) + } else { + print_or_save_plot( + pca_plot, + filename = file.path(plots_subdir, plot_filename), + print_plots = print_plots, + save_plots = save_plots + ) + } return(pca_plot) } @@ -415,6 +477,7 @@ S7::method(plot_pca_2d, S7::class_data.frame) <- function( #' #' @rdname plot_pca_3d #' @aliases plot_pca_3d +#' @param ... additional arguments passed to methods #' @export plot_pca_3d <- S7::new_generic( "plot_pca_3d", @@ -432,25 +495,16 @@ plot_pca_3d <- S7::new_generic( principal_components = c(1, 2, 3), point_size = 8, label_font_size = 24, - color_values = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), + log_transform = FALSE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", + color_values = NULL, plot_title = "PCA 3D", plot_filename = "pca_3D.html", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), - plots_subdir = "pca" + plots_subdir = "pca", + ... ) { return(S7::S7_dispatch()) } @@ -470,27 +524,19 @@ S7::method(plot_pca_3d, multiOmicDataSet) <- function( principal_components = c(1, 2, 3), point_size = 8, label_font_size = 24, - color_values = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), + log_transform = FALSE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", + color_values = NULL, plot_title = "PCA 3D", plot_filename = "pca_3D.html", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), - plots_subdir = "pca" + plots_subdir = "pca", + ... ) { counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) + color_values <- color_values %||% moo_counts@analyses$colors[[group_colname]] return( plot_pca_3d( counts_dat, @@ -505,6 +551,9 @@ S7::method(plot_pca_3d, multiOmicDataSet) <- function( principal_components = principal_components, point_size = point_size, label_font_size = label_font_size, + log_transform = log_transform, + log_transform_pseudocount = log_transform_pseudocount, + log_transform_base = log_transform_base, color_values = color_values, plot_title = plot_title, plot_filename = plot_filename, @@ -527,7 +576,10 @@ S7::method(plot_pca_3d, multiOmicDataSet) <- function( #' @param group_colname The column from sample metadata containing sample group information. #' @param label_colname The column from sample metadata containing sample labels. #' @param label_font_size font size used for labels in the interactive figure. -#' @param color_values vector of colors as hex values or names recognized by R. +#' @param color_values vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +#' level order when the grouping column is a factor; otherwise, they follow the order in which groups first appear in +#' the metadata column. Defaults to `NULL`; when `NULL`, `mosuite_palette` is used for `data.frame` dispatch and +#' stored colors are used for `multiOmicDataSet` dispatch. #' @param plot_filename output filename when saving plots. #' @param print_plots whether to print plot to the active graphics device. #' @param save_plots whether to save plot to disk. @@ -535,6 +587,13 @@ S7::method(plot_pca_3d, multiOmicDataSet) <- function( #' #' @param principal_components vector with numbered principal components to plot #' @param point_size size for `ggplot2::geom_point()` +#' @param log_transform If `TRUE`, apply `log(x + log_transform_pseudocount, base = log_transform_base)` to sample +#' count columns before PCA. Use this for count-like data such as raw, clean, filt, or CPM-like counts; leave it +#' `FALSE` for already normalized/log-scale or batch-corrected values to avoid double transformation. +#' @param log_transform_pseudocount Pseudocount added before log-transforming counts when `log_transform` is +#' `TRUE`. +#' @param log_transform_base Logarithm base to use when `log_transform` is `TRUE`. Use a numeric value, or `"e"`, +#' `"ln"`, or `"natural"` for natural log. Default is `"ln"` to match the original PCA transform. #' @param plot_title title for the plot #' #' @returns `plotly::plot_ly` figure @@ -555,27 +614,19 @@ S7::method(plot_pca_3d, S7::class_data.frame) <- function( principal_components = c(1, 2, 3), point_size = 8, label_font_size = 24, - color_values = c( - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ), + log_transform = FALSE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", + color_values = NULL, plot_title = "PCA 3D", plot_filename = "pca_3D.html", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), - plots_subdir = "pca" + plots_subdir = "pca", + ... ) { PC <- std.dev <- percent <- cumulative <- NULL + color_values <- color_values %||% mosuite_palette if (length(principal_components) != 3) { stop( glue::glue( @@ -590,6 +641,17 @@ S7::method(plot_pca_3d, S7::class_data.frame) <- function( if (is.null(sample_id_colname)) { sample_id_colname <- colnames(sample_metadata)[1] } + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(moo_counts)[1] + } + if (isTRUE(log_transform)) { + moo_counts <- log_transform_counts( + moo_counts, + feature_id_colname = feature_id_colname, + pseudocount = log_transform_pseudocount, + base = log_transform_base + ) + } # if (is.null(color_values)) { # color_values <- moo_nidap@analyses[['colors']][['Group']] @@ -610,9 +672,16 @@ S7::method(plot_pca_3d, S7::class_data.frame) <- function( names_prefix = "PC", values_from = "value" ) + pca_wide$pca_hover_text <- build_pca_hover_text( + pca_wide, + sample_id_colname, + group_colname, + label_colname + ) prin_comp_x <- principal_components[1] prin_comp_y <- principal_components[2] prin_comp_z <- principal_components[3] + color_values <- resolve_plot_colors(pca_wide, group_colname, color_values) fig <- plotly::plot_ly( pca_wide, @@ -625,7 +694,7 @@ S7::method(plot_pca_3d, S7::class_data.frame) <- function( mode = "markers", marker = list(size = point_size), hoverinfo = "text", - text = stats::as.formula(paste("~", sample_id_colname)), + text = ~pca_hover_text, size = label_font_size ) @@ -702,6 +771,13 @@ calc_pca <- function( tedf_filt <- tedf[, colSums(is.na(tedf)) != nrow(tedf)] # remove samples with zero variance tedf_var <- tedf_filt[, apply(tedf_filt, 2, var) != 0] + if (ncol(tedf_var) == 0) { + stop( + "No features with non-zero variance remain after filtering. ", + "PCA cannot be computed on an empty or constant matrix. ", + "Check that filter thresholds are appropriate for the number of samples." + ) + } # calculate PCA pca_fit <- stats::prcomp(tedf_var, scale = TRUE) pca_df <- pca_fit |> diff --git a/code/MOSuite/R/plot_read_depth.R b/code/MOSuite/R/plot_read_depth.R index f78d073..afe2018 100644 --- a/code/MOSuite/R/plot_read_depth.R +++ b/code/MOSuite/R/plot_read_depth.R @@ -56,6 +56,12 @@ plot_read_depth <- S7::new_generic( #' @param count_type the type of counts to use. Must be a name in the counts slot (`names(moo@counts)`). #' @param sub_count_type used if `count_type` is a list in the counts slot: specify the sub count type within the list. #' Must be a name in `names(moo@counts[[count_type]])`. +#' @param sample_id_colname column in sample metadata containing sample IDs. +#' @param group_colname sample metadata column used to color bars. Leave blank to use the current single-color bar fill. +#' @param color_values colors used when `group_colname` is supplied. Named vectors are matched to group values; +#' unnamed vectors follow group order and are extended with MOSuite colors when too few colors are supplied. +#' Defaults to `NULL`; when `NULL`, `mosuite_palette` is used for `data.frame` dispatch and stored colors +#' are used for `multiOmicDataSet` dispatch. #' #' @return ggplot barplot #' @@ -78,10 +84,25 @@ S7::method(plot_read_depth, multiOmicDataSet) <- function( moo_counts, count_type, sub_count_type = NULL, + sample_id_colname = NULL, + group_colname = "", + color_values = NULL, ... ) { counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) - return(plot_read_depth(counts_dat, ...)) + color_by_group <- !is.null(group_colname) && trimws(group_colname) != "" + if (!isTRUE(color_by_group)) { + return(plot_read_depth(counts_dat, ...)) + } + color_values <- color_values %||% moo_counts@analyses$colors[[group_colname]] + return(plot_read_depth( + counts_dat, + sample_metadata = moo_counts@sample_meta, + sample_id_colname = sample_id_colname, + group_colname = group_colname, + color_values = color_values, + ... + )) } #' Plot read depth for `data.frame` @@ -90,6 +111,12 @@ S7::method(plot_read_depth, multiOmicDataSet) <- function( #' @aliases plot_read_depth.data.frame #' @usage NULL #' +#' @param sample_metadata sample metadata dataframe, required when `group_colname` is supplied. +#' @param sample_id_colname column in sample metadata containing sample IDs. +#' @param group_colname sample metadata column used to color bars. Leave blank to use the current single-color bar fill. +#' @param color_values colors used when `group_colname` is supplied. Named vectors are matched to group values; +#' unnamed vectors follow group order and are extended with MOSuite colors when too few colors are supplied. +#' Defaults to `NULL`; when `NULL`, `mosuite_palette` is used. #' @param ... additional arguments (ignored; accepted for compatibility with the moo dispatch) #' #' @return ggplot barplot @@ -100,8 +127,16 @@ S7::method(plot_read_depth, multiOmicDataSet) <- function( #' #' @seealso [plot_read_depth()] generic #' @family plotters for counts dataframes -S7::method(plot_read_depth, S7::class_data.frame) <- function(moo_counts, ...) { +S7::method(plot_read_depth, S7::class_data.frame) <- function( + moo_counts, + sample_metadata = NULL, + sample_id_colname = NULL, + group_colname = "", + color_values = NULL, + ... +) { sample_names <- column_sums <- NULL + color_values <- color_values %||% mosuite_palette counts_dat <- moo_counts sum_df <- counts_dat |> dplyr::summarize(dplyr::across(tidyselect::where(is.numeric), sum)) |> @@ -111,12 +146,48 @@ S7::method(plot_read_depth, S7::class_data.frame) <- function(moo_counts, ...) { values_to = "column_sums" ) + color_by_group <- !is.null(group_colname) && trimws(group_colname) != "" + if (color_by_group) { + if (is.null(sample_metadata)) { + stop("sample_metadata is required when group_colname is supplied") + } + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } + sum_df <- sum_df |> + dplyr::left_join( + sample_metadata, + by = stats::setNames(sample_id_colname, "sample_names") + ) |> + dplyr::filter(!is.na(!!rlang::sym(group_colname))) + color_values <- resolve_plot_colors(sum_df, group_colname, color_values) + sum_df <- sum_df |> + dplyr::mutate( + !!rlang::sym(group_colname) := as.character( + !!rlang::sym(group_colname) + ) + ) + } + # Plotting read_plot <- ggplot2::ggplot( sum_df, ggplot2::aes(x = sample_names, y = column_sums) - ) + - ggplot2::geom_bar(stat = "identity", fill = "blue") + + ) + + if (color_by_group) { + read_plot <- read_plot + + ggplot2::geom_bar( + ggplot2::aes(fill = !!rlang::sym(group_colname)), + stat = "identity" + ) + + ggplot2::scale_fill_manual(values = color_values) + } else { + read_plot <- read_plot + + ggplot2::geom_bar(stat = "identity", fill = "blue") + } + + read_plot <- read_plot + ggplot2::labs( title = "Total Reads per Sample", x = "Samples", diff --git a/code/MOSuite/R/plot_volcano_enhanced.R b/code/MOSuite/R/plot_volcano_enhanced.R index 30e2fe8..140c18c 100644 --- a/code/MOSuite/R/plot_volcano_enhanced.R +++ b/code/MOSuite/R/plot_volcano_enhanced.R @@ -13,29 +13,43 @@ plot_volcano_enhanced <- S7::new_generic( function( moo_diff, feature_id_colname = NULL, - signif_colname = c("B-A_adjpval", "B-C_adjpval"), + change_colname = NULL, + signif_colname = NULL, signif_threshold = 0.05, - change_colname = c("B-A_logFC", "B-C_logFC"), change_threshold = 1.0, value_to_sort_the_output_dataset = "p-value", num_features_to_label = 30, - use_only_addition_labels = FALSE, - additional_labels = "", - is_red = TRUE, - lab_size = 4, + label_features = FALSE, + custom_gene_list = "", + label_significant_features_only = TRUE, + label_font_size = 7, + draw_connectors = FALSE, change_sig_name = "p-value", change_lfc_name = "log2FC", title = "Volcano Plots", + title_font_size = 24, use_custom_lab = FALSE, - ylim = 0, - custom_xlim = "", - xlim_additional = 0, - ylim_additional = 0, + use_default_x_axis_limit = TRUE, + x_axis_limit = 5, + use_default_y_axis_limit = TRUE, + y_axis_limit = 10, axis_lab_size = 24, + axis_tick_lab_size = 16, point_size = 2, + default_label_color = "black", + custom_label_color = "black", + color_of_signif_threshold_line = "black", + color_of_non_significant_features = "grey30", + color_of_logfold_change_threshold_line = "forestgreen", + color_of_features_meeting_only_signif_threshold = "royalblue", + color_for_features_meeting_pvalue_and_foldchange_thresholds = "red2", + graphics_device = grDevices::png, image_width = 3000, image_height = 3000, dpi = 300, + use_default_grid_layout = TRUE, + number_of_rows_in_grid_layout = NULL, + scale_image_to_grid = FALSE, interactive_plots = FALSE, print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), @@ -50,29 +64,43 @@ plot_volcano_enhanced <- S7::new_generic( S7::method(plot_volcano_enhanced, multiOmicDataSet) <- function( moo_diff, feature_id_colname = NULL, - signif_colname = c("B-A_adjpval", "B-C_adjpval"), + change_colname = NULL, + signif_colname = NULL, signif_threshold = 0.05, - change_colname = c("B-A_logFC", "B-C_logFC"), change_threshold = 1.0, value_to_sort_the_output_dataset = "p-value", num_features_to_label = 30, - use_only_addition_labels = FALSE, - additional_labels = "", - is_red = TRUE, - lab_size = 4, + label_features = FALSE, + custom_gene_list = "", + label_significant_features_only = TRUE, + label_font_size = 7, + draw_connectors = FALSE, change_sig_name = "p-value", change_lfc_name = "log2FC", title = "Volcano Plots", + title_font_size = 24, use_custom_lab = FALSE, - ylim = 0, - custom_xlim = "", - xlim_additional = 0, - ylim_additional = 0, + use_default_x_axis_limit = TRUE, + x_axis_limit = 5, + use_default_y_axis_limit = TRUE, + y_axis_limit = 10, axis_lab_size = 24, + axis_tick_lab_size = 16, point_size = 2, + default_label_color = "black", + custom_label_color = "black", + color_of_signif_threshold_line = "black", + color_of_non_significant_features = "grey30", + color_of_logfold_change_threshold_line = "forestgreen", + color_of_features_meeting_only_signif_threshold = "royalblue", + color_for_features_meeting_pvalue_and_foldchange_thresholds = "red2", + graphics_device = grDevices::png, image_width = 3000, image_height = 3000, dpi = 300, + use_default_grid_layout = TRUE, + number_of_rows_in_grid_layout = NULL, + scale_image_to_grid = FALSE, interactive_plots = FALSE, print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), @@ -83,34 +111,48 @@ S7::method(plot_volcano_enhanced, multiOmicDataSet) <- function( join_dfs_wide(moo_diff@analyses$diff) |> plot_volcano_enhanced( feature_id_colname, + change_colname, signif_colname, signif_threshold, - change_colname, change_threshold, value_to_sort_the_output_dataset, num_features_to_label, - use_only_addition_labels, - additional_labels, - is_red, - lab_size, - change_sig_name, - change_lfc_name, - title, - use_custom_lab, - ylim, - custom_xlim, - xlim_additional, - ylim_additional, - axis_lab_size, - point_size, - image_width, - image_height, - dpi, - interactive_plots, - print_plots, - save_plots, - plots_subdir, - plot_filename + label_features = label_features, + custom_gene_list = custom_gene_list, + label_significant_features_only = label_significant_features_only, + label_font_size = label_font_size, + draw_connectors = draw_connectors, + change_sig_name = change_sig_name, + change_lfc_name = change_lfc_name, + title = title, + title_font_size = title_font_size, + use_custom_lab = use_custom_lab, + use_default_x_axis_limit = use_default_x_axis_limit, + x_axis_limit = x_axis_limit, + use_default_y_axis_limit = use_default_y_axis_limit, + y_axis_limit = y_axis_limit, + axis_lab_size = axis_lab_size, + axis_tick_lab_size = axis_tick_lab_size, + point_size = point_size, + default_label_color = default_label_color, + custom_label_color = custom_label_color, + color_of_signif_threshold_line = color_of_signif_threshold_line, + color_of_non_significant_features = color_of_non_significant_features, + color_of_logfold_change_threshold_line = color_of_logfold_change_threshold_line, + color_of_features_meeting_only_signif_threshold = color_of_features_meeting_only_signif_threshold, + color_for_features_meeting_pvalue_and_foldchange_thresholds = color_for_features_meeting_pvalue_and_foldchange_thresholds, + graphics_device = graphics_device, + image_width = image_width, + image_height = image_height, + dpi = dpi, + use_default_grid_layout = use_default_grid_layout, + number_of_rows_in_grid_layout = number_of_rows_in_grid_layout, + scale_image_to_grid = scale_image_to_grid, + interactive_plots = interactive_plots, + print_plots = print_plots, + save_plots = save_plots, + plots_subdir = plots_subdir, + plot_filename = plot_filename ) ) } @@ -119,34 +161,58 @@ S7::method(plot_volcano_enhanced, multiOmicDataSet) <- function( #' @inheritParams filter_counts #' #' @param moo_diff Differential expression analysis result from one or more contrasts. This must be a dataframe. -#' @param signif_colname column name of significance values (e.g., adjusted p-values or FDR). This column will be used -#' to determine which points are considered significant in the volcano plot. -#' @param signif_threshold Numeric value specifying the significance cutoff for p-values (i.e. filters on -#' `signif_colname`) -#' @param change_colname column name of fold change values. +#' @param change_colname Character vector of logFC column names, one per +#' contrast (e.g. `c("B-A_logFC", "C-A_logFC")`). Defaults to `NULL`, which +#' auto-detects all columns ending in `_logFC`. +#' @param signif_colname Character vector of significance column names, one per +#' contrast (e.g. `c("B-A_adjpval", "C-A_adjpval")`). Defaults to `NULL`, +#' which auto-detects corresponding columns by checking for `_adjpval` first, +#' then `_pval`, for each contrast in `change_colname`. +#' @param signif_threshold Numeric significance threshold (p-value or adjusted p-value cutoff). Default: 0.05 #' @param change_threshold Numeric value specifying the fold change cutoff for significance (i.e. filters on #' `change_colname`) -#' @param value_to_sort_the_output_dataset How to sort the output dataset. Options are "fold-change" or "p-value". +#' @param value_to_sort_the_output_dataset How to sort the output dataset. Options are "fold-change", "p-value", or +#' "t-statistic". #' @param num_features_to_label Number of top features/genes to label in the volcano plot. Default is 30. -#' @param use_only_addition_labels If `TRUE`, only the additional labels specified in `additional_labels` will be used -#' for labeling in the volcano plot, ignoring the top features. -#' @param additional_labels comma-separated string of feature names or IDs to include in the volcano plot. -#' @param is_red Logical. If TRUE, highlights points in red. -#' @param lab_size Size of the labels in the volcano plot. +#' @param label_features If `TRUE`, only the features specified in `custom_gene_list` will be used for labeling in the +#' volcano plot, ignoring the top features. +#' @param custom_gene_list comma-separated string of feature names or IDs to include in the volcano plot. +#' @param label_significant_features_only If `TRUE`, automatic labels are selected only from features that pass both +#' the significance and fold-change thresholds. +#' @param label_font_size Size of the labels in the volcano plot. +#' @param draw_connectors If `TRUE`, draw connector lines from labels to their points and spread labels to reduce +#' overlap. #' @param change_sig_name Name for the significance column in the plot. Default is "p-value". #' @param change_lfc_name Name for the fold change column in the plot. Default is "log2FC". #' @param title Title of the plot. Default is "Volcano Plots". +#' @param title_font_size Size of the plot title. #' @param use_custom_lab If TRUE, uses custom labels for the plot (set by `change_sig_name` and `change_lfc_name`) -#' @param ylim Y-axis limits for the plot. -#' @param custom_xlim Custom X-axis limits for the plot. -#' @param xlim_additional Additional space to add to the X-axis limits. -#' @param ylim_additional Additional space to add to the Y-axis limits. +#' @param use_default_x_axis_limit Set to TRUE to use the default x-axis limit. +#' @param x_axis_limit Custom x-axis limit. A single value is treated symmetrically, and a two-value vector is treated +#' as lower and upper limits. +#' @param use_default_y_axis_limit Set to TRUE to use the default y-axis limit. +#' @param y_axis_limit Custom y-axis limit. #' @param axis_lab_size Size of the axis labels. +#' @param axis_tick_lab_size Size of the axis tick labels. #' @param point_size Size of the points in the plot. +#' @param default_label_color Set the color for the text used to add feature labels to points. +#' @param custom_label_color Set the color for labels from `custom_gene_list`. +#' @param color_of_signif_threshold_line Color of the significance threshold line. +#' @param color_of_non_significant_features Color of the non-significant features. +#' @param color_of_logfold_change_threshold_line Color of the features that meet only the log fold change threshold. +#' @param color_of_features_meeting_only_signif_threshold Color of the features that meet only the significance +#' threshold. +#' @param color_for_features_meeting_pvalue_and_foldchange_thresholds Color of the features that meet both the p-value +#' and fold change thresholds. +#' @param graphics_device passed to `ggsave(device)`. Default: `grDevices::png` #' @param image_width output image width in pixels - only used if save_plots is TRUE #' @param image_height output image height in pixels - only used if save_plots is TRUE #' @param dpi dots-per-inch of the output image (see `ggsave()`) - only used if save_plots is TRUE -#' @param plot_filename plot output filename - only used if save_plots is TRUE +#' @param use_default_grid_layout Retained for compatibility. Grid layout is handled by `plot_volcano_summary()`. +#' @param number_of_rows_in_grid_layout Retained for compatibility. Grid layout is handled by `plot_volcano_summary()`. +#' @param plot_filename plot output filename - only used if save_plots is TRUE. When multiple comparisons are saved +#' separately, the comparison name is appended before the file extension. +#' @param scale_image_to_grid Retained for compatibility. Grid layout is handled by `plot_volcano_summary()`. #' #' @keywords plotters volcano #' @@ -157,29 +223,43 @@ S7::method(plot_volcano_enhanced, multiOmicDataSet) <- function( S7::method(plot_volcano_enhanced, S7::class_data.frame) <- function( moo_diff, feature_id_colname = NULL, - signif_colname = c("B-A_adjpval", "B-C_adjpval"), + change_colname = NULL, + signif_colname = NULL, signif_threshold = 0.05, - change_colname = c("B-A_logFC", "B-C_logFC"), change_threshold = 1.0, value_to_sort_the_output_dataset = "p-value", num_features_to_label = 30, - use_only_addition_labels = FALSE, - additional_labels = "", - is_red = TRUE, - lab_size = 4, + label_features = FALSE, + custom_gene_list = "", + label_significant_features_only = TRUE, + label_font_size = 7, + draw_connectors = FALSE, change_sig_name = "p-value", change_lfc_name = "log2FC", title = "Volcano Plots", + title_font_size = 24, use_custom_lab = FALSE, - ylim = 0, - custom_xlim = "", - xlim_additional = 0, - ylim_additional = 0, + use_default_x_axis_limit = TRUE, + x_axis_limit = 5, + use_default_y_axis_limit = TRUE, + y_axis_limit = 10, axis_lab_size = 24, + axis_tick_lab_size = 16, point_size = 2, + default_label_color = "black", + custom_label_color = "black", + color_of_signif_threshold_line = "black", + color_of_non_significant_features = "grey30", + color_of_logfold_change_threshold_line = "forestgreen", + color_of_features_meeting_only_signif_threshold = "royalblue", + color_for_features_meeting_pvalue_and_foldchange_thresholds = "red2", + graphics_device = grDevices::png, image_width = 3000, image_height = 3000, dpi = 300, + use_default_grid_layout = TRUE, + number_of_rows_in_grid_layout = NULL, + scale_image_to_grid = FALSE, interactive_plots = FALSE, print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), @@ -199,6 +279,11 @@ S7::method(plot_volcano_enhanced, S7::class_data.frame) <- function( } label_col <- feature_id_colname + # Resolve/auto-detect change_colname and signif_colname + resolved <- resolve_volcano_colnames(diff_dat, change_colname, signif_colname) + change_colname <- resolved$change_colname + signif_colname <- resolved$signif_colname + rank <- list() plots_list <- list() @@ -220,13 +305,17 @@ S7::method(plot_volcano_enhanced, S7::class_data.frame) <- function( # mutate(.data[[lfc.col[i]]] = replace_na(.data[[lfc.col[i]]], 0)) |> # mutate(.data[[sig.col[i]]] = replace_na(.data[[sig.col[i]]], 1)) if (use_custom_lab == TRUE) { - if (nchar(change_lfc_name) == 0) { - lfc_name <- change_colname[i] + lfc_name <- if (nchar(change_lfc_name) == 0) { + change_colname[i] + } else { + change_lfc_name } - if (nchar(change_sig_name) == 0) { - sig_name <- signif_colname[i] + sig_name <- if (nchar(change_sig_name) == 0) { + signif_colname[i] + } else { + change_sig_name } - colnames(df) <- c(label_col, change_lfc_name, sig_name) + colnames(df) <- c(label_col, lfc_name, sig_name) } else { lfc_name <- change_colname[i] sig_name <- signif_colname[i] @@ -243,31 +332,42 @@ S7::method(plot_volcano_enhanced, S7::class_data.frame) <- function( message(paste0("Genes in initial dataset: ", nrow(df), "\n")) # Select top genes by logFC or Significance + contrast_label <- gsub("_logFC$", "", change_colname[i]) + tstat_colname <- paste0(contrast_label, "_tstat") if (value_to_sort_the_output_dataset == "fold-change") { df <- df |> dplyr::arrange(dplyr::desc(.data[[lfc_name]])) } else if (value_to_sort_the_output_dataset == "p-value") { df <- df |> dplyr::arrange(.data[[sig_name]]) + } else if (value_to_sort_the_output_dataset == "t-statistic") { + if (tstat_colname %in% colnames(diff_dat)) { + df <- df |> + dplyr::mutate(.mosuite_sort_tstat = diff_dat[[tstat_colname]]) |> + dplyr::arrange(dplyr::desc(abs(.data$.mosuite_sort_tstat))) |> + # Previous tidyselect form: dplyr::select(-.data$.mosuite_sort_tstat) + dplyr::select(-tidyselect::all_of(".mosuite_sort_tstat")) + } else { + warning(glue::glue( + "Could not find t-statistic column '{tstat_colname}'. Labels were not sorted by t-statistic." + )) + } } - if (is_red) { + if (label_significant_features_only) { df_sub <- df[ - df[[sigcol]] <= signif_threshold & - abs(df[[lfccol]]) >= change_threshold, + df[[sig_name]] <= signif_threshold & + abs(df[[lfc_name]]) >= change_threshold, ] } else { df_sub <- df } genes_to_label <- as.character(df_sub[1:num_features_to_label, label_col]) - # additional_labels <- unlist(str_split(additional_labels,",")) - ## Modifying Additional Labels List: - ## Replace commas with spaces and split the string - split_values <- unlist(strsplit(gsub(",", " ", additional_labels), " ")) - additional_labels <- split_values[split_values != ""] + split_values <- unlist(strsplit(gsub(",", " ", custom_gene_list), " ")) + custom_labels <- split_values[split_values != ""] - filter <- additional_labels %in% df[, label_col] - missing_labels <- additional_labels[!filter] - additional_labels <- additional_labels[filter] + filter <- custom_labels %in% df[, label_col] + missing_labels <- custom_labels[!filter] + custom_labels <- custom_labels[filter] if (length(missing_labels) > 0) { message(glue::glue( @@ -275,10 +375,17 @@ S7::method(plot_volcano_enhanced, S7::class_data.frame) <- function( )) } - if (use_only_addition_labels) { - genes_to_label <- additional_labels + if (label_features) { + genes_to_label <- custom_labels } else { - genes_to_label <- unique(append(genes_to_label, additional_labels)) + genes_to_label <- unique(append(genes_to_label, custom_labels)) + } + + labels_in_plot_order <- df[[label_col]][df[[label_col]] %in% genes_to_label] + label_colors <- rep(default_label_color, length(labels_in_plot_order)) + label_colors[labels_in_plot_order %in% custom_labels] <- custom_label_color + if (length(label_colors) == 0) { + label_colors <- default_label_color } significant <- vector(length = nrow(df)) @@ -300,8 +407,8 @@ S7::method(plot_volcano_enhanced, S7::class_data.frame) <- function( # fix pvalue == 0 shapeCustom <- rep(19, nrow(df)) maxy <- max(-log10(df[[sig_name]]), na.rm = TRUE) - if (ylim > 0) { - maxy <- ylim + if (!isTRUE(use_default_y_axis_limit)) { + maxy <- y_axis_limit } message(paste0("Max y: ", maxy, "\n")) @@ -331,24 +438,21 @@ S7::method(plot_volcano_enhanced, S7::class_data.frame) <- function( maxy <- ceiling(maxy) ## X-axis custom range change: - if (custom_xlim == "") { + if (isTRUE(use_default_x_axis_limit)) { xlim <- c( - floor(min(df[, lfc_name])) - xlim_additional, - ceiling(max(df[, lfc_name])) + xlim_additional + floor(min(df[, lfc_name])), + ceiling(max(df[, lfc_name])) ) - } else if (grepl(",", custom_xlim) == FALSE) { + } else if (is.character(x_axis_limit) && grepl(",", x_axis_limit)) { + split_values <- strsplit(x_axis_limit, ",")[[1]] + xlim <- as.numeric(trimws(split_values[1:2])) + } else if (length(x_axis_limit) == 1) { xlim <- c( - -1 * as.numeric(trimws(custom_xlim)), - as.numeric(trimws(custom_xlim)) + -1 * as.numeric(x_axis_limit), + as.numeric(x_axis_limit) ) } else { - split_values <- strsplit(custom_xlim, ",")[[1]] - - # Trim whitespace and convert to numeric values - x_min <- as.numeric(trimws(split_values[1])) - x_max <- as.numeric(trimws(split_values[2])) - - xlim <- c(x_min, x_max) + xlim <- as.numeric(x_axis_limit[1:2]) } ### Create axis labels @@ -361,9 +465,19 @@ S7::method(plot_volcano_enhanced, S7::class_data.frame) <- function( } if (grepl("adj", signif_colname[i])) { ylab <- bquote(~ -Log[10] ~ "FDR") + signif_legend_label <- "FDR" + signif_and_fc_legend_label <- "FDR and log2 FC" } else { ylab <- bquote(~ -Log[10] ~ "p-value") + signif_legend_label <- "p-value" + signif_and_fc_legend_label <- "p-value and log2 FC" } + legend_labels <- c( + "NS", + expression(Log[2] ~ FC), + signif_legend_label, + signif_and_fc_legend_label + ) if (use_custom_lab) { if (lfc_name != change_colname[i]) { xlab <- gsub("_", " ", lfc_name) @@ -373,26 +487,50 @@ S7::method(plot_volcano_enhanced, S7::class_data.frame) <- function( } } + title_is_default <- identical(title, "Volcano Plots") + title_is_per_plot <- length(title) == length(change_colname) + plot_title <- if (title_is_default) { + contrast_label + } else if (title_is_per_plot) { + title[i] + } else { + title + } + plot_subtitle <- if (title_is_default || title_is_per_plot) NULL else group + volcano_plot <- EnhancedVolcano::EnhancedVolcano( df, x = lfc_name, y = sig_name, lab = df[, label_col], selectLab = genes_to_label, - title = title, - # CHANGE NW: See line 78 - subtitle = group, + title = plot_title, + subtitle = plot_subtitle, xlab = xlab, ylab = ylab, xlim = xlim, - ylim = c(0, maxy + ylim_additional), + ylim = c(0, maxy), pCutoff = signif_threshold, FCcutoff = change_threshold, axisLabSize = axis_lab_size, - labSize = lab_size, + titleLabSize = title_font_size, + legendLabels = legend_labels, + labSize = label_font_size, + drawConnectors = draw_connectors, + labCol = label_colors, pointSize = point_size, + col = c( + color_of_non_significant_features, + color_of_logfold_change_threshold_line, + color_of_features_meeting_only_signif_threshold, + color_for_features_meeting_pvalue_and_foldchange_thresholds + ), + cutoffLineCol = color_of_signif_threshold_line, shapeCustom = shapeCustom - ) + ) + + ggplot2::theme( + axis.text = ggplot2::element_text(size = axis_tick_lab_size) + ) ## Creating plot that can be converted to plotly interactive plot (no labels): ## PH: make this feature an option not default @@ -404,20 +542,33 @@ S7::method(plot_volcano_enhanced, S7::class_data.frame) <- function( lab = rep("", nrow(df)), # Setting labels to empty strings selectLab = NULL, - title = title, - # CHANGE NW: See line 78 - subtitle = group, + title = plot_title, + subtitle = plot_subtitle, xlab = xlab, ylab = ylab, xlim = xlim, - ylim = c(0, maxy + ylim_additional), + ylim = c(0, maxy), pCutoff = signif_threshold, FCcutoff = change_threshold, axisLabSize = axis_lab_size, - labSize = lab_size, + titleLabSize = title_font_size, + legendLabels = legend_labels, + labSize = label_font_size, + drawConnectors = draw_connectors, + labCol = default_label_color, pointSize = point_size, + col = c( + color_of_non_significant_features, + color_of_logfold_change_threshold_line, + color_of_features_meeting_only_signif_threshold, + color_for_features_meeting_pvalue_and_foldchange_thresholds + ), + cutoffLineCol = color_of_signif_threshold_line, shapeCustom = shapeCustom - ) + ) + + ggplot2::theme( + axis.text = ggplot2::element_text(size = axis_tick_lab_size) + ) # Extract the data used for plotting plot_data <- ggplot2::ggplot_build(p_empty)$data[[1]] @@ -452,18 +603,62 @@ S7::method(plot_volcano_enhanced, S7::class_data.frame) <- function( } plots_list[[i]] <- volcano_plot } - plot_patchwork <- patchwork::wrap_plots(plots_list) - print_or_save_plot( - plot_patchwork, - filename = file.path(plots_subdir, plot_filename), - print_plots = print_plots, - save_plots = save_plots, - units = "px", - width = image_width, - height = image_height, - dpi = dpi - ) + suffix_plot_filename <- function(filename, suffix) { + filename_dir <- dirname(filename) + filename_base <- basename(filename) + extension <- tools::file_ext(filename_base) + filename_stem <- if (nzchar(extension)) { + sub(paste0("\\.", extension, "$"), "", filename_base) + } else { + filename_base + } + safe_suffix <- gsub("[^[:alnum:]_.-]+", "_", suffix) + safe_suffix <- gsub("^_+|_+$", "", safe_suffix) + if (!nzchar(safe_suffix)) { + safe_suffix <- "plot" + } + + suffixed_filename <- paste0( + filename_stem, + "_", + safe_suffix, + if (nzchar(extension)) paste0(".", extension) else "" + ) + if (filename_dir %in% c(".", "")) { + suffixed_filename + } else { + file.path(filename_dir, suffixed_filename) + } + } + + nplots <- length(plots_list) + plot_output_filenames <- rep(plot_filename, nplots) + if (nplots > 1) { + comparison_labels <- gsub("_logFC$", "", change_colname[seq_len(nplots)]) + plot_output_filenames <- vapply( + comparison_labels, + function(comparison_label) { + suffix_plot_filename(plot_filename, comparison_label) + }, + character(1) + ) + } + + for (i in seq_along(plots_list)) { + print_or_save_plot( + plots_list[[i]], + filename = file.path(plots_subdir, plot_output_filenames[[i]]), + print_plots = print_plots, + save_plots = save_plots, + units = "px", + width = image_width, + height = image_height, + dpi = dpi, + device = graphics_device + ) + } df_final <- cbind(diff_dat, do.call(cbind, rank)) + attr(df_final, "plots") <- plots_list return(df_final) } diff --git a/code/MOSuite/R/plot_volcano_summary.R b/code/MOSuite/R/plot_volcano_summary.R index 92a50f3..8ab1da1 100644 --- a/code/MOSuite/R/plot_volcano_summary.R +++ b/code/MOSuite/R/plot_volcano_summary.R @@ -15,7 +15,8 @@ plot_volcano_summary <- S7::new_generic( function( moo_diff, feature_id_colname = NULL, - signif_colname = "pval", + change_colname = NULL, + signif_colname = NULL, signif_threshold = 0.05, change_threshold = 1, value_to_sort_the_output_dataset = "t-statistic", @@ -23,28 +24,29 @@ plot_volcano_summary <- S7::new_generic( add_features = FALSE, label_features = FALSE, custom_gene_list = "", + label_significant_features_only = TRUE, default_label_color = "black", - custom_label_color = "green3", - label_x_adj = 0.2, - label_y_adj = 0.2, - line_thickness = 0.5, - label_font_size = 4, - label_font_type = 1, - displace_feature_labels = FALSE, - custom_gene_list_special_label_displacement = "", - special_label_displacement_x_axis = 2, - special_label_displacement_y_axis = 2, - color_of_signif_threshold_line = "blue", - color_of_non_significant_features = "black", - color_of_logfold_change_threshold_line = "red", - color_of_features_meeting_only_signif_threshold = "lightgoldenrod2", - color_for_features_meeting_pvalue_and_foldchange_thresholds = "red", + custom_label_color = "black", + label_font_size = 7, + draw_connectors = FALSE, + change_sig_name = "p-value", + change_lfc_name = "log2FC", + title = "Volcano Plots", + title_font_size = 24, + use_custom_lab = FALSE, + color_of_signif_threshold_line = "black", + color_of_non_significant_features = "grey30", + color_of_logfold_change_threshold_line = "forestgreen", + color_of_features_meeting_only_signif_threshold = "royalblue", + color_for_features_meeting_pvalue_and_foldchange_thresholds = "red2", flip_vplot = FALSE, use_default_x_axis_limit = TRUE, x_axis_limit = 5, use_default_y_axis_limit = TRUE, y_axis_limit = 10, point_size = 2, + axis_lab_size = 24, + axis_tick_lab_size = 16, add_deg_columns = c("FC", "logFC", "tstat", "pval", "adjpval"), graphics_device = grDevices::png, image_width = 15, @@ -52,7 +54,6 @@ plot_volcano_summary <- S7::new_generic( dpi = 300, use_default_grid_layout = TRUE, number_of_rows_in_grid_layout = 1, - aspect_ratio = 0, plot_filename = "volcano_summary.png", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), @@ -66,7 +67,8 @@ plot_volcano_summary <- S7::new_generic( S7::method(plot_volcano_summary, multiOmicDataSet) <- function( moo_diff, feature_id_colname = NULL, - signif_colname = "pval", + change_colname = NULL, + signif_colname = NULL, signif_threshold = 0.05, change_threshold = 1, value_to_sort_the_output_dataset = "t-statistic", @@ -74,28 +76,29 @@ S7::method(plot_volcano_summary, multiOmicDataSet) <- function( add_features = FALSE, label_features = FALSE, custom_gene_list = "", + label_significant_features_only = TRUE, default_label_color = "black", - custom_label_color = "green3", - label_x_adj = 0.2, - label_y_adj = 0.2, - line_thickness = 0.5, - label_font_size = 4, - label_font_type = 1, - displace_feature_labels = FALSE, - custom_gene_list_special_label_displacement = "", - special_label_displacement_x_axis = 2, - special_label_displacement_y_axis = 2, - color_of_signif_threshold_line = "blue", - color_of_non_significant_features = "black", - color_of_logfold_change_threshold_line = "red", - color_of_features_meeting_only_signif_threshold = "lightgoldenrod2", - color_for_features_meeting_pvalue_and_foldchange_thresholds = "red", + custom_label_color = "black", + label_font_size = 7, + draw_connectors = FALSE, + change_sig_name = "p-value", + change_lfc_name = "log2FC", + title = "Volcano Plots", + title_font_size = 24, + use_custom_lab = FALSE, + color_of_signif_threshold_line = "black", + color_of_non_significant_features = "grey30", + color_of_logfold_change_threshold_line = "forestgreen", + color_of_features_meeting_only_signif_threshold = "royalblue", + color_for_features_meeting_pvalue_and_foldchange_thresholds = "red2", flip_vplot = FALSE, use_default_x_axis_limit = TRUE, x_axis_limit = 5, use_default_y_axis_limit = TRUE, y_axis_limit = 10, point_size = 2, + axis_lab_size = 24, + axis_tick_lab_size = 16, add_deg_columns = c("FC", "logFC", "tstat", "pval", "adjpval"), graphics_device = grDevices::png, image_width = 15, @@ -103,7 +106,6 @@ S7::method(plot_volcano_summary, multiOmicDataSet) <- function( dpi = 300, use_default_grid_layout = TRUE, number_of_rows_in_grid_layout = 1, - aspect_ratio = 0, plot_filename = "volcano_summary.png", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), @@ -114,6 +116,7 @@ S7::method(plot_volcano_summary, multiOmicDataSet) <- function( join_dfs_wide() |> plot_volcano_summary( feature_id_colname, + change_colname, signif_colname, signif_threshold, change_threshold, @@ -122,17 +125,16 @@ S7::method(plot_volcano_summary, multiOmicDataSet) <- function( add_features, label_features, custom_gene_list, + label_significant_features_only, default_label_color, custom_label_color, - label_x_adj, - label_y_adj, - line_thickness, label_font_size, - label_font_type, - displace_feature_labels, - custom_gene_list_special_label_displacement, - special_label_displacement_x_axis, - special_label_displacement_y_axis, + draw_connectors, + change_sig_name, + change_lfc_name, + title, + title_font_size, + use_custom_lab, color_of_signif_threshold_line, color_of_non_significant_features, color_of_logfold_change_threshold_line, @@ -144,6 +146,8 @@ S7::method(plot_volcano_summary, multiOmicDataSet) <- function( use_default_y_axis_limit, y_axis_limit, point_size, + axis_lab_size, + axis_tick_lab_size, add_deg_columns, graphics_device, image_width, @@ -151,7 +155,6 @@ S7::method(plot_volcano_summary, multiOmicDataSet) <- function( dpi, use_default_grid_layout, number_of_rows_in_grid_layout, - aspect_ratio, plot_filename, print_plots, save_plots, @@ -164,6 +167,14 @@ S7::method(plot_volcano_summary, multiOmicDataSet) <- function( #' @inheritParams plot_volcano_enhanced #' @inheritParams filter_counts #' +#' @param change_colname Character vector of full logFC column names, one per +#' contrast (e.g. `c("B-A_logFC", "C-A_logFC")`). Defaults to `NULL`, which +#' auto-detects all columns ending in `_logFC`. +#' @param signif_colname Character vector of full significance column names, one +#' per contrast (e.g. `c("B-A_adjpval", "C-A_adjpval")`). Defaults to `NULL`, +#' which auto-detects corresponding columns by checking for `_adjpval` first, +#' then `_pval`, for each contrast in `change_colname`. +#' @param signif_threshold Numeric significance threshold (p-value or adjusted p-value cutoff). Default: 0.05 #' @param add_features Add custom_gene_list To Labels. Set TRUE when you want to label a specific set of features #' (features) in the "custom_gene_list" parameter" IN ADDITION to the number of features you set in the "Number of #' Features to Label" parameter. @@ -171,28 +182,27 @@ S7::method(plot_volcano_summary, multiOmicDataSet) <- function( #' "custom_gene_list" parameter. #' @param custom_gene_list Provide a list of features (comma separated) to be labeled on the volcano plot. You must #' toggle one of the following ON to see these labels: "Add features" or "Label Only My Feature List". +#' @param label_significant_features_only If `TRUE`, automatic labels are selected only from features that pass both +#' the significance and fold-change thresholds. #' @param default_label_color Set the color for the text used to add feature (gene) name labels to points. #' @param custom_label_color Set the color for the specific list of features (features) provided in the "Feature List" #' parameter. -#' @param label_x_adj adjust position of the labels on the x-axis. Default: 0.2 -#' @param label_y_adj adjust position of the labels on the y-axis. Default: 0.2 -#' @param line_thickness Set the thickness of the lines in the plot. Default: 0.5 -#' @param label_font_size Set the font size of the labels. Default: 4 -#' @param label_font_type Set the font type of the labels. Default: 1 -#' @param displace_feature_labels Set to TRUE to displace gene labels. Default: FALSE. Set TRUE if you want to displace -#' the feature (gene) label for a specific set of features. Make sure to use custom x- and y- limits and give -#' sufficient space for displacement; otherwise other labels than the desired ones will appear displaced. -#' @param custom_gene_list_special_label_displacement Provide a list of features (comma separated) for which you want -#' special displacement of the feature label. -#' @param special_label_displacement_x_axis Displacement of the feature label on the x-axis. Default: 2 -#' @param special_label_displacement_y_axis Displacement of the feature label on the y-axis. Default: 2 -#' @param color_of_signif_threshold_line Color of the significance threshold line. Default: "blue" -#' @param color_of_non_significant_features Color of the non-significant features. Default: "black" -#' @param color_of_logfold_change_threshold_line Color of the log fold change threshold line. Default: "red" +#' @param label_font_size Set the font size of the labels. Default: 7 +#' @param draw_connectors If `TRUE`, draw connector lines from labels to their points and spread labels to reduce +#' overlap. +#' @param change_sig_name Name for the significance column in the plot. Default is "p-value". +#' @param change_lfc_name Name for the fold change column in the plot. Default is "log2FC". +#' @param title Title of the plot. Default is "Volcano Plots". +#' @param title_font_size Size of the plot title. Default: 24 +#' @param use_custom_lab If TRUE, uses custom labels for the plot axes, set by `change_sig_name` and +#' `change_lfc_name`. +#' @param color_of_signif_threshold_line Color of the significance threshold line. Default: "black" +#' @param color_of_non_significant_features Color of the non-significant features. Default: "grey30" +#' @param color_of_logfold_change_threshold_line Color of the log fold change threshold line. Default: "forestgreen" #' @param color_of_features_meeting_only_signif_threshold Color of the features that meet only the significance -#' threshold. Default: "lightgoldenrod2" +#' threshold. Default: "royalblue" #' @param color_for_features_meeting_pvalue_and_foldchange_thresholds Color of the features that meet both the p-value -#' and fold change thresholds. Default: "red" +#' and fold change thresholds. Default: "red2" #' @param flip_vplot Set to TRUE to flip the fold change values so that the volcano plot looks like a comparison was #' B-A. Default: FALSE #' @param use_default_x_axis_limit Set to TRUE to use the default x-axis limit. Default: TRUE @@ -200,11 +210,12 @@ S7::method(plot_volcano_summary, multiOmicDataSet) <- function( #' @param use_default_y_axis_limit Set to TRUE to use the default y-axis limit. Default: TRUE #' @param y_axis_limit Custom y-axis limit. Default: c(0, 10) #' @param point_size Size of the points in the plot. Default: 1 +#' @param axis_lab_size Size of the axis labels. Default: 24 +#' @param axis_tick_lab_size Size of the axis tick labels. Default: 16 #' @param add_deg_columns Add additional columns from the DEG analysis to the #' output dataset. Default: `"FC", "logFC", "tstat", "pval", "adjpval"` #' @param use_default_grid_layout Set to TRUE to use the default grid layout. Default: TRUE #' @param number_of_rows_in_grid_layout Number of rows in the grid layout. Default: 1 -#' @param aspect_ratio Aspect ratio of the output image. Default: 4/3 #' @param graphics_device passed to `ggsave(device)`. Default: `grDevices::png` #' @param plot_filename Filename for the output plot. Default: "volcano_plot.png" #' @@ -218,7 +229,8 @@ S7::method(plot_volcano_summary, multiOmicDataSet) <- function( S7::method(plot_volcano_summary, S7::class_data.frame) <- function( moo_diff, feature_id_colname = NULL, - signif_colname = "pval", + change_colname = NULL, + signif_colname = NULL, signif_threshold = 0.05, change_threshold = 1, value_to_sort_the_output_dataset = "t-statistic", @@ -226,28 +238,29 @@ S7::method(plot_volcano_summary, S7::class_data.frame) <- function( add_features = FALSE, label_features = FALSE, custom_gene_list = "", + label_significant_features_only = TRUE, default_label_color = "black", - custom_label_color = "green3", - label_x_adj = 0.2, - label_y_adj = 0.2, - line_thickness = 0.5, - label_font_size = 4, - label_font_type = 1, - displace_feature_labels = FALSE, - custom_gene_list_special_label_displacement = "", - special_label_displacement_x_axis = 2, - special_label_displacement_y_axis = 2, - color_of_signif_threshold_line = "blue", - color_of_non_significant_features = "black", - color_of_logfold_change_threshold_line = "red", - color_of_features_meeting_only_signif_threshold = "lightgoldenrod2", - color_for_features_meeting_pvalue_and_foldchange_thresholds = "red", + custom_label_color = "black", + label_font_size = 7, + draw_connectors = FALSE, + change_sig_name = "p-value", + change_lfc_name = "log2FC", + title = "Volcano Plots", + title_font_size = 24, + use_custom_lab = FALSE, + color_of_signif_threshold_line = "black", + color_of_non_significant_features = "grey30", + color_of_logfold_change_threshold_line = "forestgreen", + color_of_features_meeting_only_signif_threshold = "royalblue", + color_for_features_meeting_pvalue_and_foldchange_thresholds = "red2", flip_vplot = FALSE, use_default_x_axis_limit = TRUE, x_axis_limit = 5, use_default_y_axis_limit = TRUE, y_axis_limit = 10, point_size = 2, + axis_lab_size = 24, + axis_tick_lab_size = 16, add_deg_columns = c("FC", "logFC", "tstat", "pval", "adjpval"), graphics_device = grDevices::png, image_width = 15, @@ -255,13 +268,12 @@ S7::method(plot_volcano_summary, S7::class_data.frame) <- function( dpi = 300, use_default_grid_layout = TRUE, number_of_rows_in_grid_layout = 1, - aspect_ratio = 0, plot_filename = "volcano_summary.png", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), plots_subdir = "diff" ) { - abort_packages_not_installed("patchwork", "ggrepel") + abort_packages_not_installed("EnhancedVolcano") diff_dat <- as.data.frame(moo_diff) ## -------------------------------- ## @@ -280,23 +292,30 @@ S7::method(plot_volcano_summary, S7::class_data.frame) <- function( } # Identify all contrasts in DEG output table - volcols <- colnames(diff_dat) - statcols <- volcols[grepl("logFC", volcols)] - contrasts <- unique(gsub("_logFC", "", statcols)) + resolved <- resolve_volcano_colnames(diff_dat, change_colname, signif_colname) + change_colname <- resolved$change_colname + signif_colname <- resolved$signif_colname + contrasts <- unique(sub("_logFC$", "", change_colname)) - Plots <- list() df_outs <- list() + plot_change_colnames <- character(0) + plot_signif_colnames <- character(0) # Create Volcano for each DEG comparison - for (contrast in contrasts) { + for (i in seq_along(contrasts)) { + contrast <- contrasts[i] ### PH: START Build table for Volcano plot message(paste0("Preparing table for contrast: ", contrast)) - lfccol <- paste0(contrast, "_logFC") - pvalcol <- paste0(contrast, "_", signif_colname) + lfccol <- change_colname[i] + pvalcol <- signif_colname[i] tstatcol <- paste0(contrast, "_", "tstat") message(paste0("Fold change column: ", lfccol)) - message(paste0(signif_colname, " column: ", pvalcol)) + message(paste0("Significance column: ", pvalcol)) + message(paste0( + "Total number of features included in volcano plot: ", + nrow(diff_dat) + )) if (value_to_sort_the_output_dataset == "fold-change") { diff_dat <- diff_dat |> @@ -307,47 +326,7 @@ S7::method(plot_volcano_summary, S7::class_data.frame) <- function( diff_dat <- diff_dat |> dplyr::arrange(dplyr::desc(abs(diff_dat[, tstatcol]))) } - - ## optional Parameter: Provide a list of features to label on Volcano plot - ## work with a list of features - if (add_features == TRUE) { - gl <- trimws( - unlist(strsplit( - c( - custom_gene_list - ), - "," - )), - which = c("both") - ) - ind <- match(gl, diff_dat$Gene) # get the indices of the listed features - custom_gene_list_ind <- c(1:num_features_to_label, ind) # when list provided - color_gene_label <- c( - rep(c(default_label_color), num_features_to_label), - rep(c(custom_label_color), length(ind)) - ) - } else if (label_features == TRUE) { - gl <- trimws( - unlist(strsplit( - c( - custom_gene_list - ), - "," - )), - which = c("both") - ) # unpack the gene list provided by the user and remove white spaces - ind <- match(gl, diff_dat$Gene) # get the indices of the listed features - custom_gene_list_ind <- ind # when list provided - color_gene_label <- rep(c(custom_label_color), length(ind)) - } else { - if (num_features_to_label > 0) { - # if no list provided label the number of features given by the user - custom_gene_list_ind <- 1:num_features_to_label - color_gene_label <- rep(c(default_label_color), num_features_to_label) - } else if (num_features_to_label == 0) { - custom_gene_list_ind <- 0 - } - } + feature_ids <- diff_dat[[feature_id_colname]] ## optional Parameter: IF DEG was set up A-B User can Flip FC values so that Volcano plot looks like comparison was ## B-A @@ -377,8 +356,10 @@ S7::method(plot_volcano_summary, S7::class_data.frame) <- function( } else { new_contrast_label <- old_contrast } + plot_change_colnames <- c(plot_change_colnames, new_contrast_label) + plot_signif_colnames <- c(plot_signif_colnames, pvalcol) - filtered_features <- diff_dat$Gene[ + filtered_features <- feature_ids[ diff_dat[, pvalcol] < signif_threshold & abs(diff_dat[, new_contrast_label]) > change_threshold ] @@ -408,130 +389,102 @@ S7::method(plot_volcano_summary, S7::class_data.frame) <- function( df_out1 <- new_df df_outs[[contrast]] <- df_out1 - ### PH: END Build table for Volcano plot + } - ### PH: START Make plot - Can we use Enhanced volcano function from other template to make figure instead of ggplot - ### shown here + # Only pass custom labels when the summary label toggles request them. + plot_additional_labels <- "" + if (isTRUE(add_features) || isTRUE(label_features)) { + plot_additional_labels <- custom_gene_list + } + plot_titles <- gsub("_logFC$", "", plot_change_colnames) + plot_titles <- if (identical(title, "Volcano Plots")) plot_titles else title - message(paste0( - "Total number of features included in volcano plot: ", - nrow(diff_dat) - )) - ## special nudge/repel of specific features - if (displace_feature_labels) { - gn <- trimws( - unlist(strsplit( - c(custom_gene_list_special_label_displacement), - "," - )), - which = c("both") - ) - ind_gn <- match(gn, diff_dat$Gene[custom_gene_list_ind]) # get the indices of the listed features - nudge_x_all <- rep(c(0.2), length(diff_dat$Gene[custom_gene_list_ind])) - nudge_y_all <- rep(c(0.2), length(diff_dat$Gene[custom_gene_list_ind])) - nudge_x_all[ind_gn] <- c(special_label_displacement_x_axis) - nudge_y_all[ind_gn] <- c(special_label_displacement_y_axis) - } else { - nudge_x_all <- label_x_adj - nudge_y_all <- label_y_adj - } + message("\nRunning Enhanced Volcano:") + volcano_enhanced_result <- plot_volcano_enhanced( + diff_dat, + feature_id_colname = feature_id_colname, + signif_colname = plot_signif_colnames, + signif_threshold = signif_threshold, + change_colname = plot_change_colnames, + change_threshold = change_threshold, + value_to_sort_the_output_dataset = value_to_sort_the_output_dataset, + num_features_to_label = num_features_to_label, + label_features = label_features, + custom_gene_list = plot_additional_labels, + label_significant_features_only = label_significant_features_only, + label_font_size = label_font_size, + draw_connectors = draw_connectors, + change_sig_name = change_sig_name, + change_lfc_name = change_lfc_name, + title = plot_titles, + title_font_size = title_font_size, + use_custom_lab = use_custom_lab, + use_default_x_axis_limit = use_default_x_axis_limit, + x_axis_limit = x_axis_limit, + use_default_y_axis_limit = use_default_y_axis_limit, + y_axis_limit = y_axis_limit, + axis_lab_size = axis_lab_size, + axis_tick_lab_size = axis_tick_lab_size, + point_size = point_size, + default_label_color = default_label_color, + custom_label_color = custom_label_color, + color_of_signif_threshold_line = color_of_signif_threshold_line, + color_of_non_significant_features = color_of_non_significant_features, + color_of_logfold_change_threshold_line = color_of_logfold_change_threshold_line, + color_of_features_meeting_only_signif_threshold = color_of_features_meeting_only_signif_threshold, + color_for_features_meeting_pvalue_and_foldchange_thresholds = color_for_features_meeting_pvalue_and_foldchange_thresholds, + graphics_device = graphics_device, + image_width = image_width * dpi, + image_height = image_height * dpi, + dpi = dpi, + use_default_grid_layout = use_default_grid_layout, + number_of_rows_in_grid_layout = number_of_rows_in_grid_layout, + scale_image_to_grid = FALSE, + print_plots = FALSE, + save_plots = FALSE, + plots_subdir = plots_subdir, + plot_filename = plot_filename + ) - # set plot parameters - if (use_default_y_axis_limit) { - negative_log10_p_values <- -log10(diff_dat[, pvalcol]) - ymax <- ceiling(max(negative_log10_p_values[is.finite( - negative_log10_p_values - )])) - } else { - ymax <- y_axis_limit - } - if (use_default_x_axis_limit) { - xmax1 <- ceiling(max(diff_dat[, lfccol])) - xmax2 <- ceiling(max(-diff_dat[, lfccol])) - xmax <- max(xmax1, xmax2) + plots_list <- attr(volcano_enhanced_result, "plots") + if (length(plots_list) > 0) { + nplots <- length(plots_list) + if (nplots > 1) { + abort_packages_not_installed("patchwork") + if ( + isTRUE(use_default_grid_layout) || + is.null(number_of_rows_in_grid_layout) + ) { + nrows <- ceiling(nplots / ceiling(sqrt(nplots))) + } else { + nrows <- number_of_rows_in_grid_layout + } + if ( + !is.numeric(nrows) || length(nrows) != 1 || is.na(nrows) || nrows < 1 + ) { + nrows <- 1 + } + nrows <- as.integer(nrows) + ncols <- ceiling(nplots / nrows) + plot_obj <- patchwork::wrap_plots(plots_list, nrow = nrows) } else { - xmax <- x_axis_limit + nrows <- 1 + ncols <- 1 + plot_obj <- plots_list[[1]] } - - grm <- diff_dat[, c(new_contrast_label, pvalcol)] - grm[, "neglogpval"] <- -log10(diff_dat[, pvalcol]) - colnames(grm) <- c("FC", "pval", "neglogpval") - # message(grm[custom_gene_list_ind, ]) - p <- ggplot2::ggplot( - grm, - ggplot2::aes( - x = !!rlang::sym("FC"), - y = !!rlang::sym("neglogpval") - ) - ) + # modified by RAS - ggplot2::theme_classic() + - ggplot2::geom_point( - color = color_of_non_significant_features, - size = point_size - ) + - ggplot2::geom_vline( - xintercept = c(-change_threshold, change_threshold), - color = color_of_logfold_change_threshold_line, - alpha = 1.0 - ) + - ggplot2::geom_hline( - yintercept = -log10(signif_threshold), - color = color_of_signif_threshold_line, - alpha = 1.0 - ) + - ggplot2::geom_point( - data = grm[diff_dat[, pvalcol] < signif_threshold, ], - color = color_of_features_meeting_only_signif_threshold, - size = point_size - ) + - ggplot2::geom_point( - data = grm[ - diff_dat[, pvalcol] < signif_threshold & - abs(grm[, "FC"]) > change_threshold, - ], - color = color_for_features_meeting_pvalue_and_foldchange_thresholds, - size = point_size - ) + - ggrepel::geom_text_repel( - data = grm[custom_gene_list_ind, ], - label = diff_dat$Gene[custom_gene_list_ind], - color = color_gene_label, - fontface = label_font_type, - nudge_x = nudge_x_all, - nudge_y = nudge_y_all, - size = label_font_size, - segment.size = line_thickness - ) + - ggplot2::xlim(-xmax, xmax) + - ggplot2::ylim(0, ymax) + - ggplot2::xlab(new_contrast_label) + - ggplot2::ylab(pvalcol) - - if (aspect_ratio > 0) { - p <- p + ggplot2::coord_fixed(ratio = aspect_ratio) - } - - Plots[[contrast]] <- p - ### PH: END Make plot - Can we use Enhanced volcano function from other template to make figure instead of ggplot - ### shown here - } - - ## Print plots - nplots <- length(Plots) - if (use_default_grid_layout) { - nrows <- ceiling(nplots / ceiling(sqrt(nplots))) - } else { - nrows <- number_of_rows_in_grid_layout + print_or_save_plot( + plot_obj, + filename = file.path(plots_subdir, plot_filename), + print_plots = print_plots, + save_plots = save_plots, + units = "px", + width = image_width * dpi * ncols, + height = image_height * dpi * nrows, + dpi = dpi, + device = graphics_device + ) } - plot_patchwork <- patchwork::wrap_plots(Plots, nrow = nrows) - print_or_save_plot( - plot_patchwork, - filename = file.path(plots_subdir, plot_filename), - print_plots = print_plots, - save_plots = save_plots, - graphics_device = graphics_device - ) df_out <- unique(do.call("rbind", df_outs)) diff --git a/code/MOSuite/R/plots.R b/code/MOSuite/R/plots.R index 1d5770e..81e3ee9 100644 --- a/code/MOSuite/R/plots.R +++ b/code/MOSuite/R/plots.R @@ -39,6 +39,7 @@ print_or_save_plot <- function( gp = grid::gpar(fontsize = 9, col = "grey40") ) } + return(invisible(NULL)) } if (!is.null(caption) && inherits(plot_obj, "ggplot")) { plot_obj <- plot_obj + ggplot2::labs(caption = caption) @@ -77,3 +78,184 @@ print_or_save_plot <- function( } return(invisible(filename)) } + +format_hover_text <- function( + plot_data, + primary_colname, + secondary_colname = NULL, + missing_col_context = "plot", + require_secondary = TRUE +) { + required_cols <- primary_colname + if (isTRUE(require_secondary) && !is.null(secondary_colname)) { + required_cols <- c(required_cols, secondary_colname) + } + + missing_cols <- setdiff(required_cols, colnames(plot_data)) + if (length(missing_cols) > 0) { + stop(glue::glue( + "Missing required {missing_col_context} metadata column(s): {glue::glue_collapse(missing_cols, sep = ", + ")}" + )) + } + + primary_text <- paste0( + primary_colname, + ": ", + plot_data[[primary_colname]] + ) + + if ( + is.null(secondary_colname) || !secondary_colname %in% colnames(plot_data) + ) { + return(primary_text) + } + + return(paste0( + primary_text, + "
", + secondary_colname, + ": ", + plot_data[[secondary_colname]] + )) +} + +#' Compute a wrapped colour legend column count +#' +#' Computes a conservative number of legend columns for horizontal ggplot colour +#' legends. Top and bottom legends are wrapped based on the number of labels and +#' the longest label length. Other legend positions return `NULL` so their +#' existing ggplot layout is preserved. +#' +#' @param labels Character vector of legend labels. +#' @param legend_position Legend position passed to `ggplot2::theme()`. +#' @param ncol Optional maximum number of legend columns. +#' @param legend_text_size Legend text size used to scale the horizontal space +#' estimate. Larger legend text uses fewer columns. +#' @param max_label_characters_per_row Approximate total label characters to fit +#' on one horizontal legend row. +#' +#' @return Integer column count for top/bottom legends, or `NULL` when no +#' wrapping should be applied. +#' @keywords internal +#' @noRd +get_legend_column_count <- function( + labels, + legend_position = "top", + ncol = NULL, + legend_text_size = 10, + max_label_characters_per_row = 45 +) { + if (!legend_position %in% c("top", "bottom")) { + return(NULL) + } + + labels <- stats::na.omit(as.character(labels)) + if (length(labels) == 0) { + return(NULL) + } + + max_label_length <- max(nchar(labels), 1) + text_size_multiplier <- legend_text_size / 10 + columns_by_label_length <- max( + 1, + floor( + max_label_characters_per_row / (max_label_length * text_size_multiplier) + ) + ) + legend_columns <- min(length(labels), columns_by_label_length) + if (!is.null(ncol)) { + legend_columns <- min(ncol, legend_columns) + } + return(legend_columns) +} + +#' Compute colour legend text size +#' +#' Computes legend text size from legend labels. Short legends keep the larger +#' default text used by simple group legends, while longer or denser legends are +#' scaled down. +#' +#' @param labels Character vector of legend labels. +#' @param legend_text_size Optional explicit legend text size. When supplied, +#' this value is returned unchanged. +#' @param min_legend_text_size Smallest automatically selected legend text size. +#' @param max_legend_text_size Largest automatically selected legend text size. +#' +#' @return Numeric legend text size. +#' @keywords internal +#' @noRd +get_legend_text_size <- function( + labels, + legend_text_size = NULL, + min_legend_text_size = 8, + max_legend_text_size = 18 +) { + if (!is.null(legend_text_size)) { + return(legend_text_size) + } + + labels <- stats::na.omit(as.character(labels)) + if (length(labels) == 0) { + return(max_legend_text_size) + } + + label_pressure <- max( + max(nchar(labels), 1) / 5, + length(labels) / 4, + 1 + ) + + return(max( + min_legend_text_size, + floor(max_legend_text_size / sqrt(label_pressure)) + )) +} + +#' Add wrapped colour legend layout to a ggplot +#' +#' Applies a colour guide with a wrapped column count for top and bottom legends. +#' Left, right, and hidden legends are returned unchanged. +#' +#' @param plot A `ggplot2` plot object. +#' @inheritParams get_legend_column_count +#' +#' @return A `ggplot2` plot object with colour legend layout applied when needed. +#' @keywords internal +#' @noRd +add_colour_legend_layout <- function( + plot, + labels, + legend_position = "top", + ncol = NULL, + legend_text_size = 10, + max_label_characters_per_row = 45, + guide_override_aes = NULL +) { + legend_columns <- get_legend_column_count( + labels = labels, + legend_position = legend_position, + ncol = ncol, + legend_text_size = legend_text_size, + max_label_characters_per_row = max_label_characters_per_row + ) + + if (is.null(legend_columns)) { + return(plot) + } + + guide_args <- list(ncol = legend_columns, byrow = TRUE) + if (!is.null(guide_override_aes)) { + guide_args$override.aes <- guide_override_aes + } + + return( + plot + + ggplot2::guides( + colour = do.call(ggplot2::guide_legend, guide_args) + ) + + ggplot2::theme( + legend.box = "vertical" + ) + ) +} diff --git a/code/MOSuite/R/reexports.R b/code/MOSuite/R/reexports.R index c7c32ad..f586a0a 100644 --- a/code/MOSuite/R/reexports.R +++ b/code/MOSuite/R/reexports.R @@ -13,6 +13,11 @@ rlang::`!!` #' @export rlang::.data +#' default for null values +#' @importFrom rlang %||% +#' @export +rlang::`%||%` + # Suppress R CMD check note 'All declared Imports should be used'. # These are used in S7 methods. #' @importFrom dendextend rotate diff --git a/code/MOSuite/R/render_report.R b/code/MOSuite/R/render_report.R new file mode 100644 index 0000000..2a4d686 --- /dev/null +++ b/code/MOSuite/R/render_report.R @@ -0,0 +1,64 @@ +#' Render the template report +#' +#' Copy the Quarto template to the current working directory and render it +#' using `quarto::quarto_render()`. The rendered report will be saved in the +#' current working directory. You can specify additional arguments to +#' `quarto::quarto_render()` to customize the rendering process. +#' +#' You can edit the copy of `report.qmd` in the current working directory to customize the report. +#' +#' @param qmd_template Path to the Quarto report file (default is the template report in the package). +#' @param qmd_src Optional path to copy the Quarto report template to before +#' rendering. If `NULL` (default), the template will be copied to the current +#' working directory with the same filename as the template. If a file already +#' exists at `qmd_src`, it will not be overwritten. +#' @param ... Additional arguments passed to `quarto::quarto_render()`, such as +#' `execute_params` (a named list of parameters) or `quarto_args` (a +#' character vector of CLI flags, e.g. `c("--output-dir", "/path/to/out")`). +#' +#' @export +#' +#' @examples +#' render_report(execute_params = list( +#' counts_csv = system.file("extdata", "nidap", "Raw_Counts.csv.gz", +#' package = "MOSuite"), +#' samplesheet_csv = system.file("extdata", "nidap", +#' "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", +#' package = "MOSuite") +#' )) +#' +#' # Render to a specific output directory +#' render_report( +#' quarto_args = c("--output-dir", "./results"), +#' execute_params = list( +#' counts_csv = system.file("extdata", "nidap", "Raw_Counts.csv.gz", +#' package = "MOSuite"), +#' samplesheet_csv = system.file("extdata", "nidap", +#' "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", +#' package = "MOSuite") +#' ) +#' ) +render_report <- function( + qmd_template = system.file("quarto", "report.qmd", package = "MOSuite"), + qmd_src = NULL, + ... +) { + abort_packages_not_installed(c("quarto", "knitr", "rmarkdown")) # nolint: object_usage_linter + if (is.null(qmd_src)) { + qmd_src <- basename(qmd_template) + } + # Resolve to absolute path so quarto subprocess uses the correct directory + qmd_src <- normalizePath(qmd_src, mustWork = FALSE) + if (!file.exists(qmd_src)) { + ok <- file.copy(qmd_template, qmd_src, overwrite = FALSE) + if (!isTRUE(ok)) { + stop(glue::glue( + "Failed to copy template from '{qmd_template}' to '{qmd_src}'" + )) + } + } + return(quarto::quarto_render( + input = qmd_src, + ... + )) +} diff --git a/code/MOSuite/R/volcano.R b/code/MOSuite/R/volcano.R new file mode 100644 index 0000000..0ed3b3f --- /dev/null +++ b/code/MOSuite/R/volcano.R @@ -0,0 +1,55 @@ +#' Resolve volcano plot column names +#' +#' Auto-detects `change_colname` and `signif_colname` from a data frame when +#' either is `NULL`. Used by [plot_volcano_enhanced()] and +#' [plot_volcano_summary()]. +#' +#' When `change_colname` is `NULL`, all columns ending in `_logFC` are used. +#' When `signif_colname` is `NULL`, significance columns are detected by +#' checking for `_adjpval` columns first, then `_pval`, for each contrast +#' derived from `change_colname`. +#' +#' @param diff_dat A data frame of differential analysis results. +#' @param change_colname Character vector of logFC column names, or `NULL` to +#' auto-detect columns ending in `_logFC`. +#' @param signif_colname Character vector of significance column names, or +#' `NULL` to auto-detect, preferring `_adjpval` over `_pval`. +#' @return A named list with elements `change_colname` and `signif_colname`. +#' @keywords internal +resolve_volcano_colnames <- function(diff_dat, change_colname, signif_colname) { + if (is.null(change_colname)) { + change_colname <- grep("_logFC$", colnames(diff_dat), value = TRUE) + if (length(change_colname) == 0) { + cli::cli_abort( + "No columns ending in {.val _logFC} found. \\ + Supply {.arg change_colname} explicitly." + ) + } + } + if (is.null(signif_colname)) { + contrasts <- sub("_logFC$", "", change_colname) + detected_suffix <- NULL + for (suffix in c("adjpval", "pval")) { + if (all(paste0(contrasts, "_", suffix) %in% colnames(diff_dat))) { + detected_suffix <- suffix + break + } + } + if (is.null(detected_suffix)) { + cli::cli_abort( + "Could not auto-detect significance columns. \\ + Supply {.arg signif_colname} explicitly \\ + (e.g. {.code c(\"B-A_adjpval\", \"C-A_adjpval\")})." + ) + } + signif_colname <- paste0(contrasts, "_", detected_suffix) + } + if (length(change_colname) != length(signif_colname)) { + cli::cli_abort( + "{.arg change_colname} (length {length(change_colname)}) and \\ + {.arg signif_colname} (length {length(signif_colname)}) must have the \\ + same length." + ) + } + list(change_colname = change_colname, signif_colname = signif_colname) +} diff --git a/code/MOSuite/SECURITY.md b/code/MOSuite/SECURITY.md new file mode 100644 index 0000000..99da43f --- /dev/null +++ b/code/MOSuite/SECURITY.md @@ -0,0 +1,18 @@ +# NCI Standard Public Repository Security Policy + +## Maintained Versions + +Actively maintained versions of contained software will vary from repository to repository, or may not be relevant at all. +The developers of this repository will update this section if any actively maintained versions of the software need to be publicly disclosed. Otherwise, contact the developers directly for any version information. + +## Vulnerability Disclosure: + +### Option 1: HHS Vulnerability Disclosure + +Follow the instructions listed in the [HHS vulnerability disclosure policy](https://www.hhs.gov/vulnerability-disclosure-policy/index.html). + +### Option 2: Private Vulnerability Report + +1. Click on the **Security and quality** tab of this repository. +2. Locate the **Report a vulnerability** button. If the button is not on the **Security and quality** landing page, look under the **Advisories** section in the side bar. +3. Click the **Report a vulnerability** button and submit the form. The developers will receive a notification of your submission. diff --git a/code/MOSuite/_pkgdown.yml b/code/MOSuite/_pkgdown.yml index 504949b..cd69bc6 100644 --- a/code/MOSuite/_pkgdown.yml +++ b/code/MOSuite/_pkgdown.yml @@ -38,7 +38,6 @@ articles: - intro - renee - visualization - - cli - memory reference: @@ -53,9 +52,9 @@ reference: - title: Visualization contents: - has_keyword("plotters") -- subtitle: Color selectors - contents: - contains("color") + - contains("palette") + - render_report - title: Misc. helpers & utilities contents: - starts_with('calc_') diff --git a/code/MOSuite/codemeta.json b/code/MOSuite/codemeta.json index 5cf8660..53c9282 100644 --- a/code/MOSuite/codemeta.json +++ b/code/MOSuite/codemeta.json @@ -32,5 +32,5 @@ "license": "https://spdx.org/licenses/MIT", "name": "MOSuite: R package for differential multi-omics analysis", "url": "https://ccbr.github.io/MOSuite/", - "version": "0.3.1.9001" + "version": "0.4.0.9000" } diff --git a/code/MOSuite/data-raw/mosuite_palette.R b/code/MOSuite/data-raw/mosuite_palette.R new file mode 100644 index 0000000..402fd4e --- /dev/null +++ b/code/MOSuite/data-raw/mosuite_palette.R @@ -0,0 +1,26 @@ +mosuite_palette <- c( + "#5954d6", + "#e1562c", + "#b80058", + "#00c6f8", + "#d163e6", + "#00a76c", + "#ff9287", + "#008cf9", + "#006e00", + "#796880", + "#FFA500", + "#878500" +) + +usethis::use_data(mosuite_palette, overwrite = TRUE) + +ggplot2::ggsave( + filename = "mosuite_palette.png", + plot = display_palette(mosuite_palette), + path = "man/figures", + width = 7, + height = 2, + units = "in", + dpi = 300 +) diff --git a/code/MOSuite/data/mosuite_palette.rda b/code/MOSuite/data/mosuite_palette.rda new file mode 100644 index 0000000000000000000000000000000000000000..ab1004ba4962e614aa0f7bbeb7a3fca233b0bcd1 GIT binary patch literal 174 zcmV;f08#%!T4*^jL0KkKSsZ(N4FCXae}Mk9zyJsWf8Zqm7C^ry&Hw-bAOMmWGGPIx zfEqM3&@{+0AxDaOjik`pj6i4rIT-bL2Qp(*MW{#-r6}p;Js8!h5JC*dC_+t00gO;V z<3%G8jAHi+!Pgp~jRja%RE*LM;t2by5;20){\n par(mar=c(0,0,0,0))\n heatmap.2(m,\n labRow = NA, \n labCol = NA,\n col=new.palette(20),\n trace=\"none\",\n colRow = col[idx], \n colCol = col[idx],\n rowDendrogram=dend,\n colDendrogram=dend,\n RowSideColors = col[idx],\n ColSideColors = col[idx],\n dendrogram = \"row\",\n cexRow=3,\n cexCol=3,\n margins=c(0,0), \n lmat=rbind( c(0,0,2),c(4,1,3) ,c(0,5,6) ), \n lhei=c(.2,4,2), \n lwid=c(1, .2,4 ), \n key.par=list(mgp=c(1.75, .5, 0), \n mar=c(7, 2, 3.5, 0), \n cex.axis=.1, \n cex.lab=3, \n cex.main=1, \n cex.sub=1),\n key.xlab = \"Correlation\",\n key.ylab=\"Count\",\n key.title=\" \") \n } else {\n heatmap.2(m,col=new.palette(20),\n trace=\"none\",\n colRow = col[idx], \n colCol = col[idx],\n rowDendrogram=dend,\n colDendrogram=dend,\n RowSideColors = col[idx],\n ColSideColors = col[idx],\n dendrogram = \"row\",\n cexRow=3,cexCol=3,margins=c(4,1), \n lmat=rbind( c(0,0,2),c(4,1,3) ,c(0,5,6) ), \n lhei=c( .2,4,2), \n lwid=c(1, .2,4),\n key.par=list(mgp=c(1.75, .5, 0), mar=c(7, 2, 3.5, 0), cex.axis=.1, cex.lab=3, cex.main=1, cex.sub=1),\n key.xlab = \"Correlation\",\n key.ylab=\"Count\",\n key.title=\" \")\n }\n }\n \n tg<-mk()\n grid.echo(mk)\n gh1<-grid.grab()\n mklegend<-function(){\n plot.new()\n legend(x=\"top\", legend=levels(idx), col=col[as.factor(levels(idx))],pch=15,x.intersp=3,bty =\"n\",cex=2)\n }\n grid.echo(mklegend )\n gh2<-grid.grab()\n lay <- c(1,3)\n grid.newpage()\n grid.arrange(gh1,gh2,nrow=1,widths=c(unit(1000, \"bigpts\"),unit(300, \"bigpts\")))\n gh<-grid.grab()\n return(gh)\n }\n\n ## --------------- ##\n ## Main Code Block ##\n ## --------------- ##\n\n samples_to_include=columns_to_include[columns_to_include%in%sample_metadata[,sample_names_column,drop=T]]\n anno_col=columns_to_include[columns_to_include%in%sample_metadata[,sample_names_column,drop=T]==F]\n\n samples_to_include <- samples_to_include[samples_to_include != gene_names_column]\n samples_to_include <- samples_to_include[samples_to_include != \"Gene\"]\n samples_to_include <- samples_to_include[samples_to_include != \"GeneName\"]\n cat(\"Number of input samples:\\n\")\n cat(length(samples_to_include))\n cat(\"\\n\\n\")\n\n ##create unique rownames to correctly add back Annocolumns at end of template\n counts_matrix[,gene_names_column]=paste0(counts_matrix[,gene_names_column],'_',1:nrow(counts_matrix))\n anno_col=c(anno_col,gene_names_column)%>%unique\n anno_tbl=counts_matrix[,anno_col,drop=F]%>%as.data.frame\n\n df.filt <- counts_matrix[,samples_to_include]\n dim(df.filt)\n gene_names <- NULL\n gene_names$GeneID <- counts_matrix[,gene_names_column]\n\n sample_metadata <- sample_metadata[match(colnames(df.filt),sample_metadata[[sample_names_column]]),] #First match sample metadata to counts matrix\n sample_metadata <- sample_metadata[rowSums(is.na(sample_metadata)) != ncol(sample_metadata), ] # Remove empty rows\n sample_metadata <- sample_metadata[, colSums(is.na(sample_metadata)) == 0] #Remove empty columns\n rownames(sample_metadata) <- sample_metadata[[sample_names_column]]\n\n df.filt <- df.filt[,match(sample_metadata[[sample_names_column]],colnames(df.filt))] #Match counts matrix columns to sample metadata\n rownames(df.filt) <- gene_names$GeneID\n\n #Running ComBat:\n for(cov in covariates){\n sample_metadata[[cov]] <- as.factor(sample_metadata[[cov]])\n }\n dm.formula <- as.formula(paste(\"~\", paste(covariates, sep=\"+\", collapse=\"+\")))\n modcombat <- model.matrix(dm.formula, data=sample_metadata)\n Batch <- sample_metadata[[batch_column]]\n\n if(skip_batch_correction == FALSE){\n if(length(unique(Batch))<=1){\n combat_edata=as.matrix(df.filt)\n } else {\n combat_edata = ComBat(as.matrix(df.filt), batch=Batch, mod=modcombat,\n par.prior=TRUE, prior.plots=FALSE)\n }\n } else {\n combat_edata=as.matrix(df.filt)\n }\n \n edf <- combat_edata\n as.data.frame(combat_edata) %>% rownames_to_column(gene_names_column) -> combat_edata\n cat(paste0(\"\\nThe total number of features in output: \", nrow(combat_edata)))\n\n #Start PCA Plot:\n tedf <- t(edf)\n tedf <- tedf[, colSums(is.na(tedf)) != nrow(tedf)]\n tedf <- tedf[, apply(tedf, 2, var) != 0]\n pca <- prcomp(tedf, scale.=T)\n \n pcx <- paste0(\"PC\",principal_component_on_x_axis_for_pca)\n pcy <- paste0(\"PC\",principal_component_on_y_axis_for_pca)\n pca.df <- as.data.frame(pca$x) %>% dplyr::select(.data[[pcx]], .data[[pcy]])\n pca.df$group <- sample_metadata[[groups_column]]\n pca.df$sample <- sample_metadata[[labels_column]]\n perc.var <- (pca$sdev^2/sum(pca$sdev^2))*100\n perc.var <- formatC(perc.var,format = \"g\",digits=4)\n pc.x.lab <- paste0(pcx,\" \", perc.var[principal_component_on_x_axis_for_pca],\"%\")\n pc.y.lab <- paste0(pcy,\" \", perc.var[principal_component_on_y_axis_for_pca],\"%\")\n labelpos <- pca.df\n labelpos$mean_y <- pca.df[[pcy]]+label_offset_y_for_pca\n labelpos$mean_x <- pca.df[[pcx]]+label_offset_x_for_pca\n pca.df$xdata <- pca.df[[pcx]]\n pca.df$ydata <- pca.df[[pcy]]\n\n # Manual changes to sample names\n replacements = samples_to_rename_manually_on_pca\n\n if (!is.null(replacements)) {\n if (replacements != c(\"\")) {\n for (x in replacements) {\n old <- strsplit(x, \": ?\")[[1]][1]\n new <- strsplit(x, \": ?\")[[1]][2]\n pca.df$sample <- ifelse(pca.df$sample==old, new, pca.df$sample)\n }\n }\n }\n\n colorlist <- c(\"#5954d6\",\"#e1562c\",\"#b80058\",\"#00c6f8\",\"#d163e6\",\"#00a76c\",\"#ff9287\",\"#008cf9\",\"#006e00\",\"#796880\",\"#FFA500\",\"#878500\")\n names(colorlist) <- c(\"indigo\",\"carrot\",\"lipstick\",\"turquoise\",\"lavender\",\"jade\",\"coral\",\"azure\",\"green\",\"rum\",\"orange\",\"olive\")\n if(length(colors_for_plots) == 0){\n colors_for_plots <- c(\"indigo\",\"carrot\",\"lipstick\",\"turquoise\",\"lavender\",\"jade\",\"coral\",\"azure\",\"green\",\"rum\",\"orange\",\"olive\")\n }\n colorval <- colorlist[colors_for_plots]\n colorval <- unname(colorval) #remove names which affect ggplot\n\n if (length(unique(sample_metadata[[groups_column]])) > length(colorval)) {\n ## Original color-picking code.\n k=length(unique(sample_metadata[[groups_column]]))-length(colorval)\n more_cols<- getourrandomcolors(k) \n colorval <- c(colorval , more_cols)\n }\n\n if (add_labels_to_pca){\n g <- ggplot(pca.df, aes(x=xdata, y=ydata)) +\n theme_bw() +\n theme(legend.title=element_blank()) +\n theme(legend.position=legend_position_for_pca) +\n geom_point(aes(color=group), size=point_size_for_pca) +\n geom_text(data=labelpos, aes(x=labelpos$mean_x, y=labelpos$mean_y, \n label=sample, color=group, vjust=\"inward\", hjust=\"inward\"), size=label_font_size_for_pca, show.legend=FALSE) +\n theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),\n panel.background = element_blank()) +\n scale_colour_manual(values = colorval) +\n xlab(pc.x.lab) + ylab(pc.y.lab)\n } else {\n g <- ggplot(pca.df, aes(x=xdata, y=ydata)) +\n theme_bw() +\n theme(legend.title=element_blank()) +\n theme(legend.position=legend_position_for_pca) +\n geom_point(aes(color=group), size=point_size_for_pca) +\n theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),\n panel.background = element_blank()) +\n scale_colour_manual(values = colorval) +\n xlab(pc.x.lab) + ylab(pc.y.lab) \n }\n\n par(mfrow = c(2,1))\n\n df.m <- melt(edf,id.vars=c(gene_names_column))\n df.m = dplyr::rename(df.m,sample=Var2)\n\n if(set_min_max_for_x_axis_for_histogram == TRUE){\n xmin = minimum_for_x_axis_for_histogram\n xmax = maximum_for_x_axis_for_histogram\n } else {\n xmin = min(df.m$value)\n xmax = max(df.m$value)\n }\n\n if(color_histogram_by_group == TRUE){\n df.m %>% mutate(colgroup = sample_metadata[sample,groups_column]) -> df.m\n df.m = df.m[complete.cases(df.m[, \"colgroup\"]),]\n df.m$colgroup = gsub(\"\\\\s\",\"_\",df.m$colgroup)\n df.m$colgroup = factor(df.m$colgroup, levels=unique(df.m$colgroup))\n\n # plot Density \n g2 = ggplot(df.m, aes(x=value, group=sample)) + \n geom_density(aes(colour = colgroup)) +\n xlab(\"Filtered Counts\") + ylab(\"Density\") +\n theme_bw() +\n theme(legend.position=legend_position_for_histogram,legend.text = element_text(size = legend_font_size_for_histogram)) + \n ggtitle(\"Frequency Histogram\") +\n xlim(xmin,xmax) +\n scale_colour_manual(values=colorval)\n } else {\n \n df.m$sample = sample_metadata[df.m$sample,labels_column]\n n=length(unique(df.m$sample))\n cols<- getourrandomcolors(n) \n \n g2 = ggplot(df.m, aes(x=value, group=sample)) + \n geom_density(aes(colour = sample)) +\n xlab(\"Filtered Counts\") + ylab(\"Density\") +\n theme_bw() +\n theme(legend.position=legend_position_for_histogram,legend.text = element_text(size = legend_font_size_for_histogram)) + \n ggtitle(\"Frequency Histogram\") +\n xlim(xmin,xmax) +\n scale_colour_manual(values=cols)\n }\n\n # dev.off()\n\n imageWidth = 3000\n imageHeight = 1500*2\n dpi = 300\n\n png(\n filename=graphicsFile,\n width=imageWidth,\n height=imageHeight,\n units=\"px\",\n pointsize=4,\n bg=\"white\",\n res=dpi,\n type=\"cairo\")\n\n if(plot_correlation_matrix_heatmap == TRUE){\n if(make_plots_interactive == TRUE){\n p1=(g)%>%ggplotly(tooltip = c(\"sample\",\"group\"))\n p2=(g2+theme(legend.position = \"none\")) %>%ggplotly(tooltip = c(\"sample\"))\n fig=subplot(p1,p2,which_layout = 'merge',margin=.05,shareX = F,shareY = F,titleY = T,titleX = T,widths=c(.5,.5),nrows = 1)\n fig=fig %>% layout(title = 'Interactive PCA and Histogram')\n print(fig)\n } else {\n require(gridExtra)\n gh<-make_heatmap(df.filt,sample_metadata,colorval)\n grid.arrange(g,g2,gh, nrow=number_of_image_rows)\n # dev.off()\n } \n } else {\n if(make_plots_interactive == TRUE){\n p1=(g)%>%ggplotly(tooltip = c(\"sample\",\"group\"))\n p2=(g2+theme(legend.position = \"none\")) %>%ggplotly(tooltip = \"sample\" )\n fig=subplot(p1,p2,which_layout = 'merge',margin=.05,shareX = F,shareY = F,titleY = T,titleX = T,widths=c(.5,.5),nrows = 1)\n fig=fig %>% layout(title = 'Interactive PCA and Histogram')\n print(fig)\n } else {\n grid.arrange(g,g2, nrow=number_of_image_rows)\n # dev.off()\n }\n } \n \n#print('')\ncat('\\n\\nSamples:\\n')\ncat(colnames(combat_edata[,!colnames(combat_edata)%in%gene_names_column]))\n\ncat(\"\\n\\nNumber of samples after batch correction:\\n\")\ncat(length(samples_to_include))\n\n combat_edata=merge(anno_tbl,combat_edata,by=gene_names_column,all.y=T)\n combat_edata[,gene_names_column]=gsub('_[0-9]+$',\"\",combat_edata[,gene_names_column])\n\n return(combat_edata)\n}\n\n\n\n#################################################\n## Global imports and functions included below ##\n#################################################\n\n", - "columns": [ - { - "key": "Feature_ID_Column", - "displayName": "Feature ID Column", - "description": "The column from your input Counts Matrix containing the Feature IDs (Usually Gene or Protein ID). This is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts Matrix will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Columns_to_Include", - "displayName": "Columns to Include", - "description": "Which Columns would you like to include? Usually, you will choose to \"Add all\" (see button on right). Columns excluded here will be removed in this step and from further analysis downstream of this step.", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "Sample_Names_Column", - "displayName": "Sample Names Column", - "description": "The column from your input Sample Metadata table containing the sample names. The names in this column must exactly match the names used as the sample column names of your input Counts Matrix. Only columns of Text type from your input Sample Metadata table will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Groups_Column", - "displayName": "Groups Column", - "description": "The column from your input Sample Metadata table containing the sample group information. This is usually a column showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal, Before, After, etc.). Only columns of Text type from your input Sample Metadata will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Covariates", - "displayName": "Covariates", - "description": "The column(s) from your input Sample Metadata table containing variable(s) of interest, such as phenotype. Most commonly this will be the same column you selected for your Groups Column (above). Some experimental designs may require that you add additional covariate columns here. \nNB. Do not include the \"Batch\" column here.", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "Batch_Column", - "displayName": "Batch Column", - "description": "The column from your input Sample Metadata table containing the batch information. Samples extracted, prepared, or sequenced at separate times or using separate materials/staff/equipment may belong to different batches. Not all datasets have batches. If yours dataset has no batches, you must still provide a Batch column with the same value in every row.", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "Labels_Column", - "displayName": "Labels Column", - "description": "The column from your input Sample Metadata table containing the sample labels as you wish them to appear in the plots produced by this template. This can be the same Sample Names Column (see above). However, you may desire different labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the column with your preferred Labels here.", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - } - ], - "condaDependencies": [], - "description": "This template performs batch correction on RNA-seq expression data to account for batch effects that can arise whenever some samples are prepared in a different manner or at a different time than others. It takes a counts matrix (usually the normalized counts matrix) and your metadata table as input and provides two QC plots and a normalized expression matrix as output. This template is only necessary if your dataset has more than one batch. When necessary, it is usually the third step (after normalization) in the QC portion of a bulk RNA-seq analysis.\n\nBatch correction can only be attempted if your Batch variable is not completely confounded with your Group variable (see your metadata table). The two QC plots, a PCA plot and counts frequency histogram, are provided to help assess within and between group variance and the dis/similarity of sample count distributions, respectively.\n\nThe batch correction applied by this template is performed using the 'sva' R package's ComBat method.", - "externalId": "Batch_Correction_CCBR_", - "inputDatasets": [ - { - "key": "counts_matrix", - "displayName": "Counts Matrix", - "description": "The input Counts Matrix. Usually, this will be your Normalized Counts matrix.", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - }, - { - "key": "sample_metadata", - "displayName": "Sample Metadata", - "description": "The Sample Metadata table containing your sample metadata. At minimum, this table must include one column each of the following: Samples, Groups, Batches, and Labels. The names in the Samples column of your input Sample Metadata must match the Sample Column Names of your input Counts Matrix exactly. You may have more than one column showing different Groups by which your samples may be organized (e.g. Genotype, Response, Time, etc.).", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - } - ], - "vectorLanguage": "R", - "codeLanguage": "R", - "parameters": [ - { - "key": "Samples_to_Rename_Manually_on_PCA", - "displayName": "Samples to Rename Manually on PCA", - "description": "Enter each sample to rename in the format: old_name: new_name", - "paramType": "VECTOR", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "c(\"\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Add_Labels_to_PCA", - "displayName": "Add Labels to PCA", - "description": "Toggle to TRUE to use the column from \"Label Column to Use for Plots\" (above) to label points on the PCA plot. Toggle to FALSE to remove these labels from the plot. Default is TRUE.", - "paramType": "BOOLEAN", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Principal_Component_on_X_axis_for_PCA", - "displayName": "Principal Component on X-axis for PCA", - "description": "The principle component to plot on the x-axis. Choices include 1, 2, 3, ... (default: 1)", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Principal_Component_on_Y_axis_for_PCA", - "displayName": "Principal Component on Y-axis for PCA", - "description": "The principle component to plot on the y-axis. Choices include 1, 2, 3, ... (default: 2)", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Legend_Position_for_PCA", - "displayName": "Legend Position for PCA", - "description": "Legend position relative to the plot", - "paramType": "SELECT", - "paramGroup": "PCA", - "paramValues": [ - "top", - "bottom", - "left", - "right", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Offset_x_for_PCA", - "displayName": "Label Offset (x) for PCA", - "description": "", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Offset_y_for_PCA", - "displayName": "Label Offset (y) for PCA", - "description": "", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Point_Size_for_PCA", - "displayName": "Point Size for PCA", - "description": "Size of a each data point on the PCA.", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Font_Size_for_PCA", - "displayName": "Label Font Size for PCA", - "description": "Font size for sample labels on the PCA. Set to 0 to remove labels.", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "3", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Color_Histogram_by_Group", - "displayName": "Color Histogram by Group", - "description": "Toggle to FALSE to label histogram by Sample Names. Toggle to TRUE to label histogram by the column you select in the \"Group Column Used to Color Histogram\" parameter (below). Default is FALSE.", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Set_Max_Min_for_X_axis_for_Histogram", - "displayName": "Set Max/Min for X-axis for Histogram", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Maximum_X_axis_in_Histogram", - "displayName": "Maximum X-axis in Histogram", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Minimum_X_axis_in_Histogram", - "displayName": "Minimum X-axis in Histogram", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "-1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Legend_Font_Size_for_Histogram", - "displayName": "Legend Font Size for Histogram", - "description": "Legend font size for the histogram.", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "10", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Legend_Position_for_Histogram", - "displayName": "Legend Position for Histogram", - "description": "Legend position on histogram plot, can be 'none' if large number of samples", - "paramType": "SELECT", - "paramGroup": "Histogram", - "paramValues": [ - "right", - "bottom", - "left", - "top", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Number_of_Histogram_Legend_Columns", - "displayName": "Number of Histogram Legend Columns", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "6", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Colors_for_plots", - "displayName": "Colors for plots", - "description": "Colors for the PCA and histogram will be picked, in order, from this list. If more colors are needed, program will choose from a wide range of random colors", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "indigo", - "carrot", - "lipstick", - "turquoise", - "lavender", - "jade", - "coral", - "azure", - "green", - "rum", - "orange", - "olive" - ], - "defaultValue": "c(\"indigo\",\"carrot\",\"lipstick\",\"turquoise\",\"lavender\",\"jade\",\"coral\",\"azure\",\"green\",\"rum\",\"orange\",\"olive\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Number_of_Image_Rows", - "displayName": "Number of Image Rows", - "description": "1 = side-by-side, 2 = stacked", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Make_Plots_Interactive", - "displayName": "Make Plots Interactive", - "description": "Toggle TRUE to make PCA and Histogram plots interactive, allowing you to hover your mouse over a point or line to view sample information. The similarity heatmap will not display if this toggle is set to TRUE. Default is FALSE.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Plot_Correlation_Matrix_Heatmap_", - "displayName": "Plot Correlation Matrix Heatmap ", - "description": "Datasets with a large number of samples may be too large to create a correlation matix heatmap. If this template takes longer than 5 minutes to run, Toggle switch to FALSE and the correlation matrix will not be be created. Default is TRUE.", - "paramType": "BOOLEAN", - "paramGroup": "TCGA", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Skip_Batch_Correction", - "displayName": "Skip Batch Correction", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "title": "Batch Correction [CCBR]", - "templateApiVersion": "0.1.0" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Clean_Raw_Counts_CCBR_.code-template.json b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Clean_Raw_Counts_CCBR_.code-template.json deleted file mode 100644 index cdfc6d3..0000000 --- a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Clean_Raw_Counts_CCBR_.code-template.json +++ /dev/null @@ -1,119 +0,0 @@ -{ - "codeTemplate": "Clean_Raw_Counts <- function({{{Raw_Counts_Matrix}}}) {\n\n\nlibrary(stringr)\nlibrary(tidyr)\nlibrary(dplyr)\n\n## -------------------------------- ##\n## User-Defined Template Parameters ##\n## -------------------------------- ##\n\n#Basic Parameters:\nraw_counts_matrix={{{Raw_Counts_Matrix}}}\nData_type='{{{data_type}}}'\ngene_id_column='{{{Feature_ID_Column}}}'\nsamples_to_rename = {{{Samples_to_Rename}}}\n\n#Advanced Parameters:\ncleanup_column_names={{{Cleanup_Column_Names}}}\nsplit_gene_name = {{{Split_Feature_ID}}}\naggregate_rows_with_duplicate_gene_names={{{Aggregate_Rows_with_Duplicate_Feature_Names}}}\ngene_name_column_to_use_for_collapsing_duplicates='{{{Column_Used_to_Aggregate_Duplicates_Feature_IDs}}}'\n\n###################################################################################\nremoveVersion <- function(ids){\n return(unlist(lapply(stringr::str_split(ids, \"[.]\"), \"[[\",1)))\n} \n\nprint(Data_type)\n\n\n################################## \n##### Sample Name Check\n################################## \n\n## duplicate col name\nif(sum(duplicated(colnames(raw_counts_matrix)))!=0){\n print(\"Duplicate column names are not allowed, the following columns were duplicated.\\n\")\n colnames(raw_counts_matrix)[duplicated(colnames(raw_counts_matrix))]\n stop(\"Duplicated columns\")\n}\n\n\n\n\n################################## \n##### Manually rename samples\n################################## \n\n if (!is.null(samples_to_rename)) {\n if (samples_to_rename != c(\"\")) {\n for (x in samples_to_rename) {\n old <- strsplit(x, \": ?\")[[1]][1]\n new <- strsplit(x, \": ?\")[[1]][2]\n colnames(raw_counts_matrix)[colnames(raw_counts_matrix)%in%old]=new\n }\n }\n }\n\n \n\n ################################## \n ##### Cleanup Columns\n ################################## \nif(cleanup_column_names){\ncl_og=colnames(raw_counts_matrix)\n ## convert special charchers to _\n cl2 <- gsub('-| |\\\\:','_',colnames(raw_counts_matrix))\n if (length(cl2[(cl2)!=colnames(raw_counts_matrix)])>0) {\n print('Columns had special characters relpaced with _ ')\n # (colnames(raw_counts_matrix)[(colnames(raw_counts_matrix))!=cl2])\n # print(cl2[(cl2)!=colnames(raw_counts_matrix)])\n colnames(raw_counts_matrix) = cl2\n }\n \n ## if names begin with number add X\n cl2=sub(\"^(\\\\d)\", \"X\\\\1\", colnames(raw_counts_matrix))\n if (length(cl2[(cl2)!=colnames(raw_counts_matrix)])>0) {\n\n print('Columns started with numbers and an X was added to colname :')\n # (colnames(raw_counts_matrix)[(colnames(raw_counts_matrix))!=cl2])\n # print(cl2[(cl2)!=colnames(raw_counts_matrix)])\n colnames(raw_counts_matrix) = cl2\n }\n #print(\"Original Colnames:\")\n #print(cl_og[(cl_og)!=colnames(df)])\n #print(\"Modified Colnames:\")\n #print(colnames(df)[colnames(df)!=(cl_og)]%>%as.data.frame)\n \n #print(\"Final Colnames:\") \n \n}else{\n\n ## invalid name format\n if(any(make.names(colnames(raw_counts_matrix))!=colnames(raw_counts_matrix))){\n print(\"Error: The following counts matrix column names are not valid:\\n\")\n print(colnames(raw_counts_matrix)[make.names(colnames(raw_counts_matrix))!=colnames(raw_counts_matrix)])\n print(\"Likely causes are columns starting with numbers or other special characters eg spaces.\\n\")\n # stop(\"Bad column names.\")\n }\n ## Names Contain dashes\n if(sum(grepl(\"-\",colnames(raw_counts_matrix)))!=0){\n print(\"The sample names cannot contain dashes.\")\n print(colnames(raw_counts_matrix)[grepl(\"-\",colnames(raw_counts_matrix))])\n # stop(\"No dashes allowed in column names\")\n }\n}\n \n\n################################## \n## Split Ensemble + Gene name\n##################################\n## First check if Feature ID column can be split by \",|_-:\"\n## Then check if one column contains Ensemble (regex '^ENS[A-Z]+[0-9]+')\n## check if Ensemble ID has version info and remove version\n## If one column contains Ensemble ID Assume other column is Gene names\n## If Column does not contain Ensmeble ID name split columns Gene_ID_1 and Gene_ID_2\nprint(\"\")\n\nif(split_gene_name==T){\nEnsembl_ID= str_split_fixed(raw_counts_matrix[,gene_id_column],'_|-|:|\\\\|',n=2)%>%data.frame()\nEnsCol= apply(Ensembl_ID, c(1,2), function(x) grepl('^ENS[A-Z]+[0-9]+', x))\n \n \nif(\"\"%in%Ensembl_ID[,1]|\"\"%in%Ensembl_ID[,2]){\nprint(paste0(\"Not able to identify multiple id's in \", gene_id_column ))\n # colnames(df)[colnames(df)%in%clm]=gene_col\n if(Data_type=='Bulk RNAseq') { \n colnames(raw_counts_matrix)[colnames(raw_counts_matrix)%in%gene_id_column]='Gene'\n }else if(Data_type=='Proteomics'){\n colnames(raw_counts_matrix)[colnames(raw_counts_matrix)%in%gene_id_column]='FeatureID'\n }else { print('incorrect Data Type'); incorrect_Data_Type }\n}else{\n## at least one column must have all ensemble ids found in EnsCol \n if (nrow(EnsCol[EnsCol[,1]==T,])==nrow(Ensembl_ID)|nrow(EnsCol[EnsCol[,2]==T,])==nrow(Ensembl_ID)){\n if(Data_type=='Bulk RNAseq') { \n colnames(Ensembl_ID)[colSums(EnsCol)!=nrow(Ensembl_ID)]='Gene'\n }else if(Data_type=='Proteomics'){\n colnames(Ensembl_ID)[colSums(EnsCol)!=nrow(Ensembl_ID)]='FeatureID'\n }\n## check if Ensmble column has version information\n if(grepl('^ENS[A-Z]+[0-9]+\\\\.[0-9]+$', Ensembl_ID[,colSums(EnsCol)==nrow(Ensembl_ID)])%>%sum()==nrow(Ensembl_ID)){\n colnames(Ensembl_ID)[colSums(EnsCol)==nrow(Ensembl_ID)]='Ensembl_ID_version'\n Ensembl_ID$Ensembl_ID=removeVersion(Ensembl_ID$Ensembl_ID_version)\n }else{\n colnames(Ensembl_ID)[colSums(EnsCol)==nrow(Ensembl_ID)]='Ensembl_ID'\n }\n }else{\n colnames(Ensembl_ID)=c('Feature_id_1','Feature_id_2')\n print(\"Could not determine ID formats from split 'Feature ID' Column\")\n\n}\n raw_counts_matrix <- cbind(Ensembl_ID,raw_counts_matrix[,!colnames(raw_counts_matrix)%in%gene_id_column])\n} \n}else{\n if(Data_type=='Bulk RNAseq') { \n colnames(raw_counts_matrix)[colnames(raw_counts_matrix)%in%gene_id_column]='Gene'\n }else if(Data_type=='Proteomics'){\n colnames(raw_counts_matrix)[colnames(raw_counts_matrix)%in%gene_id_column]='FeatureID'\n }else { print('incorrect Data Type'); incorrect_Data_Type }\n}\n\n##################################\n## If duplicate gene aggregate information to single row\n################################## \n## If user uses \"Feature ID\" column then switch to empty for appropriate behavor based on other parameters\nif(gene_name_column_to_use_for_collapsing_duplicates==gene_id_column){\n gene_name_column_to_use_for_collapsing_duplicates=\"\"\n}\n\n if(gene_name_column_to_use_for_collapsing_duplicates==\"\"&\n ('Feature_id_1'%in%colnames(raw_counts_matrix))==F){\n if(Data_type=='Bulk RNAseq') { \n gene_name_column_to_use_for_collapsing_duplicates='Gene'\n }else if(Data_type=='Proteomics'){\n gene_name_column_to_use_for_collapsing_duplicates='FeatureID'\n }\n } \n\n#geneids<-df[,gene_col]\n nums <- unlist(lapply(raw_counts_matrix, is.numeric)) \n nums = names(nums[nums])\n print('')\n print('Columns that can be used to aggregate gene information' )\n print(raw_counts_matrix[,!names(raw_counts_matrix) %in% nums,drop=F]%>%colnames())\n \n print('')\n\n \n if(gene_name_column_to_use_for_collapsing_duplicates==\"\"){\n\n if(split_gene_name==F){ \n ## If no additional Column name given for Aggregation then display Feature ID duplicates\n print(paste0(\"genes with duplicate IDs in \",gene_id_column,\":\")) \n\n ## Print original Column name for user Reference then use new Column name to subset table\n if(Data_type=='Bulk RNAseq') { \n gene_id_column='Gene'\n }else if(Data_type=='Proteomics'){\n gene_id_column='FeatureID'\n }\n raw_counts_matrix[duplicated(raw_counts_matrix[,gene_id_column]),gene_id_column]%>%unique()%>%as.character()%>%write( stdout())\n\n }else if(split_gene_name==T&grepl('Feature_id_1',colnames(raw_counts_matrix))==F){ \n if(Data_type=='Bulk RNAseq') { \n gene_id_column='Gene'\n }else if(Data_type=='Proteomics'){\n gene_id_column='FeatureID'\n }\n print(paste0(\"genes with duplicate IDs in \",gene_id_column,\":\"))\n \n raw_counts_matrix[duplicated(raw_counts_matrix[,gene_name_column_to_use_for_collapsing_duplicates]),gene_name_column_to_use_for_collapsing_duplicates]%>%unique()%>%as.character()%>%write( stdout())\n \n\n }else if(split_gene_name==T&grepl('Feature_id_1',colnames(raw_counts_matrix))==T){ \n print(paste0(\"genes with duplicate IDs in \",'Feature_id_1',\":\"))\n \n raw_counts_matrix[duplicated(raw_counts_matrix[,'Feature_id_1']),'Feature_id_1']%>%unique()%>%as.character()%>%write( stdout())\n\n print(paste0(\"genes with duplicate IDs in \",'Feature_id_2',\":\"))\n \n raw_counts_matrix[duplicated(raw_counts_matrix[,'Feature_id_2']),'Feature_id_2']%>%unique()%>%as.character()%>%write( stdout())\n\n }\n }\n\n\n\n\n\n\nif(aggregate_rows_with_duplicate_gene_names == TRUE){\n\n print(\"Aggregating the counts for the same ID in different chromosome locations.\")\n print(\"Column used to Aggregate duplicate IDs: \")\n print(gene_name_column_to_use_for_collapsing_duplicates)\n print(\"Number of rows before Collapse: \")\n print(nrow(raw_counts_matrix))\n\n if(sum(duplicated(raw_counts_matrix[,gene_name_column_to_use_for_collapsing_duplicates]))!=0){\n print(\"\")\n print(\"Duplicate IDs: \")\n print(raw_counts_matrix[duplicated(raw_counts_matrix[,gene_name_column_to_use_for_collapsing_duplicates]),gene_name_column_to_use_for_collapsing_duplicates]%>%as.character%>%unique)\n\n dfagg=raw_counts_matrix[,c(gene_name_column_to_use_for_collapsing_duplicates,nums)]%>%group_by_at(gene_name_column_to_use_for_collapsing_duplicates)%>%summarise_all(sum)\n\n if (ncol(raw_counts_matrix[,!names(raw_counts_matrix) %in% nums, drop = FALSE])>1) {\n ## collapse non-numeric columns\n dfagg2=raw_counts_matrix[,!names(raw_counts_matrix) %in% nums]%>%group_by_at(gene_name_column_to_use_for_collapsing_duplicates)%>%summarise_all(paste,collapse=',')\n \n dfagg=merge(dfagg2,dfagg,by=eval(gene_name_column_to_use_for_collapsing_duplicates),sort = F)%>%as.data.frame()\n }\n dfout=dfagg\n print(\"Number of rows after Collapse: \")\n print(nrow(dfout))\n }else{\n print(paste0(\"no duplicated IDs in \",gene_name_column_to_use_for_collapsing_duplicates))\n dfout=raw_counts_matrix\n }\n}else{\n if(gene_name_column_to_use_for_collapsing_duplicates!=\"\"){\n print(\"\")\n print(paste0(\"Duplicate IDs in \",gene_name_column_to_use_for_collapsing_duplicates,\" Column:\"))\n print(raw_counts_matrix[duplicated(raw_counts_matrix[,gene_name_column_to_use_for_collapsing_duplicates]),gene_name_column_to_use_for_collapsing_duplicates]%>%as.character%>%unique)\n }\n \n print(\"\")\n print(paste0(\"If you desire to Aggregate row feature information select appropriate Column to use for collapsing duplicates\"))\n\n dfout=raw_counts_matrix}\n\nreturn(dfout)\n} \n \n\n#################################################\n## Global imports and functions included below ##\n#################################################\n\n# Functions defined here will be available to call in\n# the code for any table.\n\n#install_bioconductor_package <- function(pkg) {\n# install.packages(paste0(\"https://gypsum.palantircloud.com/assets/dyn/bioconductor-packages/\", pkg, \".tar.gz\"), repos=NULL)\n", - "columns": [ - { - "key": "Feature_ID_Column", - "displayName": "Feature ID Column", - "description": "Select a column from your raw counts that contains Feature IDs for each row.\n\nIf this column contains special character (| - , or space) separating multiple gene identifiers, then the column will be split into separate columns for each identifier.\n\nExample: a column with gene identifiers initially listed like \"ENSG00000000003.14_TSPAN6\" will be divided into two columns, one for the Ensemble ID (e.g. \"ENSG00000000003.14\") and another for the Gene Name (e.g. \"TSPAN6\").", - "paramGroup": "Basic", - "sourceDataset": "Raw_Counts_Matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - } - ], - "condaDependencies": [], - "description": "This template checks the input raw counts matrix for common formatting problems with Feature identifiers (Gene or Peptide/Protein Names) and sample names. \n\nIf Feature IDs contain multiple IDs separated by special Characters((| - , or space) they will be split into multiple columns. \n\nIf Duplicate Feature ID's are detected the counts are summed across duplicate Feature ID rows within each sample.\n\nInvalid sample names will also be reported in the template Log and can be automatically corrected. If your sample names are corrected here, be sure to make equivalent changes to your metadata table.", - "externalId": "Clean_Raw_Counts_CCBR_", - "inputDatasets": [ - { - "key": "Raw_Counts_Matrix", - "displayName": "Raw Counts Matrix", - "description": "The input dataset of raw counts.", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - } - ], - "vectorLanguage": "R", - "codeLanguage": "R", - "parameters": [ - { - "key": "data_type", - "displayName": "data type", - "description": "", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "Bulk RNAseq", - "Proteomics" - ], - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Samples_to_Rename", - "displayName": "Samples to Rename", - "description": "Enter each sample that you want to rename in the format:\n\nold_name: new_name", - "paramType": "VECTOR", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "c(\"\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Cleanup_Column_Names", - "displayName": "Cleanup Column Names", - "description": "Invalid raw counts column names can cause errors in the downstream analysis. If this toggle is ON, any invalid column names will be automatically altered to a correct format.\n\nThese format changes will include adding an \"X\" as the first character in any column name that began with a numeral and replacing some special characters (\"-,:. \") with underscores (\"_\"). Invalid sample names and any changes made will be detailed in the template log.", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Split_Feature_ID", - "displayName": "Split Feature ID", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Aggregate_Rows_with_Duplicate_Feature_Names", - "displayName": "Aggregate Rows with Duplicate Feature Names", - "description": "Regardless of the toggle status (ON/OFF), if a Feature ID (from the \"Cleanup Column Names\" parameter above) is found to be duplicated on multiple rows of the raw counts, the Log will report these Feature IDs.\n\nUsing the default behavior (ON), the counts for all rows with a duplicate Feature IDs are aggregated into a single row. Counts are summed across duplicate Feature ID rows within each sample. Additional identifier columns, if present (e.g. Ensembl IDs), will be preserved and multiple matching identifiers in such additional columns will appear as comma-separated values in an aggregated row.", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Column_Used_to_Aggregate_Duplicates_Feature_IDs", - "displayName": "Column Used to Aggregate Duplicates Feature IDs", - "description": "Select the column with Feature IDs to use as grouping elements to collapse the counts matrix.\n\nThe log output will list the columns available to identify duplicate row IDs in order to aggregate information. \n\nIf Bulk RNAseq data your column selected for Feature ID will be renamed to \"Gene\" \nIf analyzing Proteomics data your column selected for Feature ID will be renamed to \"Feature ID\".\n\nIf left blank your \"Feature ID\" Column will be used to Aggregate Rows.\n\nIf \"Feature ID\" column can be split into multiple IDs the non Ensembl ID name will be used to aggregate duplicate IDs.\nIf \"Feature ID\" column does not contain Ensembl IDs the split Feature IDs will be named 'Feature_id_1' and 'Feature_id_2'. For this case the Template will error out and you will have to manually enter Column ID for this field.", - "paramType": "STRING", - "paramGroup": "Advanced", - "paramValues": [ - "Gene", - "Pepetide", - "Protein", - "Ensembl_ID", - "Ensembl_ID_version", - "Gene_id_1", - "Gene_id_2", - "Original Gene Column" - ], - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "title": "Clean Raw Counts [CCBR]", - "templateApiVersion": "0.1.0" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/DEG_Analysis_CCBR_.code-template.json b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/DEG_Analysis_CCBR_.code-template.json deleted file mode 100644 index cbc29a8..0000000 --- a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/DEG_Analysis_CCBR_.code-template.json +++ /dev/null @@ -1,153 +0,0 @@ -{ - "codeTemplate": "DEG_Analysis <- function({{{Counts_Matrix}}}, {{{Sample_Metadata}}}) {\n \n ## --------- ##\n ## Libraries ##\n ## --------- ##\n \n library(limma)\n library(tidyverse)\n library(edgeR)\n library(stringr)\n library(grid)\n library(gridExtra)\n \n\n ## -------------------------------- ##\n ## User-Defined Template Parameters ##\n ## -------------------------------- ##\n\n #Basic Parameters:\n counts_matrix <- {{{Counts_Matrix}}} \n sample_metadata <- {{{Sample_Metadata}}}\n gene_names_column=\"{{{Feature_Gene_Names_Column}}}\"\n sample_name_column<-\"{{{Sample_Names_Column}}}\"\n columns_to_include = {{{Columns_to_Include}}}\n contrast_variable_column<-{{{Contrast_Variable_Column}}}\n contrasts<-{{{Contrasts}}}\n covariates_columns={{{Covariates_Column_s_}}}\n\n #Advanced Parameters:\n input_in_log_counts <- {{{input_in_log_counts}}}\n return_mean_and_sd<-{{{return_mean_and_sd}}}\n return_normalized_counts<-{{{Return_Normalized_Counts}}}\n normalization_method<-\"{{{Normalization_Method}}}\"\n \n ##--------------- ##\n ## Error Messages ##\n ## -------------- ##\n\n if(make.names(colnames(counts_matrix))!=colnames(counts_matrix)){\n print(\"Error: The following counts matrix column names are not valid:\\n\")\n print(colnames(counts_matrix)[make.names(colnames(counts_matrix))!=colnames(counts_matrix)])\n\n print(\"Likely causes are columns starting with numbers or other special characters eg spaces.\")\n stop(\"Bad column names.\")\n }\n \n ## --------------- ##\n ## Main Code Block ##\n ## --------------- ##\n \n samples_to_include=columns_to_include[columns_to_include%in%sample_metadata[,sample_name_column,drop=T]]\n anno_col=columns_to_include[columns_to_include%in%sample_metadata[,sample_name_column,drop=T]==F]\n\n samples_to_include <- samples_to_include[samples_to_include != gene_names_column]\n samples_to_include <- samples_to_include[samples_to_include != \"Gene\"]\n samples_to_include <- samples_to_include[samples_to_include != \"GeneName\"]\n \n\n ##create unique rownames to correctly add back Annocolumns at end of template\n counts_matrix[,gene_names_column]=paste0(counts_matrix[,gene_names_column],'_',1:nrow(counts_matrix))\n\n anno_col=c(anno_col,gene_names_column)%>%unique\n anno_tbl=counts_matrix[,anno_col,drop=F]%>%as.data.frame\n\n df.m <- counts_matrix[,c(gene_names_column,samples_to_include)]\n gene_names <- NULL\n gene_names$GeneID <- counts_matrix[,gene_names_column]\n \n ### This code block does input data validation\n sample_metadata <- sample_metadata[match(colnames(df.m),sample_metadata[,sample_name_column]),]\n sample_metadata <- sample_metadata[rowSums(is.na(sample_metadata)) != ncol(sample_metadata), ]\n df.m <- df.m[,match(sample_metadata[,sample_name_column],colnames(df.m))]\n \n #Create DGEList object from counts\n if(input_in_log_counts == TRUE){\n x <- DGEList(counts=2^df.m, genes=gene_names)\n } else {\n x <- DGEList(counts=df.m, genes=gene_names) \n }\n \n #Put covariates in order \n covariates_columns=covariates_columns[order(covariates_columns!=contrast_variable_column)]\n \n for(ocv in covariates_columns){\n sample_metadata[,ocv]=gsub(\" \",\"_\",sample_metadata[,ocv])\n }\n\n contrasts=gsub(\" \",\"_\",contrasts)\n cov <- covariates_columns[!covariates_columns %in% contrast_variable_column]\n\n #Combine columns if 2-factor analysis\n if(length(contrast_variable_column)>1){\n sample_metadata %>% dplyr::mutate(contmerge = paste0(.data[[contrast_variable_column[1]]],\".\",.data[[contrast_variable_column[2]]])) -> sample_metadata\n } else {\n sample_metadata %>% dplyr::mutate(contmerge = .data[[contrast_variable_column]]) -> sample_metadata\n }\n\n contrast_var <- factor(sample_metadata$contmerge)\n\n if(length(cov) >0){\n dm.formula <- as.formula(paste(\"~0 +\", paste(\"contmerge\", paste(cov, sep=\"+\", collapse=\"+\"),sep=\"+\")))\n design=model.matrix(dm.formula, sample_metadata)\n colnames(design) <- gsub(\"contmerge\",\"\",colnames(design))\n } else {\n dm.formula <- as.formula(~0 + contmerge)\n design=model.matrix(dm.formula, sample_metadata)\n colnames(design) <- levels(contrast_var)\n }\n\n #colnames(design) <- str_replace_all(colnames(design), contrast_variable_column, \"\")\n \n if (normalization_method %in% c(\"TMM\",\"TMMwzp\",\"RLE\",\"upperquartile\")){\n x <- calcNormFactors(x, method = normalization_method) \n rownames(x) <- x$genes$GeneID\n v <- voom(x,design=design,normalize=\"none\")\n } else {\n v <- voom(x,design=design,normalize=normalization_method,save.plot = TRUE)\n }\n \n rownames(v$E) <- v$genes$GeneID\n as.data.frame(v$E) %>% rownames_to_column(\"Gene\") -> df.voom\n fit <- lmFit(v, design)\n cm <- makeContrasts(contrasts = contrasts, levels=design)\n\n #Print Mean-variance Plot\n sx <- v$voom.xy$x\n sy <- v$voom.xy$y\n xyplot <- as.data.frame(cbind(sx,sy))\n voomline <- as.data.frame(cbind(x=v$voom.line$x,y=v$voom.line$y))\n \n g <- ggplot() +\n geom_point(data=xyplot, aes(x=sx,y=sy),size=1) +\n theme_bw() +\n geom_smooth(data=voomline, aes(x=x,y=y),color = \"red\") +\n ggtitle(\"voom: Mean-variance trend\") +\n xlab(v$voom.xy$xlab) + ylab(v$voom.xy$ylab) + \n theme(axis.title=element_text(size=12),\n plot.title = element_text(size = 14, face = \"bold\",hjust = 0.5))\n\n #Print out sample numbers:\n #\n sampsize <- colSums(design)\n titleval <- \"Please note Sample size:\"\n titletext <- paste(names(sampsize), sampsize, sep = \"=\", collapse = \" \\n \") \n titleall <- paste(titleval,\"\\n\",titletext,\"\\n\\n\\n\")\n\n contrast <- colnames(cm)\n connames <- strsplit(contrast,\"-\")\n connames <- lapply(connames,function(x) {gsub(\"\\\\(\",\"\",gsub(\"\\\\)\",\"\",x))})\n contrastsize <- lapply(connames,function(x) sampsize[unlist(x)])\n footnotetext <- paste(contrast, contrastsize, sep = \" : \", collapse = \"\\n\") \n footnotetext <- paste(\"\\n\\n\\nContrasts:\\n\",footnotetext)\n\n textall <- textGrob(paste0(titleall, footnotetext),gp=gpar(fontsize=10))\n\n\n #Run Contrasts\n fit2 <- contrasts.fit(fit, cm)\n fit2 <- eBayes(fit2)\n logFC = fit2$coefficients\n colnames(logFC)=paste(colnames(logFC),\"logFC\",sep=\"_\")\n tstat = fit2$t\n colnames(tstat)=paste(colnames(tstat),\"tstat\",sep=\"_\")\n FC = 2^fit2$coefficients\n FC = ifelse(FC<1,-1/FC,FC)\n colnames(FC)=paste(colnames(FC),\"FC\",sep=\"_\")\n pvalall=fit2$p.value\n colnames(pvalall)=paste(colnames(pvalall),\"pval\",sep=\"_\")\n pvaladjall=apply(pvalall,2,function(x) p.adjust(x,\"BH\"))\n colnames(pvaladjall)=paste(colnames(fit2$coefficients),\"adjpval\",sep=\"_\")\n\n \n if(return_mean_and_sd == TRUE){\n tve <- t(v$E) \n mean.df <- as.data.frame(tve) %>% rownames_to_column(\"Sample\") %>% dplyr::mutate(group=sample_metadata[sample_metadata[,sample_name_column]==Sample,contrast_variable_column]) %>% group_by(group) %>% summarise_all(funs(mean)) %>% as.data.frame()\n mean.df[,-c(1,2)] %>% as.matrix() %>% t() -> mean\n colnames(mean) <- mean.df[,1]\n colnames(mean)=paste(colnames(mean),\"mean\", sep=\"_\")\n colnames(mean) = gsub(\"\\\\.\", \"_\", colnames(mean))\n \n sd.df <- as.data.frame(tve) %>% rownames_to_column(\"Sample\") %>% dplyr::mutate(group=sample_metadata[sample_metadata[,sample_name_column]==Sample,contrast_variable_column]) %>% group_by(group) %>% summarise_all(funs(sd)) %>% as.data.frame()\n sd.df[,-c(1,2)] %>% as.matrix() %>% t() -> sd\n colnames(sd) <- sd.df[,1]\n colnames(sd)=paste(colnames(sd), \"sd\",sep=\"_\")\n colnames(sd) = gsub(\"\\\\.\", \"_\", colnames(sd))\n finalres=as.data.frame(cbind(mean, sd, FC, logFC, tstat, pvalall, pvaladjall)) \n } else {\n finalres=as.data.frame(cbind(FC, logFC, tstat, pvalall, pvaladjall))\n }\n\n if(return_normalized_counts == TRUE){\n finalres = as.data.frame(cbind(finalres, v$E))\n }\n\n finalres %>% rownames_to_column(\"Gene\") -> finalres\n print(paste0(\"Total number of genes included: \", nrow(finalres)))\n\n\n getgenelists <- function(FClimit,pvallimit,pval){\n upreggenes <- list()\n downreggenes <- list()\n for(i in 1:length(contrasts)){\n if(pval == \"pval\"){\n finalres %>% dplyr::filter(.data[[colnames(FC)[i]]] > FClimit & .data[[colnames(pvalall)[i]]] < pvallimit) %>% pull(Gene) %>% length() -> upreggenes[[i]] \n finalres %>% dplyr::filter(.data[[colnames(FC)[i]]] < -FClimit & .data[[colnames(pvalall)[i]]] < pvallimit) %>% pull(Gene) %>% length() -> downreggenes[[i]] \n } else {\n finalres %>% dplyr::filter(.data[[colnames(FC)[i]]] > FClimit & .data[[colnames(pvaladjall)[i]]] < pvallimit) %>% pull(Gene) %>% length() -> upreggenes[[i]] \n finalres %>% dplyr::filter(.data[[colnames(FC)[i]]] < -FClimit & .data[[colnames(pvaladjall)[i]]] < pvallimit) %>% pull(Gene) %>% length() -> downreggenes[[i]] \n }\n }\n names(upreggenes) <- contrasts\n names(downreggenes) <- contrasts\n allreggenes <- rbind(unlist(upreggenes),unlist(downreggenes))\n rownames(allreggenes) <- c(paste0(\"upreg>\",FClimit, \", \",pval,\"<\",pvallimit),paste0(\"downreg<-\",FClimit, \", \",pval,\"<\",pvallimit))\n return(allreggenes)\n }\n\n\n FCpval1 <- getgenelists(FClimit = 1.2, pvallimit = 0.05,\"pval\")\n FCpval2 <- getgenelists(FClimit = 1.2, pvallimit = 0.01,\"pval\")\n FCadjpval1 <- getgenelists(FClimit = 1.2, pvallimit = 0.05,\"adjpval\")\n FCadjpval2 <- getgenelists(FClimit = 1.2, pvallimit = 0.01,\"adjpval\")\n\n wraplines <- function(y){\n j = unlist(strsplit(y,\"-\"))\n k = strwrap(j, width = 10)\n l = paste(k,collapse=\"\\n-\")\n return(l)\n }\n \n pvaltab <- rbind(FCpval1,FCpval2,FCadjpval1,FCadjpval2)\n colnames(pvaltab) <- sapply(colnames(pvaltab), function(x) wraplines(x))\n table2 <- tableGrob(pvaltab, theme=ttheme_default(base_size = 10))\n table2$layout$clip <- \"off\"\n\n layout <- rbind(c(1,2),\n c(1,2),\n c(3,3))\n \n\n #Printing all together (tables and plot)\n grid.newpage()\n grid.arrange(textall, g, table2, layout_matrix=layout)\n\n #Printing in brand new multiviz\n grid.newpage()\n print(g)\n grid.newpage()\n grid.draw(textall)\n grid.newpage()\n grid.draw(table2)\n\n\n### add back Anno columns and Remove row number from Feature Column\n colnames(finalres)[colnames(finalres)%in%\"Gene\"]=gene_names_column\n\n finalres=merge(anno_tbl,finalres,by=gene_names_column,all.y=T)\n finalres[,gene_names_column]=gsub('_[0-9]+$',\"\",finalres[,gene_names_column])\n\n\n call_me_alias<-colnames(finalres)\n colnames(finalres)<-gsub(\"\\\\(|\\\\)\",\"\", call_me_alias)\n df.final<-createDataFrame(finalres)\n \n return(df.final) \n}\n\n\n\n", - "columns": [ - { - "key": "Feature_Gene_Names_Column", - "displayName": "Feature/Gene Names Column", - "description": "The column from your counts matrix containing the Feature ID (gene names).", - "paramGroup": "Basic", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Sample_Names_Column", - "displayName": "Sample Names Column", - "description": "Column containing sample names", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "Columns_to_Include", - "displayName": "Columns to Include", - "description": "Select the sample columns from the input counts matrix that you want to process. Only numeric columns can be selected.", - "paramGroup": "Basic", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "Contrast_Variable_Column", - "displayName": "Contrast Variable Column", - "description": "The column in the input Sample Metadata that contains the group variables you wish to find differential expression between. User can add up to 2 columns (2-factor analysis)", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "Covariates_Column_s_", - "displayName": "Covariates Column(s)", - "description": "Columns to be used as covariates in linear modeling. Must include column from \"Contrast Variable\". Most commonly your covariate will be group and batch (if you have different batches in your data).", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - } - ], - "condaDependencies": [], - "description": "Performs Differential Expression of Genes (DEG) Analysis.\n\nThis template takes (filtered) raw counts as its input and transforms this count data to log2-counts per million (logCPM). The normalization and DEG analysis is implemented using the Limma Voom R package.\n\nThe returned counts matrix contains normalized counts, not batch corrected counts. The DEG analysis accounts for batch using covariates, however. You can optionally also return mean and standard deviation of normalized expression within groups.\n\nThis template will support up to 2 factors", - "externalId": "DEG_Analysis_CCBR_", - "inputDatasets": [ - { - "key": "Counts_Matrix", - "displayName": "Counts Matrix", - "description": "Input counts dataset having one column for feature (such as gene, isoform, peptide etc) names, and the rest containing counts for each sample. This might be the raw counts file or the low-counts-removed dataset.", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - }, - { - "key": "Sample_Metadata", - "displayName": "Sample Metadata", - "description": "Dataset containing sample group information created during the process of requesting analysis (counts file)", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - } - ], - "vectorLanguage": "R", - "codeLanguage": "R", - "parameters": [ - { - "key": "Contrasts", - "displayName": "Contrasts", - "description": "Specify each contrast in the format group1-group2, e.g. treated-control", - "paramType": "VECTOR", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "input_in_log_counts", - "displayName": "Input in log Counts", - "description": "Set to TRUE if input is in log counts.", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "return_mean_and_sd", - "displayName": "Return Mean and SD", - "description": "if TRUE, return Mean and Standard Deviation of groups in addition to DEG estimates for contrast(s)", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Return_Normalized_Counts", - "displayName": "Return Normalized Counts", - "description": "if TRUE, return normalized counts for samples included in the limma model", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Normalization_Method", - "displayName": "Normalization Method", - "description": "Normalization method to be applied to the logCPM values", - "paramType": "SELECT", - "paramGroup": "Advanced", - "paramValues": [ - "none", - "scale", - "quantile", - "cyclicloess", - "TMM", - "TMMwzp", - "RLE", - "upperquartile" - ], - "defaultValue": "quantile", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "title": "DEG Analysis [CCBR]", - "templateApiVersion": "0.1.0" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/DEG_Gene_List_CCBR_.code-template.json b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/DEG_Gene_List_CCBR_.code-template.json deleted file mode 100644 index ab1578a..0000000 --- a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/DEG_Gene_List_CCBR_.code-template.json +++ /dev/null @@ -1,316 +0,0 @@ -{ - "codeTemplate": "DEGGeneList <- function({{{DEG_Table}}}) {\n\n## This function filters DEG table\n\n## --------- ##\n## Libraries ##\n## --------- ##\n\nlibrary(tidyverse)\nlibrary(dplyr)\nlibrary(tidyselect)\nlibrary(tibble)\nlibrary(ggplot2)\nlibrary(plotrix)\n \n## -------------------------------- ##\n## User-Defined Template Parameters ##\n## -------------------------------- ##\n\n# Input parameters\ndeg_table <- {{{DEG_Table}}} \n\n# Basic parameters\ngene_names_column <- \"{{{Gene_Names_Column}}}\"\nsignificance_column <- \"{{{Significance_Column}}}\"\nsignificance_cutoff <- {{{Significance_Cutoff}}}\nchange_column <- \"{{{Change_Column}}}\"\nchange_cutoff <- {{{Change_Cutoff}}}\nfiltering_mode <- \"{{{Filtering_Mode}}}\"\n\n# Advanced parameters\ninclude_estimates <- {{{Include_Estimates}}}\nround_estimates <- {{{Round_Estimates}}}\nrounding_decimal_for_percent_cells = {{{Rounding_Decimal_for_Percent_Calls}}}\n\n# Filter parameters\ncontrast_filter = \"{{{Contrasts_Filter}}}\"\ncontrasts = {{{Contrasts}}}\ngroups = {{{Groups}}}\ngroups_filter = \"{{{Groups_Filter}}}\"\n\n# Label parameters\nlabel_font_size = {{{Label_Font_Size}}}\nlabel_distance = {{{Label_Distance}}}\n\n# Visualization parameters\ny_axis_expansion = {{{Y_Axis_Expansion}}}\nfill_colors ={{{Fill_Colors_}}}\npie_chart_in_3d = {{{Pie_Chart_in_3D}}}\nbar_width = {{{Bar_Width}}}\ndraw_bar_border = {{{Draw_Bar_Border}}}\nforce_barchart = {{{Force_Barchart}}}\n\n\n## -------------------------------- ##\n## Parameter Misspecifation Errors ##\n## -------------------------------- ##\n\n## -------------------------------- ##\n## Functions ##\n## -------------------------------- ##\n\n## --------------- ##\n## Main Code Block ##\n## --------------- ##\n\n\n## If include_estimates param is empty due to template upgrade,\n## then fill it with default values.\nif (length(include_estimates) == 0){\n include_estimates <- c(\"FC\",\"logFC\",\"tstat\",\"pval\",\"adjpval\")\n}\n## select DEG stat columns\nestimates = paste0(\"_\",include_estimates)\nsignif = paste0(\"_\", significance_column)\nchange = paste0(\"_\", change_column)\ndeg_table <- deg_table %>% dplyr::select(gene_names_column, ends_with(c(estimates, signif, change)))\n\n\ncontrasts_name = deg_table %>% dplyr::select(ends_with(signif)) %>% colnames() \ncontrasts_name = unlist(strsplit(contrasts_name, signif))\nif ( contrast_filter == \"keep\") {\n contrasts_name = intersect(contrasts_name, contrasts) \n} else if ( contrast_filter == \"remove\") {\n contrasts_name = setdiff(contrasts_name, contrasts) \n}\ncontrasts_name = paste0(contrasts_name, \"_\")\n\ngroups_name = deg_table %>% dplyr::select(ends_with(c(\"_mean\",\"_sd\"))) %>% colnames() \ngroups_name = unique(gsub(\"_mean|_sd\", \"\", groups_name))\nif ( groups_filter == \"keep\") {\n groups_name = intersect(groups_name, groups) \n} else if ( contrast_filter == \"remove\") {\n groups_name = setdiff(groups_name, groups) \n}\ngroups_name = paste0(groups_name,\"_\")\n\ndeg_table <- deg_table %>% dplyr::select(gene_names_column, starts_with(c(groups_name,contrasts_name)))\n\n## select filter variables\ndatsignif <- deg_table %>% \n dplyr::select(gene_names_column, ends_with(signif)) %>%\n tibble::column_to_rownames(gene_names_column)\ndatchange <- deg_table %>%\n dplyr::select(gene_names_column, ends_with(change)) %>% tibble::column_to_rownames(gene_names_column)\ngenes <- deg_table[,gene_names_column]\n\n## filter genes\nsignificant <- datsignif <= significance_cutoff\nchanged <- abs(datchange) >= change_cutoff\nif (filtering_mode == \"in any contrast\") {\n selgenes <- apply(significant & changed, 1, any)\n select_genes <- genes[selgenes]\n } else {\n selgenes <- apply(significant & changed, 1, all)\n select_genes <- genes[selgenes]\n \n}\n# stop if 0 genes selected with the selection criteria\nif (length(select_genes) == 0) {\n stop(\"ERROR: Selection criteria select no genes - change stringency of the Significance cutoff and/or Change cutoff parameters\")\n}\ncat(sprintf(\"Total number of genes selected with %s ≤ %g and |%s| < %g is %g\", significance_column, significance_cutoff, change_column, change_cutoff, sum(selgenes)))\n\n\n##.output dataset\nout <- deg_table %>% dplyr::filter(get(gene_names_column) %in% select_genes)\nif (round_estimates) {\n out <- out %>% mutate_if(is.numeric, ~signif(., 3))\n}\n\n## do plot\nsignificant <- apply( datsignif, 2, function(x) x <= significance_cutoff ) \nchanged <- apply( datchange, 2, function(x) abs(x) >= change_cutoff )\ndd <- significant & changed\nif (draw_bar_border){\n bar_border = 'black'\n} else {\n bar_border = NA\n}\n\n## If fill_colors is blank due to template upgrade, then\n## give it default values.\nif(length(fill_colors) == 0){\n fill_colors <- c(\"steelblue1\",\"whitesmoke\")\n}\n\nif (filtering_mode == \"in any contrast\") {\n say_contrast = paste(colnames(dd), collapse=\" | \")\n say_contrast = gsub(\"_pval|_adjpval\",\"\", say_contrast)\n\nVar2df <- reshape2::melt(apply(dd, 2, table))\nif (\"L1\" %in% names(Var2df)) {\n Var2df <- Var2df %>%\n rename(Var2 = L1)\n}\n\n tab <- Var2df %>% \n dplyr::mutate(Significant=ifelse(Var1, \"TRUE\", \"FALSE\")) %>% \n dplyr::mutate(Significant=factor(Significant, levels=c(\"TRUE\",\"FALSE\")), Count=value, Count_format=format(round(value, 1), nsmall=0, big.mark=\",\")) %>% \n dplyr::mutate(Var2=gsub(\"_pval|_adjpval\", \"\", Var2)) %>%\n group_by(Var2) %>% \n dplyr::mutate(Percent=round(Count / sum(Count)*100,rounding_decimal_for_percent_cells)) %>% \n dplyr::mutate(Label=sprintf(\"%s (%g%%)\", Count_format, Percent))\n\n pp <- ggplot(tab, aes(x=\"\", y=Count, labels=Significant, fill=Significant)) +\n geom_col(width=bar_width, position=\"dodge\", col=bar_border) + facet_wrap(~Var2) +\n scale_fill_manual(values=fill_colors) + theme_bw(base_size=20) +\n xlab(\"Contrast\") + ylab(\"Number of Genes\") +\n geom_text(aes(label=Label), color=c(\"black\"), size=label_font_size, position=position_dodge(width=bar_width), vjust=-label_distance) +\n theme(axis.ticks.x=element_blank(), axis.text.x=element_blank()) +\n ggtitle(sprintf(\"%s<%g & |%s|>%g %s\", significance_column, significance_cutoff, change_column, change_cutoff, filtering_mode)) + \n theme(legend.key.size = unit(3,\"line\"), legend.position='top') +\n theme(panel.grid.major.x = element_blank(), panel.grid.minor.x = element_blank()) +\n theme(strip.background = element_blank(), strip.text = element_text(size=26)) +\n xlab(\"\") + \n scale_y_continuous(name=\"\", expand=c(y_axis_expansion, 0))\nprint(pp) \n\n} else {\n \n say_contrast = paste(colnames(dd), collapse=\" & \")\n say_contrast = gsub(\"_pval|_adjpval\",\"\", say_contrast)\n dd <- apply(dd, 1, function(x) all(x==TRUE))\n \n if (force_barchart) {\n dd = data.frame(dd) \n colnames(dd) = say_contrast \n tab <- reshape2::melt(apply(dd, 2, table)) %>% \n dplyr::mutate(Significant=ifelse(Var1, \"TRUE\", \"FALSE\")) %>% \n dplyr::mutate(Significant=factor(Significant, levels=c(\"TRUE\",\"FALSE\")), Count=value, Count_format=format(round(value, 1), nsmall=0, big.mark=\",\")) %>% \n group_by(Var2) %>% \n dplyr::mutate(Percent=round(Count / sum(Count)*100,rounding_decimal_for_percent_cells)) %>% \n dplyr::mutate(Label=sprintf(\"%s (%g%%)\", Count_format, Percent))\n\n pp <- ggplot(tab, aes(x=\"\", y=Count, labels=Significant, fill=Significant)) +\n geom_col(width=bar_width, position=\"dodge\", col=bar_border) + facet_wrap(~Var2) +\n scale_fill_manual(values=fill_colors) + theme_bw(base_size=20) +\n xlab(\"Contrast\") + ylab(\"Number of Genes\") +\n geom_text(aes(label=Label), color=c(\"black\"), size=label_font_size, position=position_dodge(width=bar_width), vjust=-label_distance) +\n theme(axis.ticks.x=element_blank(), axis.text.x=element_blank()) +\n ggtitle(sprintf(\"%s<%g & |%s|>%g %s\", significance_column, significance_cutoff, change_column, change_cutoff, filtering_mode)) + \n theme(legend.key.size = unit(3,\"line\"), legend.position='top') +\n theme(panel.grid.major.x = element_blank(), panel.grid.minor.x = element_blank()) +\n theme(strip.background = element_blank(), strip.text = element_text(size=26)) +\n xlab(\"\") + \n scale_y_continuous(name=\"\", expand=c(y_axis_expansion, 0))\nprint(pp) \n } else {\n \n N = c( sum(dd), length(dd)-sum(dd))\n Nk = format(round(as.numeric(N), 1), nsmall=0, big.mark=\",\")\n P = round(N/sum(N)*100,rounding_decimal_for_percent_cells)\n if (label_font_size > 0) {\n labs = c(sprintf(\"Significant\\n%s (%g%%)\", Nk[1], P[1]) , sprintf(\"Non-Significant\\n%s (%g%%)\", Nk[2], P[2]))\n } else { \n labs = NULL\n }\n if (pie_chart_in_3d) {\n pie3D(N, radius=0.8, height=0.06, col = fill_colors, theta=0.9, start=0, explode=0, labels=labs, labelcex=label_font_size, shade=0.7, sector.order=1:2, border=FALSE)\n title(main=sprintf(\"%s<%g & |%s|>%g %s: %s\", significance_column, significance_cutoff, change_column, change_cutoff, filtering_mode, say_contrast), cex.main=4, line=-2)\n } else {\n labs = gsub(\"\\n\", \": \", labs)\n pie3D(N, radius=0.8, height=0.06, col = fill_colors, theta=0.9, start=45, explode=0, labels=labs, labelcex=label_font_size, shade=0.7, sector.order=1:2, border=NULL)\n title(main=sprintf(\"%s<%g & |%s|>%g %s: %s\", significance_column, significance_cutoff, change_column, change_cutoff, filtering_mode, say_contrast), cex.main=4, line=-2)\n }\n}\n\n} \n\nreturn(out)\n \n}\n\n#################################################\n## Global imports and functions included below ##\n#################################################\n\n# Functions defined here will be available to call in the code for any table.\n\n#######################\n## End of Template ##\n#######################", - "columns": [ - { - "key": "Gene_Names_Column", - "displayName": "Gene Names Column", - "description": "The column from your input DEG Table containing the gene names. This is usually the first column of your input DEG Table. Only columns of Text type from your input DEG Table will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - } - ], - "condaDependencies": [], - "description": "Outputs dataset of significant genes from DEG table; filters genes based on statistical significance (p-value or adjusted p-value) and change (fold change, log2 fold change, or t-statistic); in addition allows for selection of DEG estimates and for sub-setting of contrasts and groups included in the output gene list.", - "externalId": "DEG_Gene_List_CCBR_", - "inputDatasets": [ - { - "key": "DEG_Table", - "displayName": "DEG Table", - "description": "", - "paramGroup": null, - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - } - ], - "vectorLanguage": "R", - "codeLanguage": "R", - "parameters": [ - { - "key": "Significance_Column", - "displayName": "Significance Column", - "description": "", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "adjpval", - "pval" - ], - "defaultValue": "adjpval", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Significance_Cutoff", - "displayName": "Significance Cutoff", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "0.01", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Change_Column", - "displayName": "Change Column", - "description": "", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "FC", - "logFC", - "tstat" - ], - "defaultValue": "logFC", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Change_Cutoff", - "displayName": "Change Cutoff", - "description": "Absolute value of the cutoff; default cutoff set to 1 in log2 scale (2-fold change)", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Filtering_Mode", - "displayName": "Filtering Mode", - "description": "", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "in any contrast", - "in all contrasts" - ], - "defaultValue": "in any contrast", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Include_Estimates", - "displayName": "Include Estimates", - "description": "", - "paramType": "MULTISELECT", - "paramGroup": "Advanced", - "paramValues": [ - "mean", - "sd", - "FC", - "logFC", - "tstat", - "pval", - "adjpval" - ], - "defaultValue": "c(\"FC\",\"logFC\",\"tstat\",\"pval\",\"adjpval\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Round_Estimates", - "displayName": "Round Estimates", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Contrasts_Filter", - "displayName": "Contrasts Filter", - "description": "", - "paramType": "SELECT", - "paramGroup": "Filter", - "paramValues": [ - "none", - "keep", - "remove" - ], - "defaultValue": "none", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Contrasts", - "displayName": "Contrasts", - "description": "", - "paramType": "VECTOR", - "paramGroup": "Filter", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Groups_Filter", - "displayName": "Groups Filter", - "description": "", - "paramType": "SELECT", - "paramGroup": "Filter", - "paramValues": [ - "none", - "keep", - "remove" - ], - "defaultValue": "none", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Groups", - "displayName": "Groups", - "description": "", - "paramType": "VECTOR", - "paramGroup": "Filter", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Font_Size", - "displayName": "Label Font Size", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "6", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Distance", - "displayName": "Label Distance", - "description": "Distance of text label from top of a bar", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Y_Axis_Expansion", - "displayName": "Y-Axis Expansion", - "description": "multiplicative expansion of y-axis limits; increase/decrease this number if the text label above the bar requires more/less space", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "0.08", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Fill_Colors_", - "displayName": "Fill Colors ", - "description": "", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "aliceblue", - "antiquewhite4", - "darkorange", - "gold", - "red3", - "springgreen", - "steelblue1", - "blue2", - "violetred3", - "whitesmoke", - "gray60", - "gray90", - "black", - "white" - ], - "defaultValue": "c(\"steelblue1\",\"whitesmoke\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Pie_Chart_in_3D", - "displayName": "Pie Chart in 3D", - "description": "If TRUE, a 3D Pie chart is plotted with 'Filtering mode' set to 'in all contrasts', if FALSE, a 2D chart will be plotted for this filtering mode.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Bar_Width", - "displayName": "Bar Width", - "description": "Bar width in the bar chart plotted with Filtering mode set to 'in any contrast'", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "0.4", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Draw_Bar_Border", - "displayName": "Draw Bar Border", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Force_Barchart", - "displayName": "Force Barchart", - "description": "applies only to 'Filtering mode' set to 'in all contrasts'; if TRUE, bar chart instead of pie chart is plotted", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Rounding_Decimal_for_Percent_Calls", - "displayName": "Rounding Decimal for Percent Calls", - "description": "applies to display of percent significant and non-significant calls", - "paramType": "NUMBER", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "0", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "title": "DEG Gene List [CCBR]", - "templateApiVersion": "0.1.0" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Expression_Heatmap_CCBR_.code-template.json b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Expression_Heatmap_CCBR_.code-template.json deleted file mode 100644 index 4f27bd6..0000000 --- a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Expression_Heatmap_CCBR_.code-template.json +++ /dev/null @@ -1,571 +0,0 @@ -{ - "codeTemplate": "L2P_Heatmap <- function({{{Counts_Matrix}}},{{{Sample_Metadata}}}) {\n ## This function uses pheatmap to draw a heatmap, scaling first by rows\n ## (with samples in columns and genes in rows)\n\n ## --------- ##\n ## Libraries ##\n ## --------- ##\n\n library(colorspace)\n library(dendsort)\n library(ComplexHeatmap)\n library(dendextend)\n library(tibble)\n library(stringr)\n library(RColorBrewer)\n library(dplyr)\n library(grid)\n library(gtable)\n library(gridExtra)\n library(gridGraphics)\n\n ## -------------------------------- ##\n ## User-Defined Template Parameters ##\n ## -------------------------------- ##\n\n #Basic Parameters:\n counts_matrix <- {{{Counts_Matrix}}}\n sample_metadata <- {{{Sample_Metadata}}}\n gene_column_name <- \"{{{Gene_Column_Name}}}\"\n sample_name_column <- \"{{{Sample_Name_Column}}}\"\n sample_label_column = \"{{{Sample_Labels_Column}}}\"\n samples_to_include = {{{Samples_to_Include}}}\n \n #Gene Parameters\n include_all_genes <- {{{Include_All_Genes}}}\n filter_top_genes_by_variance = {{{Filter_Top_Genes_by_Variance}}}\n top_genes_by_variance_to_include <- {{{Top_Genes_by_Variance_to_Include}}}\n specific_genes_to_include_in_heatmap = \"{{{Specific_Genes_to_Include_in_Heatmap}}}\" \n cluster_genes <- {{{Cluster_Genes}}}\n gene_distance_metric <- \"{{{Gene_Distance_Metric}}}\"\n gene_clustering_method <- \"{{{Gene_Clustering_Method}}}\"\n display_gene_dendrograms = {{{Display_Gene_Dendrogram}}}\n display_gene_names <- {{{Display_Gene_Names}}}\n center_and_rescale_expression <- {{{Center_and_Rescale_Expression}}}\n\n\n #Sample Parameters\n cluster_samples <- {{{Cluster_Samples}}}\n arrange_sample_columns <- {{{Arrange_Sample_Columns}}}\n order_by_gene_expression <- {{{Order_by_Gene_Expression}}}\n gene_to_order_columns <- \"{{{Gene_to_Order_Columns}}}\"\n gene_expression_order <- \"{{{Gene_Expression_Order}}}\"\n smpl_distance_metric <- \"{{{Sample_Distance_Metric}}}\"\n smpl_clustering_method <- \"{{{Sample_Clustering_Method}}}\"\ndisplay_smpl_dendrograms <- {{{Display_Sample_Dendrograms}}}\n reorder_dendrogram <- {{{Reorder_Sample_Dendrogram}}}\n reorder_dendrogram_order <- {{{Reorder_Sample_Dendrogram_Order}}}\n display_sample_names <- {{{Display_Sample_Names}}}\n manually_rename_samples <- {{{Manually_Rename_Samples}}}\n samples_to_rename <- {{{Samples_to_Rename}}}\n\n #Annotation\n group_columns <- {{{Group_Columns}}}\n assign_group_colors <- {{{Assign_Group_Colors}}}\n assign_color_to_sample_groups <- {{{Assign_Color_to_Sample_Groups}}}\n group_colors <- {{{Group_Colors}}}\n\n #Visual Parameters:\n heatmap_color_scheme <- \"{{{Heatmap_Color_Scheme}}}\"\n autoscale_heatmap_color <- {{{Autoscale_Heatmap_Color}}}\n set_min_heatmap_color <- {{{Set_Min_Heatmap_Color}}}\n set_max_heatmap_color <- {{{Set_Max_Heatmap_Color}}}\n aspect_ratio <- \"{{{Aspect_Ratio}}}\"\n legend_font_size <- {{{Legend_Font_Size}}} \n gene_name_font_size <- {{{Gene_Name_Font_Size}}}\n sample_name_font_size <- {{{Sample_Name_Font_Size}}}\n display_numbers <- {{{Display_Numbers}}}\n\n #Advanced Parameters\n return_z_scores <- {{{Return_Z_Scores}}}\n\n\n ##--------------- ##\n ## Error Messages ##\n ## -------------- ##\n\n if(include_all_genes == TRUE && filter_top_genes_by_variance == TRUE){\n stop(\"ERROR: Choose only one of 'Include all genes' or 'Filter top genes by variance' as TRUE\")\n }\n\n if((cluster_samples == TRUE && arrange_sample_columns == TRUE) | (arrange_sample_columns == TRUE && order_by_gene_expression == TRUE) | \n (order_by_gene_expression == TRUE && cluster_samples == TRUE)) {\n stop(\"ERROR: Only one of 'Cluster Samples', 'Arrange sample columns', or 'order by gene expression' may be set as TRUE at one time. Leaving all three of these FALSE will result in the sample column order matching the 'Samples to Include'.\") \n }\n\n ## --------- ##\n ## Functions ##\n ## --------- ##\n\n getourrandomcolors<-function(k){\n seed=10\n n <- 2e3\n ourColorSpace <- colorspace::RGB(runif(n), runif(n), runif(n))\n ourColorSpace <- as(ourColorSpace, \"LAB\")\n currentColorSpace <- ourColorSpace@coords\n # Set iter.max to 20 to avoid convergence warnings.\n set.seed(seed)\n km <- kmeans(currentColorSpace, k, iter.max=20)\n return( unname(hex(LAB(km$centers))))\n }\n\n ## Begin pal() color palette function∂:\n pal = function (n, h=c(237, 43), c=100, l=c(70, 90), power=1, fixup=TRUE, gamma=NULL, alpha=1, ...) {\n if (n < 1L) {\n return(character(0L))\n }\n h <- rep(h, length.out = 2L)\n c <- c[1L]\n l <- rep(l, length.out = 2L)\n power <- rep(power, length.out = 2L)\n rval <- seq(1, -1, length = n)\n rval <- hex(\n polarLUV(\n L = l[2L] - diff(l) * abs(rval)^power[2L], \n C = c * abs(rval)^power[1L],\n H = ifelse(rval > 0, h[1L], h[2L])\n ),\n fixup=fixup, ...\n )\n if (!missing(alpha)) {\n alpha <- pmax(pmin(alpha, 1), 0)\n alpha <- format(as.hexmode(round(alpha * 255 + 1e-04)), \n width = 2L, upper.case = TRUE)\n rval <- paste(rval, alpha, sep = \"\")\n }\n return(rval)\n } \n # End pal() color palette function:\n\n ## Begin doheatmap() function:\n doheatmap <- function(dat, clus, clus2, ht, rn, cn, col, dispnum) {\n #require(pheatmap)\n #require(dendsort)\n col.pal <- np[[col]]\n if (FALSE) {\n col.pal = rev(col.pal)\n }\n # Define metrics for clustering\n drows1 <- gene_distance_metric\n dcols1 <- smpl_distance_metric\n minx = min(dat)\n maxx = max(dat)\n if (autoscale_heatmap_color) {\n breaks = seq(minx, maxx, length=100)\n legbreaks = seq(minx, maxx, length=5)\n } else {\n breaks = seq(set_min_heatmap_color, set_max_heatmap_color, length=100)\n legbreaks = seq(set_min_heatmap_color, set_max_heatmap_color, length=5)\n }\n breaks = sapply(breaks, signif, 4)\n legbreaks = sapply(legbreaks, signif, 4)\n # Run cluster method using \n hcrow = hclust(dist(dat), method=gene_clustering_method)\n hc = hclust(dist(t(dat)), method=smpl_clustering_method)\n\n if (FALSE) {\n sort_hclust <- function(...) as.hclust(rev(dendsort(as.dendrogram(...))))\n } else {\n sort_hclust <- function(...) as.hclust(dendsort(as.dendrogram(...)))\n }\n if (clus) {\n colclus <- sort_hclust(hc)\n } else {\n colclus = FALSE\n }\n if (clus2) {\n rowclus <- sort_hclust(hcrow)\n } else {\n rowclus = FALSE\n }\n if (display_smpl_dendrograms) {\n smpl_treeheight <- 25\n } else {\n smpl_treeheight <- 0\n }\n if (display_gene_dendrograms) {\n gene_treeheight <- 25\n } else {\n gene_treeheight <- 0\n }\n hm.parameters <- list(\n dat, \n color=col.pal,\n legend_breaks=legbreaks,\n legend=TRUE,\n scale=\"none\",\n treeheight_col=smpl_treeheight,\n treeheight_row=gene_treeheight,\n kmeans_k=NA,\n breaks=breaks,\n display_numbers=dispnum,\n number_color = \"black\",\n fontsize_number = 8,\n height=80,\n cellwidth = NA, \n cellheight = NA, \n fontsize= legend_font_size, \n fontsize_row=gene_name_font_size,\n fontsize_col=sample_name_font_size,\n show_rownames=rn, \n show_colnames=cn,\n cluster_rows=rowclus, \n cluster_cols=clus,\n clustering_distance_rows=drows1, \n clustering_distance_cols=dcols1,\n annotation_col = annotation_col,\n annotation_colors = annot_col,\n labels_col = labels_col\n )\n mat = t(dat)\n callback = function(hc, mat) {\n dend = rev(dendsort(as.dendrogram(hc)))\n if(reorder_dendrogram == TRUE) {\n dend %>% dendextend::rotate(reorder_dendrogram_order) -> dend\n } else {\n dend %>% dendextend::rotate(c(1:nobs(dend))) \n }\n as.hclust(dend)\n }\n\n ## Make Heatmap\n phm <- do.call(\"pheatmap\", c(hm.parameters, list(clustering_callback=callback)))\n \n }\n # End doheatmap() function.\n\n ## --------------- ##\n ## Main Code Block ##\n ## --------------- ##\n\n ## Build different color spectra options for heatmap:\n np0 = pal(100) \n np1 = diverge_hcl(100, c=100, l=c(30, 80), power=1) # Blue to Red\n np2 = heat_hcl(100, c=c(80, 30), l=c(30, 90), power=c(1/5, 2)) # Red to Vanilla\n np3 = rev(heat_hcl(100, h=c(0, -100), c=c(40, 80), l=c(75, 40), power=1)) # Violet to Pink\n np4 = rev(colorRampPalette(brewer.pal(10, \"RdYlBu\"))(100)) #Red to yellow to blue\n np5 = colorRampPalette(c(\"steelblue\",\"white\", \"red\"))(100) # Steelblue to White to Red\n\n ## Gather list of color spectra and give them names for the GUI to show.\n np = list(np0, np1, np2, np3, np4, np5)\n names(np) = c(\"Default\",\"Blue to Red\",\"Red to Vanilla\",\"Violet to Pink\",\"Bu Yl Rd\",\"Bu Wt Rd\")\n\n ## Parse input counts matrix. Subset by samples.\n df1 <- counts_matrix\n # Swap out Gene Name column name, if it's not 'Gene'.\n if(gene_column_name != \"Gene\"){\n # Drop original Gene column\n df1 = df1[,!(colnames(df1)%in% c(\"Gene\")) ]\n # Rename column to Gene\n colnames(df1)[which(colnames(df1) == gene_column_name)] <- 'Gene'\n }\n # Get sample columns\n samples_to_include <- samples_to_include[samples_to_include != gene_column_name]\n samples_to_include <- samples_to_include[samples_to_include != \"Gene\"]\n samples_to_include <- samples_to_include[samples_to_include != \"GeneName\"]\n\n # Build new counts matrix containing only sample subset chosen by user.\n df1 <- df1[,append(\"Gene\", samples_to_include)]\n df.orig = df1\n df.orig %>% dplyr::group_by(Gene) %>% summarise_all(funs(mean)) -> df\n df.mat = df[ , (colnames(df) != \"Gene\" )] %>% as.data.frame\n #df %>% dplyr::mutate(Gene = stringr::str_replace_all(Gene, \"_\", \" \")) -> df\n row.names(df.mat) <- df$Gene\n rownames(df.mat) <- str_wrap(rownames(df.mat),30) #for really long geneset names\n df.mat <- as.data.frame(df.mat)\n\n ## Subset counts matrix by genes.\n # Toggle to include all genes in counts matrix (in addition to any user-submitted gene list).\n if (include_all_genes == FALSE) {\n # Add user-submitted gene list (optional).\n genes_to_include_parsed = c()\n genes_to_include_parsed = strsplit(specific_genes_to_include_in_heatmap, \" \")[[1]]\n #genes_to_include_parsed = gsub(\"_\",\" \",genes_to_include_parsed)\n df.mat[genes_to_include_parsed,] -> df.final.extra.genes\n if(filter_top_genes_by_variance == TRUE) {\n # Want to filter all genes by variance.\n df.final = as.matrix(df.mat)\n var <- matrixStats::rowVars(df.final)\n df <- as.data.frame(df.final)\n rownames(df) <- rownames(df.final)\n df.final <- df\n df.final$var <- var\n df.final %>% rownames_to_column(\"Gene\") -> df.final \n df.final %>% dplyr::arrange(desc(var)) -> df.final\n df.final.extra.genes = dplyr::filter(df.final, Gene %in% genes_to_include_parsed)\n df.final = df.final[1:top_genes_by_variance_to_include,]\n df.final = df.final[complete.cases(df.final),]\n # Rbind user gene list to variance-filtered gene list and deduplicate.\n df.final <- rbind(df.final, df.final.extra.genes)\n df.final <- df.final[!duplicated(df.final),] \n rownames(df.final) <- df.final$Gene\n df.final$Gene <- NULL\n df.final$var <- NULL\n } else {\n # Want to use ONLY user-provided gene list.\n df.final <- df.final.extra.genes\n df.final <- df.final[!duplicated(df.final),]\n # Order genes in heatmap by user-submitted order of gene names.\n df.final <- df.final[genes_to_include_parsed,]\n #df.final$Gene <- NULL\n }\n } else {\n df.final <- df.mat\n df.final$Gene <- NULL\n }\n \n ## Optionally apply centering and rescaling (default TRUE).\n if (center_and_rescale_expression == TRUE) {\n tmean.scale = t(scale(t(df.final)))\n tmean.scale = tmean.scale[!is.infinite(rowSums(tmean.scale)),]\n tmean.scale = na.omit(tmean.scale)\n } else {\n tmean.scale = df.final\n }\n\n if(order_by_gene_expression == TRUE){\n gene_to_order_columns <- gsub(\" \",\"\",gene_to_order_columns)\n if(gene_expression_order == \"low_to_high\"){\n tmean.scale <- tmean.scale[,order(tmean.scale[gene_to_order_columns,])] #order from low to high \n } else{\n tmean.scale <- tmean.scale[,order(-tmean.scale[gene_to_order_columns,])] #order from high to low \n }\n }\n\n df.final <- as.data.frame(tmean.scale)\n\n ## Parse input sample metadata and add annotation tracks to top of heatmap.\n annot <- sample_metadata\n # Filter to only samples user requests.\n annot=annot %>% dplyr::filter(.data[[sample_name_column]] %in% samples_to_include) \n \n # Arrange sample options.\n if(arrange_sample_columns) {\n annot = annot[match(samples_to_include,annot[[sample_name_column]]),]\n for(x in group_columns){\n annot[,x]= factor(annot[,x],levels=unique(annot[,x])) \n } \n annot = annot %>% dplyr::arrange_(.dots=group_columns,.by_group = TRUE)\n df.final <- df.final[,match(annot[[sample_name_column]],colnames(df.final))] \n }\n \n # Build subsetted sample metadata table to use for figure.\n colorlist <- c(\"#5954d6\",\"#e1562c\",\"#b80058\",\"#00c6f8\",\"#d163e6\",\"#00a76c\",\"#ff9287\",\"#008cf9\",\"#006e00\",\"#796880\",\"#FFA500\",\"#878500\")\n names(colorlist) <- c(\"indigo\",\"carrot\",\"lipstick\",\"turquoise\",\"lavender\",\"jade\",\"coral\",\"azure\",\"green\",\"rum\",\"orange\",\"olive\")\n group_colors <- colorlist[group_colors]\n\n annot %>% dplyr::select(group_columns) -> annotation_col \n annotation_col = as.data.frame(unclass(annotation_col))\n annotation_col[] <- lapply(annotation_col,factor)\n x <- length(unlist(lapply(annotation_col,levels)))\n if(x>length(group_colors)){\n k=x-length(group_colors)\n more_cols<- getourrandomcolors(k) \n group_colors <- c(group_colors, more_cols)\n }\n rownames(annotation_col) <- annot[[sample_label_column]]\n annot_col = list()\n b=1\n i=1\n while (i <= length(group_columns)){\n nam <- group_columns[i]\n grp <- as.factor(annotation_col[,i])\n c <- b+length(levels(grp))-1\n col = group_colors[b:c]\n names(col) <- levels(grp)\n assign(nam,col)\n annot_col = append(annot_col,mget(nam))\n b = c+1\n i=i+1\n }\n\n if(assign_group_colors == TRUE){\n colassign <- assign_color_to_sample_groups\n groupname <- c()\n groupcol <- c() \n for (i in 1:length(colassign)) {\n groupname[i] <- strsplit(colassign[i], \": ?\")[[1]][1]\n groupcol[i] <- strsplit(colassign[i], \": ?\")[[1]][2]\n }\n annot_col[[1]][groupname] <- groupcol\n }\n\n ## Setting labels_col for pheatmap column labels.\n \n ## Set order of columns based on smaple name input\n #colnames(df.final)%>%print\n #df.final=df.final[,c(samples_to_include)]\n\n if (manually_rename_samples == TRUE) {\n # Use user-provided names to rename samples.\n replacements = samples_to_rename\n old <- c()\n new <- c()\n labels_col <- colnames(df.final)\n for (i in 1:length(replacements)) {\n old <- strsplit(replacements[i], \": ?\")[[1]][1]\n new <- strsplit(replacements[i], \": ?\")[[1]][2]\n old=gsub(\"^[[:space:]]+|[[:space:]]+$\",\"\",old)\n new=gsub(\"^[[:space:]]+|[[:space:]]+$\",\"\",new)\n labels_col[labels_col==old]=new \n }\n } else {\n \n #annot=annot[match(colnames(df.final),annot[[sample_name_column]]),]\n #print(annot[[sample_label_column]])\n #print(colnames(df.final))\n #colnames(df.final)=annot[[sample_label_column]]\n\n old=annot[[sample_name_column]]\n new=annot[[sample_label_column]]\n names(old)=new\n df.final=rename(df.final,any_of(old))\n labels_col <- colnames(df.final)\n }\n\n ## Print number of genes to log.\n print(paste0(\"The total number of genes in heatmap: \", nrow(df.final)))\n\n ## Make the final heatmap.\n p <- doheatmap(dat=df.final, clus=cluster_samples, clus2=cluster_genes, ht=50, rn=display_gene_names, cn=display_sample_names, col=heatmap_color_scheme, dispnum=display_numbers)\n p@matrix_color_mapping@name <- \" \"\n p@matrix_legend_param$at <- as.numeric(formatC(p@matrix_legend_param$at, 2))\n p@column_title_param$gp$fontsize <- 10\n print(p)\n\n ## If user sets toggle to TRUE, return Z-scores.\n ## Else return input counts matrix by default (toggle FALSE).\n ## Returned matrix includes only genes & samples used in heatmap.\n if(return_z_scores){\n df.new <- data.frame(tmean.scale) # Convert to Z-scores.\n df.new %>% rownames_to_column(\"Gene\") -> df.new\n return(df.new)\n } else {\n df.final %>% rownames_to_column(\"Gene\") -> df.new\n return(df.new)\n }\n}\n\n\n## ---------------------------- ##\n## Global Imports and Functions ##\n## ---------------------------- ##\n\n## Functions defined here will be available to call in\n## the code for any table.\n\n## --------------- ##\n## End of Template ##\n## --------------- ##\n", - "columns": [ - { - "key": "Gene_Column_Name", - "displayName": "Gene Column Name", - "description": "Column containing gene names.", - "paramGroup": "Data Setup", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Sample_Name_Column", - "displayName": "Sample Name Column", - "description": "Column containing sample names.", - "paramGroup": "Data Setup", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "Sample_Labels_Column", - "displayName": "Sample Labels Column", - "description": "Select column from metadata that contains the sample names that will appear as column names on the heatmap.", - "paramGroup": "Data Setup", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "Samples_to_Include", - "displayName": "Samples to Include", - "description": "Select the sample columns from the input counts matrix that you want to include in the heatmap. Only numeric columns can be selected.", - "paramGroup": "Data Setup", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "NUMBER", - "isMulti": true - }, - { - "key": "Reorder_Sample_Dendrogram_Order", - "displayName": "Reorder Sample Dendrogram Order", - "description": "Reorder the samples (columns) of the dendrogram by name, e.g. “sample2”,“sample3\",“sample1\".", - "paramGroup": "Sample", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "Group_Columns", - "displayName": "Group Columns", - "description": "Columns containing the sample groups for annotation tracks", - "paramGroup": "Annotation", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - } - ], - "condaDependencies": [], - "description": "This template is intended for use with Bulk RNA-seq data. It generates a heatmap for normalized (or batch corrected) RNA-seq data.\n\nThis template takes as input an expression matrix and your sample metadata table. The expression matrix is usually (though not always) going to consist of your normalized or batch corrected counts. It should always have one row per gene, a first column of gene names, and one additional column per sample.\n\nBy default, the samples (i.e. the columns) are allowed to cluster in an unsupervised fashion based on how similar their expression profiles are across the included genes. This can help identify samples that are non clustering with their group as you might expect based on the experimental design.\n\nAgain, by default, the top 500 genes by variance are used, as these are generally going to include those genes that most distinguish your samples from one another. You can change this as well as many other parameters about this heatmap if you explore the advanced options.", - "externalId": "Expression_Heatmap_CCBR_scRNA_seq_Bulk_", - "inputDatasets": [ - { - "key": "Counts_Matrix", - "displayName": "Counts Matrix", - "description": "Input counts dataset should have gene names in the first column and counts values for each sample in the remaining columns. This might be the raw counts dataset, the low-count-genes-removed counts dataset, the voom-normalized counts dataset, or the batch corrected counts dataset.", - "paramGroup": null, - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - }, - { - "key": "Sample_Metadata", - "displayName": "Sample Metadata", - "description": "Dataset containing sample metadata created or modified by using Actions dropdown menu (upper-right) > Enter Sample Metadata. Must include columns for Sample Name, Group, Batch, and Label.", - "paramGroup": null, - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - } - ], - "vectorLanguage": "R", - "codeLanguage": "R", - "parameters": [ - { - "key": "Include_All_Genes", - "displayName": "Include All Genes", - "description": "Set to TRUE if all genes are to be included. Set to FALSE if you want to filter genes by variance and/or provide a list of specific genes that will appear in the heatmap.", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Filter_Top_Genes_by_Variance", - "displayName": "Filter Top Genes by Variance", - "description": "Set to TRUE if you want to only include the top genes by variance. Set to FALSE if you do not want to filter genes by variance.", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Top_Genes_by_Variance_to_Include", - "displayName": "Top Genes by Variance to Include", - "description": "The number of genes to include if filtering genes by variance. This parameter is ignored if \"Filter top genes by variance\" is set to FALSE.", - "paramType": "NUMBER", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "500", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Specific_Genes_to_Include_in_Heatmap", - "displayName": "Specific Genes to Include in Heatmap", - "description": "Enter the gene symbols to be included in the heatmap, with each gene symbol separated with a space from the others. Alternatively, paste in a column of gene names from any spreadsheet application. This parameter is ignored if \"Include all genes\" is set to TRUE.", - "paramType": "STRING", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "None", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Cluster_Genes", - "displayName": "Cluster Genes", - "description": "Choose whether to cluster the rows (genes). If TRUE, rows will have clustering applied. If FALSE, clustering will not be applied to rows.", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Gene_Clustering_Method", - "displayName": "Gene Clustering Method", - "description": "Clustering method metric to be used in clustering samples.", - "paramType": "SELECT", - "paramGroup": "Gene", - "paramValues": [ - "ward.D", - "ward.D2", - "single", - "complete", - "average", - "mcquitty", - "median", - "centroid" - ], - "defaultValue": "average", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Gene_Distance_Metric", - "displayName": "Gene Distance Metric", - "description": "Distance metric to be used in clustering genes.", - "paramType": "SELECT", - "paramGroup": "Gene", - "paramValues": [ - "euclidean", - "maximum", - "manhattan", - "canberra", - "binary", - "minkowski", - "correlation" - ], - "defaultValue": "correlation", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Display_Gene_Dendrogram", - "displayName": "Display Gene Dendrogram", - "description": "Set to TRUE to show gene dendrograms. Set to FALSE to hide dendrograms.", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Display_Gene_Names", - "displayName": "Display Gene Names", - "description": "Set to TRUE to display gene names on the right side of the heatmap. Set to FALSE to hide gene names.", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Center_and_Rescale_Expression", - "displayName": "Center and Rescale Expression", - "description": "Center and rescale expression for each gene across all included samples.", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Cluster_Samples", - "displayName": "Cluster Samples", - "description": "Choose whether to cluster the columns (samples). If TRUE, columns will have clustering applied. If FALSE, clustering will not be applied to columns.", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Arrange_Sample_Columns", - "displayName": "Arrange Sample Columns", - "description": "If TRUE, your samples will be arranged by the order that Groups are found in the \"Samples to Include\" parameter above. If FALSE, and \"Cluster Samples\" is FALSE, and \"Order by Gene Expression is FALSE, then samples will appear in the order of input (Samples to Include).", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Order_by_Gene_Expression", - "displayName": "Order by Gene Expression", - "description": "If TRUE, set gene name below and direction for ordering", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Gene_to_Order_Columns", - "displayName": "Gene to Order Columns", - "description": "Gene to order columns by expression levels", - "paramType": "STRING", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": " ", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Gene_Expression_Order", - "displayName": "Gene Expression Order", - "description": "Choose direction for gene order", - "paramType": "SELECT", - "paramGroup": "Sample", - "paramValues": [ - "low_to_high", - "high_to_low" - ], - "defaultValue": "low_to_high", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Sample_Clustering_Method", - "displayName": "Sample Clustering Method", - "description": "Clustering method to be used in clustering samples.", - "paramType": "SELECT", - "paramGroup": "Sample", - "paramValues": [ - "ward.D", - "ward.D2", - "single", - "complete", - "average", - "mcquitty", - "median", - "centroid" - ], - "defaultValue": " ", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Sample_Distance_Metric", - "displayName": "Sample Distance Metric", - "description": "Distance metric to be used in clustering samples.", - "paramType": "SELECT", - "paramGroup": "Sample", - "paramValues": [ - "euclidean", - "maximum", - "manhattan", - "canberra", - "binary", - "minkowski", - "correlation" - ], - "defaultValue": "correlation", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Display_Sample_Dendrograms", - "displayName": "Display Sample Dendrograms", - "description": "Set to TRUE to show sample dendrograms. Set to FALSE to hide dendrogram.", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Reorder_Sample_Dendrogram", - "displayName": "Reorder Sample Dendrogram", - "description": "If TRUE, set the order of the dendrogram (below)", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Display_Sample_Names", - "displayName": "Display Sample Names", - "description": "Set to TRUE if you want sample names to be displayed on the plot. Set to FALSE to hide sample names.", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Manually_Rename_Samples", - "displayName": "Manually Rename Samples", - "description": "Set to TRUE if you'd like to manually rename the sample names.", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Samples_to_Rename", - "displayName": "Samples to Rename", - "description": "Enter each sample to rename in the format:\n\nold_name: new_name\n\nThis parameter is ignored if \"Manually rename samples\" is set to FALSE.", - "paramType": "VECTOR", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "c(\"\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Assign_Group_Colors", - "displayName": "Assign Group Colors", - "description": "If TRUE, set the groups assigned colors (below)", - "paramType": "BOOLEAN", - "paramGroup": "Annotation", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Assign_Color_to_Sample_Groups", - "displayName": "Assign Color to Sample Groups", - "description": "Enter each sample to color in the format: group_name: color This parameter is ignored if \"Assign Colors\" is set to FALSE. Use this link to select colors: https://nidap.nih.gov/workspace/preview-app/ri.blobster.main.pdf.7922ce2b-39d7-40e7-85ea-8b8146bbf363", - "paramType": "VECTOR", - "paramGroup": "Annotation", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Group_Colors", - "displayName": "Group Colors", - "description": "Set group annotation colors.", - "paramType": "MULTISELECT", - "paramGroup": "Annotation", - "paramValues": [ - "indigo", - "carrot", - "lipstick", - "turquoise", - "lavender", - "jade", - "coral", - "azure", - "green", - "rum", - "orange", - "olive" - ], - "defaultValue": "c(\"indigo\",\"carrot\",\"lipstick\",\"turquoise\",\"lavender\",\"jade\",\"coral\",\"azure\",\"green\",\"rum\",\"orange\",\"olive\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Heatmap_Color_Scheme", - "displayName": "Heatmap Color Scheme", - "description": "Color scheme for heatmap.", - "paramType": "SELECT", - "paramGroup": "Visual", - "paramValues": [ - "Default", - "Blue to Red", - "Red to Vanilla", - "Violet to Pink", - "Bu Yl Rd", - "Bu Wt Rd" - ], - "defaultValue": "Default", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Autoscale_Heatmap_Color", - "displayName": "Autoscale Heatmap Color", - "description": "Set to TRUE to autoscale the heatmap colors between the maximum and minimum heatmap color parameters. If FALSE, set the heatmap colors between \"Set max heatmap color\" and \"Set min heatmap color\" (below).", - "paramType": "BOOLEAN", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Set_Max_Heatmap_Color", - "displayName": "Set Max Heatmap Color", - "description": "If Autoscale heatmap color is set to FALSE, set the maximum heatmap z-score value.", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Set_Min_Heatmap_Color", - "displayName": "Set Min Heatmap Color", - "description": "If Autoscale heatmap color is set to FALSE, set the minimum heatmap z-score value.", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "-2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Aspect_Ratio", - "displayName": "Aspect Ratio", - "description": "Set figure Aspect Ratio. Ratio refers to entire figure including legend. If set to Auto figure size is based on number of rows and columns form counts matrix. default - Auto", - "paramType": "STRING", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "Auto", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Display_Numbers", - "displayName": "Display Numbers", - "description": "Setting to FALSE (default) will not display numerical value of heat on heatmap. Set to TRUE if you want to see these numbers on the plot.", - "paramType": "BOOLEAN", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Gene_Name_Font_Size", - "displayName": "Gene Name Font Size", - "description": "Font size for gene names. If you don't want gene labels to show, toggle \"Display Gene Names\" below to FALSE", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "4", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Legend_Font_Size", - "displayName": "Legend Font Size", - "description": "Set Font size for figure legend. Default is 10.", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "10", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Sample_Name_Font_Size", - "displayName": "Sample Name Font Size", - "description": "Font size for sample names. If you don't want to display samples names, toggle \"Display sample names\" (below) to FALSE", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "8", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Return_Z_Scores", - "displayName": "Return Z-Scores", - "description": "Toggle is OFF by default, which returns the expression dataset that was the input for the heatmap. However, sometimes you want the Z-scores that are calculated to draw this specific heatmap. To return the Z-scores instead of the expression values, switch this toggle to ON.", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "title": "Expression Heatmap [CCBR] [scRNA-seq] [Bulk]", - "templateApiVersion": "0.1.0" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Filter_Low_Counts_CCBR_.code-template.json b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Filter_Low_Counts_CCBR_.code-template.json deleted file mode 100644 index 66fa2bf..0000000 --- a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Filter_Low_Counts_CCBR_.code-template.json +++ /dev/null @@ -1,419 +0,0 @@ -{ - "codeTemplate": "unnamed <- function({{{counts_matrix}}}, {{{Sample_Metadata}}}) {\n \n ## --------- ##\n ## Libraries ##\n ## --------- ##\n\n library(limma)\n library(amap)\n library(colorspace)\n library(dendsort)\n library(dplyr)\n library(edgeR)\n library(ggplot2)\n library(gplots)\n library(gridExtra)\n library(gridGraphics)\n library(lattice)\n library(magrittr)\n library(plotly)\n library(RColorBrewer)\n library(RCurl)\n library(reshape2)\n library(stringr)\n library(tidyverse)\n library(tibble)\n\n\n ## -------------------------------- ##\n ## User-Defined Template Parameters ##\n ## -------------------------------- ##\n \n #Basic Parameters:\n counts_matrix = {{{counts_matrix}}}\n sample_metadata <- {{{Sample_Metadata}}} \n gene_names_column <- \"{{{Feature_ID_Column}}}\"\n columns_to_include <- {{{Columns_to_Include}}}\n sample_names_column <- \"{{{Sample_Names_Column}}}\"\n groups_column <- \"{{{Groups_Column}}}\"\n labels_column <- \"{{{Labels_Column}}}\"\n\n\n #Filtering Parameters:\n outlier_samples_to_remove <- {{{Outlier_Samples_to_Remove}}}\n use_cpm_counts_to_filter <- {{{Use_CPM_Counts_to_filter}}}\n Minimum_Count_Value_to_be_Considered_Nonzero <- {{{Minimum_Count_Value_to_be_Considered_Nonzero}}}\n Minimum_Number_of_Samples_with_Nonzero_Counts_in_Total <- {{{Minimum_Number_of_Samples_with_Nonzero_Counts_in_Total}}}\n Use_Group_Based_Filtering <- {{{Use_Group_Based_Filtering}}}\n Minimum_Number_of_Samples_with_Nonzero_Counts_in_a_Group <- {{{Minimum_Number_of_Samples_with_Nonzero_Counts_in_a_Group}}}\n \n #PCA Parameters:\n principal_component_on_x_axis<-{{{Principal_Component_on_X_axis}}} \n principal_component_on_y_axis<-{{{Principal_Component_on_Y_axis}}} \n legend_position_for_PCA <- \"{{{Legend_Position_for_PCA}}}\"\n point_size_for_pca<-{{{Point_Size_for_PCA}}}\n add_labels_to_PCA <- {{{Add_Labels_to_PCA}}}\n label_font_size <- {{{Label_Font_Size_for_PCA}}}\n label_offset_y_ <- {{{Label_Offset_Y_}}}\n label_offset_x_ <- {{{Label_Offset_x_}}}\n samples_to_rename_manually <- {{{Samples_to_Rename_Manually_on_PCA}}}\n\n #Histogram Parameters:\n color_histogram_by_group <- {{{Color_Histogram_by_Group}}} \n set_min_max_for_x_axis_for_histogram <- {{{Set_Min_Max_for_X_axis_for_Histogram}}}\n minimum_for_x_axis_for_histogram <- {{{Minimum_for_X_axis_for_Histogram}}}\n maximum_for_x_axis_for_histogram <- {{{Maximum_for_X_axis_for_Histogram}}}\n legend_position_for_histogram <- '{{{Legend_Position_for_Histogram}}}'\n legend_font_size_for_histogram <- {{{Legend_Font_Size_for_Histogram}}}\n number_of_histogram_legend_columns <- {{{Number_of_Histogram_Legend_Columns}}}\n\n\n #Visualization Parameters:\n colors_for_plots <- {{{Colors_for_Plots}}}\n number_of_image_rows <- {{{Number_of_Image_Rows}}}\n interactive_plots <- {{{Interactive_Plots}}}\n\n #TCGA:\n plot_correlation_matrix_heatmap <- {{{Plot_Correlation_Matrix_Heatmap}}}\n \n ##--------------- ##\n ## Error Messages ##\n ## -------------- ##\n\n \n ## --------- ##\n ## Functions ##\n ## --------- ##\n\n getourrandomcolors<-function(k){\n seed=10\n n <- 2e3\n ourColorSpace <- colorspace::RGB(runif(n), runif(n), runif(n))\n ourColorSpace <- as(ourColorSpace, \"LAB\")\n currentColorSpace <- ourColorSpace@coords\n # Set iter.max to 20 to avoid convergence warnings.\n set.seed(seed)\n km <- kmeans(currentColorSpace, k, iter.max=20)\n return( unname(hex(LAB(km$centers))))\n }\n\n make_heatmap <- function(counts_matrix, metadata,colorval) {\n mat <- as.matrix(counts_matrix) \n tcounts=t(mat)\n tcounts=merge(metadata,tcounts,by.x=sample_names_column,by.y='row.names')\n rownames(tcounts)=tcounts[,labels_column]\n tcounts=tcounts[,!colnames(tcounts)%in%colnames(metadata)]\n d=Dist(tcounts,method=\"correlation\",diag=TRUE)\n dend = rev(dendsort(as.dendrogram(hclust( d,method=\"average\"))))\n m=as.matrix(d)\n sample_metadata <- metadata\n rownames(sample_metadata) = sample_metadata[[labels_column]]\n idx = as.factor(sample_metadata[rownames(m),groups_column])\n col = colorval\n cols <- col[idx]\n new.palette=colorRampPalette(c(\"blue\",\"green\",\"yellow\"),space=\"rgb\")\n \n mk<-function(){\n if(length(colnames(m))>20){\n par(mar=c(0,0,0,0))\n heatmap.2(m,\n labRow = NA, \n labCol = NA,\n col=new.palette(20),\n trace=\"none\",\n colRow = col[idx], \n colCol = col[idx],\n rowDendrogram=dend,\n colDendrogram=dend,\n RowSideColors = col[idx],\n ColSideColors = col[idx],\n dendrogram = \"row\",\n cexRow=3,\n cexCol=3,\n margins=c(0,0), \n lmat=rbind( c(0,0,2),c(4,1,3) ,c(0,5,6) ), \n lhei=c(.2,4,2), \n lwid=c(1, .2,4 ), \n key.par=list(mgp=c(1.75, .5, 0), \n mar=c(7, 2, 3.5, 0), \n cex.axis=.1, \n cex.lab=3, \n cex.main=1, \n cex.sub=1),\n key.xlab = \"Correlation\",\n key.ylab=\"Count\",\n key.title=\" \") \n } else {\n heatmap.2(m,col=new.palette(20),\n trace=\"none\",\n colRow = col[idx], \n colCol = col[idx],\n rowDendrogram=dend,\n colDendrogram=dend,\n RowSideColors = col[idx],\n ColSideColors = col[idx],\n dendrogram = \"row\",\n cexRow=3,cexCol=3,margins=c(4,1), \n lmat=rbind( c(0,0,2),c(4,1,3) ,c(0,5,6) ), \n lhei=c( .2,4,2), \n lwid=c(1, .2,4),\n key.par=list(mgp=c(1.75, .5, 0), mar=c(7, 2, 3.5, 0), cex.axis=.1, cex.lab=3, cex.main=1, cex.sub=1),\n key.xlab = \"Correlation\",\n key.ylab=\"Count\",\n key.title=\" \")\n }\n }\n \n tg<-mk()\n grid.echo(mk)\n gh1<-grid.grab()\n mklegend<-function(){\n plot.new()\n legend(x=\"top\", legend=levels(idx), col=col[as.factor(levels(idx))],pch=15,x.intersp=3,bty =\"n\",cex=2)\n }\n grid.echo(mklegend )\n gh2<-grid.grab()\n lay <- c(1,3)\n grid.newpage()\n grid.arrange(gh1,gh2,nrow=1,widths=c(unit(1000, \"bigpts\"),unit(300, \"bigpts\")))\n gh<-grid.grab()\n return(gh)\n }\n\n ## --------------- ##\n ## Main Code Block ##\n ## --------------- ##\n\nsamples_to_include=columns_to_include[columns_to_include%in%sample_metadata[,sample_names_column,drop=T]]\n anno_col=columns_to_include[columns_to_include%in%sample_metadata[,sample_names_column,drop=T]==F]\n\n\n samples_to_include <- samples_to_include[! samples_to_include %in% outlier_samples_to_remove]\n samples_to_include <- samples_to_include[samples_to_include != gene_names_column]\n samples_to_include <- samples_to_include[samples_to_include != \"Gene\"]\n samples_to_include <- samples_to_include[samples_to_include != \"GeneName\"]\n samples_to_include <- samples_to_include[samples_to_include %in% sample_metadata[[sample_names_column]]]\n\n\n\n##create unique rownames to correctly add back Annocolumns at end of template\ncounts_matrix[,gene_names_column]=paste0(counts_matrix[,gene_names_column],'_',1:nrow(counts_matrix))\n\n anno_col=c(anno_col,gene_names_column)%>%unique\n anno_tbl=counts_matrix[,anno_col,drop=F]%>%as.data.frame\n\n df <- counts_matrix[,c(gene_names_column,samples_to_include)]\n gene_names <- NULL\n gene_names$GeneID <- counts_matrix[,gene_names_column]\n\n\n\n#print(colnames(df.final))\n\n ### This code block does input data validation\n \n sample_metadata <- sample_metadata[match(colnames(df),sample_metadata[[sample_names_column]]),] #First match sample metadata to counts matrix\n sample_metadata <- sample_metadata[rowSums(is.na(sample_metadata)) != ncol(sample_metadata), ] # Remove empty rows\n sample_metadata <- sample_metadata[, colSums(is.na(sample_metadata)) == 0] #Remove empty columns\n rownames(sample_metadata) <- sample_metadata[[sample_names_column]]\n \n \n ### Remove specal characters from Metadata Column. Replace with _\n sample_metadata[,groups_column]=gsub('-| |!|\\\\*|\\\\.',\"_\",sample_metadata[,groups_column])\n\n \n #### remove low count genes ########\n \n df <- df[complete.cases(df),]\n ## duplicate Rows should be removed in Clean_Raw_Counts template\n #df %>% dplyr::group_by(.data[[gene_names_column]]) %>% summarise_all(sum) %>% as.data.frame() -> df\n print(paste0(\"Number of features before filtering: \", nrow(df)))\n\n ## USE CPM Transformation\n if (use_cpm_counts_to_filter == TRUE){\n trans.df=df\n trans.df[, -1]=edgeR::cpm(as.matrix(df[, -1]))\n counts_label=\"Filtered Counts (CPM)\"\n } else {\n trans.df=df\n counts_label=\"Filtered Counts\"\n\n }\n\n\n if (Use_Group_Based_Filtering == TRUE) {\n rownames(trans.df) <- trans.df[,gene_names_column]\n trans.df[,gene_names_column] <- NULL\n \n counts <- trans.df > Minimum_Count_Value_to_be_Considered_Nonzero # boolean matrix\n \n tcounts <- as.data.frame(t(counts))\n colnum <- dim(counts)[1] # number of genes\n tcounts <- merge(sample_metadata[groups_column], tcounts, by=\"row.names\")\n tcounts$Row.names <- NULL\n melted <- melt(tcounts, id.vars=groups_column)\n tcounts.tot <- dplyr::summarise(dplyr::group_by_at(melted, c(groups_column, \"variable\")), sum=sum(value))\n tcounts.tot %>% tidyr::spread(variable, sum) -> tcounts.group\n colSums(tcounts.group[(1:colnum+1)]>=Minimum_Number_of_Samples_with_Nonzero_Counts_in_a_Group) >= 1 -> tcounts.keep \n df.filt <- trans.df[tcounts.keep, ]\n df.filt %>% rownames_to_column(gene_names_column) -> df.filt\n } else {\n\n trans.df$isexpr1 <- rowSums(as.matrix(trans.df[, -1]) > Minimum_Count_Value_to_be_Considered_Nonzero) >= Minimum_Number_of_Samples_with_Nonzero_Counts_in_Total\n\n df.filt <- as.data.frame(trans.df[trans.df$isexpr1, ])\n }\n\n #colnames(df.filt)[colnames(df.filt)==gene_names_column] <- \"Gene\"\n print(paste0(\"Number of features after filtering: \", nrow(df.filt)))\n\n ######## Start PCA ###############\n\n edf <- log((as.matrix(df.filt[,samples_to_include]+0.5)))\n rownames(edf) <- df.filt[,1]\n tedf <- t(edf)\n tedf <- tedf[, colSums(is.na(tedf)) != nrow(tedf)]\n tedf <- tedf[, apply(tedf, 2, var) != 0]\n pca <- prcomp(tedf, scale.=T)\n \n pcx <- paste0(\"PC\",principal_component_on_x_axis)\n pcy <- paste0(\"PC\",principal_component_on_y_axis)\n pca.df <- as.data.frame(pca$x) %>% dplyr::select(.data[[pcx]], .data[[pcy]])\n pca.df$group <- sample_metadata[[groups_column]]\n pca.df$sample <- sample_metadata[[labels_column]]\n perc.var <- (pca$sdev^2/sum(pca$sdev^2))*100\n perc.var <- formatC(perc.var,format = \"g\",digits=4)\n pc.x.lab <- paste0(pcx,\" \", perc.var[principal_component_on_x_axis],\"%\")\n pc.y.lab <- paste0(pcy,\" \", perc.var[principal_component_on_y_axis],\"%\")\n labelpos <- pca.df\n labelpos$mean_y <- pca.df[[pcy]]+label_offset_y_\n labelpos$mean_x <- pca.df[[pcx]]+label_offset_x_\n pca.df$xdata <- pca.df[[pcx]]\n pca.df$ydata <- pca.df[[pcy]]\n\n # Manual changes to sample names\n replacements = samples_to_rename_manually\n\n if (!is.null(samples_to_rename_manually)) {\n if (replacements != c(\"\")) {\n for (x in replacements) {\n old <- strsplit(x, \": ?\")[[1]][1]\n new <- strsplit(x, \": ?\")[[1]][2]\n pca.df$sample <- ifelse(pca.df$sample==old, new, pca.df$sample)\n }\n }\n }\n\n colorlist <- c(\"#5954d6\",\"#e1562c\",\"#b80058\",\"#00c6f8\",\"#d163e6\",\"#00a76c\",\"#ff9287\",\"#008cf9\",\"#006e00\",\"#796880\",\"#FFA500\",\"#878500\")\n names(colorlist) <- c(\"indigo\",\"carrot\",\"lipstick\",\"turquoise\",\"lavender\",\"jade\",\"coral\",\"azure\",\"green\",\"rum\",\"orange\",\"olive\")\n if(length(colors_for_plots) == 0){\n colors_for_plots <- c(\"indigo\",\"carrot\",\"lipstick\",\"turquoise\",\"lavender\",\"jade\",\"coral\",\"azure\",\"green\",\"rum\",\"orange\",\"olive\")\n }\n colorval <- colorlist[colors_for_plots]\n colorval <- unname(colorval) #remove names which affect ggplot\n\n if (length(unique(sample_metadata[[groups_column]])) > length(colorval)) {\n ## Original color-picking code.\n k=length(unique(sample_metadata[[groups_column]]))-length(colorval)\n more_cols<- getourrandomcolors(k) \n colorval <- c(colorval , more_cols)\n }\n\n if (add_labels_to_PCA == TRUE){\n g <- ggplot(pca.df, aes(x=xdata, y=ydata)) +\n theme_bw() +\n theme(legend.title=element_blank()) +\n theme(legend.position=legend_position_for_PCA) +\n geom_point(aes(color=group), size=point_size_for_pca) +\n geom_text(data=labelpos, aes(x=labelpos$mean_x, y=labelpos$mean_y, \n label=sample, color=group, vjust=\"inward\", hjust=\"inward\"), size=label_font_size, show.legend=FALSE) +\n theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),\n panel.background = element_blank()) +\n scale_colour_manual(values = colorval) +\n xlab(pc.x.lab) + ylab(pc.y.lab)\n } else {\n g <- ggplot(pca.df, aes(x=xdata, y=ydata)) +\n theme_bw() +\n theme(legend.title=element_blank()) +\n theme(legend.position=legend_position_for_PCA) +\n geom_point(aes(color=group,text=sample), size=point_size_for_pca) +\n theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),\n panel.background = element_blank()) +\n scale_colour_manual(values = colorval) +\n xlab(pc.x.lab) + ylab(pc.y.lab) \n }\n\n par(mfrow = c(2,1))\n\n df.m <- melt(edf,id.vars=c(gene_names_column))\n df.m = dplyr::rename(df.m,sample=Var2)\n\n if(set_min_max_for_x_axis_for_histogram == TRUE){\n xmin = minimum_for_x_axis_for_histogram\n xmax = maximum_for_x_axis_for_histogram\n } else {\n xmin = min(df.m$value)\n xmax = max(df.m$value)\n }\n\n if(color_histogram_by_group == TRUE){\n df.m %>% mutate(colgroup = sample_metadata[sample,groups_column]) -> df.m\n df.m = df.m[complete.cases(df.m[, \"colgroup\"]),]\n df.m$colgroup = gsub(\"\\\\s\",\"_\",df.m$colgroup)\n #df.m$colgroup = factor(df.m$colgroup, levels=unique(df.m$colgroup))\n #print(unique(df.m$sample))\n\n # plot Density \n g2 = ggplot(df.m, aes(x=value, group=sample)) + \n geom_density(aes(colour = colgroup)) +\n xlab(counts_label) + ylab(\"Density\") +\n theme_bw() +\n theme(legend.position=legend_position_for_histogram,legend.text = element_text(size = legend_font_size_for_histogram)) + \n ggtitle(\"Frequency Histogram\") +\n xlim(xmin,xmax) +\n #scale_linetype_manual(values=rep(c('solid', 'dashed','dotted','twodash'),40)) +\n scale_colour_manual(values=colorval)\n guides(linetype = guide_legend(ncol = number_of_histogram_legend_columns))\n } else {\n \n df.m$sample = sample_metadata[df.m$sample,labels_column]\n n=length(unique(df.m$sample))\n cols<- getourrandomcolors(n) \n \n g2 = ggplot(df.m, aes(x=value, group=sample)) + \n geom_density(aes(colour = sample )) +\n xlab(counts_label) + ylab(\"Density\") +\n theme_bw() +\n theme(legend.position=legend_position_for_histogram,legend.text = element_text(size = legend_font_size_for_histogram)) + \n ggtitle(\"Frequency Histogram\") +\n xlim(xmin,xmax) +\n #scale_linetype_manual(values=rep(c('solid', 'dashed','dotted','twodash'),n)) +\n scale_colour_manual(values=cols) +\n guides(linetype = guide_legend(ncol = number_of_histogram_legend_columns))\n }\n \n #dev.off()\n\n imageWidth = 3000\n imageHeight = 1500*2\n dpi = 300\n\n png(\n filename=graphicsFile,\n width=imageWidth,\n height=imageHeight,\n units=\"px\",\n pointsize=4,\n bg=\"white\",\n res=dpi,\n type=\"cairo\")\n\n \n if(plot_correlation_matrix_heatmap == TRUE){\n if(interactive_plots == TRUE){\n p1=(g)%>%ggplotly(tooltip = c(\"sample\",\"group\"))\n p2=(g2+theme(legend.position = \"none\")) %>%ggplotly(tooltip = c(\"sample\"))\n fig=subplot(p1,p2,which_layout = 'merge',margin=.05,shareX = F,shareY = F,titleY = T,titleX = T,widths=c(.5,.5),nrows = 1)\n fig=fig %>% layout(title = 'Interactive PCA and Histogram')\n print(fig)\n } else {\n require(gridExtra)\n gh<-make_heatmap(df.filt[,samples_to_include],sample_metadata,colorval)\n grid.arrange(g,g2,gh, nrow=number_of_image_rows)\n #dev.off()\n } \n } else {\n if(interactive_plots == TRUE){\n p1=(g)%>%ggplotly(tooltip = c(\"sample\",\"group\"))\n p2=(g2+theme(legend.position = \"none\")) %>%ggplotly(tooltip = \"sample\" )\n fig=subplot(p1,p2,which_layout = 'merge',margin=.05,shareX = F,shareY = F,titleY = T,titleX = T,widths=c(.5,.5),nrows = 1)\n fig=fig %>% layout(title = 'Interactive PCA and Histogram')\n print(fig)\n } else {\n grid.arrange(g,g2, nrow=number_of_image_rows)\n #dev.off()\n }\n }\n \n df %>% filter(.data[[gene_names_column]] %in% df.filt[,gene_names_column]) -> df.final\n # colnames(df.final)[colnames(df.final)==gene_names_column] <- \"Gene\"\n\nprint('')\nprint('Sample Columns')\nprint(colnames(df.final[,!colnames(df.final)%in%gene_names_column]))\nprint('Annotation Columns')\nprint(colnames(anno_tbl))\n\n df.final=merge(anno_tbl,df.final,by=gene_names_column,all.y=T)\n df.final[,gene_names_column]=gsub('_[0-9]+$',\"\",df.final[,gene_names_column])\n\n return(df.final)\n}\n\n\n", - "columns": [ - { - "key": "Feature_ID_Column", - "displayName": "Feature ID Column", - "description": "The column from your input Counts Matrix containing the Feature IDs (Usually Gene or Protein ID). This is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts Matrix will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Columns_to_Include", - "displayName": "Columns to Include", - "description": "Which Columns would you like to include? Usually, you will choose to \"Add all\" (see button on right). Columns excluded here will be removed in this step and from further analysis downstream of this step.", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "Sample_Names_Column", - "displayName": "Sample Names Column", - "description": "The column from your input Sample Metadata table containing the sample names. The names in this column must exactly match the names used as the sample column names of your input Counts Matrix. Only columns of Text type from your input Sample Metadata table will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Groups_Column", - "displayName": "Groups Column", - "description": "The column from your input Sample Metadata table containing the sample group information. This is usually a column showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal, Before, After, etc.). Only columns of Text type from your input Sample Metadata will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Labels_Column", - "displayName": "Labels Column", - "description": "The column from your input Sample Metadata table containing the sample labels as you wish them to appear in the plots produced by this template. This can be the same Sample Names Column (see above). However, you may desire different labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the column with your preferred Labels here. The selected column should contain unique names for each sample.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "Outlier_Samples_to_Remove", - "displayName": "Outlier Samples to Remove", - "description": "", - "paramGroup": "Filtering", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "NUMBER", - "isMulti": true - } - ], - "condaDependencies": [], - "description": "This template is intended for use with Bulk RNA-seq data and is often the first step in the QC portion of an analysis. It filters out Features that have very low raw counts across most or all of your samples.\n\nThis template takes as input a raw counts expression matrix and your sample metadata table. It provides as output an image consisting of three QC plots (see below) and a filtered raw counts expression matrix. You have an option to use CPM counts as input instead.\n\nThe threshold for tuning how low counts for a given gene are before they are deemed \"too low\" and filtered out of downstream analysis is a tunable parameter. By default, this parameter is set to 1, meaning any raw count value less than 1 will count as \"too low\".\n\nThe QC plots are provided to help you assess: (1) PCA Plot: the within and between group variance in expression after dimensionality reduction; (2) Count Density Histogram: the dis/similarity of count distributions between samples; and (3) Similarity Heatmap: the overall similarity of samples to one another based on unsupervised clustering.", - "externalId": "Filter_Low_Counts_CCBR_", - "inputDatasets": [ - { - "key": "counts_matrix", - "displayName": "Counts Matrix", - "description": "The input Counts Matrix. Usually, this will be your Cleaned Counts matrix.", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - }, - { - "key": "Sample_Metadata", - "displayName": "Sample Metadata", - "description": "The Sample Metadata table containing your sample metadata. At minimum, this table must include one column each of the following: Samples, Groups, Batches, and Labels. The names in the Samples column of your input Sample Metadata must match the Sample Column Names of your input Counts Matrix exactly. You may have more than one column showing different Groups by which your samples may be organized (e.g. Genotype, Response, Time, etc.).", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - } - ], - "vectorLanguage": "R", - "codeLanguage": "R", - "parameters": [ - { - "key": "Use_CPM_Counts_to_filter", - "displayName": "Use CPM Counts to filter", - "description": "If no transformation has been been performed on counts matrix (eg Raw Counts) set to TRUE. If TRUE counts will be transformed to CPM and filtered based on given criteria.\n If gene counts matrix has been transformed (eg log2, CPM, FPKM or some form of Normalization) set to FALSE. If FALSE no further transformation will be applied and features will be filtered as is. For RNAseq data RAW counts should be transformed to CPM in order to properly filter.", - "paramType": "BOOLEAN", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Minimum_Count_Value_to_be_Considered_Nonzero", - "displayName": "Minimum Count Value to be Considered Nonzero", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Minimum_Number_of_Samples_with_Nonzero_Counts_in_Total", - "displayName": "Minimum Number of Samples with Nonzero Counts in Total", - "description": "Minimum number of samples (total) with non-zero counts", - "paramType": "NUMBER", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Use_Group_Based_Filtering", - "displayName": "Use Group-Based Filtering", - "description": "If TRUE, only keeps genes that have at least a certain number of samples with nonzero CPM counts in at least one group", - "paramType": "BOOLEAN", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Minimum_Number_of_Samples_with_Nonzero_Counts_in_a_Group", - "displayName": "Minimum Number of Samples with Nonzero Counts in a Group", - "description": "Only keeps genes that have at least this number of samples with nonzero CPM counts in at least one group", - "paramType": "NUMBER", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": "3", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Principal_Component_on_X_axis", - "displayName": "Principal Component on X-axis", - "description": "The principle component to plot on the x-axis. Choices include 1, 2, 3, ... (default: 1)", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Principal_Component_on_Y_axis", - "displayName": "Principal Component on Y-axis", - "description": "The principle component to plot on the y-axis. Choices include 1, 2, 3, ... (default: 2)", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Legend_Position_for_PCA", - "displayName": "Legend Position for PCA", - "description": "Legend position relative to the plot", - "paramType": "SELECT", - "paramGroup": "PCA", - "paramValues": [ - "top", - "bottom", - "left", - "right", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Point_Size_for_PCA", - "displayName": "Point Size for PCA", - "description": "", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Add_Labels_to_PCA", - "displayName": "Add Labels to PCA", - "description": "Label points on graph", - "paramType": "BOOLEAN", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Font_Size_for_PCA", - "displayName": "Label Font Size for PCA", - "description": "Font size for sample labels. Set to 0 to remove labels.", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "3", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Offset_x_", - "displayName": "Label Offset (x)", - "description": "", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Offset_Y_", - "displayName": "Label Offset (Y)", - "description": "", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Samples_to_Rename_Manually_on_PCA", - "displayName": "Samples to Rename Manually on PCA", - "description": "If you do not have a Plot Labels Column (see above) in your sample metadata table, you can use this parameter to rename samples manually for display on the PCA plot. Use \"Add item\" to add each additional sample for renaming. Use the following format to describe which old name (in your sample metadata table) you want to rename to which new name: old_name: new_name", - "paramType": "VECTOR", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "c(\"\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Color_Histogram_by_Group", - "displayName": "Color Histogram by Group", - "description": "Toggle to FALSE to label histogram by Sample Names. Toggle to TRUE to label histogram by the column you select in the \"Group Column Used to Color Histogram\" parameter (below). Default is FALSE.", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Set_Min_Max_for_X_axis_for_Histogram", - "displayName": "Set Min/Max for X-axis for Histogram", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Minimum_for_X_axis_for_Histogram", - "displayName": "Minimum for X-axis for Histogram", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "-1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Maximum_for_X_axis_for_Histogram", - "displayName": "Maximum for X-axis for Histogram", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Legend_Font_Size_for_Histogram", - "displayName": "Legend Font Size for Histogram", - "description": "Legend font size", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "10", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Legend_Position_for_Histogram", - "displayName": "Legend Position for Histogram", - "description": "Legend position on histogram plot, can be 'none' if large number of samples", - "paramType": "SELECT", - "paramGroup": "Histogram", - "paramValues": [ - "right", - "bottom", - "left", - "top", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Number_of_Histogram_Legend_Columns", - "displayName": "Number of Histogram Legend Columns", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "6", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Colors_for_Plots", - "displayName": "Colors for Plots", - "description": "Colors for the PCA and histogram will be picked, in order, from this list. If you have >12 samples or groups, program will choose from a wide range of random colors", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "indigo", - "carrot", - "lipstick", - "turquoise", - "lavender", - "jade", - "coral", - "azure", - "green", - "rum", - "orange", - "olive" - ], - "defaultValue": "c(\"indigo\",\"carrot\",\"lipstick\",\"turquoise\",\"lavender\",\"jade\",\"coral\",\"azure\",\"green\",\"rum\",\"orange\",\"olive\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Number_of_Image_Rows", - "displayName": "Number of Image Rows", - "description": "1 = side-by-side, 2 = stacked", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Interactive_Plots", - "displayName": "Interactive Plots", - "description": "Toggle TRUE to make PCA and Histogram plots interactive, allowing you to hover your mouse over a point or line to view sample information. The similarity heatmap will not display if this toggle is set to TRUE. Default is FALSE.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Plot_Correlation_Matrix_Heatmap", - "displayName": "Plot Correlation Matrix Heatmap", - "description": "Datasets with a large number of samples may be too large to create a correlation matix heatmap. If this template takes longer than 5 minutes to run, Toggle switch to FALSE and the correlation matrix will not be be created. Default is TRUE.", - "paramType": "BOOLEAN", - "paramGroup": "TCGA", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "title": "Filter Low Counts [CCBR]", - "templateApiVersion": "0.1.0" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/NIDAPBulkTemplate_parameterTo_MOSuiteMapping.json b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/NIDAPBulkTemplate_parameterTo_MOSuiteMapping.json deleted file mode 100644 index 2158ed3..0000000 --- a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/NIDAPBulkTemplate_parameterTo_MOSuiteMapping.json +++ /dev/null @@ -1,350 +0,0 @@ -{ - "template_mappings": { - "Normalization_CCBR_.code-template.json": { - "r_function": "normalize_counts", - "r_file": "R/normalize.R", - "parameter_mappings": [ - {"Feature_ID_Column": "feature_id_colname"}, - {"Columns_to_Include": "samples_to_include"}, - {"Sample_Names_Column": "sample_id_colname"}, - {"Groups_Column": "group_colname"}, - {"Labels_Column": "label_colname"}, - {"Input_in_Log_Counts": "input_in_log_counts"}, - {"Normalization_Method": "voom_normalization_method"}, - {"Samples_to_Rename_Manually_on_PCA": "samples_to_rename"}, - {"Add_Labels_to_PCA": "add_label_to_pca"}, - {"Principal_Component_on_X_axis_for_PCA": "principal_component_on_x_axis"}, - {"Principal_Component_on_Y_axis_for_PCA": "principal_component_on_y_axis"}, - {"Legend_position_for_PCA": "legend_position_for_pca"}, - {"Label_Offset_x_for_PCA": "label_offset_x_"}, - {"Label_Offset_y_for_PCA": "label_offset_y_"}, - {"Label_Font_Size_for_PCA": "label_font_size"}, - {"Point_Size_for_PCA": "point_size_for_pca"}, - {"Color_Histogram_by_Group": "color_histogram_by_group"}, - {"Set_Min_Max_for_X_axis_for_Histogram": "set_min_max_for_x_axis_for_histogram"}, - {"Minimum_for_X_axis_in_Histogram": "minimum_for_x_axis_for_histogram"}, - {"Maximum_for_X_axis_in_Histogram": "maximum_for_x_axis_for_histogram"}, - {"Legend_Font_Size_for_Histogram": "legend_font_size_for_histogram"}, - {"Legend_Position_for_Histogram": "legend_position_for_histogram"}, - {"Colors_for_Plots": "colors_for_plots"}, - {"Make_Plots_Interactive": "interactive_plots"} - ], - "data_input_parameters": [ - {"counts_matrix": "DATA_INPUT"}, - {"Sample_Metadata": "DATA_INPUT"} - ], - "missing_parameters": [ - {"Number_of_Histogram_Legend_Columns": "NOT_IN_R_FUNCTION"}, - {"Number_of_Image_Rows": "NOT_IN_R_FUNCTION"}, - {"Plot_Correlation_Matrix_Heatmap": "NOT_IN_R_FUNCTION"} - ] - }, - "Batch_Correction_CCBR_.code-template.json": { - "r_function": "batch_correct_counts", - "r_file": "R/batch-correction.R", - "parameter_mappings": [ - {"Feature_ID_Column": "feature_id_colname"}, - {"Columns_to_Include": "samples_to_include"}, - {"Sample_Names_Column": "sample_id_colname"}, - {"Groups_Column": "group_colname"}, - {"Covariates": "covariates_colnames"}, - {"Batch_Column": "batch_colname"}, - {"Labels_Column": "label_colname"}, - {"Skip_Batch_Correction": "skip_batch_correction"}, - {"Principal_Component_on_X_axis_for_PCA": "principal_component_on_x_axis"}, - {"Principal_Component_on_Y_axis_for_PCA": "principal_component_on_y_axis"}, - {"Colors_for_plots": "colors_for_plots"}, - {"Point_Size_for_PCA": "point_size_for_pca"}, - {"Add_Labels_to_PCA": "add_label_to_pca"}, - {"Label_Offset_y_for_PCA": "label_offset_y_"}, - {"Label_Offset_x_for_PCA": "label_offset_x_"}, - {"Label_Font_Size_for_PCA": "label_font_size"}, - {"Legend_Position_for_PCA": "legend_position_for_pca"}, - {"Samples_to_Rename_Manually_on_PCA": "samples_to_rename"}, - {"Color_Histogram_by_Group": "color_histogram_by_group"}, - {"Set_Max_Min_for_X_axis_for_Histogram": "set_min_max_for_x_axis_for_histogram"}, - {"Minimum_X_axis_in_Histogram": "minimum_for_x_axis_for_histogram"}, - {"Maximum_X_axis_in_Histogram": "maximum_for_x_axis_for_histogram"}, - {"Legend_Position_for_Histogram": "legend_position_for_histogram"}, - {"Legend_Font_Size_for_Histogram": "legend_font_size_for_histogram"}, - {"Make_Plots_Interactive": "interactive_plots"} - ], - "missing_parameters": [ - {"Number_of_Histogram_Legend_Columns": "NOT_IN_R_FUNCTION"}, - {"Number_of_Image_Rows": "NOT_IN_R_FUNCTION"}, - {"Plot_Correlation_Matrix_Heatmap": "NOT_IN_R_FUNCTION"} - ] - }, - "Clean_Raw_Counts_CCBR_.code-template.json": { - "r_function": "clean_raw_counts", - "r_file": "R/clean.R", - "parameter_mappings": [ - {"Feature_ID_Column": "feature_id_colname"}, - {"data_type": "data_type"}, - {"Samples_to_Rename": "samples_to_rename"}, - {"Cleanup_Column_Names": "cleanup_column_names"}, - {"Split_Feature_ID": "split_gene_name"}, - {"Aggregate_Rows_with_Duplicate_Feature_Names": "aggregate_rows_with_duplicate_gene_names"}, - {"Column_Used_to_Aggregate_Duplicates_Feature_IDs": "gene_name_column_to_use_for_collapsing_duplicates"} - ], - "data_input_parameters": [ - {"Raw_Counts_Matrix": "DATA_INPUT"} - ] - }, - "DEG_Analysis_CCBR_.code-template.json": { - "r_function": "diff_counts", - "r_file": "R/differential.R", - "parameter_mappings": [ - {"Feature_Gene_Names_Column": "feature_id_colname"}, - {"Sample_Names_Column": "sample_id_colname"}, - {"Columns_to_Include": "samples_to_include"}, - {"Contrast_Variable_Column": "contrast_colname"}, - {"Covariates_Column_s_": "covariates_colnames"}, - {"Contrasts": "contrasts"}, - {"input_in_log_counts": "input_in_log_counts"}, - {"return_mean_and_sd": "return_mean_and_sd"}, - {"Return_Normalized_Counts": "return_normalized_counts"}, - {"Normalization_Method": "voom_normalization_method"} - ], - "data_input_parameters": [ - {"Counts_Matrix": "DATA_INPUT"}, - {"Sample_Metadata": "DATA_INPUT"} - ] - }, - "DEG_Gene_List_CCBR_.code-template.json": { - "r_function": "filter_diff", - "r_file": "R/differential.R", - "parameter_mappings": [ - {"Gene_Names_Column": "feature_id_colname"}, - {"Significance_Column": "significance_column"}, - {"Significance_Cutoff": "significance_cutoff"}, - {"Change_Column": "change_column"}, - {"Change_Cutoff": "change_cutoff"}, - {"Filtering_Mode": "filtering_mode"}, - {"Include_Estimates": "include_estimates"}, - {"Round_Estimates": "round_estimates"}, - {"Rounding_Decimal_for_Percent_Calls": "rounding_decimal_for_percent_cells"}, - {"Contrasts_Filter": "contrast_filter"}, - {"Contrasts": "contrasts"}, - {"Groups": "groups"}, - {"Groups_Filter": "groups_filter"} - ], - "data_input_parameters": [ - {"DEG_Table": "DATA_INPUT"} - ], - "missing_parameters": [ - {"Label_Font_Size": "NOT_IN_R_FUNCTION"}, - {"Label_Distance": "NOT_IN_R_FUNCTION"}, - {"Y_Axis_Expansion": "NOT_IN_R_FUNCTION"}, - {"Fill_Colors_": "NOT_IN_R_FUNCTION"}, - {"Pie_Chart_in_3D": "NOT_IN_R_FUNCTION"}, - {"Bar_Width": "NOT_IN_R_FUNCTION"}, - {"Draw_Bar_Border": "NOT_IN_R_FUNCTION"}, - {"Force_Barchart": "NOT_IN_R_FUNCTION"} - ] - }, - "Expression_Heatmap_CCBR_scRNA_seq_Bulk_.code-template.json": { - "r_function": "plot_expr_heatmap", - "r_file": "R/plot_heatmap.R", - "parameter_mappings": [ - {"Gene_Column_Name": "feature_id_colname"}, - {"Sample_Name_Column": "sample_id_colname"}, - {"Sample_Labels_Column": "label_colname"}, - {"Samples_to_Include": "samples_to_include"}, - {"Include_All_Genes": "include_all_genes"}, - {"Filter_Top_Genes_by_Variance": "filter_top_genes_by_variance"}, - {"Top_Genes_by_Variance_to_Include": "top_genes_by_variance_to_include"}, - {"Specific_Genes_to_Include_in_Heatmap": "specific_genes_to_include_in_heatmap"}, - {"Cluster_Genes": "cluster_genes"}, - {"Gene_Distance_Metric": "gene_distance_metric"}, - {"Gene_Clustering_Method": "gene_clustering_method"}, - {"Display_Gene_Dendrogram": "display_gene_dendrograms"}, - {"Display_Gene_Names": "display_gene_names"}, - {"Center_and_Rescale_Expression": "center_and_rescale_expression"}, - {"Cluster_Samples": "cluster_samples"}, - {"Arrange_Sample_Columns": "arrange_sample_columns"}, - {"Order_by_Gene_Expression": "order_by_gene_expression"}, - {"Gene_to_Order_Columns": "gene_to_order_columns"}, - {"Gene_Expression_Order": "gene_expression_order"}, - {"Sample_Distance_Metric": "smpl_distance_metric"}, - {"Sample_Clustering_Method": "smpl_clustering_method"}, - {"Display_Sample_Dendrograms": "display_smpl_dendrograms"}, - {"Reorder_Sample_Dendrogram": "reorder_dendrogram"}, - {"Reorder_Sample_Dendrogram_Order": "reorder_dendrogram_order"}, - {"Display_Sample_Names": "display_sample_names"}, - {"Manually_Rename_Samples": "manually_rename_samples"}, - {"Samples_to_Rename": "samples_to_rename"}, - {"Group_Columns": "group_columns"}, - {"Assign_Group_Colors": "assign_group_colors"}, - {"Assign_Color_to_Sample_Groups": "assign_color_to_sample_groups"}, - {"Group_Colors": "group_colors"}, - {"Heatmap_Color_Scheme": "heatmap_color_scheme"}, - {"Autoscale_Heatmap_Color": "autoscale_heatmap_color"}, - {"Set_Min_Heatmap_Color": "set_min_heatmap_color"}, - {"Set_Max_Heatmap_Color": "set_max_heatmap_color"}, - {"Aspect_Ratio": "aspect_ratio"}, - {"Legend_Font_Size": "legend_font_size"}, - {"Gene_Name_Font_Size": "gene_name_font_size"}, - {"Sample_Name_Font_Size": "sample_name_font_size"}, - {"Display_Numbers": "display_numbers"}, - {"Return_Z_Scores": "return_z_scores"} - ] - }, - "Filter_Low_Counts_CCBR_.code-template.json": { - "r_function": "filter_counts", - "r_file": "R/filter.R", - "parameter_mappings": [ - {"Feature_ID_Column": "feature_id_colname"}, - {"Columns_to_Include": "samples_to_include"}, - {"Sample_Names_Column": "sample_id_colname"}, - {"Groups_Column": "group_colname"}, - {"Labels_Column": "label_colname"}, - {"Outlier_Samples_to_Remove": "outlier_samples_to_remove"}, - {"Use_CPM_Counts_to_filter": "use_cpm_counts_to_filter"}, - {"Minimum_Count_Value_to_be_Considered_Nonzero": "minimum_count_value_to_be_considered_nonzero"}, - {"Minimum_Number_of_Samples_with_Nonzero_Counts_in_Total": "minimum_number_of_samples_with_nonzero_counts_in_total"}, - {"Use_Group_Based_Filtering": "use_group_based_filtering"}, - {"Minimum_Number_of_Samples_with_Nonzero_Counts_in_a_Group": "minimum_number_of_samples_with_nonzero_counts_in_a_group"}, - {"Principal_Component_on_X_axis": "principal_component_on_x_axis"}, - {"Principal_Component_on_Y_axis": "principal_component_on_y_axis"}, - {"Legend_Position_for_PCA": "legend_position_for_pca"}, - {"Point_Size_for_PCA": "point_size_for_pca"}, - {"Add_Labels_to_PCA": "add_label_to_pca"}, - {"Label_Font_Size_for_PCA": "label_font_size"}, - {"Label_Offset_Y_": "label_offset_y_"}, - {"Label_Offset_x_": "label_offset_x_"}, - {"Samples_to_Rename_Manually_on_PCA": "samples_to_rename"}, - {"Color_Histogram_by_Group": "color_histogram_by_group"}, - {"Set_Min_Max_for_X_axis_for_Histogram": "set_min_max_for_x_axis_for_histogram"}, - {"Minimum_for_X_axis_for_Histogram": "minimum_for_x_axis_for_histogram"}, - {"Maximum_for_X_axis_for_Histogram": "maximum_for_x_axis_for_histogram"}, - {"Legend_Position_for_Histogram": "legend_position_for_histogram"}, - {"Legend_Font_Size_for_Histogram": "legend_font_size_for_histogram"}, - {"Colors_for_Plots": "colors_for_plots"}, - {"Interactive_Plots": "interactive_plots"} - ] - }, - "PCA_3D_CCBR_.code-template.json": { - "r_function": "plot_pca_3d", - "r_file": "R/plot_pca.R", - "parameter_mappings": [ - {"FeatureID_Name_Column": "feature_id_colname"}, - {"Sample_Names_Column": "sample_id_colname"}, - {"Samples_to_Include": "samples_to_include"}, - {"Group_Column": "group_colname"}, - {"Plot_Labels_Column": "label_colname"}, - {"Outlier_Samples_to_Remove": "outlier_samples_to_remove"}, - {"Samples_to_Rename_Manually": "samples_to_rename"}, - {"Use_CPM": "use_cpm"}, - {"Point_Size": "point_size"}, - {"Point_Color": "point_color"}, - {"Plot_Title": "plot_title"} - ] - }, - "Venn_Diagram_CCBR_.code-template.json": { - "r_function": "plot_venn_diagram", - "r_file": "R/plot_venn_diagram.R", - "parameter_mappings": [ - {"Elements_Column": "feature_id_colname"}, - {"Categories_Column": "contrasts_colname"}, - {"Selected_Categories": "select_contrasts"}, - {"Select_Plot_Type": "plot_type"}, - {"Intersection_IDs": "intersection_ids"}, - {"Venn_Force_Unique": "venn_force_unique"}, - {"Venn_Numbers_Format": "venn_numbers_format"}, - {"Venn_Significant_Digits": "venn_significant_digits"}, - {"Venn_Fill_Colors": "venn_fill_colors"}, - {"Venn_Fill_Transparency": "venn_fill_transparency"}, - {"Venn_Border_Colors": "venn_border_colors"}, - {"Venn_Font_Size_for_Category_Names": "venn_font_size_for_category_names"}, - {"Venn_Category_Names_Distance": "venn_category_names_distance"}, - {"Venn_Category_Names_Position": "venn_category_names_position"}, - {"Venn_Font_Size_for_Counts": "venn_font_size_for_counts"}, - {"Venn_Outer_Margin": "venn_outer_margin"}, - {"Intersections_Order": "intersections_order"}, - {"Display_Empty_Intersections": "display_empty_intersections"}, - {"Intersection_Bar_Color": "intersection_bar_color"}, - {"Intersection_Point_Size": "intersection_point_size"}, - {"Intersection_Line_Width": "intersection_line_width"}, - {"Table_Font_Size": "table_font_size"}, - {"Table_Content": "table_content"} - ] - }, - "Volcano_Plot_Enhanced_CCBR_scRNA_seq_Bulk_.code-template.json": { - "r_function": "plot_volcano_enhanced", - "r_file": "R/plot_volcano.R", - "parameter_mappings": [ - {"Column_with_Feature_ID": "feature_id_colname"}, - {"Significance_Column": "significance_column"}, - {"Log2_Fold_Change_Column": "log2_fold_change_column"}, - {"P_Value_Threshold": "p_value_threshold"}, - {"Log2_Fold_Change_Threshold": "log2_fold_change_threshold"}, - {"Choose_Feature_to_Label_By": "choose_feature_to_label_by"}, - {"Number_of_Features_to_Label": "number_of_features_to_label"}, - {"Label_Only_My_Feature_List": "label_only_my_feature_list"}, - {"My_Feature_List": "my_feature_list"}, - {"Top_Genes_Labeled_Only_If_Passing_Thresholds": "top_genes_labeled_only_if_passing_thresholds"}, - {"Label_Size": "label_size"}, - {"Custom_Significance_Label": "custom_significance_label"}, - {"Custom_Log_Fold_Change_Label": "custom_log_fold_change_label"}, - {"Plot_Title": "plot_title"}, - {"Use_Custom_Axis_Label": "use_custom_axis_label"}, - {"Y_Limit": "y_limit"}, - {"Custom_X_axis_limits": "custom_x_axis_limits"}, - {"X_Limit_Padding": "x_limit_padding"}, - {"Y_Limit_Padding": "y_limit_padding"}, - {"Axis_Label_Size": "axis_label_size"}, - {"Point_Size": "point_size"} - ], - "data_input_parameters": [ - {"DEG_Table": "DATA_INPUT"} - ], - "missing_parameters": [ - {"Image_Width": "NOT_IN_R_FUNCTION"}, - {"Image_Height": "NOT_IN_R_FUNCTION"}, - {"Resolution_DPI_": "NOT_IN_R_FUNCTION"} - ] - }, - "Volcano_Plot_Summary_CCBR_.code-template.json": { - "r_function": "plot_volcano_summary", - "r_file": "R/plot_volcano.R", - "parameter_mappings": [ - {"Gene_Names_Column": "feature_id_colname"}, - {"Volcano_P_value_Type": "volcano_p_value_type"}, - {"P_Value_Threshold": "p_value_threshold"}, - {"Log2_Fold_Change_Threshold": "log2_fold_change_threshold"}, - {"Choose_Genes_To_Label_By": "choose_genes_to_label_by"}, - {"Number_of_Genes_to_Label": "number_of_genes_to_label"}, - {"DEG_Columns_to_Keep_in_Output_Table": "deg_columns_to_keep_in_output_table"}, - {"Use_Default_Y_Axis_Limit": "use_default_y_axis_limit"}, - {"Y_Axis_Limit": "y_axis_limit"}, - {"Use_Default_X_Axis_Limit": "use_default_x_axis_limit"}, - {"X_Axis_Limit": "x_axis_limit"}, - {"Add_My_Gene_List_To_Labels": "add_my_gene_list_to_labels"}, - {"My_Gene_List": "my_gene_list"}, - {"Label_Only_My_Gene_List": "label_only_my_gene_list"}, - {"Gene_Label_Text_Color": "gene_label_text_color"}, - {"Gene_Label_Text_Color_for_My_Genes": "gene_label_text_color_for_my_genes"}, - {"Displace_Gene_Labels": "displace_gene_labels"}, - {"Gene_List_Special_Label_Displacement": "gene_list_special_label_displacement"}, - {"Special_Label_Displacement_X_Axis_": "special_label_displacement_x_axis"}, - {"Special_Label_Displacement_Y_Axis_": "special_label_displacement_y_axis"}, - {"Label_Position_Adjustment_X_Axis_": "label_position_adjustment_x_axis"}, - {"Label_Position_Adjustment_Y_Axis_": "label_position_adjustment_y_axis"}, - {"Flip_Contrast": "flip_contrast"}, - {"Color_of_Non_Significant_Genes": "color_of_non_significant_genes"}, - {"Point_Size": "point_size"}, - {"Color_of_Log_Fold_Change_Threshold_Line": "color_of_log_fold_change_threshold_line"}, - {"Color_of_P_Value_Threshold_Line": "color_of_p_value_threshold_line"}, - {"Color_of_Genes_Meeting_Only_P_Value_Threshold": "color_of_genes_meeting_only_p_value_threshold"}, - {"color_for_genes_meeting_p_value_and_fold_change_thresholds": "color_for_genes_meeting_p_value_and_fold_change_thresholds"}, - {"Label_Font_Type": "label_font_type"}, - {"Label_Font_Size": "label_font_size"}, - {"Line_Segment_Thickness": "line_segment_thickness"}, - {"Figure_Aspect_Ratio": "figure_aspect_ratio"}, - {"Use_Default_Grid_Layout": "use_default_grid_layout"}, - {"Number_of_Rows_in_Grid_Layout": "number_of_rows_in_grid_layout"} - ] - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Normalization_CCBR_.code-template.json b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Normalization_CCBR_.code-template.json deleted file mode 100644 index 5f74711..0000000 --- a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Normalization_CCBR_.code-template.json +++ /dev/null @@ -1,378 +0,0 @@ -{ - "codeTemplate": "Normalized_Counts <- function({{{counts_matrix}}}, {{{Sample_Metadata}}}) {\n \n ## --------- ##\n ## Libraries ##\n ## --------- ##\n\n library(limma)\n library(tidyverse)\n library(edgeR)\n library(ggplot2)\n library(plotly)\n library(dplyr)\n library(RColorBrewer)\n library(colorspace)\n library(stringr)\n library(RCurl)\n library(reshape2)\n library(gridExtra)\n library(amap)\n library(lattice)\n library(gplots)\n library(gridGraphics)\n library(dendsort)\n\n\n ## -------------------------------- ##\n ## User-Defined Template Parameters ##\n ## -------------------------------- ##\n \n #Basic Parameters:\n counts_matrix <- {{{counts_matrix}}}\n sample_metadata <- {{{Sample_Metadata}}}\n gene_names_column <- \"{{{Feature_ID_Column}}}\"\n columns_to_include = {{{Columns_to_Include}}}\n sample_names_column <- \"{{{Sample_Names_Column}}}\"\n groups_column <- \"{{{Groups_Column}}}\"\n labels_column <- \"{{{Labels_Column}}}\"\n\n\n #Normalization Parameters:\n input_in_log_counts <- {{{Input_in_Log_Counts}}}\n normalization_method <- \"{{{Normalization_Method}}}\"\n \n #PCA parameters:\n samples_to_rename_manually_on_pca <- {{{Samples_to_Rename_Manually_on_PCA}}}\n add_labels_to_pca <- {{{Add_Labels_to_PCA}}}\n principal_component_on_x_axis_for_pca <- {{{Principal_Component_on_X_axis_for_PCA}}}\n principal_component_on_y_axis_for_pca <- {{{Principal_Component_on_Y_axis_for_PCA}}}\n legend_position_for_pca <- \"{{{Legend_position_for_PCA}}}\"\n label_offset_x_for_pca <- {{{Label_Offset_x_for_PCA}}}\n label_offset_y_for_pca <- {{{Label_Offset_y_for_PCA}}}\n label_font_size_for_pca <- {{{Label_Font_Size_for_PCA}}}\n point_size_for_pca <- {{{Point_Size_for_PCA}}}\n\n #Histogram parameters:\n color_histogram_by_group <- {{{Color_Histogram_by_Group}}}\n set_min_max_for_x_axis_for_histogram <- {{{Set_Min_Max_for_X_axis_for_Histogram}}} \n minimum_for_x_axis_for_histogram <- {{{Minimum_for_X_axis_in_Histogram}}}\n maximum_for_x_axis_for_histogram <- {{{Maximum_for_X_axis_in_Histogram}}}\n legend_font_size_for_histogram <- {{{Legend_Font_Size_for_Histogram}}}\n legend_position_for_histogram <- \"{{{Legend_Position_for_Histogram}}}\"\n number_of_histogram_legend_columns <- {{{Number_of_Histogram_Legend_Columns}}}\n \n #Visualization Parameters:\n number_of_image_rows <- {{{Number_of_Image_Rows}}}\n colors_for_plots <- {{{Colors_for_Plots}}}\n make_plots_interactive <- {{{Make_Plots_Interactive}}}\n plot_correlation_matrix_heatmap <- {{{Plot_Correlation_Matrix_Heatmap}}}\n \n\n ##--------------- ##\n ## Error Messages ##\n ## -------------- ##\n\n \n ## --------- ##\n ## Functions ##\n ## --------- ##\n\n getourrandomcolors<-function(k){\n seed=10\n n <- 2e3\n ourColorSpace <- colorspace::RGB(runif(n), runif(n), runif(n))\n ourColorSpace <- as(ourColorSpace, \"LAB\")\n currentColorSpace <- ourColorSpace@coords\n # Set iter.max to 20 to avoid convergence warnings.\n set.seed(seed)\n km <- kmeans(currentColorSpace, k, iter.max=20)\n return( unname(hex(LAB(km$centers))))\n }\n\n make_heatmap <- function(counts_matrix, metadata,colorval) {\n mat <- as.matrix(counts_matrix) \n tcounts=t(mat)\n tcounts=merge(metadata,tcounts,by.x=sample_names_column,by.y='row.names')\n rownames(tcounts)=tcounts[,labels_column]\n tcounts=tcounts[,!colnames(tcounts)%in%colnames(metadata)]\n d=Dist(tcounts,method=\"correlation\",diag=TRUE)\n dend = rev(dendsort(as.dendrogram(hclust( d,method=\"average\"))))\n m=as.matrix(d)\n sample_metadata <- metadata\n rownames(sample_metadata) = sample_metadata[[labels_column]]\n idx = as.factor(sample_metadata[rownames(m),groups_column])\n col = colorval\n cols <- col[idx]\n new.palette=colorRampPalette(c(\"blue\",\"green\",\"yellow\"),space=\"rgb\")\n \n mk<-function(){\n if(length(colnames(m))>20){\n par(mar=c(0,0,0,0))\n heatmap.2(m,\n labRow = NA, \n labCol = NA,\n col=new.palette(20),\n trace=\"none\",\n colRow = col[idx], \n colCol = col[idx],\n rowDendrogram=dend,\n colDendrogram=dend,\n RowSideColors = col[idx],\n ColSideColors = col[idx],\n dendrogram = \"row\",\n cexRow=3,\n cexCol=3,\n margins=c(0,0), \n lmat=rbind( c(0,0,2),c(4,1,3) ,c(0,5,6) ), \n lhei=c(.2,4,2), \n lwid=c(1, .2,4 ), \n key.par=list(mgp=c(1.75, .5, 0), \n mar=c(7, 2, 3.5, 0), \n cex.axis=.1, \n cex.lab=3, \n cex.main=1, \n cex.sub=1),\n key.xlab = \"Correlation\",\n key.ylab=\"Count\",\n key.title=\" \") \n } else {\n heatmap.2(m,col=new.palette(20),\n trace=\"none\",\n colRow = col[idx], \n colCol = col[idx],\n rowDendrogram=dend,\n colDendrogram=dend,\n RowSideColors = col[idx],\n ColSideColors = col[idx],\n dendrogram = \"row\",\n cexRow=3,cexCol=3,margins=c(4,1), \n lmat=rbind( c(0,0,2),c(4,1,3) ,c(0,5,6) ), \n lhei=c( .2,4,2), \n lwid=c(1, .2,4),\n key.par=list(mgp=c(1.75, .5, 0), mar=c(7, 2, 3.5, 0), cex.axis=.1, cex.lab=3, cex.main=1, cex.sub=1),\n key.xlab = \"Correlation\",\n key.ylab=\"Count\",\n key.title=\" \")\n }\n }\n \n tg<-mk()\n grid.echo(mk)\n gh1<-grid.grab()\n mklegend<-function(){\n plot.new()\n legend(x=\"top\", legend=levels(idx), col=col[as.factor(levels(idx))],pch=15,x.intersp=3,bty =\"n\",cex=2)\n }\n grid.echo(mklegend )\n gh2<-grid.grab()\n lay <- c(1,3)\n grid.newpage()\n grid.arrange(gh1,gh2,nrow=1,widths=c(unit(1000, \"bigpts\"),unit(300, \"bigpts\")))\n gh<-grid.grab()\n return(gh)\n }\n\n ## --------------- ##\n ## Main Code Block ##\n ## --------------- ##\nsamples_to_include=columns_to_include[columns_to_include%in%sample_metadata[,sample_names_column,drop=T]]\n anno_col=columns_to_include[columns_to_include%in%sample_metadata[,sample_names_column,drop=T]==F]\n\n\n samples_to_include <- samples_to_include[samples_to_include != gene_names_column]\n samples_to_include <- samples_to_include[samples_to_include != \"Gene\"]\n samples_to_include <- samples_to_include[samples_to_include != \"GeneName\"]\n \n##create unique rownames to correctly add back Annocolumns at end of template\ncounts_matrix[,gene_names_column]=paste0(counts_matrix[,gene_names_column],'_',1:nrow(counts_matrix))\n\n\n anno_col=c(anno_col,gene_names_column)%>%unique\n anno_tbl=counts_matrix[,anno_col,drop=F]%>%as.data.frame\n \n \n df.filt <- counts_matrix[,samples_to_include]\n gene_names <- NULL\n gene_names$GeneID <- counts_matrix[,1]\n\n \n \n sample_metadata <- sample_metadata[match(colnames(df.filt),sample_metadata[[sample_names_column]]),] #First match sample metadata to counts matrix\n sample_metadata <- sample_metadata[rowSums(is.na(sample_metadata)) != ncol(sample_metadata), ] # Remove empty rows\n sample_metadata <- sample_metadata[, colSums(is.na(sample_metadata)) == 0] #Remove empty columns\n rownames(sample_metadata) <- sample_metadata[[sample_names_column]]\n\n df.filt <- df.filt[,match(sample_metadata[[sample_names_column]],colnames(df.filt))] #Match counts matrix columns to sample metadata\n \n #If input is in log space, linearize\n if(input_in_log_counts == TRUE){\n x <- DGEList(counts=2^df.filt, genes=gene_names)\n } else {\n x <- DGEList(counts=df.filt, genes=gene_names) \n }\n\n v <- voom(x,normalize=normalization_method)\n rownames(v$E) <- v$genes$GeneID\n as.data.frame(v$E) %>% rownames_to_column(gene_names_column) -> df.voom\n print(paste0(\"Total number of features included: \", nrow(df.voom)))\n\n #Start PCA Plot:\n \n edf <- v$E\n tedf <- t(edf)\n tedf <- tedf[, colSums(is.na(tedf)) != nrow(tedf)]\n tedf <- tedf[, apply(tedf, 2, var) != 0]\n pca <- prcomp(tedf, scale.=T)\n \n pcx <- paste0(\"PC\",principal_component_on_x_axis_for_pca)\n pcy <- paste0(\"PC\",principal_component_on_y_axis_for_pca)\n pca.df <- as.data.frame(pca$x) %>% dplyr::select(.data[[pcx]], .data[[pcy]])\n pca.df$group <- sample_metadata[[groups_column]]\n pca.df$sample <- sample_metadata[[labels_column]]\n perc.var <- (pca$sdev^2/sum(pca$sdev^2))*100\n perc.var <- formatC(perc.var,format = \"g\",digits=4)\n pc.x.lab <- paste0(pcx,\" \", perc.var[principal_component_on_x_axis_for_pca],\"%\")\n pc.y.lab <- paste0(pcy,\" \", perc.var[principal_component_on_y_axis_for_pca],\"%\")\n labelpos <- pca.df\n labelpos$mean_y <- pca.df[[pcy]]+label_offset_y_for_pca\n labelpos$mean_x <- pca.df[[pcx]]+label_offset_x_for_pca\n pca.df$xdata <- pca.df[[pcx]]\n pca.df$ydata <- pca.df[[pcy]]\n\n # Manual changes to sample names\n replacements = samples_to_rename_manually_on_pca\n\n if (!is.null(replacements)) {\n if (replacements != c(\"\")) {\n for (x in replacements) {\n old <- strsplit(x, \": ?\")[[1]][1]\n new <- strsplit(x, \": ?\")[[1]][2]\n pca.df$sample <- ifelse(pca.df$sample==old, new, pca.df$sample)\n }\n }\n }\n\n colorlist <- c(\"#5954d6\",\"#e1562c\",\"#b80058\",\"#00c6f8\",\"#d163e6\",\"#00a76c\",\"#ff9287\",\"#008cf9\",\"#006e00\",\"#796880\",\"#FFA500\",\"#878500\")\n names(colorlist) <- c(\"indigo\",\"carrot\",\"lipstick\",\"turquoise\",\"lavender\",\"jade\",\"coral\",\"azure\",\"green\",\"rum\",\"orange\",\"olive\")\n if(length(colors_for_plots) == 0){\n colors_for_plots <- c(\"indigo\",\"carrot\",\"lipstick\",\"turquoise\",\"lavender\",\"jade\",\"coral\",\"azure\",\"green\",\"rum\",\"orange\",\"olive\")\n }\n colorval <- colorlist[colors_for_plots]\n colorval <- unname(colorval) #remove names which affect ggplot\n\n if (length(unique(sample_metadata[[groups_column]])) > length(colorval)) {\n ## Original color-picking code.\n k=length(unique(sample_metadata[[groups_column]]))-length(colorval)\n more_cols<- getourrandomcolors(k) \n colorval <- c(colorval , more_cols)\n }\n\n if (add_labels_to_pca == TRUE){\n g <- ggplot(pca.df, aes(x=xdata, y=ydata)) +\n theme_bw() +\n theme(legend.title=element_blank()) +\n theme(legend.position=legend_position_for_pca) +\n geom_point(aes(color=group), size=point_size_for_pca) +\n geom_text(data=labelpos, aes(x=labelpos$mean_x, y=labelpos$mean_y, \n label=sample, color=group, vjust=\"inward\", hjust=\"inward\"), size=label_font_size_for_pca, show.legend=FALSE) +\n theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),\n panel.background = element_blank()) +\n scale_colour_manual(values = colorval) +\n xlab(pc.x.lab) + ylab(pc.y.lab)\n } else {\n g <- ggplot(pca.df, aes(x=xdata, y=ydata)) +\n theme_bw() +\n theme(legend.title=element_blank()) +\n theme(legend.position=legend_position_for_pca) +\n geom_point(aes(color=group,text=sample), size=point_size_for_pca) +\n theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),\n panel.background = element_blank()) +\n scale_colour_manual(values = colorval) +\n xlab(pc.x.lab) + ylab(pc.y.lab) \n }\n\n par(mfrow = c(2,1))\n\n #Histogram Plot:\n \n df.m <- melt(edf,id.vars=c(gene_names_column))\n df.m = dplyr::rename(df.m,sample=Var2)\n\n if(set_min_max_for_x_axis_for_histogram == TRUE){\n xmin = minimum_for_x_axis_for_histogram\n xmax = maximum_for_x_axis_for_histogram\n } else {\n xmin = min(df.m$value)\n xmax = max(df.m$value)\n }\n\n if(color_histogram_by_group == TRUE){\n df.m %>% mutate(colgroup = sample_metadata[sample,groups_column]) -> df.m\n df.m = df.m[complete.cases(df.m[, \"colgroup\"]),]\n df.m$colgroup = gsub(\"\\\\s\",\"_\",df.m$colgroup)\n df.m$colgroup = factor(df.m$colgroup, levels=unique(df.m$colgroup))\n #print(unique(df.m$sample))\n\n # plot Density \n g2 = ggplot(df.m, aes(x=value, group=sample)) + \n geom_density(aes(colour = colgroup)) +\n xlab(\"Filtered Counts\") + ylab(\"Density\") +\n theme_bw() +\n theme(legend.position=legend_position_for_histogram,legend.text = element_text(size = legend_font_size_for_histogram)) + \n ggtitle(\"Frequency Histogram\") +\n xlim(xmin,xmax) +\n #scale_linetype_manual(values=rep(c('solid', 'dashed','dotted','twodash'),40)) +\n scale_colour_manual(values=colorval)\n } else {\n \n df.m$sample = sample_metadata[df.m$sample,labels_column]\n n=length(unique(df.m$sample))\n cols<- getourrandomcolors(n) \n \n g2 = ggplot(df.m, aes(x=value, group=sample)) + \n geom_density(aes(colour = sample)) +\n xlab(\"Filtered Counts\") + ylab(\"Density\") +\n theme_bw() +\n theme(legend.position=legend_position_for_histogram,legend.text = element_text(size = legend_font_size_for_histogram)) + \n ggtitle(\"Frequency Histogram\") +\n xlim(xmin,xmax) +\n #scale_linetype_manual(values=rep(c('solid', 'dashed','dotted','twodash'),n)) +\n scale_colour_manual(values=cols)#+\n guides(linetype = guide_legend(ncol = number_of_histogram_legend_columns))\n }\n\n # dev.off()\n\n imageWidth = 3000\n imageHeight = 1500*2\n dpi = 300\n\n png(\n filename=graphicsFile,\n width=imageWidth,\n height=imageHeight,\n units=\"px\",\n pointsize=4,\n bg=\"white\",\n res=dpi,\n type=\"cairo\")\n\n if(plot_correlation_matrix_heatmap == TRUE){\n if(make_plots_interactive == TRUE){\n p1=(g)%>%ggplotly(tooltip = c(\"sample\",\"group\"))\n p2=(g2+theme(legend.position = \"none\")) %>%ggplotly(tooltip = c(\"sample\"))\n fig=subplot(p1,p2,which_layout = 'merge',margin=.05,shareX = F,shareY = F,titleY = T,titleX = T,widths=c(.5,.5),nrows = 1)\n fig=fig %>% layout(title = 'Interactive PCA and Histogram')\n print(fig)\n } else {\n require(gridExtra)\n gh<-make_heatmap(df.filt,sample_metadata,colorval)\n grid.arrange(g,g2,gh, nrow=number_of_image_rows)\n # dev.off()\n } \n } else {\n if(make_plots_interactive == TRUE){\n p1=(g)%>%ggplotly(tooltip = c(\"sample\",\"group\"))\n p2=(g2+theme(legend.position = \"none\")) %>%ggplotly(tooltip = \"sample\" )\n fig=subplot(p1,p2,which_layout = 'merge',margin=.05,shareX = F,shareY = F,titleY = T,titleX = T,widths=c(.5,.5),nrows = 1)\n fig=fig %>% layout(title = 'Interactive PCA and Histogram')\n print(fig)\n } else {\n grid.arrange(g,g2, nrow=number_of_image_rows)\n # dev.off()\n }\n } \n\nprint(\"Sample columns\")\nprint(colnames(df.voom)[!colnames(df.voom)%in%gene_names_column])\nprint(\"Feature Columns\")\nprint(colnames(anno_tbl))\n\n df.voom=merge(anno_tbl,df.voom,by=gene_names_column,all.y=T)\n df.voom[,gene_names_column]=gsub('_[0-9]+$',\"\",df.voom[,gene_names_column])\n\n return(df.voom)\n}\n\n#################################################\n## Global imports and functions included below ##\n#################################################\n\n", - "columns": [ - { - "key": "Feature_ID_Column", - "displayName": "Feature ID Column", - "description": "The column from your input Counts Matrix containing the Feature IDs (Usually Gene or Protein ID). This is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts Matrix will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Columns_to_Include", - "displayName": "Columns to Include", - "description": "Which Columns would you like to include? Usually, you will choose to \"Add all\" (see button on right). Columns excluded here will be removed in this step and from further analysis downstream of this step.", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "Sample_Names_Column", - "displayName": "Sample Names Column", - "description": "The column from your input Sample Metadata table containing the sample names. The names in this column must exactly match the names used as the sample column names of your input Counts Matrix. Only columns of Text type from your input Sample Metadata table will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Groups_Column", - "displayName": "Groups Column", - "description": "The column from your input Sample Metadata table containing the sample group information. This is usually a column showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal, Before, After, etc.). Only columns of Text type from your input Sample Metadata will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "Labels_Column", - "displayName": "Labels Column", - "description": "The column from your input Sample Metadata table containing the sample labels as you wish them to appear in the plots produced by this template. This can be the same Sample Names Column (see above). However, you may desire different labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the column with your preferred Labels here.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - } - ], - "condaDependencies": [], - "description": "This template is intended for use with Bulk RNA-seq data and is often performed immediately after filtering for low count genes. It normalizes RNA-seq expression data to account for factors that would prevent direct comparisons between samples.\n\nThis template takes as input a counts matrix (usually the filtered counts matrix) and your sample metadata table. It provides as output an image consisting of three QC plots (see below) and a normalized expression matrix.\n\nThe default normalization method is quantile, which is a very common way to normalize bulk RNA-seq data. Other normalization methods are selectable, as needed.\n\nThe QC plots provided are: (1) PCA Plot: shows the within- and between-group variance in expression after dimensionality reduction; (2) Count Density Histogram: shows the dis/similarity of count distributions between samples; and (3) Similarity Heatmap: shows the overall similarity of samples to one another based on unsupervised clustering.", - "externalId": "Normalization_CCBR_", - "inputDatasets": [ - { - "key": "counts_matrix", - "displayName": "Counts Matrix", - "description": "The input Counts Matrix. Usually, this will be your Filtered Counts matrix.", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - }, - { - "key": "Sample_Metadata", - "displayName": "Sample Metadata", - "description": "The Sample Metadata table containing your sample metadata. At minimum, this table must include one column each of the following: Samples, Groups, Batches, and Labels. The names in the Samples column of your input Sample Metadata must match the Sample Column Names of your input Counts Matrix exactly. You may have more than one column showing different Groups by which your samples may be organized (e.g. Genotype, Response, Time, etc.).", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - } - ], - "vectorLanguage": "R", - "codeLanguage": "R", - "parameters": [ - { - "key": "Input_in_Log_Counts", - "displayName": "Input in Log Counts", - "description": "TRUE if input is in log counts", - "paramType": "BOOLEAN", - "paramGroup": "Normalization", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Normalization_Method", - "displayName": "Normalization Method", - "description": "Normalization method to be applied to the logCPM values", - "paramType": "SELECT", - "paramGroup": "Normalization", - "paramValues": [ - "none", - "scale", - "quantile", - "cyclicloess" - ], - "defaultValue": "quantile", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Samples_to_Rename_Manually_on_PCA", - "displayName": "Samples to Rename Manually on PCA", - "description": "Enter each sample to rename in the format: old_name: new_name", - "paramType": "VECTOR", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "c(\"\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Add_Labels_to_PCA", - "displayName": "Add Labels to PCA", - "description": "Toggle to TRUE to use the column from \"Label Column to Use for Plots\" (above) to label points on the PCA plot. Toggle to FALSE to remove these labels from the plot. Default is TRUE.", - "paramType": "BOOLEAN", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Principal_Component_on_X_axis_for_PCA", - "displayName": "Principal Component on X-axis for PCA", - "description": "The principle component to plot on the x-axis. Choices include 1, 2, 3, ... (default: 1)", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Principal_Component_on_Y_axis_for_PCA", - "displayName": "Principal Component on Y-axis for PCA", - "description": "The principle component to plot on the y-axis. Choices include 1, 2, 3, ... (default: 2)", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Legend_position_for_PCA", - "displayName": "Legend position for PCA", - "description": "Legend position relative to the plot", - "paramType": "SELECT", - "paramGroup": "PCA", - "paramValues": [ - "top", - "bottom", - "left", - "right", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Offset_x_for_PCA", - "displayName": "Label Offset (x) for PCA", - "description": "", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Offset_y_for_PCA", - "displayName": "Label Offset (y) for PCA", - "description": "", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Font_Size_for_PCA", - "displayName": "Label Font Size for PCA", - "description": "Font size for sample labels on the PCA. Set to 0 to remove labels.", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "3", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Point_Size_for_PCA", - "displayName": "Point Size for PCA", - "description": "Size of a each data point on the PCA.", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Color_Histogram_by_Group", - "displayName": "Color Histogram by Group", - "description": "Toggle to FALSE to label histogram by Sample Names. Toggle to TRUE to label histogram by the column you select in the \"Group Column Used to Color Histogram\" parameter (below). Default is FALSE.", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Maximum_for_X_axis_in_Histogram", - "displayName": "Maximum for X-axis in Histogram", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Minimum_for_X_axis_in_Histogram", - "displayName": "Minimum for X-axis in Histogram", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "-1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Set_Min_Max_for_X_axis_for_Histogram", - "displayName": "Set Min/Max for X-axis for Histogram", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Legend_Font_Size_for_Histogram", - "displayName": "Legend Font Size for Histogram", - "description": "Legend font size for the histogram.", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "10", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Legend_Position_for_Histogram", - "displayName": "Legend Position for Histogram", - "description": "Legend position on histogram plot, can be 'none' if large number of samples", - "paramType": "SELECT", - "paramGroup": "Histogram", - "paramValues": [ - "top", - "bottom", - "left", - "right", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Number_of_Histogram_Legend_Columns", - "displayName": "Number of Histogram Legend Columns", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "6", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Colors_for_Plots", - "displayName": "Colors for Plots", - "description": "Colors for the PCA and histogram will be picked, in order, from this list. If more colors are needed, program will choose from a wide range of random colors", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "indigo", - "carrot", - "lipstick", - "turquoise", - "lavender", - "jade", - "coral", - "azure", - "green", - "rum", - "orange", - "olive" - ], - "defaultValue": "c(\"indigo\",\"carrot\",\"lipstick\",\"turquoise\",\"lavender\",\"jade\",\"coral\",\"azure\",\"green\",\"rum\",\"orange\",\"olive\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Number_of_Image_Rows", - "displayName": "Number of Image Rows", - "description": "1 = side-by-side, 2 = stacked", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Make_Plots_Interactive", - "displayName": "Make Plots Interactive", - "description": "Toggle TRUE to make PCA and Histogram plots interactive, allowing you to hover your mouse over a point or line to view sample information. The similarity heatmap will not display if this toggle is set to TRUE. Default is FALSE.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Plot_Correlation_Matrix_Heatmap", - "displayName": "Plot Correlation Matrix Heatmap", - "description": "Datasets with a large number of samples may be too large to create a correlation matix Heatmap. If Template takes longer than 5 min to run Toggle switch to off and the correlation matrix will not be be created", - "paramType": "BOOLEAN", - "paramGroup": "TCGA", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "title": "Normalization [CCBR]", - "templateApiVersion": "0.1.0" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/PCA_3D_CCBR_.code-template.json b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/PCA_3D_CCBR_.code-template.json deleted file mode 100644 index 16d088d..0000000 --- a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/PCA_3D_CCBR_.code-template.json +++ /dev/null @@ -1,229 +0,0 @@ -{ - "codeTemplate": "PCA_3D <- function({{{Counts_Matrix}}}, {{{Sample_Metadata_Table}}}) {\n\n## This function generates an interactive 3D PCA plot\n\n## --------- ##\n## Libraries ##\n## --------- ##\n\nlibrary(edgeR)\nlibrary(colorspace)\nlibrary(plotly)\nlibrary(htmlwidgets)\n \n## -------------------------------- ##\n## User-Defined Template Parameters ##\n## -------------------------------- ##\n\n# Basic parmaters\nCounts_Matrix <- {{{Counts_Matrix}}}\nSample_Metadata_Table <- {{{Sample_Metadata_Table}}}\nFeatureID_Name_Column <- \"{{{FeatureID_Name_Column}}}\"\nSample_Names_Column <- \"{{{Sample_Names_Column}}}\"\nSamples_to_Include <- {{{Samples_to_Include}}}\nGroup_Column <- \"{{{Group_Column}}}\"\nPlot_Labels_Column <-\"{{{Plot_Labels_Column}}}\"\nSamples_to_Rename_Manually <- {{{Samples_to_Rename_Manually}}}\n# Advanced parameters\nOutlier_Samples_to_Remove <- {{{Outlier_Samples_to_Remove}}}\nUse_CPM <- {{{Use_CPM}}} \n# Visualization parameters\nPoints_Size <-{{{Point_Size}}}\nPoint_Color <- {{{Point_Color}}}\nPlot_Title <- \"{{{Plot_Title}}}\" \n\n##--------------- ##\n## Error Messages ##\n## -------------- ##\n\n## --------- ##\n## Functions ##\n## --------- ##\n\n# generate random colors\ngetourrandomcolors <- function(k) {\n seed = 10\n n <- 2e3\n ourColorSpace <- colorspace::RGB(runif(n), runif(n), runif(n))\n ourColorSpace <- as(ourColorSpace, \"LAB\")\n currentColorSpace <- ourColorSpace@coords\n # Set iter.max to 20 to avoid convergence warnings.\n set.seed(seed) \n km <- kmeans(currentColorSpace, k, iter.max = 20)\n return(unname(hex(LAB(km$centers))))\n}\n\n## --------------- ##\n## Main Code Block ##\n## --------------- ##\n\n###########################################\n#This code block does input data validation\n\n# get the sample data\n\n# remove outliers\nSamples_to_Include <-\n Samples_to_Include[!Samples_to_Include %in% Outlier_Samples_to_Remove]\n# include samples\nSamples_to_Include <-\n Samples_to_Include[Samples_to_Include != FeatureID_Name_Column]\n cat(sprintf(\"Total number of samples included in the PCA plot: %g\", length(Samples_to_Include)))\nCounts_Matrix[, append(FeatureID_Name_Column, Samples_to_Include)] -> df\nSample_Metadata_Table <-\n Sample_Metadata_Table[Sample_Metadata_Table[, Sample_Names_Column] %in% Samples_to_Include, ]\nSampinfo <- Sample_Metadata_Table\ncolnames(df)[colnames(df) == FeatureID_Name_Column] <- \"Gene\"\ndf -> edf.orig\n\n###### PCA plot ##############\n\n# evaluate and display PCA plot\nrownames(Sampinfo) <- Sampinfo[, Sample_Names_Column]\nSampinfo <-\n Sampinfo[match(colnames(edf.orig[, -1]), Sampinfo[, Sample_Names_Column]),]\nSampinfo = Sampinfo[complete.cases(Sampinfo[, Sample_Names_Column]), ]\ncat(paste0(\n \"\\nTotal number of genes included in the PCA plot: \",\n nrow(edf.orig)\n))\nedf <- edf.orig[, match(Sampinfo[, Sample_Names_Column], colnames(edf.orig))]\nidx = !rowMeans(edf) == 0\nif (Use_CPM) {\n edf = edgeR::cpm(edf[idx, ])\n}\nedf.orig = edf.orig[idx, ]\ntedf <- t(edf)\ncolnames(tedf) <- edf.orig[, 1]\ntedf <- tedf[, colSums(is.na(tedf)) != nrow(tedf)]\ntedf <- tedf[, apply(tedf, 2, var) != 0]\npca <- prcomp(tedf, scale. = T)\npca.df <- as.data.frame(pca$x)\npca.df$group <- Sampinfo[, Group_Column]\npca.df$sample <- Sampinfo[, Plot_Labels_Column]\n\n# pca stats\nstats <-\n data.frame(id = paste0(\"PC\", 1:length(pca$sdev)),\n eigenvalue = (pca$sdev) ^ 2) %>% mutate(variance = eigenvalue * 100 / sum(eigenvalue)) %>% mutate(cumvariance =\n cumsum(variance)) %>% mutate(\n variance_label = sprintf(\"%s (%.1f%% variance)\", id, variance),\n cumvariance_label = sprintf(\"%s (%.1f%% cumulative variance)\", id, cumvariance)\n )\naxis_title = sub(\" variance\", \"\", stats$variance_label)\n# if rename samplea\nif (!is.null(Samples_to_Rename_Manually)) {\n if (Samples_to_Rename_Manually != c(\"\")) {\n for (x in Samples_to_Rename_Manually) {\n old <- strsplit(x, \": ?\")[[1]][1]\n new <- strsplit(x, \": ?\")[[1]][2]\n pca.df$sample <-\n ifelse(pca.df$sample == old, new, pca.df$sample)\n }\n }\n}\n# set the colors to be used in the plot\nif (length(unique(Sampinfo[, Group_Column])) > length(Point_Color)) {\n ## Original color-picking code.\n k = length(unique(Sampinfo[, Group_Column])) - length(Point_Color)\n more_cols <- getourrandomcolors(k)\n Point_Color <- c(Point_Color , more_cols)\n} else {\n Point_Color <- Point_Color[1:length(unique(Sampinfo[, Group_Column]))]\n}\nnames(Point_Color) <- unique(Sampinfo[, Group_Column])\n# set label size (may add to user-defined parameters in the future)\nLabel_Font_Size <- 24\n\n# plot PCA\ncat(\"\\nRunning PCA...\")\nfig <- plot_ly(\n pca.df,\n x = ~ PC1,\n y = ~ PC2,\n z = ~ PC3,\n color = ~ group,\n colors = Point_Color,\n type = \"scatter3d\",\n mode = \"markers\",\n marker = list(size = Points_Size),\n hoverinfo = 'text',\n text = ~ sample,\n size = Label_Font_Size\n )\nlegend = TRUE\nif (legend == FALSE) {\n fig <- hide_legend(fig)\n}\nfig <-\n fig %>% layout(\n title = list(text = Plot_Title, size = 5),\n scene = list(\n xaxis = list(title = axis_title[1]),\n yaxis = list(title = axis_title[2]),\n zaxis = list(title = axis_title[3])\n ),\n legend = list(\n itemsizing = 'constant',\n size = 12,\n y = 0.5\n )\n)\n \n###### OUTPUT ##############\n# save in dataset container\noutput <- new.output()\noutput_fs <- output$fileSystem()\n# html widget\nhtml_file <- sprintf(\"Plot_%s.html\", gsub(\" \", \"_\", Plot_Title))\nhtmlwidgets::saveWidget(fig, html_file)\noutput_fs$upload(html_file, html_file)\ncat(sprintf(\"\\nFiles saved in the output dataset:\\n• %s\", html_file))\n# components table\ncomponent_file <-\n sprintf(\"Components_%s.csv\", gsub(\" \", \"_\", Plot_Title))\n write.csv(stats, row.names = FALSE, output_fs$get_path (component_file, 'w'))\ncat(sprintf(\"\\n• %s\", component_file))\n# coordinates table\ncoordinate_file <-\n sprintf(\"Coordinates_%s.csv\", gsub(\" \", \"_\", Plot_Title))\nwrite.csv(pca.df,\n row.names = FALSE,\n output_fs$get_path(coordinate_file, 'w'))\ncat(sprintf(\"\\n• %s\", coordinate_file))\n \n ## keep for later solution to quality of the downloaded static image\n #fig = config(fig, toImageButtonOptions = list(format= 'svg', # one of png, svg, jpeg, webp\n #filename= sub(\".html\",\"\", html_file), height= 300, width= 500, scale= 1)) \n \n# display visualization\nprint(fig)\n\n}\n\n## ---------------------------- ##\n## Global Imports and Functions ##\n## ---------------------------- ##\n\n## Functions defined here will be available to call in\n## the code for any table.\n\n## --------------- ##\n## End of Template ##\n## --------------- ##\n", - "columns": [ - { - "key": "FeatureID_Name_Column", - "displayName": "FeatureID Name Column", - "description": "The column from your counts matrix containing the Feature IDs (such as gene names, isoform names and so on). This is usually the first column of your counts matrix.", - "paramGroup": "Basic", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Sample_Names_Column", - "displayName": "Sample Names Column", - "description": "The column from your sample metadata table containing the sample names. These should be the same as the sample names found in the column names of the counts matrix.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Samples_to_Include", - "displayName": "Samples to Include", - "description": "Which samples would you like to include? Usually, you will choose to \"Add all\" samples. Excluded samples will be removed from downstream analysis. Only Numeric columns can be selected.", - "paramGroup": "Basic", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "NUMBER", - "isMulti": true - }, - { - "key": "Group_Column", - "displayName": "Group Column", - "description": "The column from your sample metadata table containing sample group information. This is usually a column showing which of your experimental treatments each sample belongs to (e.g. WildType, Knockout, Tumor, Normal, Before, After, etc.).", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "Plot_Labels_Column", - "displayName": "Plot Labels Column", - "description": "The column from your sample metadata table containing the sample names as you wish them to appear in the QC figure. This is often the same Sample Name Column (see parameter above). However, you may desire different labels to display on your PCA figure (e.g. shorter labels). These labels can be added as an additional column in your metadata table and used here to label your plot.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "Outlier_Samples_to_Remove", - "displayName": "Outlier Samples to Remove", - "description": "Enter outlier samples you want to remove from analysis here and downstream of this template.", - "paramGroup": "Advanced", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "NUMBER", - "isMulti": true - } - ], - "condaDependencies": [], - "description": "This template is based on Bulk RNA-seq QC PCA template and is intended to provide interactive 3D view of a PCA plot generated from the data.", - "externalId": "PCA_3D_CCBR_", - "inputDatasets": [ - { - "key": "Counts_Matrix", - "displayName": "Counts Matrix", - "description": "The input counts matrix from which you want to build a 3D PCA plot. This will usually be either Filtered Counts, Normalized Counts, or Batch Corrected Counts.", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - }, - { - "key": "Sample_Metadata_Table", - "displayName": "Sample Metadata Table", - "description": "The input sample metadata table.", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - } - ], - "vectorLanguage": "R", - "codeLanguage": "R", - "parameters": [ - { - "key": "Samples_to_Rename_Manually", - "displayName": "Samples to Rename Manually", - "description": "If you do not have a Plot Labels Column (see above) in your sample metadata table, you can use this parameter to rename samples manually for display on the PCA plot. Use \"Add item\" to add each additional sample for renaming. Use the following format to describe which old name (in your sample metadata table) you want to rename to which new name:\n\nold_name: new_name", - "paramType": "VECTOR", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Use_CPM", - "displayName": "Use CPM", - "description": "Set to TRUE if you want to enable CPM normalization for counts matrix", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Point_Size", - "displayName": "Point Size", - "description": "The size of the points in the 3D PCA plot.", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "8", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Point_Color", - "displayName": "Point Color", - "description": "Colors for the PCA will be picked, in order, from this list. There are thousands of colors. You may remove or add colors as you choose, but take care that there are always at least as many colors in this list than you need to color items in your plot.\n\nExample: if you are coloring by Group and have 3 groups, you should have at least 3 colors in your list.", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "slateblue3", - "tomato2", - "maroon", - "deepskyblue", - "mediumorchid2", - "mediumseagreen", - "salmon", - "dodgerblue", - "darkgreen", - "plum4", - "orange", - "yellow4", - "aquamarine3", - "salmon1", - "lightskyblue3", - "plum3", - "firebrick", - "darkolivegreen3", - "goldenrod1", - "burlywood2", - "gray70", - "firebrick2", - "steelblue", - "palegreen4", - "orchid4", - "darkorange1", - "yellow", - "sienna", - "palevioletred1", - "gray60", - "cyan4", - "darkorange3", - "mediumpurple3", - "violetred2", - "olivedrab", - "darkgoldenrod2", - "darkgoldenrod", - "gray40", - "palegreen3", - "thistle3", - "khaki1", - "deeppink2", - "chocolate3", - "paleturquoise3", - "wheat1", - "lightsteelblue", - "sandybrown", - "darkolivegreen2", - "thistle2", - "gray85", - "orchid3", - "darkseagreen1", - "lightgoldenrod1", - "lightskyblue2", - "dodgerblue3", - "darkseagreen3", - "forestgreen", - "lightpink2", - "mediumpurple4", - "lightpink1", - "thistle", - "navajowhite", - "lemonchiffon", - "bisque2", - "mistyrose", - "gray95", - "lightcyan3", - "peachpuff2", - "lightsteelblue2", - "lightyellow2", - "moccasin", - "antiquewhite2", - "gray80", - "lightgrey" - ], - "defaultValue": "c(\"slateblue3\",\"tomato2\",\"maroon\",\"deepskyblue\",\"mediumorchid2\",\"mediumseagreen\",\"salmon\",\"dodgerblue\",\"darkgreen\",\"plum4\",\"orange\",\"yellow4\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Plot_Title", - "displayName": "Plot Title", - "description": "", - "paramType": "STRING", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "PCA 3D", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "title": "PCA 3D [CCBR]", - "templateApiVersion": "0.1.0" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Venn_Diagram_CCBR_.code-template.json b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Venn_Diagram_CCBR_.code-template.json deleted file mode 100644 index e58edd6..0000000 --- a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Venn_Diagram_CCBR_.code-template.json +++ /dev/null @@ -1,1087 +0,0 @@ -{ - "codeTemplate": "Venn_Diagram <- function({{{Input_Dataset}}}) {\n\n## --------- ##\n## Libraries ##\n## --------- ##\n\nlibrary(VennDiagram)\nlibrary(gridExtra)\nlibrary(patchwork)\nlibrary(UpSetR)\nlibrary(dplyr)\nlibrary(tibble)\n \n## -------------------------------- ##\n## User-Defined Template Parameters ##\n## -------------------------------- ##\n\n# Basic parameters\ninput_dataset <- {{{Input_Dataset}}}\nelements_column <- '{{{Elements_Column}}}'\ncategories_column <- '{{{Categories_Column}}}'\n\n# Advanced parameters\nselected_categories = {{{Selected_Categories}}}\nselect_plot_type <- '{{{Select_Plot_Type}}}'\nintersection_ids = {{{Intersection_IDs}}}\n\n# Venn Diagram parameters\nvenn_force_unique <- {{{Venn_Force_Unique}}}\nvenn_numbers_format <- '{{{Venn_Numbers_Format}}}'\nvenn_significant_digits <- {{{Venn_Significant_Digits}}}\nvenn_fill_colors = {{{Venn_Fill_Colors}}}\nvenn_fill_transparency <- {{{Venn_Fill_Transparency}}}\nvenn_border_colors <- '{{{Venn_Border_Colors}}}'\nvenn_font_size_for_category_names <- {{{Venn_Font_Size_for_Category_Names}}}\nvenn_category_names_distance <- {{{Venn_Category_Names_Distance}}}\nvenn_category_names_position <- {{{Venn_Category_Names_Position}}}\nvenn_font_size_for_counts <- {{{Venn_Font_Size_for_Counts}}}\nvenn_outer_margin <- {{{Venn_Outer_Margin}}}\n\n# Intersection Plot parameters\nintersections_order <- '{{{Intersections_Order}}}'\ndisplay_empty_intersections <- {{{Display_Empty_Intersections}}}\nintersection_bar_color <- \"{{{Intersection_Bar_Color}}}\"\nintersection_point_size <- {{{Intersection_Point_Size}}}\nintersection_line_width <- {{{Intersection_Line_Width}}}\n\n# Table parameters\ntable_font_size <- {{{Table_Font_Size}}}\ntable_content <- \"{{{Table_Content}}}\"\n\n# Image parameters\nimage_output_format <- '{{{Image_Output_Format}}}'\nimage_resolution <- {{{Image_Resolution}}}\nimage_width <- {{{Image_Width}}}\nimage_height <- {{{Image_Height}}}\n\n##--------------- ##\n## Error Messages ##\n## -------------- ##\n\n## --------- ##\n## Functions ##\n## --------- ##\n\n# modify UpSetR function (keep gene names as rownames of intersection matrix)\nfromList <- function (input) {\n # Same as original fromList()...\n elements <- unique(unlist(input))\n data <- unlist(lapply(input, function(x) {\n x <- as.vector(match(elements, x))\n }))\n data[is.na(data)] <- as.integer(0)\n data[data != 0] <- as.integer(1)\n data <- data.frame(matrix(data, ncol = length(input), byrow = F))\n data <- data[which(rowSums(data) != 0), ]\n names(data) <- names(input)\n # ... Except now it conserves your original value names!\n row.names(data) <- elements\n return(data)\n}\n\n\n## --------------- ##\n## Main Code Block ##\n## --------------- ##\n\n# SET IMAGE ====\n\nif(image_output_format == 'png') {\n png(filename=graphicsFile, width=image_width, height=image_height, units=\"px\", pointsize=4, bg=\"white\", res=image_resolution, type=\"cairo\")\n} else {\n svglite::svglite(file=graphicsFile, width=round(image_width/image_resolution,digits=2), height=round(image_height/image_resolution,digits=2), pointsize=1, bg=\"white\")\n}\n\n# SET INPUT ==== \n \n# select required columns\nset_elements <- input_dataset[, elements_column]\nset_names <- input_dataset[, categories_column]\n \n# prepare format - R list\nvlist = split(set_elements, set_names)\nif(!is.null(selected_categories)){\n vlist = vlist[selected_categories]\n}\nnum_categories = length(vlist)\n\n# generate upset object\n\nif(num_categories > 1) {\n \n sets = fromList(vlist)\n \n if(!is.null(selected_categories)){\n Intersection = sets[,match(selected_categories, colnames(sets))]\n } else {\n Intersection = sets\n }\n\n # generate intersection frequency table and gene list (all intersections for the output dataset/table not the plot)\n Intersection = sapply(colnames(Intersection), function(x){ifelse(Intersection[,x]==1, x, \"{}\")})\n rownames(Intersection) = rownames(sets)\n Intersection = apply(Intersection, 1, function(x) sprintf(\"(%s)\", paste(x, collapse=' ')))\n tab = table(Intersection)\n tab = tab[order(tab)]\n nn = stringr::str_count(names(tab), pattern = \"\\\\{\\\\}\")\n tab = tab[order(nn, decreasing=FALSE)]\n names(tab) = gsub(\"\\\\{\\\\} | \\\\{\\\\}|\\\\{\\\\} |\\\\{\\\\} \\\\{\\\\}\",\"\", names(tab))\n names(tab) = sub(\"\\\\( \",\"(\", names(tab))\n names(tab) = gsub(\" \",\" ∩ \", names(tab))\n tab = tab[names(tab) != \"()\"] %>% data.frame() %>% dplyr::rename(\"Intersection\"=Var1, \"Size\"=Freq) %>% tibble::rownames_to_column('Id') %>% dplyr::mutate(Id=as.numeric(Id)) %>% dplyr::select(Intersection, Id, Size)\n Intersection = gsub(\"\\\\{\\\\} | \\\\{\\\\}|\\\\{\\\\} |\\\\{\\\\} \\\\{\\\\}\",\"\", Intersection)\n Intersection = sub(\"\\\\( \",\"(\", Intersection)\n Intersection = gsub(\" \",\" ∩ \", Intersection)\n Intersection = data.frame(Intersection) %>% tibble::rownames_to_column(\"Gene\") %>% dplyr::inner_join(tab, by=c(Intersection=\"Intersection\")) %>% dplyr::select(Gene, Intersection, Id, Size) %>% dplyr::arrange(Id)\n\n} else if (num_categories == 1) {\n Intersection = data.frame(Gene=vlist[[1]], Intersection = sprintf(\"(%s)\", names(vlist)), Id = 1, Size = length(vlist[[1]]))\n tab = table(Intersection$Intersection)\n tab = data.frame(Id=1, tab) %>% dplyr::rename(Intersection=Var1, Size=Freq) %>% dplyr::select(Intersection, Id, Size)\n}\n\n# returned intersections\n\nif (!is.null(intersection_ids) ) {\n intersection_ids = sort(as.numeric(intersection_ids))\n tabsel = tab[tab$Id %in% intersection_ids,]\n Intersectionsel = Intersection[Intersection$Id %in% intersection_ids,]\n} else {\n tabsel = tab\n Intersectionsel = Intersection\n}\ntab$\"Return\" = ifelse(tab$Intersection %in% tabsel$Intersection, \"Yes\", \"—\")\n\nif(intersections_order == 'freq'){\n tab = tab %>% dplyr::arrange(-Size)\n tabsel = tabsel %>% dplyr::arrange(-Size)\n}\n\n# screen log\ncat('All intersections\\n')\nprint(tab)\ncat('\\nIntersections returned\\n')\nprint(tabsel)\n\n# DO PLOT ====\n\nif(num_categories == 1) {\n if(select_plot_type == \"Intersection plot\") { \n select_plot_type = 'Venn diagram'\n cat(\"\\nIntersection plot not available for a single contrast, the Venn diagram genereated instead\")\n }\n} else if(num_categories > 5) {\n select_plot_type = 'Intersection plot'\n cat(\"\\nVenn diagram available for up to 5 contrasts, the Intersection plot genereated instead\")\n}\n\n# Intersection Plot\n\nif(select_plot_type == 'Intersection plot') {\n\n# do plot\nempty = display_empty_intersections\nif(empty) {keepEmpty='on'} else {keepEmpty=NULL}\n\nbarcol = intersection_bar_color\n\npSet = upset(sets,\n nsets = num_categories,\n sets = selected_categories,\n order.by = intersections_order,\n nintersects = NA,\n text.scale = 2,\n empty.intersections = keepEmpty,\n matrix.color = barcol, main.bar.color = barcol, sets.bar.color = barcol,\n point.size =intersection_point_size, line.size = intersection_line_width)\n\nprint(pSet)\n\n} else if (select_plot_type == 'Venn diagram') {\n # Venn diagram\n\n ## If venn fill color param empty upon template upgrade,\n ## then fill it with the default colors.\n if (length(venn_fill_colors) == 0) {\n venn_fill_colors <- c(\"darkgoldenrod2\",\"darkolivegreen2\",\"mediumpurple3\",\"darkorange2\",\"lightgreen\")\n }\n\n color_border = venn_border_colors\n if(color_border != 'black') { color_border = venn_fill_colors[1:num_categories] }\n\n print_mode = venn_numbers_format \n if(print_mode == 'raw-percent') {\n print_mode = c('raw','percent')\n } else if(print_mode == 'percent-raw'){\n print_mode = c('percent','raw')\n }\n\n distance = venn_category_names_distance \n position = venn_category_names_position \n\n if( is.null(distance) & is.null(position) ) {\n\n vobj = venn.diagram( vlist, file=NULL, force_unique = venn_force_unique, print.mode = print_mode, sigdigs = venn_significant_digits, margin=venn_outer_margin, main = '', cat.cex=venn_font_size_for_category_names, cex=venn_font_size_for_counts, main.cex=3, fill=venn_fill_colors[1:num_categories], alpha=venn_fill_transparency, col=color_border )\n\n } else if ( !is.null(distance) & is.null(position) ) {\n\n distance = as.numeric(distance)\n\n vobj = venn.diagram( vlist, file=NULL, force_unique = venn_force_unique, print.mode = print_mode, sigdigs = venn_significant_digits, margin=venn_outer_margin, main = '', cat.cex=venn_font_size_for_category_names, cex=venn_font_size_for_counts, main.cex=3, fill=venn_fill_colors[1:num_categories], alpha=venn_fill_transparency, col=color_border, cat.dist = distance)\n\n } else if ( is.null(distance) & !is.null(position) ) {\n\n position = as.numeric(position)\n\n vobj = venn.diagram( vlist, file=NULL, force_unique = venn_force_unique, print.mode = print_mode, sigdigs = venn_significant_digits, margin=venn_outer_margin, main = '', cat.cex=venn_font_size_for_category_names, cex=venn_font_size_for_counts, main.cex=3, fill=venn_fill_colors[1:num_categories], alpha=venn_fill_transparency, col=color_border, cat.pos = position)\n\n } else {\n\n distance = as.numeric(distance)\n position = as.numeric(position)\n\n vobj = venn.diagram( vlist, file=NULL, force_unique = venn_force_unique, print.mode = print_mode, sigdigs = venn_significant_digits, margin=venn_outer_margin, main = '', cat.cex=venn_font_size_for_category_names, cex=venn_font_size_for_counts, main.cex=3, fill=venn_fill_colors[1:num_categories], alpha=venn_fill_transparency, col=color_border, cat.dist = distance, cat.pos = position)\n\n }\n \n pVenn = wrap_elements( gTree(children=vobj) )\n print(pVenn)\n \n} else {\n\n font_size_table = table_font_size\n table_content = table_content\n if(table_content == \"all intersections\"){\n pTab = wrap_elements( tableGrob(tab, rows=NULL, theme = ttheme_default(core=list(fg_params=list(cex=font_size_table)), colhead = list(fg_params=list(cex = font_size_table)), rowhead=list(fg_params=list(cex= font_size_table)))) )\n } else {\n pTab = wrap_elements( tableGrob(tabsel, rows=NULL, theme = ttheme_default(core=list(fg_params=list(cex=font_size_table)), colhead = list(fg_params=list(cex = font_size_table)), rowhead=list(fg_params=list(cex= font_size_table)))) )\n }\n print(pTab)\n}\n\n# SAVE DATASET ====\nreturn(Intersectionsel)\n\n}\n\n## ---------------------------- ##\n## Global Imports and Functions ##\n## ---------------------------- ##\n\n## Functions defined here will be available to call in the code for any table.\n\n## --------------- ##\n## End of Template ##\n## --------------- ##\n", - "columns": [ - { - "key": "Elements_Column", - "displayName": "Elements Column", - "description": "Column containing the names of elements. These elements will be counted and the number displayed in each intersection of your Venn diagram. Commonly this will be the Genes column of the output of the \"Volcno Plot. -Summary\" template.", - "paramGroup": "Basic", - "sourceDataset": "Input_Dataset", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Categories_Column", - "displayName": "Categories Column", - "description": "Column containing the category names. These categories will be used to draw the circles of your Venn diagram. Commonly, this will be your Contrasts column from the output of the \"Volcano Plot - Summary\" template.", - "paramGroup": "Basic", - "sourceDataset": "Input_Dataset", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - } - ], - "condaDependencies": [], - "description": "Template generates Venn diagram of intersections across a series of sets (e.g., intersections of significant genes across tested contrasts).\nThis Venn diagram is available for up to five sets; Intersection plot is available for any number of sets. Specific sets can be selected for the visualizations and the returned dataset may include all (default) or specified intersections.\n", - "externalId": "Venn_Diagram_CCBR_", - "inputDatasets": [ - { - "key": "Input_Dataset", - "displayName": "Input Dataset", - "description": "The input dataset containing cateogry membership information. Should contain at least two columns: elements and categories. If an element is contained in multiple categories, there should be one row for each category.", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - } - ], - "vectorLanguage": "R", - "codeLanguage": "R", - "parameters": [ - { - "key": "Selected_Categories", - "displayName": "Selected Categories", - "description": "If no categories are listed then all available categories will be used; if a single category is listed only Venn diagram or Intersection table can be plotted; if more than 5 categories are listed only Intersection plot or Intersection table can be plotted", - "paramType": "VECTOR", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Select_Plot_Type", - "displayName": "Select Plot Type", - "description": "", - "paramType": "SELECT", - "paramGroup": "Advanced", - "paramValues": [ - "Venn diagram", - "Intersection plot", - "Intersection table" - ], - "defaultValue": "Venn diagram", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Intersection_IDs", - "displayName": "Intersection IDs", - "description": "Enter Intersection id(s); the intersection id displayed in the Logs tab after the first run of the template or in the Intersection table if selected as the option of the Plot selection parameter above; if none entered, all intersections are returned", - "paramType": "VECTOR", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Venn_Force_Unique", - "displayName": "Venn Force Unique", - "description": "If TRUE, count each element in a given category only once (ignore duplicate entries)", - "paramType": "BOOLEAN", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Venn_Numbers_Format", - "displayName": "Venn Numbers Format", - "description": "The format that the numbers will be printed in", - "paramType": "SELECT", - "paramGroup": "Venn Diagram", - "paramValues": [ - "raw", - "percent", - "raw-percent", - "percent-raw" - ], - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Venn_Significant_Digits", - "displayName": "Venn Significant Digits", - "description": "The number of significant digits in percent values", - "paramType": "NUMBER", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Venn_Fill_Colors", - "displayName": "Venn Fill Colors", - "description": "The colour of each circle's interior. The number of colors you choose should be at least the number of input datasets.", - "paramType": "MULTISELECT", - "paramGroup": "Venn Diagram", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "c(\"darkgoldenrod2\",\"darkolivegreen2\",\"mediumpurple3\",\"darkorange2\",\"lightgreen\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Venn_Fill_Transparency", - "displayName": "Venn Fill Transparency", - "description": "The transparency of each circle's interior. Enter a value between 0 and 1 (from transparent to opaque)", - "paramType": "STRING", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "0.2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Venn_Border_Colors", - "displayName": "Venn Border Colors", - "description": "The colour of each circle's circumference; if the option 'fill colors' is chosen the same as \"Colors: fill\" above", - "paramType": "SELECT", - "paramGroup": "Venn Diagram", - "paramValues": [ - "black", - "fill colors" - ], - "defaultValue": "fill colors", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Venn_Font_Size_for_Category_Names", - "displayName": "Venn Font Size for Category Names", - "description": "The font size for each category name", - "paramType": "NUMBER", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "3", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Venn_Category_Names_Distance", - "displayName": "Venn Category Names Distance", - "description": "A numeric vector giving the distance of each category name from the edge of the circle (can be negative); the default values are between 0.025 - 0.22; adjusting both the distance and position (below) may be optimal.", - "paramType": "VECTOR", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Venn_Category_Names_Position", - "displayName": "Venn Category Names Position", - "description": "A numeric vector giving the position (in degrees) of each category name along the circle, with 0 at 12 o'clock; adjusting both the position and distance (above) may be optimal.", - "paramType": "VECTOR", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Venn_Font_Size_for_Counts", - "displayName": "Venn Font Size for Counts", - "description": "The font size for each area label", - "paramType": "NUMBER", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "6", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Venn_Outer_Margin", - "displayName": "Venn Outer Margin", - "description": "The amount of whitespace around the diagram in grid units; recommended values are between 0.05 - 0.2; adding more space can help fit the category names.", - "paramType": "NUMBER", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "0", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Intersections_Order", - "displayName": "Intersections Order", - "description": "The intersections ordering; the options include degree and freq (frequency)", - "paramType": "SELECT", - "paramGroup": "Intersection Plot", - "paramValues": [ - "degree", - "freq" - ], - "defaultValue": "degree", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Display_Empty_Intersections", - "displayName": "Display Empty Intersections", - "description": "If FALSE (default) empty sets are not plotted", - "paramType": "BOOLEAN", - "paramGroup": "Intersection Plot", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Intersection_Bar_Color", - "displayName": "Intersection Bar Color", - "description": "", - "paramType": "SELECT", - "paramGroup": "Intersection Plot", - "paramValues": [ - "steelblue4", - "aquamarine3", - "salmon1", - "lightskyblue3", - "plum3", - "darkolivegreen3", - "goldenrod1", - "burlywood2", - "gray70", - "firebrick2", - "steelblue", - "palegreen4", - "orchid4", - "darkorange1", - "yellow", - "sienna", - "palevioletred1", - "gray60", - "cyan4", - "darkorange3", - "mediumpurple3", - "violetred2", - "olivedrab", - "darkgoldenrod2", - "darkgoldenrod", - "gray40", - "palegreen3", - "thistle3", - "khaki1", - "deeppink2", - "chocolate3", - "paleturquoise3", - "wheat1", - "lightsteelblue", - "salmon", - "sandybrown", - "darkolivegreen2", - "thistle2", - "gray85", - "orchid3", - "darkseagreen1", - "lightgoldenrod1", - "lightskyblue2", - "dodgerblue3", - "darkseagreen3", - "forestgreen", - "lightpink2", - "mediumpurple4", - "lightpink1", - "thistle", - "navajowhite", - "lemonchiffon", - "bisque2", - "mistyrose", - "gray95", - "lightcyan3", - "peachpuff2", - "lightsteelblue2", - "lightyellow2", - "moccasin", - "antiquewhite2", - "gray80", - "lightgrey" - ], - "defaultValue": "steelblue4", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Intersection_Line_Width", - "displayName": "Intersection Line Width", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Intersection Plot", - "paramValues": null, - "defaultValue": "0.7", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Intersection_Point_Size", - "displayName": "Intersection Point Size", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Intersection Plot", - "paramValues": null, - "defaultValue": "2.2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Table_Font_Size", - "displayName": "Table Font Size", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Table", - "paramValues": null, - "defaultValue": "0.7", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Table_Content", - "displayName": "Table Content", - "description": "", - "paramType": "SELECT", - "paramGroup": "Table", - "paramValues": [ - "all intersections", - "returned intersections" - ], - "defaultValue": "all intersections", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Image_Output_Format", - "displayName": "Image Output Format", - "description": "Select the image format for saved images: currently only .png available", - "paramType": "SELECT", - "paramGroup": "Image", - "paramValues": [ - "png" - ], - "defaultValue": "png", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Image_Resolution", - "displayName": "Image Resolution", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "300", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Image_Height", - "displayName": "Image Height", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "3000", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Image_Width", - "displayName": "Image Width", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "4000", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "title": "Venn Diagram [CCBR]", - "templateApiVersion": "0.1.0" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Volcano_Plot_Enhanced_CCBR_.code-template.json b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Volcano_Plot_Enhanced_CCBR_.code-template.json deleted file mode 100644 index e5f62eb..0000000 --- a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Volcano_Plot_Enhanced_CCBR_.code-template.json +++ /dev/null @@ -1,310 +0,0 @@ -{ - "codeTemplate": "VolcanoPlot <- function({{{DEG_Table}}}) {\n # image: png\n\n\n # Changelog\n # 2022-09-14 Rearranged structure and description\n # 2020-10-29 Add support for pval == 0\n\n\n\n ## --------- ##\n ## Libraries ##\n ## --------- ##\n\n library(stringr)\n library(ggplot2)\n library(ggrepel)\n library(dplyr)\n library(tidyr)\n\n library(EnhancedVolcano)\n # For interactive plot:\n library(plotly)\n library(grid)\n \n\n ## -------------------------------- ##\n ## User-Defined Template Parameters ##\n ## -------------------------------- ##\n\n #Basic Parameters:\n df.orig <- {{{DEG_Table}}}\n label.col <- \"{{{Column_with_Feature_ID}}}\"\n sig.col <- {{{Significance_Column}}}\n pCutoff = {{{P_Value_Threshold}}}\n lfc.col <- {{{Log2_Fold_Change_Column}}}\n FCcutoff = {{{Log2_Fold_Change_Threshold}}}\n \n \n #Label Parameters\n value_to_sort_the_output_dataset <- \"{{{Choose_Feature_to_Label_By}}}\"\n no_genes_to_label <- {{{Number_of_Features_to_Label}}}\n use_only_addition_labels <- {{{Label_Only_My_Feature_List}}}\n additional_labels <- \"{{{My_Feature_List}}}\"\n is_red <- {{{Top_Genes_Labeled_Only_If_Passing_Thresholds}}}\n labSize <- {{{Label_Size}}} \n\n\n #Title and Axis labels Parameters\n change_sig_name <- \"{{{Custom_Significance_Label}}}\"\n change_lfc_name <- \"{{{Custom_Log_Fold_Change_Label}}}\"\n title <- \"{{{Plot_Title}}}\"\n #subtitle <- \"\"\n use_custom_lab <- {{{Use_Custom_Axis_Label}}}\n \n #Plot Parameters\n ylim <- {{{Y_Limit}}}\n custom_xlim <- \"{{{Custom_X_axis_limits}}}\"\n xlim_additional <- {{{X_Limit_Padding}}}\n ylim_additional <- {{{Y_Limit_Padding}}}\n axisLabSize <- {{{Axis_Label_Size}}}\n pointSize <- {{{Point_Size}}}\n\n\n #Image Parameters\n imageWidth = {{{Image_Width}}}\n imageHeight = {{{Image_Height}}}\n dpi = {{{Resolution_DPI_}}}\n\n\n \n ##--------------- ##\n ## Error Messages ##\n ## -------------- ##\n\n ## --------------- ##\n ## Main Code Block ##\n ## --------------- ##\n\n rank <- list()\n for(i in 1:length(lfc.col)){\n lfccol <- lfc.col[i]\n sigcol <- sig.col[i]\n columns_of_interest <- c(label.col,lfc.col[i],sig.col[i])\n df <- df.orig %>% dplyr::select(one_of(columns_of_interest)) %>% \n mutate(!!sym(lfccol) := replace_na(!!sym(lfccol), 0)) %>%\n mutate(!!sym(sigcol) := replace_na(!!sym(sigcol), 1)) \n #mutate(.data[[lfc.col[i]]] = replace_na(.data[[lfc.col[i]]], 0)) %>%\n #mutate(.data[[sig.col[i]]] = replace_na(.data[[sig.col[i]]], 1)) \n if (use_custom_lab==TRUE){\n if (nchar(change_lfc_name)==0){lfc_name = lfc.col[i]}\n if (nchar(change_sig_name)==0){sig_name = sig.col[i]}\n colnames(df) <- c(label.col,change_lfc_name, sig_name)\n } else {\n lfc_name = lfc.col[i]\n sig_name = sig.col[i]\n }\n \n group <- gsub(\"_pval|p_val_\",\"\",sig_name)\n rank[[i]] <- -log10(df[[sig_name]]) * sign(df[[lfc_name]]) \n names(rank)[i] <- paste0(\"C_\",group,\"_rank\")\n \n cat(paste0(\"Genes in initial dataset: \", nrow(df),\"\\n\"))\n\n #Select top genes by logFC or Significance\n \n if (value_to_sort_the_output_dataset==\"fold-change\") {\n df <- df %>% dplyr::arrange(desc(.data[[lfc_name]]))\n } else if (value_to_sort_the_output_dataset==\"p-value\") {\n df <- df %>% dplyr::arrange(.data[[sig_name]]) \n }\n\n if (is_red) {\n df_sub <- df[df[[sigcol]] <= pCutoff & abs(df[[lfccol]]) >= FCcutoff, ]\n } else {\n df_sub <- df\n }\n\n genes_to_label <- as.character(df_sub[1:no_genes_to_label,label.col])\n# additional_labels <- unlist(str_split(additional_labels,\",\"))\n ## Modifying Additional Labels List:\n ## Replace commas with spaces and split the string\nsplit_values <- unlist(strsplit(gsub(\",\", \" \", additional_labels), \" \"))\nadditional_labels <- split_values[split_values != \"\"]\n\n filter <- additional_labels %in% df[,label.col]\n missing_labels <- additional_labels[!filter]\n additional_labels <- additional_labels[filter]\n\n if(length(missing_labels) > 0){\n cat(\"Could not find:\\n\")\n print(missing_labels)\n }\n\n if(use_only_addition_labels){\n genes_to_label <- additional_labels\n }else{\n genes_to_label <- unique(append(genes_to_label, additional_labels))\n }\n\n significant = vector(length = nrow(df))\n significant[] = \"Not significant\"\n significant[which(abs(df[,2]) > FCcutoff)] = \"Fold change only\"\n significant[which(df[,3] < pCutoff)] = \"Significant only\"\n significant[which(abs(df[,2]) > FCcutoff & df[,3] < pCutoff)] = \"Significant and fold change\"\n print(table(significant))\n \n # fix pvalue == 0\n shapeCustom <- rep(19,nrow(df))\n maxy <- max(-log10(df[[sig_name]]), na.rm=TRUE)\n if(ylim > 0){\n maxy <- ylim\n }\n \n cat(paste0(\"Maxy: \",maxy,\"\\n\"))\n if(maxy == Inf){\n # Sometimes, pvalues == 0\n keep <- df[[sig_name]] > 0\n df[[sig_name]][!keep] <- min(df[[sig_name]][keep])\n shapeCustom[!keep] <- 17\n\n maxy <- -log10(min(df[[sig_name]][keep]))\n cat(\"Some p-values equal zero. Adjusting y-limits.\\n\")\n cat(paste0(\"Maxy adjusted: \",maxy,\"\\n\"))\n\n }\n\n # By default, nothing will be greater than maxy. User can set this value lower\n keep <- -log10(df[[sig_name]]) <= maxy\n df[[sig_name]][!keep] <- maxy\n shapeCustom[!keep] <- 17\n\n names(shapeCustom)<- rep(\"Exact\",length(shapeCustom))\n names(shapeCustom)[shapeCustom == 17] <- \"Adjusted\"\n \n #Remove if nothin' doin'\n if(all(shapeCustom == 19)){\n shapeCustom <- NULL\n }\n \n maxy <- ceiling(maxy)\n\n if (grepl(\"log\",lfc.col[i]) ){\n xlab <- bquote(~Log[2]~ \"fold change\")\n } else {\n xlab <- \"Fold change\"\n }\n if (grepl(\"adj\",sig.col[i])){\n ylab <- bquote(~-Log[10]~ \"FDR\")\n } else {\n ylab <- bquote (~-Log[10]~ \"p-value\")\n }\n if(use_custom_lab){\n if(lfc_name != lfc.col[i]){\n xlab <- gsub(\"_\",\" \",lfc_name)\n }\n if (sig_name != sig.col[i]){ \n ylab <- gsub(\"_\",\" \",sig_name)\n }\n }\n \n## X-axis custom range change:\nif (custom_xlim == \"\") {\n xlim=c(floor(min(df[,lfc_name])) - xlim_additional,ceiling(max(df[,lfc_name]))+ xlim_additional)\n} else if (grepl(\",\", custom_xlim) == FALSE) {\n xlim=c(-1*as.numeric(trimws(custom_xlim)), as.numeric(trimws(custom_xlim)))\n} else {\n split_values <- strsplit(custom_xlim, \",\")[[1]]\n\n # Trim whitespace and convert to numeric values\n x_min <- as.numeric(trimws(split_values[1]))\n x_max <- as.numeric(trimws(split_values[2]))\n\n xlim <- c(x_min, x_max)\n}\n\n\n p <- EnhancedVolcano( df,x=lfc_name,y=sig_name,\n lab=df[,label.col],\n selectLab = genes_to_label,\n title=title, #CHANGE NW: See line 78\n subtitle <- group,\n xlab=xlab,\n ylab=ylab,\n xlim=xlim,\n ylim=c(0, maxy + ylim_additional),\n pCutoff=pCutoff,\n FCcutoff=FCcutoff,\n axisLabSize=axisLabSize,\n labSize=labSize,\n pointSize=pointSize,\n shapeCustom=shapeCustom\n )\n print(p) \n ## Adding interactive plot with no labels:\n p_empty <- EnhancedVolcano( df,x=lfc_name,y=sig_name,\n lab = rep(\"\", nrow(df)), # Setting labels to empty strings\n selectLab = NULL,\n title=title, #CHANGE NW: See line 78\n subtitle <- group,\n xlab=xlab,\n ylab=ylab,\n xlim=xlim,\n ylim=c(0, maxy + ylim_additional),\n pCutoff=pCutoff,\n FCcutoff=FCcutoff,\n axisLabSize=axisLabSize,\n labSize=labSize,\n pointSize=pointSize,\n shapeCustom=shapeCustom\n )\n## print(p_empty) \n\n# Extract the data used for plotting\nplot_data <- ggplot_build(p_empty)$data[[1]]\n\npxx <- p_empty +\n xlab(\"Fold Change\") + # Simplify x-axis label\n ylab(\"Significance\") + # Simplify y-axis label\n theme_minimal() +\n geom_point(aes(\n text = paste(\"Gene:\", df[[label.col]], \n \"
Log2FC:\", df[[lfc_name]], \n \"
P-value:\", df[[sig_name]]),\n colour = as.character(plot_data$colour),\n fill = as.character(plot_data$colour) # Set fill to the same as colour\n ), \n shape = 21, # Shape that supports both colour and fill\n size = 2, # Size of the points\n stroke = 0.1 # Stroke width\n ) + scale_fill_identity()\n\n# Add interactive hover labels for the gene names\ninteractive_plot <- ggplotly(pxx, tooltip = c(\"text\"))\n\n\n ## showing interactive plot\n grid.newpage()\n print(interactive_plot)\n grid.newpage()\n ## The end of addition\n \n }\n \n df.final <- cbind(df.orig, do.call(cbind, rank))\n return(df.final)\n}\n\n#################################################\n## Global imports and functions included below ##\n#################################################\n\n", - "columns": [ - { - "key": "Column_with_Feature_ID", - "displayName": "Column with Feature ID", - "description": "Column from the input DEG table containing Feature ID (such as Gene Names, Isoform IDs, UniProt IDs, and so on). This is usually the first column (named \"Feature_ID\" or \"Gene\"). Only Text type columns will be allowed.", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "Significance_Column", - "displayName": "Significance Column", - "description": "Choose an unadjusted or adjusted p-value column from the input DEG table to use as the measure of significance in your Volcano plot. If your DEG analysis contained more than one contrast comparison, you will only be able to select one of these at a time. Make sure you select the same contrast that was selected for the \"Log2 Fold Change Column\" parameter.", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "defaultValue": null, - "columnType": "NUMBER", - "isMulti": true - }, - { - "key": "Log2_Fold_Change_Column", - "displayName": "Log2 Fold Change Column", - "description": "Choose a log2 fold change column from the input DEG table. If your DEG analysis contained more than one contrast comparison, you will only be able to select one of these at a time. Make sure you select the same contrast that was selected for the \"Significance Column\" parameter.", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "defaultValue": null, - "columnType": "NUMBER", - "isMulti": true - } - ], - "condaDependencies": [], - "description": "Implementation of Bioconductor's Enhanced Volcano Plot (v1.6.0, https://bioconductor.org/packages/release/bioc/html/EnhancedVolcano.html). Template written by Matthew Angel and maintained by CCBR. Final Potomac Compatible Version: v52. Final Sugarloaf V1 Version: v55. Latest Sugarloaf V2 Version: v67. [View Documentation](https://nidap.nih.gov/workspace/notepad/view/ri.notepad.main.notepad.8fe3cd6c-db24-4b0a-b717-060cb77ecc5e)", - "externalId": "Volcano_Plot_Enhanced_CCBR_scRNA_seq_Bulk_", - "inputDatasets": [ - { - "key": "DEG_Table", - "displayName": "DEG Table", - "description": "Dataset containing differential expression of genes (DEG) analysis output columns. Usually, this includes columns for gene names, (log) fold changes, (adjusted) p-values, and t-statistics. Other columns may be present.", - "paramGroup": null, - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - } - ], - "vectorLanguage": "R", - "codeLanguage": "R", - "parameters": [ - { - "key": "P_Value_Threshold", - "displayName": "P-Value Threshold", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "0.001", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Log2_Fold_Change_Threshold", - "displayName": "Log2 Fold Change Threshold", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "1.0", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Choose_Feature_to_Label_By", - "displayName": "Choose Feature to Label By", - "description": "This selection determines how the feature (gene) list is sorted before choosing the top-N features as set by the \"Number of Features to Label\" parameter. Choose either (absolute) fold change, p-value, or t-statistic to label the top features by the selected metric. This also determines which features are labeled in the plot. This option is negated if only using custom labels.", - "paramType": "SELECT", - "paramGroup": "Label", - "paramValues": [ - "p-value", - "fold-change" - ], - "defaultValue": "p-value", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Number_of_Features_to_Label", - "displayName": "Number of Features to Label", - "description": "To minimize clutter on the volcano plot, it is inadvisable to label every feature (gene). You can choose to label any number of features or none. The value of this parameter (N) is used to label the top N features only. See the \"Choose Features To Label By\" parameter for options on how to sort the gene list before labeling the top N features. Will be negated if the option to use only additional labels is selected.", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "30", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Only_My_Feature_List", - "displayName": "Label Only My Feature List", - "description": "Select TRUE when you want to label ONLY a specific list of features given in the \"My Feature List\" parameter.", - "paramType": "BOOLEAN", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Use_Custom_Axis_Label", - "displayName": "Use Custom Axis Label", - "description": "Use text from \"Custom significance label\"?", - "paramType": "BOOLEAN", - "paramGroup": "Title and Axis labels", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "My_Feature_List", - "displayName": "My Feature List", - "description": "Additional features (genes) to label. If the option to use only custom labels is selected, these will be the only points labeled on the plot. Otherwise, these will be plotted in addition to the other top features. This should be a comma-separated or space-delimited list.", - "paramType": "STRING", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Top_Genes_Labeled_Only_If_Passing_Thresholds", - "displayName": "Top Genes Labeled Only If Passing Thresholds", - "description": "If TRUE, only genes passing your p-value and logFC thresholds (Basic Parameters) will be labeled on the final plot. If FALSE, genes that do not pass thresholds may be labeled, also. Default is TRUE.", - "paramType": "BOOLEAN", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Size", - "displayName": "Label Size", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "4", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Custom_Significance_Label", - "displayName": "Custom Significance Label", - "description": "This replaces bulky names for the p-value column.", - "paramType": "STRING", - "paramGroup": "Title and Axis labels", - "paramValues": null, - "defaultValue": "p-value", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Custom_Log_Fold_Change_Label", - "displayName": "Custom Log Fold Change Label", - "description": "This replaces bulky column names for the fold-change column.", - "paramType": "STRING", - "paramGroup": "Title and Axis labels", - "paramValues": null, - "defaultValue": "log2FC", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Plot_Title", - "displayName": "Plot Title", - "description": "", - "paramType": "STRING", - "paramGroup": "Title and Axis labels", - "paramValues": null, - "defaultValue": "Volcano Plots", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Y_Limit", - "displayName": "Y-Limit", - "description": "Maximum value for y-axis. Defaults to -log10(min(pval)). Set to 0 for automatic scaling.", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "0", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Custom_X_axis_limits", - "displayName": "Custom X-axis limits", - "description": "Leave empty for automatic scaling, put one number for symmetrical scale (i.e, putting \"5\" would result in a range from \"-5\" to \"5\"), or put two numbers separated by comma for \"asymmetrical\" scale (i.e, putting \"-2,4\" would result in a range from \"-2\" to \"4\")", - "paramType": "STRING", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "X_Limit_Padding", - "displayName": "X-Limit Padding", - "description": "Add additional units to x-limit", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "0", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Y_Limit_Padding", - "displayName": "Y-Limit Padding", - "description": "Adds additional units to y-limit.", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "0", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Axis_Label_Size", - "displayName": "Axis Label Size", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "24", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Point_Size", - "displayName": "Point Size", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Image_Width", - "displayName": "Image Width", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "3000", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Image_Height", - "displayName": "Image Height", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "3000", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Resolution_DPI_", - "displayName": "Resolution (DPI)", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "300", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "title": "Volcano Plot - Enhanced [CCBR] [scRNA-seq] [Bulk]", - "templateApiVersion": "0.1.0" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Volcano_Plot_Summary_CCBR_.code-template.json b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Volcano_Plot_Summary_CCBR_.code-template.json deleted file mode 100644 index a4c5a7d..0000000 --- a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Volcano_Plot_Summary_CCBR_.code-template.json +++ /dev/null @@ -1,5126 +0,0 @@ -{ - "codeTemplate": "Volcano_Summary <- function({{{DEG_Table}}}) {\n # image: {{{Image_Output_Format}}}\n \n stattype<-\"{{{Volcano_P_value_Type}}}\"\n add_deg_columns<-{{{DEG_Columns_to_Keep_in_Output_Table}}}\n image_width = {{{Image_Width}}}\n image_height = {{{Image_Height}}}\n image_resolution = {{{Image_Resolution}}}\n aspect_ratio = {{{Figure_Aspect_Ratio}}}\n\n if ({{{Use_svglite}}} & ((\"{{{Image_Output_Format}}}\" =='svg'))) {\n library(svglite)\n svglite::svglite(\n file=graphicsFile,\n width=image_width,\n height=image_height,\n pointsize=1,\n bg=\"white\",\n )} else if (\"{{{Image_Output_Format}}}\" == 'png') {\n png(\n filename=graphicsFile,\n width=image_width,\n height=image_height,\n units=\"in\",\n pointsize=4,\n bg=\"white\",\n res=image_resolution,\n type=\"cairo\")\n }\n\n suppressMessages(library(ggplot2))\n suppressMessages(library(dplyr))\n suppressMessages(library(ggrepel))\n\n genesmat <- {{{DEG_Table}}}\n value_to_sort_the_output_dataset = \"{{{Choose_Genes_To_Label_By}}}\"\n \n volcols<-colnames(genesmat)\n print(volcols)\n statcols<-volcols[grepl(\"logFC\",volcols)]\n contrasts<-unique(gsub(\"_logFC\",\"\",statcols)) \n \n Plots <- list()\n df_outs <- list()\n for(contrast in contrasts){\n print(paste0(\"Doing contrast: \",contrast))\n lfccol=paste0(contrast,\"_logFC\")\n pvalcol=paste0(contrast,\"_\",stattype)\n tstatcol=paste0(contrast,\"_\",\"tstat\")\n\n print(paste0(\"Fold change column: \",lfccol))\n print(paste0(stattype,\" column: \",pvalcol))\n\n no_genes_to_label <- {{{Number_of_Genes_to_Label}}}\n if (value_to_sort_the_output_dataset==\"fold-change\") {\n genesmat %>% dplyr::arrange(desc(abs(genesmat[,lfccol]))) -> genesmat\n } else if (value_to_sort_the_output_dataset==\"p-value\") {\n genesmat %>% dplyr::arrange(genesmat[,pvalcol]) -> genesmat\n } else if (value_to_sort_the_output_dataset == \"t-statistic\") {\n genesmat %>% dplyr::arrange(desc(abs(genesmat[,tstatcol]))) -> genesmat\n }\n print(paste0(\"Total number of genes included in volcano plot: \", nrow(genesmat)))\n if ({{{Use_Default_Y_Axis_Limit}}}){\n negative_log10_p_values <- -log10(genesmat[,pvalcol])\n ymax <- ceiling(max(negative_log10_p_values[is.finite(negative_log10_p_values)]))\n } else {\n ymax = {{{Y_Axis_Limit}}}\n }\n if ({{{Use_Default_X_Axis_Limit}}}){\n xmax1 = ceiling(max(genesmat[,lfccol]))\n xmax2 = ceiling(max(-genesmat[,lfccol]))\n xmax=max(xmax1,xmax2)\n } else {\n xmax = {{{X_Axis_Limit}}}\n }\n \n\n ## work with a list of genes\nif ({{{Add_My_Gene_List_To_Labels}}}){\n gl <- trimws(unlist(strsplit(c(\"{{{My_Gene_List}}}\"), \",\")), which=c(\"both\"))\n ind <- match(gl, genesmat$Gene) # get the indices of the listed genes\n gene_list_ind <- c(1:no_genes_to_label,ind) # when list provided\n color_gene_label <- c(rep(c(\"{{{Gene_Label_Text_Color}}}\"), no_genes_to_label), rep(c(\"{{{Gene_Label_Text_Color_for_My_Genes}}}\"),length(ind)))\n }else if ({{{Label_Only_My_Gene_List}}}){\n gl <- trimws(unlist(strsplit(c(\"{{{My_Gene_List}}}\"), \",\")), which=c(\"both\")) # unpack the gene list provided by the user and remove white spaces\n ind <- match(gl, genesmat$Gene) # get the indices of the listed genes\n gene_list_ind <- ind # when list provided\n color_gene_label <- rep(c(\"{{{Gene_Label_Text_Color_for_My_Genes}}}\"), length(ind))\n } else {\n if (no_genes_to_label>0) {\n gene_list_ind <- 1:no_genes_to_label # if no list provided label the number of genes given by the user\n color_gene_label <- rep(c(\"{{{Gene_Label_Text_Color}}}\"), no_genes_to_label)\n } else if (no_genes_to_label ==0) {\n gene_list_ind <-0\n }\n } \n\n## special nudge/repel of specific genes\nif ({{{Displace_Gene_Labels}}}){\n gn <- trimws(unlist(strsplit(c(\"{{{Gene_List_Special_Label_Displacement}}}\"), \",\")), which=c(\"both\"))\n ind_gn <- match(gn, genesmat$Gene[gene_list_ind]) # get the indices of the listed genes\n nudge_x_all <- rep(c(0.2), length(genesmat$Gene[gene_list_ind]))\n nudge_y_all <- rep(c(0.2), length(genesmat$Gene[gene_list_ind]))\n nudge_x_all[ind_gn] <- c({{{Special_Label_Displacement_X_Axis_}}})\n nudge_y_all[ind_gn] <- c({{{Special_Label_Displacement_Y_Axis_}}})\n} else {\n nudge_x_all <- {{{Label_Position_Adjustment_X_Axis_}}}\n nudge_y_all <- {{{Label_Position_Adjustment_Y_Axis_}}}\n}\n \n ## flip contrast section\n flipVplot <- {{{Flip_Contrast}}}\n indc <- which(colnames(genesmat) == lfccol) # get the indice of the column that contains the contrast_logFC data\n\n\n if (length(indc)==0){\n print(\"Please rename the logFC column to include the contrast evaluated.\")\n } else{\n old_contrast <- colnames(genesmat)[indc]\n } \n # actually flip contrast\n if (flipVplot){\n # get the indice of the contrast to flip\n indcc <- match(old_contrast,colnames(genesmat)) \n # create flipped contrast label\n splt1 <- strsplit(old_contrast, \"_\") # split by underline symbol to isolate the contrast name\n splt2 <- strsplit(splt1[[1]][1],\"-\") # split the contrast name in the respective components\n flipped_contrast <- paste(splt2[[1]][2], splt2[[1]][1],sep=\"-\") #flip contrast name\n new_contrast_label <- paste(flipped_contrast, c(\"logFC\"), sep = \"_\") \n # rename contrast column to the flipped contrast\n colnames(genesmat)[indcc] <- new_contrast_label\n # flip the contrast data around y-axis\n genesmat[,indcc] <- -genesmat[indcc]\n } else{ new_contrast_label<- old_contrast}\n\n grm<-genesmat[,c(new_contrast_label,pvalcol)]\n grm[,\"neglogpval\"]<- -log10(genesmat[,pvalcol])\n colnames(grm)=c(\"FC\",\"pval\",\"neglogpval\")\n print(grm[gene_list_ind,])\n p <- ggplot(grm,\n aes_string(x = \"FC\", y =\"neglogpval\" ))+ # modified by RAS\n theme_classic() +\n geom_point(\n color='{{{Color_of_Non_Significant_Genes}}}',\n size = {{{Point_Size}}}) +\n geom_vline(xintercept=c(-{{{Log2_Fold_Change_Threshold}}},{{{Log2_Fold_Change_Threshold}}}), color='{{{Color_of_Log_Fold_Change_Threshold_Line}}}', alpha=1.0) + \n geom_hline(yintercept=-log10({{{P_Value_Threshold}}}), color='{{{Color_of_P_Value_Threshold_Line}}}', alpha=1.0) + \n geom_point(\n data = grm[genesmat[,pvalcol] < {{{P_Value_Threshold}}},],\n color = '{{{Color_of_Genes_Meeting_Only_P_Value_Threshold}}}',\n size = {{{Point_Size}}}) +\n geom_point(\n data = grm[genesmat[,pvalcol] < {{{P_Value_Threshold}}} & abs(grm[,\"FC\"])>{{{Log2_Fold_Change_Threshold}}},], \n color = '{{{color_for_genes_meeting_p_value_and_fold_change_thresholds}}}',\n size = {{{Point_Size}}}) +\n geom_text_repel(\n data = grm[gene_list_ind,], \n label = genesmat${{{Gene_Names_Column}}}[gene_list_ind], \n color = color_gene_label,\n fontface = {{{Label_Font_Type}}},\n nudge_x = nudge_x_all,\n nudge_y = nudge_y_all,\n size = {{{Label_Font_Size}}},\n segment.size = {{{Line_Segment_Thickness}}}) +\n xlim(-xmax,xmax) +\n ylim(0,ymax) + xlab(new_contrast_label) + ylab(pvalcol)\n\n if (aspect_ratio > 0){\n p <- p + coord_fixed(ratio=aspect_ratio)\n }\n \n #print(p)\n Plots[[contrast]]=p\n print(head(genesmat[,pvalcol] ))\n filtered_genes = genesmat${{{Gene_Names_Column}}}[genesmat[,pvalcol] < {{{P_Value_Threshold}}} & abs(grm[,\"FC\"])>{{{Log2_Fold_Change_Threshold}}}]\n #print(filtered_genes)\n repeated_column = rep(contrast, length(filtered_genes))\n ## If param empty upon template upgrade, fill it with default value.\n if (length(add_deg_columns) == 0) {\n add_deg_columns <- c(\"FC\",\"logFC\",\"tstat\",\"pval\",\"adjpval\")\n }\n ## Get columns for output table.\n if (add_deg_columns == \"none\") {\n new_df <- data.frame(filtered_genes, repeated_column)\n names(new_df) <- c(\"Gene\", \"Contrast\")\n } else {\n add_deg_columns = setdiff(add_deg_columns, \"none\")\n out_columns = paste(contrast, add_deg_columns, sep=\"_\")\n deg = genesmat[,c(\"{{{Gene_Names_Column}}}\", out_columns)]\n names(deg)[1] = \"Gene\"\n new_df <- data.frame(filtered_genes, repeated_column) %>% dplyr::left_join(deg, by=c(\"filtered_genes\"=\"Gene\"))\n names(new_df) <- c(\"Gene\", \"Contrast\", add_deg_columns)\n }\n\n df_out1 <- new_df\n df_outs[[contrast]]=df_out1\n }\n\n Use_default_grid_layout = {{{Use_Default_Grid_Layout}}}\n require(gridExtra)\n nplots=length(Plots)\n if (Use_default_grid_layout) {\n nrows=ceiling(nplots/ceiling(sqrt(nplots)))\n } else {\n nrows = {{{Number_of_Rows_in_Grid_Layout}}}\n }\n\n do.call(\"grid.arrange\", c(Plots, nrow=nrows))\n print(\"done plotting\")\n\n df_out <- unique(do.call(\"rbind\", df_outs))\n print(head(df_out))\n print(colnames(df_out))\n return(df_out)\n}\n\n \n", - "columns": [ - { - "key": "Gene_Names_Column", - "displayName": "Gene Names Column", - "description": "The column from your input DEG table containing the gene names. This is usually the first column. Only columns of Text type from your DEG table will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - } - ], - "condaDependencies": [], - "description": "Produces one volcano plot for each tested contrast in the input DEG table.\n\nIt can be sorted by either fold change, t-statistic, or p-value. The returned dataset includes one row for each significant gene in each contrast, and contains columns from the DEG analysis of that contrast as well as columns useful to the Venn diagram template downstream.", - "externalId": "Volcano_Plot_Summary_CCBR_", - "inputDatasets": [ - { - "key": "DEG_Table", - "displayName": "DEG Table", - "description": "Dataset containing differential expression of genes (DEG) analysis output columns. Usually, this includes columns for gene names, (log) fold changes, (adjusted) p-values, and t-statistics. Other columns may also be present.", - "paramGroup": "Basic", - "anchorDataset": false, - "dataType": "R_NATIVE_DATAFRAME", - "tags": [] - } - ], - "vectorLanguage": "R", - "codeLanguage": "R", - "parameters": [ - { - "key": "Volcano_P_value_Type", - "displayName": "Volcano P-value Type", - "description": "Choose whether to use unadjusted or adjusted p-values in the resulting volcano plots.", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "pval", - "adjpval" - ], - "defaultValue": "pval", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "P_Value_Threshold", - "displayName": "P-Value Threshold", - "description": "Generates a horizontal blue line at -log10 of this value on the y-axis of the volcano plot. Genes located above this threshold are considered significantly differentially expressed.", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "0.001", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Log2_Fold_Change_Threshold", - "displayName": "Log2 Fold Change Threshold", - "description": "Generates two vertical red lines at +/- this value on the x-axis of the volcano plot. A value of 1 entered here will draw lines at a log2 fold change values of -1 and 1. This corresponds to unlogged fold changes of 2 and 1/2, respectively.", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Choose_Genes_To_Label_By", - "displayName": "Choose Genes To Label By", - "description": "This selection determines how the gene list is sorted before choosing the top-N genes as set by the \"Number of Genes to Label\" parameter. Choose either (absolute) fold change, p-value, or t-statistic to label the top genes by the selected metric.", - "paramType": "SELECT", - "paramGroup": "Gene Name Label", - "paramValues": [ - "fold-change", - "p-value", - "t-statistic" - ], - "defaultValue": "t-statistic", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Number_of_Genes_to_Label", - "displayName": "Number of Genes to Label", - "description": "To minimize clutter on the volcano plot, it is inadvisable to label every gene. You can choose to label any number of genes or none. The value of this parameter (N) is used to label the top N genes only. See the \"Choose Genes To Label By\" parameter for options on how to sort the gene list before labeling the top N genes.", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "30", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Add_My_Gene_List_To_Labels", - "displayName": "Add My Gene List To Labels", - "description": "Set TRUE when you want to label a specific set of genes in the \"My Gene List\" parameter\" IN ADDITION to the number of genes you set in the \"Number of Genes to Label\" parameter.", - "paramType": "BOOLEAN", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Only_My_Gene_List", - "displayName": "Label Only My Gene List", - "description": "Select TRUE when you want to label ONLY a specific list of genes given in the \"My Gene List\" parameter.", - "paramType": "BOOLEAN", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "My_Gene_List", - "displayName": "My Gene List", - "description": "Provide a list of genes (comma separated) to be labeled on the volcano plot. You must toggle one of the following ON to see these labels: \"Add My Gene List To Labels\" or \"Label Only My Gene List\".", - "paramType": "STRING", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "Provide list of genes-comma separated", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Gene_Label_Text_Color", - "displayName": "Gene Label Text Color", - "description": "Set the color for the text used to add gene name labels to points.", - "paramType": "SELECT", - "paramGroup": "Gene Name Label", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "black", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Gene_Label_Text_Color_for_My_Genes", - "displayName": "Gene Label Text Color for My Genes", - "description": "Set the color for the specific list of genes provided in the \"Gene List\" parameter.", - "paramType": "SELECT", - "paramGroup": "Gene Name Label", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "green3", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Position_Adjustment_X_Axis_", - "displayName": "Label Position Adjustment (X-Axis)", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "0.2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Position_Adjustment_Y_Axis_", - "displayName": "Label Position Adjustment (Y-Axis)", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "0.2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Line_Segment_Thickness", - "displayName": "Line Segment Thickness", - "description": "Thickness of the line connecting the point and it's gene label", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "0.5", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Font_Size", - "displayName": "Label Font Size", - "description": "Font size for sample labels. Set to 0 to remove labels.", - "paramType": "STRING", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "4", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Label_Font_Type", - "displayName": "Label Font Type", - "description": "Select the font type for the gene labels displayed in the volcano plot. The options are: 1-regular, 2-bold, 3-italic, 4-bold.italic, 5-greek alphabet.", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Displace_Gene_Labels", - "displayName": "Displace Gene Labels", - "description": "Set TRUE if you want to displace the gene label for a specific set of genes. Make sure to use custom x- and y- limits and give sufficient space for displacement; otherwise other labels than the desired ones will appear displaced.", - "paramType": "BOOLEAN", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Gene_List_Special_Label_Displacement", - "displayName": "Gene List Special Label Displacement", - "description": "Provide a list of genes (comma separated) for which you want special displacement of the gene label.", - "paramType": "STRING", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "Provide list of genes-comma separated", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Special_Label_Displacement_X_Axis_", - "displayName": "Special Label Displacement (X-Axis)", - "description": "Choose a number to set the nudge/displacement of the gene label in the x-direction.", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Special_Label_Displacement_Y_Axis_", - "displayName": "Special Label Displacement (Y-Axis)", - "description": "Choose a number (comma separated) to set the nudge/displacement of the gene label in the x-direction.", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Color_of_P_Value_Threshold_Line", - "displayName": "Color of P-Value Threshold Line", - "description": "The color of the horizontal p-value threshold line", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "blue", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Color_of_Non_Significant_Genes", - "displayName": "Color of Non-Significant Genes", - "description": "", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "black", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Color_of_Log_Fold_Change_Threshold_Line", - "displayName": "Color of Log Fold Change Threshold Line", - "description": "The color of the vertical fold-change threshold lines", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "red", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Color_of_Genes_Meeting_Only_P_Value_Threshold", - "displayName": "Color of Genes Meeting Only P-Value Threshold", - "description": "", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "lightgoldenrod2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_for_genes_meeting_p_value_and_fold_change_thresholds", - "displayName": "Color for genes meeting p-value and fold-change thresholds", - "description": "", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "red", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Flip_Contrast", - "displayName": "Flip Contrast", - "description": "Select TRUE if you want to flip the contrast to opposite direction (flip the plot around the y-axis).", - "paramType": "BOOLEAN", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Use_Default_X_Axis_Limit", - "displayName": "Use Default X-Axis Limit", - "description": "Use default x limit", - "paramType": "BOOLEAN", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "X_Axis_Limit", - "displayName": "X-Axis Limit", - "description": "The limits of the x-axis (symmetric about 0)", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "5", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Use_Default_Y_Axis_Limit", - "displayName": "Use Default Y-Axis Limit", - "description": "Use Default Y limit", - "paramType": "BOOLEAN", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Y_Axis_Limit", - "displayName": "Y-Axis Limit", - "description": "The upper limit of the y-axis", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "10", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Point_Size", - "displayName": "Point Size", - "description": "Size of a each data point", - "paramType": "STRING", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "DEG_Columns_to_Keep_in_Output_Table", - "displayName": "DEG Columns to Keep in Output Table", - "description": "Select columns from input DEG results to include in the output dataset. If \"none\" is selected, then the output will contain only columns for Gene and Contrast.", - "paramType": "MULTISELECT", - "paramGroup": "Table", - "paramValues": [ - "FC", - "logFC", - "tstat", - "pval", - "adjpval", - "none" - ], - "defaultValue": "c(\"FC\",\"logFC\",\"tstat\",\"pval\",\"adjpval\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Image_Output_Format", - "displayName": "Image Output Format", - "description": "Select the image format for saved images: .png (default) .svg (vectorized)", - "paramType": "SELECT", - "paramGroup": "Image", - "paramValues": [ - "png", - "svg" - ], - "defaultValue": "png", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Use_svglite", - "displayName": "Use svglite", - "description": "If TRUE, generates the image using the svglite library, to enable easy editing using off-the-shelf SVG editors", - "paramType": "BOOLEAN", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Image_Width", - "displayName": "Image Width", - "description": "Image width in inches", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "15", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Image_Height", - "displayName": "Image Height", - "description": "Image height in inches", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "15", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Image_Resolution", - "displayName": "Image Resolution", - "description": "Image resolution in dpi (dots-per-inch) for png output", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "300", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Use_Default_Grid_Layout", - "displayName": "Use Default Grid Layout", - "description": "if TRUE, an optimal number of rows in the figure grid layout is attempted; if you want to change the layout set the number of rows in the 'Number of rows in grid layout' parameter below", - "paramType": "BOOLEAN", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Number_of_Rows_in_Grid_Layout", - "displayName": "Number of Rows in Grid Layout", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "Figure_Aspect_Ratio", - "displayName": "Figure Aspect Ratio", - "description": "figure aspect ratio, expressed as y / x; if 0, the ratio is based on the image size", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "0", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "title": "Volcano Plot - Summary [CCBR]", - "templateApiVersion": "0.1.0" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/missing_parameters.csv b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/missing_parameters.csv deleted file mode 100644 index a8a9172..0000000 --- a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/missing_parameters.csv +++ /dev/null @@ -1,12 +0,0 @@ -function_name,missing_arguments -batch_correct_counts,count_type;moo;plots_subdir;print_plots;save_plots;sub_count_type -clean_raw_counts,count_type;moo;print_plots;sample_id_colname;save_plots -diff_counts,count_type;moo;plots_subdir;print_plots;save_plots;sub_count_type -filter_counts,count_type;moo;number_of_histogram_legend_columns;plots_subdir;print_plots;save_plots -filter_diff,bar_width;draw_bar_border;fill_colors;label_distance;label_font_size;moo;pie_chart_in_3d;plot_titles_fontsize;plot_type;plots_subdir;print_plots;save_plots;y_axis_expansion -normalize_counts,count_type;moo;norm_type;plots_subdir;print_plots;save_plots -plot_expr_heatmap,color_values;group_colname;moo_counts;sample_metadata -plot_pca_3d,color_values;counts_dat;label_font_size;principal_components;sample_metadata -plot_venn_diagram,diff_summary_dat;dpi;graphics_device;image_height;image_width;plot_filename;plots_subdir;print_plots;save_plots -plot_volcano_enhanced,additional_labels;axis_lab_size;change_colname;change_lfc_name;change_sig_name;change_threshold;custom_xlim;dpi;image_height;image_width;interactive_plots;is_red;lab_size;moo_diff;num_features_to_label;plot_filename;plots_subdir;print_plots;save_plots;signif_colname;signif_threshold;title;use_custom_lab;use_only_addition_labels;value_to_sort_the_output_dataset;xlim_additional;ylim;ylim_additional -plot_volcano_summary,add_deg_columns;add_features;aspect_ratio;change_threshold;color_for_features_meeting_pvalue_and_foldchange_thresholds;color_of_features_meeting_only_signif_threshold;color_of_logfold_change_threshold_line;color_of_non_significant_features;color_of_signif_threshold_line;custom_gene_list;custom_gene_list_special_label_displacement;custom_label_color;default_label_color;displace_feature_labels;dpi;flip_vplot;graphics_device;image_height;image_width;label_features;label_x_adj;label_y_adj;line_thickness;moo_diff;num_features_to_label;plot_filename;plots_subdir;print_plots;save_plots;signif_colname;signif_threshold;value_to_sort_the_output_dataset diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/batch_correct_counts.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/batch_correct_counts.json deleted file mode 100644 index 77344a5..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/batch_correct_counts.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "title": "Batch Correction", - "description": "This template performs batch correction on RNA-seq expression data to account for batch effects that can arise whenever some samples are prepared in a different manner or at a different time than others. It takes a counts matrix (usually the normalized counts matrix) and your metadata table as input and provides two QC plots and a normalized expression matrix as output. This template is only necessary if your dataset has more than one batch. When necessary, it is usually the third step (after normalization) in the QC portion of a bulk RNA-seq analysis.\n\nBatch correction can only be attempted if your Batch variable is not completely confounded with your Group variable (see your metadata table). The two QC plots, a PCA plot and counts frequency histogram, are provided to help assess within and between group variance and the dis/similarity of sample count distributions, respectively.\n\nThe batch correction applied by this template is performed using the 'sva' R package's ComBat method.", - "r_function": "batch_correct_counts", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Feature ID Column", - "description": "The column from your input Counts Matrix containing the Feature IDs (Usually Gene or Protein ID). This is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts Matrix will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "samples_to_include", - "displayName": "Columns to Include", - "description": "Which Columns would you like to include? Usually, you will choose to \"Add all\" (see button on right). Columns excluded here will be removed in this step and from further analysis downstream of this step.", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "sample_id_colname", - "displayName": "Sample Names Column", - "description": "The column from your input Sample Metadata table containing the sample names. The names in this column must exactly match the names used as the sample column names of your input Counts Matrix. Only columns of Text type from your input Sample Metadata table will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "covariates_colnames", - "displayName": "Covariates", - "description": "The column(s) from your input Sample Metadata table containing variable(s) of interest, such as phenotype. Most commonly this will be the same column you selected for your Groups Column (above). Some experimental designs may require that you add additional covariate columns here. \nNB. Do not include the \"Batch\" column here.", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "batch_colname", - "displayName": "Batch Column", - "description": "The column from your input Sample Metadata table containing the batch information. Samples extracted, prepared, or sequenced at separate times or using separate materials/staff/equipment may belong to different batches. Not all datasets have batches. If yours dataset has no batches, you must still provide a Batch column with the same value in every row.", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "label_colname", - "displayName": "Labels Column", - "description": "The column from your input Sample Metadata table containing the sample labels as you wish them to appear in the plots produced by this template. This can be the same Sample Names Column (see above). However, you may desire different labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the column with your preferred Labels here.", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file at the end of the function", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "count_type", - "displayName": "Count Type", - "description": "", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sub_count_type", - "displayName": "Sub Count Type", - "description": "", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "colors_for_plots", - "displayName": "Colors for plots", - "description": "Colors for the PCA and histogram will be picked, in order, from this list. If more colors are needed, program will choose from a wide range of random colors", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "If this is `TRUE`, any plots generated during the analysis will be saved to disk.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "Batch-corrected MultiOmics Dataset", - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - }, - "figures": { - "type": "directory", - "name": "figures/batch/" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/clean_raw_counts.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/clean_raw_counts.json deleted file mode 100644 index cbadece..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/clean_raw_counts.json +++ /dev/null @@ -1,159 +0,0 @@ -{ - "title": "Clean Raw Counts", - "description": "This template checks the input raw counts matrix for common formatting problems with Feature identifiers (Gene or Peptide/Protein Names) and sample names. \n\nIf Feature IDs contain multiple IDs separated by special Characters((| - , or space) they will be split into multiple columns. \n\nIf Duplicate Feature ID's are detected the counts are summed across duplicate Feature ID rows within each sample.\n\nInvalid sample names will also be reported in the template Log and can be automatically corrected. If your sample names are corrected here, be sure to make equivalent changes to your metadata table.", - "r_function": "clean_raw_counts", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Feature ID Column", - "description": "Select a column from your counts that contains Feature IDs for each row. Defaults to the first column in the counts data.", - "paramGroup": "Basic", - "sourceDataset": "moo@counts", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "sample_id_colname", - "displayName": "Sample ID Column", - "description": "Select a column from your sample metadata that contains Sample IDs for each column. Defaults to the first column in the sample metadata.", - "paramGroup": "Basic", - "sourceDataset": "moo@sample_meta", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file at the end of the function", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "count_type", - "displayName": "Count Type", - "description": "", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "samples_to_rename", - "displayName": "Samples to Rename", - "description": "Enter each sample that you want to rename in the format:\n\nold_name: new_name", - "paramType": "VECTOR", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "c(\"\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "cleanup_column_names", - "displayName": "Cleanup Column Names", - "description": "Invalid raw counts column names can cause errors in the downstream analysis. If this toggle is ON, any invalid column names will be automatically altered to a correct format.\n\nThese format changes will include adding an \"X\" as the first character in any column name that began with a numeral and replacing some special characters (\"-,:. \") with underscores (\"_\"). Invalid sample names and any changes made will be detailed in the template log.", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "split_gene_name", - "displayName": "Split Feature ID", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "aggregate_rows_with_duplicate_gene_names", - "displayName": "Aggregate Rows with Duplicate Feature Names", - "description": "Regardless of the toggle status (ON/OFF), if a Feature ID (from the \"Cleanup Column Names\" parameter above) is found to be duplicated on multiple rows of the raw counts, the Log will report these Feature IDs.\n\nUsing the default behavior (ON), the counts for all rows with a duplicate Feature IDs are aggregated into a single row. Counts are summed across duplicate Feature ID rows within each sample. Additional identifier columns, if present (e.g. Ensembl IDs), will be preserved and multiple matching identifiers in such additional columns will appear as comma-separated values in an aggregated row.", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "gene_name_column_to_use_for_collapsing_duplicates", - "displayName": "Column Used to Aggregate Duplicates Feature IDs", - "description": "Select the column with Feature IDs to use as grouping elements to collapse the counts matrix.\n\nThe log output will list the columns available to identify duplicate row IDs in order to aggregate information. \n\nIf Bulk RNAseq data your column selected for Feature ID will be renamed to \"Gene\" \nIf analyzing Proteomics data your column selected for Feature ID will be renamed to \"Feature ID\".\n\nIf left blank your \"Feature ID\" Column will be used to Aggregate Rows.\n\nIf \"Feature ID\" column can be split into multiple IDs the non Ensembl ID name will be used to aggregate duplicate IDs.\nIf \"Feature ID\" column does not contain Ensembl IDs the split Feature IDs will be named 'Feature_id_1' and 'Feature_id_2'. For this case the Template will error out and you will have to manually enter Column ID for this field.", - "paramType": "STRING", - "paramGroup": "Advanced", - "paramValues": [ - "Gene", - "Pepetide", - "Protein", - "Ensembl_ID", - "Ensembl_ID_version", - "Gene_id_1", - "Gene_id_2", - "Original Gene Column" - ], - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "If this is `TRUE`, any plots generated during the analysis will be saved to disk.", - "paramType": "BOOLEAN", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "Cleaned MultiOmics Dataset", - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - }, - "figures": { - "type": "directory", - "name": "figures/clean/" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/create_multiOmicDataSet_from_files.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/create_multiOmicDataSet_from_files.json deleted file mode 100644 index 54d8019..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/create_multiOmicDataSet_from_files.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "title": "Create Multi-Omic Dataset from Files", - "description": "", - "r_function": "create_multiOmicDataSet_from_files", - "columns": [], - "inputDatasets": [ - { - "key": "sample_meta_filepath", - "displayName": "", - "description": "", - "paramType": "TABULAR", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "feature_counts_filepath", - "displayName": "", - "description": "", - "paramType": "TABULAR", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sample_id_colname", - "displayName": "", - "description": "", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "feature_id_colname", - "displayName": "", - "description": "", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "delim", - "displayName": "", - "description": "", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "MultiOmics Dataset", - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/diff_counts.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/diff_counts.json deleted file mode 100644 index 87394f2..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/diff_counts.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "title": "Differential Analysis", - "description": "Performs Differential Expression of Genes (DEG) Analysis.\n\nThis template takes (filtered) raw counts as its input and transforms this count data to log2-counts per million (logCPM). The normalization and DEG analysis is implemented using the Limma Voom R package.\n\nThe returned counts matrix contains normalized counts, not batch corrected counts. The DEG analysis accounts for batch using covariates, however. You can optionally also return mean and standard deviation of normalized expression within groups.\n\nThis template will support up to 2 factors", - "r_function": "diff_counts", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Feature/Gene Names Column", - "description": "The column from your counts matrix containing the Feature ID (gene names).", - "paramGroup": "Basic", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "sample_id_colname", - "displayName": "Sample Names Column", - "description": "Column containing sample names", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "samples_to_include", - "displayName": "Columns to Include", - "description": "Select the sample columns from the input counts matrix that you want to process. Only numeric columns can be selected.", - "paramGroup": "Basic", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "contrast_colname", - "displayName": "Contrast Variable Column", - "description": "The column in the input Sample Metadata that contains the group variables you wish to find differential expression between. User can add up to 2 columns (2-factor analysis)", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "covariates_colnames", - "displayName": "Covariates Column(s)", - "description": "Columns to be used as covariates in linear modeling. Must include column from \"Contrast Variable\". Most commonly your covariate will be group and batch (if you have different batches in your data).", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file at the end of the function", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "count_type", - "displayName": "Count Type", - "description": "", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sub_count_type", - "displayName": "Sub Count Type", - "description": "", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "contrasts", - "displayName": "Contrasts", - "description": "Specify each contrast in the format group1-group2, e.g. treated-control", - "paramType": "VECTOR", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "input_in_log_counts", - "displayName": "Input in log Counts", - "description": "Set to TRUE if input is in log counts.", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "return_mean_and_sd", - "displayName": "Return Mean and SD", - "description": "if TRUE, return Mean and Standard Deviation of groups in addition to DEG estimates for contrast(s)", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "voom_normalization_method", - "displayName": "Normalization Method", - "description": "Normalization method to be applied to the logCPM values", - "paramType": "SELECT", - "paramGroup": "Advanced", - "paramValues": [ - "none", - "scale", - "quantile", - "cyclicloess", - "TMM", - "TMMwzp", - "RLE", - "upperquartile" - ], - "defaultValue": "quantile", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "If this is `TRUE`, any plots generated during the analysis will be saved to disk.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "Differential Counts from MultiOmics Dataset", - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - }, - "figures": { - "type": "directory", - "name": "figures/diff/" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/filter_counts.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/filter_counts.json deleted file mode 100644 index f2eca99..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/filter_counts.json +++ /dev/null @@ -1,433 +0,0 @@ -{ - "title": "Filter Low Counts", - "description": "This template is intended for use with Bulk RNA-seq data and is often the first step in the QC portion of an analysis. It filters out Features that have very low raw counts across most or all of your samples.\n\nThis template takes as input a raw counts expression matrix and your sample metadata table. It provides as output an image consisting of three QC plots (see below) and a filtered raw counts expression matrix. You have an option to use CPM counts as input instead.\n\nThe threshold for tuning how low counts for a given gene are before they are deemed \"too low\" and filtered out of downstream analysis is a tunable parameter. By default, this parameter is set to 1, meaning any raw count value less than 1 will count as \"too low\".\n\nThe QC plots are provided to help you assess: (1) PCA Plot: the within and between group variance in expression after dimensionality reduction; (2) Count Density Histogram: the dis/similarity of count distributions between samples; and (3) Similarity Heatmap: the overall similarity of samples to one another based on unsupervised clustering.", - "r_function": "filter_counts", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Feature ID Column", - "description": "The column from your input Counts Matrix containing the Feature IDs (Usually Gene or Protein ID). This is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts Matrix will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "samples_to_include", - "displayName": "Columns to Include", - "description": "Which Columns would you like to include? Usually, you will choose to \"Add all\" (see button on right). Columns excluded here will be removed in this step and from further analysis downstream of this step.", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "sample_id_colname", - "displayName": "Sample Names Column", - "description": "The column from your input Sample Metadata table containing the sample names. The names in this column must exactly match the names used as the sample column names of your input Counts Matrix. Only columns of Text type from your input Sample Metadata table will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "group_colname", - "displayName": "Groups Column", - "description": "The column from your input Sample Metadata table containing the sample group information. This is usually a column showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal, Before, After, etc.). Only columns of Text type from your input Sample Metadata will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "label_colname", - "displayName": "Labels Column", - "description": "The column from your input Sample Metadata table containing the sample labels as you wish them to appear in the plots produced by this template. This can be the same Sample Names Column (see above). However, you may desire different labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the column with your preferred Labels here. The selected column should contain unique names for each sample.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file at the end of the function", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "count_type", - "displayName": "Count Type", - "description": "", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_cpm_counts_to_filter", - "displayName": "Use CPM Counts to filter", - "description": "If no transformation has been been performed on counts matrix (eg Raw Counts) set to TRUE. If TRUE counts will be transformed to CPM and filtered based on given criteria.\n If gene counts matrix has been transformed (eg log2, CPM, FPKM or some form of Normalization) set to FALSE. If FALSE no further transformation will be applied and features will be filtered as is. For RNAseq data RAW counts should be transformed to CPM in order to properly filter.", - "paramType": "BOOLEAN", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "minimum_count_value_to_be_considered_nonzero", - "displayName": "Minimum Count Value to be Considered Nonzero", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "minimum_number_of_samples_with_nonzero_counts_in_total", - "displayName": "Minimum Number of Samples with Nonzero Counts in Total", - "description": "Minimum number of samples (total) with non-zero counts", - "paramType": "NUMBER", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_group_based_filtering", - "displayName": "Use Group-Based Filtering", - "description": "If TRUE, only keeps genes that have at least a certain number of samples with nonzero CPM counts in at least one group", - "paramType": "BOOLEAN", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "minimum_number_of_samples_with_nonzero_counts_in_a_group", - "displayName": "Minimum Number of Samples with Nonzero Counts in a Group", - "description": "Only keeps genes that have at least this number of samples with nonzero CPM counts in at least one group", - "paramType": "NUMBER", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": "3", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "principal_component_on_x_axis", - "displayName": "Principal Component on X-axis", - "description": "The principle component to plot on the x-axis. Choices include 1, 2, 3, ... (default: 1)", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "principal_component_on_y_axis", - "displayName": "Principal Component on Y-axis", - "description": "The principle component to plot on the y-axis. Choices include 1, 2, 3, ... (default: 2)", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_position_for_pca", - "displayName": "Legend Position for PCA", - "description": "Legend position relative to the plot", - "paramType": "SELECT", - "paramGroup": "PCA", - "paramValues": [ - "top", - "bottom", - "left", - "right", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "point_size_for_pca", - "displayName": "Point Size for PCA", - "description": "", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "add_label_to_pca", - "displayName": "Add Labels to PCA", - "description": "Label points on graph", - "paramType": "BOOLEAN", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_font_size", - "displayName": "Label Font Size for PCA", - "description": "Font size for sample labels. Set to 0 to remove labels.", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "3", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_offset_x_", - "displayName": "Label Offset (x)", - "description": "", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_offset_y_", - "displayName": "Label Offset (Y)", - "description": "", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "samples_to_rename", - "displayName": "Samples to Rename Manually on PCA", - "description": "If you do not have a Plot Labels Column (see above) in your sample metadata table, you can use this parameter to rename samples manually for display on the PCA plot. Use \"Add item\" to add each additional sample for renaming. Use the following format to describe which old name (in your sample metadata table) you want to rename to which new name: old_name: new_name", - "paramType": "VECTOR", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "c(\"\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_histogram_by_group", - "displayName": "Color Histogram by Group", - "description": "Toggle to FALSE to label histogram by Sample Names. Toggle to TRUE to label histogram by the column you select in the \"Group Column Used to Color Histogram\" parameter (below). Default is FALSE.", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "set_min_max_for_x_axis_for_histogram", - "displayName": "Set Min/Max for X-axis for Histogram", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "minimum_for_x_axis_for_histogram", - "displayName": "Minimum for X-axis for Histogram", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "-1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "maximum_for_x_axis_for_histogram", - "displayName": "Maximum for X-axis for Histogram", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_font_size_for_histogram", - "displayName": "Legend Font Size for Histogram", - "description": "Legend font size", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "10", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_position_for_histogram", - "displayName": "Legend Position for Histogram", - "description": "Legend position on histogram plot, can be 'none' if large number of samples", - "paramType": "SELECT", - "paramGroup": "Histogram", - "paramValues": [ - "right", - "bottom", - "left", - "top", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "number_of_histogram_legend_columns", - "displayName": "Number of Histogram Legend Columns", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "6", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "colors_for_plots", - "displayName": "Colors for Plots", - "description": "Colors for the PCA and histogram will be picked, in order, from this list. If you have >12 samples or groups, program will choose from a wide range of random colors", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "interactive_plots", - "displayName": "Interactive Plots", - "description": "Toggle TRUE to make PCA and Histogram plots interactive, allowing you to hover your mouse over a point or line to view sample information. The similarity heatmap will not display if this toggle is set to TRUE. Default is FALSE.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "plot_corr_matrix_heatmap", - "displayName": "Plot Correlation Matrix Heatmap", - "description": "Datasets with a large number of samples may be too large to create a correlation matix heatmap. If this template takes longer than 5 minutes to run, Toggle switch to FALSE and the correlation matrix will not be be created. Default is TRUE.", - "paramType": "BOOLEAN", - "paramGroup": "TCGA", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "If this is `TRUE`, any plots generated during the analysis will be saved to disk.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "Filtered MultiOmics Dataset", - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - }, - "figures": { - "type": "directory", - "name": "figures/filt/" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/filter_diff.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/filter_diff.json deleted file mode 100644 index 21bc470..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/filter_diff.json +++ /dev/null @@ -1,357 +0,0 @@ -{ - "title": "Filter Differential Features", - "description": "Outputs dataset of significant genes from DEG table; filters genes based on statistical significance (p-value or adjusted p-value) and change (fold change, log2 fold change, or t-statistic); in addition allows for selection of DEG estimates and for sub-setting of contrasts and groups included in the output gene list.", - "r_function": "filter_diff", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Gene Names Column", - "description": "The column from your input DEG Table containing the gene names. This is usually the first column of your input DEG Table. Only columns of Text type from your input DEG Table will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file at the end of the function", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "significance_column", - "displayName": "Significance Column", - "description": "", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "adjpval", - "pval" - ], - "defaultValue": "adjpval", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "significance_cutoff", - "displayName": "Significance Cutoff", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "0.01", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "change_column", - "displayName": "Change Column", - "description": "", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "FC", - "logFC", - "tstat" - ], - "defaultValue": "logFC", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "change_cutoff", - "displayName": "Change Cutoff", - "description": "Absolute value of the cutoff; default cutoff set to 1 in log2 scale (2-fold change)", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "filtering_mode", - "displayName": "Filtering Mode", - "description": "", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "any", - "all" - ], - "defaultValue": "any", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "include_estimates", - "displayName": "Include Estimates", - "description": "", - "paramType": "MULTISELECT", - "paramGroup": "Advanced", - "paramValues": [ - "mean", - "sd", - "FC", - "logFC", - "tstat", - "pval", - "adjpval" - ], - "defaultValue": [ - "mean", - "sd", - "FC", - "logFC", - "tstat", - "pval", - "adjpval" - ], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "round_estimates", - "displayName": "Round Estimates", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "contrast_filter", - "displayName": "Contrasts Filter", - "description": "", - "paramType": "SELECT", - "paramGroup": "Filter", - "paramValues": [ - "none", - "keep", - "remove" - ], - "defaultValue": "none", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "contrasts", - "displayName": "Contrasts", - "description": "", - "paramType": "VECTOR", - "paramGroup": "Filter", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "groups_filter", - "displayName": "Groups Filter", - "description": "", - "paramType": "SELECT", - "paramGroup": "Filter", - "paramValues": [ - "none", - "keep", - "remove" - ], - "defaultValue": "none", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "groups", - "displayName": "Groups", - "description": "", - "paramType": "VECTOR", - "paramGroup": "Filter", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_font_size", - "displayName": "Label Font Size", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "6", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_distance", - "displayName": "Label Distance", - "description": "Distance of text label from top of a bar", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "y_axis_expansion", - "displayName": "Y-Axis Expansion", - "description": "multiplicative expansion of y-axis limits; increase/decrease this number if the text label above the bar requires more/less space", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "0.08", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "fill_colors", - "displayName": "Fill Colors ", - "description": "", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "aliceblue", - "antiquewhite4", - "darkorange", - "gold", - "red3", - "springgreen", - "steelblue1", - "blue2", - "violetred3", - "whitesmoke", - "gray60", - "gray90", - "black", - "white" - ], - "defaultValue": "c(\"steelblue1\",\"whitesmoke\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "pie_chart_in_3d", - "displayName": "Pie Chart in 3D", - "description": "If TRUE, a 3D Pie chart is plotted with 'Filtering mode' set to 'in all contrasts', if FALSE, a 2D chart will be plotted for this filtering mode.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "bar_width", - "displayName": "Bar Width", - "description": "Bar width in the bar chart plotted with Filtering mode set to 'in any contrast'", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "0.4", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "draw_bar_border", - "displayName": "Draw Bar Border", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "rounding_decimal_for_percent_cells", - "displayName": "Rounding Decimal for Percent Calls", - "description": "applies to display of percent significant and non-significant calls", - "paramType": "NUMBER", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "0", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "plot_titles_fontsize", - "displayName": "Font Size for Plot Titles", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": 12, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "If this is `TRUE`, any plots generated during the analysis will be saved to disk.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "Filtered Differential Counts from MultiOmics Dataset", - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - }, - "figures": { - "type": "directory", - "name": "figures/diff/filt/" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/initialize-templates.py b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/initialize-templates.py deleted file mode 100644 index cc899c7..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/initialize-templates.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python - -import json -import glob -import pathlib - - -def main(): - with open( - "inst/extdata/galaxy/0_nidap-1.0/NIDAPBulkTemplate_parameterTo_MOSuiteMapping.json", - "r", - ) as infile: - template_mappings = json.load(infile)["template_mappings"] - for filename in glob.glob("inst/extdata/galaxy/0_nidap-1.0/*.code-template.json"): - code_template_file = pathlib.Path(filename) - with open(code_template_file, "r") as infile: - code_template = json.load(infile) - template_name = code_template_file.name - mapping = next( - ( - meta - for key, meta in template_mappings.items() - if key == template_name - ), - {}, - ) - new_template = { - "title": code_template["title"].replace(" [CCBR]", ""), - "description": code_template["description"], - "r_function": mapping.get("r_function", ""), - "columns": [], - "inputDatasets": [], - "parameters": [], - } - for arg_type in ("columns", "inputDatasets", "parameters"): - for param in code_template.get(arg_type, []): - param_name = param.get("key") - params_lst = mapping.get("parameter_mappings", []) - new_param = next( - (p.get(param_name) for p in params_lst if param_name in p), None - ) - if new_param: - param["key"] = new_param - new_template[arg_type].append(param) - else: - new_template[arg_type].append(param) - with open( - pathlib.Path( - f"inst/extdata/galaxy/1_mosuite-templates/{new_template['r_function']}.json" - ), - "w", - ) as outfile: - json.dump(new_template, outfile, indent=4) - - -if __name__ == "__main__": - main() diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/normalize_counts.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/normalize_counts.json deleted file mode 100644 index d6073e8..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/normalize_counts.json +++ /dev/null @@ -1,414 +0,0 @@ -{ - "title": "Normalization", - "description": "This template is intended for use with Bulk RNA-seq data and is often performed immediately after filtering for low count genes. It normalizes RNA-seq expression data to account for factors that would prevent direct comparisons between samples.\n\nThis template takes as input a counts matrix (usually the filtered counts matrix) and your sample metadata table. It provides as output an image consisting of three QC plots (see below) and a normalized expression matrix.\n\nThe default normalization method is quantile, which is a very common way to normalize bulk RNA-seq data. Other normalization methods are selectable, as needed.\n\nThe QC plots provided are: (1) PCA Plot: shows the within- and between-group variance in expression after dimensionality reduction; (2) Count Density Histogram: shows the dis/similarity of count distributions between samples; and (3) Similarity Heatmap: shows the overall similarity of samples to one another based on unsupervised clustering.", - "r_function": "normalize_counts", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Feature ID Column", - "description": "The column from your input Counts Matrix containing the Feature IDs (Usually Gene or Protein ID). This is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts Matrix will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "samples_to_include", - "displayName": "Columns to Include", - "description": "Which Columns would you like to include? Usually, you will choose to \"Add all\" (see button on right). Columns excluded here will be removed in this step and from further analysis downstream of this step.", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "sample_id_colname", - "displayName": "Sample Names Column", - "description": "The column from your input Sample Metadata table containing the sample names. The names in this column must exactly match the names used as the sample column names of your input Counts Matrix. Only columns of Text type from your input Sample Metadata table will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "group_colname", - "displayName": "Groups Column", - "description": "The column from your input Sample Metadata table containing the sample group information. This is usually a column showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal, Before, After, etc.). Only columns of Text type from your input Sample Metadata will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "label_colname", - "displayName": "Labels Column", - "description": "The column from your input Sample Metadata table containing the sample labels as you wish them to appear in the plots produced by this template. This can be the same Sample Names Column (see above). However, you may desire different labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the column with your preferred Labels here.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file at the end of the function", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "count_type", - "displayName": "Count Type", - "description": "", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "norm_type", - "displayName": "Normalization Type", - "description": "", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "input_in_log_counts", - "displayName": "Input in Log Counts", - "description": "TRUE if input is in log counts", - "paramType": "BOOLEAN", - "paramGroup": "Normalization", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "voom_normalization_method", - "displayName": "Normalization Method", - "description": "Normalization method to be applied to the logCPM values", - "paramType": "SELECT", - "paramGroup": "Normalization", - "paramValues": [ - "none", - "scale", - "quantile", - "cyclicloess" - ], - "defaultValue": "quantile", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "samples_to_rename", - "displayName": "Samples to Rename Manually on PCA", - "description": "Enter each sample to rename in the format: old_name: new_name", - "paramType": "VECTOR", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "c(\"\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "add_label_to_pca", - "displayName": "Add Labels to PCA", - "description": "Toggle to TRUE to use the column from \"Label Column to Use for Plots\" (above) to label points on the PCA plot. Toggle to FALSE to remove these labels from the plot. Default is TRUE.", - "paramType": "BOOLEAN", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "principal_component_on_x_axis", - "displayName": "Principal Component on X-axis for PCA", - "description": "The principle component to plot on the x-axis. Choices include 1, 2, 3, ... (default: 1)", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "principal_component_on_y_axis", - "displayName": "Principal Component on Y-axis for PCA", - "description": "The principle component to plot on the y-axis. Choices include 1, 2, 3, ... (default: 2)", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_position_for_pca", - "displayName": "Legend position for PCA", - "description": "Legend position relative to the plot", - "paramType": "SELECT", - "paramGroup": "PCA", - "paramValues": [ - "top", - "bottom", - "left", - "right", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_offset_x_", - "displayName": "Label Offset (x) for PCA", - "description": "", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_offset_y_", - "displayName": "Label Offset (y) for PCA", - "description": "", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_font_size", - "displayName": "Label Font Size for PCA", - "description": "Font size for sample labels on the PCA. Set to 0 to remove labels.", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "3", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "point_size_for_pca", - "displayName": "Point Size for PCA", - "description": "Size of a each data point on the PCA.", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_histogram_by_group", - "displayName": "Color Histogram by Group", - "description": "Toggle to FALSE to label histogram by Sample Names. Toggle to TRUE to label histogram by the column you select in the \"Group Column Used to Color Histogram\" parameter (below). Default is FALSE.", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "maximum_for_x_axis_for_histogram", - "displayName": "Maximum for X-axis in Histogram", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "minimum_for_x_axis_for_histogram", - "displayName": "Minimum for X-axis in Histogram", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "-1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "set_min_max_for_x_axis_for_histogram", - "displayName": "Set Min/Max for X-axis for Histogram", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_font_size_for_histogram", - "displayName": "Legend Font Size for Histogram", - "description": "Legend font size for the histogram.", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "10", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_position_for_histogram", - "displayName": "Legend Position for Histogram", - "description": "Legend position on histogram plot, can be 'none' if large number of samples", - "paramType": "SELECT", - "paramGroup": "Histogram", - "paramValues": [ - "top", - "bottom", - "left", - "right", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "number_of_histogram_legend_columns", - "displayName": "Number of Histogram Legend Columns", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": "6", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "colors_for_plots", - "displayName": "Colors for Plots", - "description": "Colors for the PCA and histogram will be picked, in order, from this list. If more colors are needed, program will choose from a wide range of random colors", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "interactive_plots", - "displayName": "Make Plots Interactive", - "description": "Toggle TRUE to make PCA and Histogram plots interactive, allowing you to hover your mouse over a point or line to view sample information. The similarity heatmap will not display if this toggle is set to TRUE. Default is FALSE.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "plot_corr_matrix_heatmap", - "displayName": "Plot Correlation Matrix Heatmap", - "description": "Datasets with a large number of samples may be too large to create a correlation matix Heatmap. If Template takes longer than 5 min to run Toggle switch to off and the correlation matrix will not be be created", - "paramType": "BOOLEAN", - "paramGroup": "TCGA", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "If this is `TRUE`, any plots generated during the analysis will be saved to disk.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "Normalized Counts in MultiOmics Dataset", - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - }, - "figures": { - "type": "directory", - "name": "figures/norm/" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_expr_heatmap.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_expr_heatmap.json deleted file mode 100644 index 550d562..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_expr_heatmap.json +++ /dev/null @@ -1,567 +0,0 @@ -{ - "title": "Plot Expression Heatmap", - "description": "This template is intended for use with Bulk RNA-seq data. It generates a heatmap for normalized (or batch corrected) RNA-seq data.\n\nThis template takes as input an expression matrix and your sample metadata table. The expression matrix is usually (though not always) going to consist of your normalized or batch corrected counts. It should always have one row per gene, a first column of gene names, and one additional column per sample.\n\nBy default, the samples (i.e. the columns) are allowed to cluster in an unsupervised fashion based on how similar their expression profiles are across the included genes. This can help identify samples that are non clustering with their group as you might expect based on the experimental design.\n\nAgain, by default, the top 500 genes by variance are used, as these are generally going to include those genes that most distinguish your samples from one another. You can change this as well as many other parameters about this heatmap if you explore the advanced options.", - "r_function": "plot_expr_heatmap", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Gene Column Name", - "description": "Column containing gene names.", - "paramGroup": "Data Setup", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "sample_id_colname", - "displayName": "Sample Name Column", - "description": "Column containing sample names.", - "paramGroup": "Data Setup", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "label_colname", - "displayName": "Sample Labels Column", - "description": "Select column from metadata that contains the sample names that will appear as column names on the heatmap.", - "paramGroup": "Data Setup", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "samples_to_include", - "displayName": "Samples to Include", - "description": "Select the sample columns from the input counts matrix that you want to include in the heatmap. Only numeric columns can be selected.", - "paramGroup": "Data Setup", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "NUMBER", - "isMulti": true - }, - { - "key": "reorder_dendrogram_order", - "displayName": "Reorder Sample Dendrogram Order", - "description": "Reorder the samples (columns) of the dendrogram by name, e.g. \u201csample2\u201d,\u201csample3\",\u201csample1\".", - "paramGroup": "Sample", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - }, - { - "key": "group_colname", - "displayName": "Group Columns", - "description": "Columns containing the sample groups for annotation tracks", - "paramGroup": "Annotation", - "sourceDataset": "Sample_Metadata", - "defaultValue": null, - "columnType": "ALL", - "isMulti": true - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "count_type", - "displayName": "Count Type", - "description": "", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sub_count_type", - "displayName": "Sub Count Type", - "description": "optional", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "include_all_genes", - "displayName": "Include All Genes", - "description": "Set to TRUE if all genes are to be included. Set to FALSE if you want to filter genes by variance and/or provide a list of specific genes that will appear in the heatmap.", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "filter_top_genes_by_variance", - "displayName": "Filter Top Genes by Variance", - "description": "Set to TRUE if you want to only include the top genes by variance. Set to FALSE if you do not want to filter genes by variance.", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "top_genes_by_variance_to_include", - "displayName": "Top Genes by Variance to Include", - "description": "The number of genes to include if filtering genes by variance. This parameter is ignored if \"Filter top genes by variance\" is set to FALSE.", - "paramType": "NUMBER", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "500", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "specific_genes_to_include_in_heatmap", - "displayName": "Specific Genes to Include in Heatmap", - "description": "Enter the gene symbols to be included in the heatmap, with each gene symbol separated with a space from the others. Alternatively, paste in a column of gene names from any spreadsheet application. This parameter is ignored if \"Include all genes\" is set to TRUE.", - "paramType": "STRING", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "None", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "cluster_genes", - "displayName": "Cluster Genes", - "description": "Choose whether to cluster the rows (genes). If TRUE, rows will have clustering applied. If FALSE, clustering will not be applied to rows.", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "gene_clustering_method", - "displayName": "Gene Clustering Method", - "description": "Clustering method metric to be used in clustering samples.", - "paramType": "SELECT", - "paramGroup": "Gene", - "paramValues": [ - "ward.D", - "ward.D2", - "single", - "complete", - "average", - "mcquitty", - "median", - "centroid" - ], - "defaultValue": "average", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "gene_distance_metric", - "displayName": "Gene Distance Metric", - "description": "Distance metric to be used in clustering genes.", - "paramType": "SELECT", - "paramGroup": "Gene", - "paramValues": [ - "euclidean", - "maximum", - "manhattan", - "canberra", - "binary", - "minkowski", - "correlation" - ], - "defaultValue": "correlation", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "display_gene_dendrograms", - "displayName": "Display Gene Dendrogram", - "description": "Set to TRUE to show gene dendrograms. Set to FALSE to hide dendrograms.", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "display_gene_names", - "displayName": "Display Gene Names", - "description": "Set to TRUE to display gene names on the right side of the heatmap. Set to FALSE to hide gene names.", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "center_and_rescale_expression", - "displayName": "Center and Rescale Expression", - "description": "Center and rescale expression for each gene across all included samples.", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "cluster_samples", - "displayName": "Cluster Samples", - "description": "Choose whether to cluster the columns (samples). If TRUE, columns will have clustering applied. If FALSE, clustering will not be applied to columns.", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "arrange_sample_columns", - "displayName": "Arrange Sample Columns", - "description": "If TRUE, your samples will be arranged by the order that Groups are found in the \"Samples to Include\" parameter above. If FALSE, and \"Cluster Samples\" is FALSE, and \"Order by Gene Expression is FALSE, then samples will appear in the order of input (Samples to Include).", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "order_by_gene_expression", - "displayName": "Order by Gene Expression", - "description": "If TRUE, set gene name below and direction for ordering", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "gene_to_order_columns", - "displayName": "Gene to Order Columns", - "description": "Gene to order columns by expression levels", - "paramType": "STRING", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": " ", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "gene_expression_order", - "displayName": "Gene Expression Order", - "description": "Choose direction for gene order", - "paramType": "SELECT", - "paramGroup": "Sample", - "paramValues": [ - "low_to_high", - "high_to_low" - ], - "defaultValue": "low_to_high", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "smpl_clustering_method", - "displayName": "Sample Clustering Method", - "description": "Clustering method to be used in clustering samples.", - "paramType": "SELECT", - "paramGroup": "Sample", - "paramValues": [ - "ward.D", - "ward.D2", - "single", - "complete", - "average", - "mcquitty", - "median", - "centroid" - ], - "defaultValue": " ", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "smpl_distance_metric", - "displayName": "Sample Distance Metric", - "description": "Distance metric to be used in clustering samples.", - "paramType": "SELECT", - "paramGroup": "Sample", - "paramValues": [ - "euclidean", - "maximum", - "manhattan", - "canberra", - "binary", - "minkowski", - "correlation" - ], - "defaultValue": "correlation", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "display_smpl_dendrograms", - "displayName": "Display Sample Dendrograms", - "description": "Set to TRUE to show sample dendrograms. Set to FALSE to hide dendrogram.", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "reorder_dendrogram", - "displayName": "Reorder Sample Dendrogram", - "description": "If TRUE, set the order of the dendrogram (below)", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "display_sample_names", - "displayName": "Display Sample Names", - "description": "Set to TRUE if you want sample names to be displayed on the plot. Set to FALSE to hide sample names.", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "assign_group_colors", - "displayName": "Assign Group Colors", - "description": "If TRUE, set the groups assigned colors (below)", - "paramType": "BOOLEAN", - "paramGroup": "Annotation", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "assign_color_to_sample_groups", - "displayName": "Assign Color to Sample Groups", - "description": "Enter each sample to color in the format: group_name: color This parameter is ignored if \"Assign Colors\" is set to FALSE. Use this link to select colors: https://nidap.nih.gov/workspace/preview-app/ri.blobster.main.pdf.7922ce2b-39d7-40e7-85ea-8b8146bbf363", - "paramType": "VECTOR", - "paramGroup": "Annotation", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "group_colors", - "displayName": "Group Colors", - "description": "Set group annotation colors.", - "paramType": "MULTISELECT", - "paramGroup": "Annotation", - "paramValues": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "defaultValue": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "heatmap_color_scheme", - "displayName": "Heatmap Color Scheme", - "description": "Color scheme for heatmap.", - "paramType": "SELECT", - "paramGroup": "Visual", - "paramValues": [ - "Default", - "Blue to Red", - "Red to Vanilla", - "Violet to Pink", - "Bu Yl Rd", - "Bu Wt Rd" - ], - "defaultValue": "Default", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "autoscale_heatmap_color", - "displayName": "Autoscale Heatmap Color", - "description": "Set to TRUE to autoscale the heatmap colors between the maximum and minimum heatmap color parameters. If FALSE, set the heatmap colors between \"Set max heatmap color\" and \"Set min heatmap color\" (below).", - "paramType": "BOOLEAN", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "set_max_heatmap_color", - "displayName": "Set Max Heatmap Color", - "description": "If Autoscale heatmap color is set to FALSE, set the maximum heatmap z-score value.", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "set_min_heatmap_color", - "displayName": "Set Min Heatmap Color", - "description": "If Autoscale heatmap color is set to FALSE, set the minimum heatmap z-score value.", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "-2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "aspect_ratio", - "displayName": "Aspect Ratio", - "description": "Set figure Aspect Ratio. Ratio refers to entire figure including legend. If set to Auto figure size is based on number of rows and columns form counts matrix. default - Auto", - "paramType": "STRING", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "Auto", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "display_numbers", - "displayName": "Display Numbers", - "description": "Setting to FALSE (default) will not display numerical value of heat on heatmap. Set to TRUE if you want to see these numbers on the plot.", - "paramType": "BOOLEAN", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "gene_name_font_size", - "displayName": "Gene Name Font Size", - "description": "Font size for gene names. If you don't want gene labels to show, toggle \"Display Gene Names\" below to FALSE", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "4", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_font_size", - "displayName": "Legend Font Size", - "description": "Set Font size for figure legend. Default is 10.", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "10", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sample_name_font_size", - "displayName": "Sample Name Font Size", - "description": "Font size for sample names. If you don't want to display samples names, toggle \"Display sample names\" (below) to FALSE", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "8", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "If this is `TRUE`, any plots generated during the analysis will be saved to disk.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "Expression Heatmap Plot", - "outputs": { - "figures": { - "type": "file", - "name": "figures/heatmap/expr_heatmap.png" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_pca_2d.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_pca_2d.json deleted file mode 100644 index 8565011..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_pca_2d.json +++ /dev/null @@ -1,296 +0,0 @@ -{ - "title": "PCA 2D", - "description": "This template is based on Bulk RNA-seq QC PCA template and is intended to provide a 2D PCA plot generated from the data.", - "r_function": "plot_pca_2d", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "FeatureID Name Column", - "description": "The column from your counts matrix containing the Feature IDs (such as gene names, isoform names and so on). This is usually the first column of your counts matrix.", - "paramGroup": "Basic", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "sample_id_colname", - "displayName": "Sample Names Column", - "description": "The column from your sample metadata table containing the sample names. These should be the same as the sample names found in the column names of the counts matrix.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "group_colname", - "displayName": "Group Column", - "description": "The column from your sample metadata table containing sample group information. This is usually a column showing which of your experimental treatments each sample belongs to (e.g. WildType, Knockout, Tumor, Normal, Before, After, etc.).", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": "Group", - "columnType": "ALL", - "isMulti": null - }, - { - "key": "label_colname", - "displayName": "Plot Labels Column", - "description": "The column from your sample metadata table containing the sample names as you wish them to appear in the QC figure. This is often the same Sample Name Column (see parameter above). However, you may desire different labels to display on your PCA figure (e.g. shorter labels). These labels can be added as an additional column in your metadata table and used here to label your plot.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": "Label", - "columnType": "ALL", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "count_type", - "displayName": "Count Type", - "description": "The type of counts to use from the multiOmicDataSet counts slot", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sub_count_type", - "displayName": "Sub Count Type", - "description": "Used if count_type is a list in the counts slot: specify the sub count type within the list (optional)", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "principal_components", - "displayName": "Principal Components", - "description": "Vector with numbered principal components to plot. For 2D PCA, specify exactly 2 components (e.g., [1, 2] for PC1 vs PC2).", - "paramType": "MULTISELECT", - "paramGroup": "Basic", - "paramValues": [ - 1, - 2, - 3, - 4, - 5 - ], - "defaultValue": [ - 1, - 2 - ], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "point_size", - "displayName": "Point Size", - "description": "The size of the points in the 2D PCA plot.", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "add_label", - "displayName": "Add Labels", - "description": "Whether to add text labels for the points on the plot.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_font_size", - "displayName": "Label Font Size", - "description": "The font size for point labels (if add_label is TRUE).", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": 3, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_position", - "displayName": "Legend Position", - "description": "Position of the legend on the plot.", - "paramType": "SELECT", - "paramGroup": "Visualization", - "paramValues": [ - "top", - "bottom", - "left", - "right", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_values", - "displayName": "Color Values", - "description": "Colors for the PCA will be picked, in order, from this list. There are thousands of colors. You may remove or add colors as you choose, but take care that there are always at least as many colors in this list than you need to color items in your plot.\n\nExample: if you are coloring by Group and have 3 groups, you should have at least 3 colors in your list.", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "slateblue3", - "tomato2", - "maroon", - "deepskyblue", - "mediumorchid2", - "mediumseagreen", - "salmon", - "dodgerblue", - "darkgreen", - "plum4", - "orange", - "yellow4", - "aquamarine3", - "salmon1", - "lightskyblue3", - "plum3", - "firebrick", - "darkolivegreen3", - "goldenrod1", - "burlywood2", - "gray70", - "firebrick2", - "steelblue", - "palegreen4", - "orchid4", - "darkorange1", - "yellow", - "sienna", - "palevioletred1", - "gray60", - "cyan4", - "darkorange3", - "mediumpurple3", - "violetred2", - "olivedrab", - "darkgoldenrod2", - "darkgoldenrod", - "gray40", - "palegreen3", - "thistle3", - "khaki1", - "deeppink2", - "chocolate3", - "paleturquoise3", - "wheat1", - "lightsteelblue", - "sandybrown", - "darkolivegreen2", - "thistle2", - "gray85", - "orchid3", - "darkseagreen1", - "lightgoldenrod1", - "lightskyblue2", - "dodgerblue3", - "darkseagreen3", - "forestgreen", - "lightpink2", - "mediumpurple4", - "lightpink1", - "thistle", - "navajowhite", - "lemonchiffon", - "bisque2", - "mistyrose", - "gray95", - "lightcyan3", - "peachpuff2", - "lightsteelblue2", - "lightyellow2", - "moccasin", - "antiquewhite2", - "gray80", - "lightgrey" - ], - "defaultValue": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "interactive_plots", - "displayName": "Interactive Plots", - "description": "If TRUE, creates an interactive plotly plot instead of a static ggplot.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "If this is `TRUE`, any plots generated during the analysis will be saved to disk.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": [ - true, - false - ], - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "2D PCA Plot", - "outputs": { - "figures": { - "type": "file", - "name": "figures/pca/pca_2D.png" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_pca_3d.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_pca_3d.json deleted file mode 100644 index 39b95b4..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_pca_3d.json +++ /dev/null @@ -1,217 +0,0 @@ -{ - "title": "PCA 3D", - "description": "This template is based on Bulk RNA-seq QC PCA template and is intended to provide interactive 3D view of a PCA plot generated from the data.", - "r_function": "plot_pca_3d", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "FeatureID Name Column", - "description": "The column from your counts matrix containing the Feature IDs (such as gene names, isoform names and so on). This is usually the first column of your counts matrix.", - "paramGroup": "Basic", - "sourceDataset": "Counts_Matrix", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "sample_id_colname", - "displayName": "Sample Names Column", - "description": "The column from your sample metadata table containing the sample names. These should be the same as the sample names found in the column names of the counts matrix.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "group_colname", - "displayName": "Group Column", - "description": "The column from your sample metadata table containing sample group information. This is usually a column showing which of your experimental treatments each sample belongs to (e.g. WildType, Knockout, Tumor, Normal, Before, After, etc.).", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - }, - { - "key": "label_colname", - "displayName": "Plot Labels Column", - "description": "The column from your sample metadata table containing the sample names as you wish them to appear in the QC figure. This is often the same Sample Name Column (see parameter above). However, you may desire different labels to display on your PCA figure (e.g. shorter labels). These labels can be added as an additional column in your metadata table and used here to label your plot.", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": null, - "columnType": "ALL", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "count_type", - "displayName": "Count Type", - "description": "", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sub_count_type", - "displayName": "Sub Count Type", - "description": "optional", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "point_size", - "displayName": "Point Size", - "description": "The size of the points in the 3D PCA plot.", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "8", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_values", - "displayName": "Color Values", - "description": "Colors for the PCA will be picked, in order, from this list. There are thousands of colors. You may remove or add colors as you choose, but take care that there are always at least as many colors in this list than you need to color items in your plot.\n\nExample: if you are coloring by Group and have 3 groups, you should have at least 3 colors in your list.", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "slateblue3", - "tomato2", - "maroon", - "deepskyblue", - "mediumorchid2", - "mediumseagreen", - "salmon", - "dodgerblue", - "darkgreen", - "plum4", - "orange", - "yellow4", - "aquamarine3", - "salmon1", - "lightskyblue3", - "plum3", - "firebrick", - "darkolivegreen3", - "goldenrod1", - "burlywood2", - "gray70", - "firebrick2", - "steelblue", - "palegreen4", - "orchid4", - "darkorange1", - "yellow", - "sienna", - "palevioletred1", - "gray60", - "cyan4", - "darkorange3", - "mediumpurple3", - "violetred2", - "olivedrab", - "darkgoldenrod2", - "darkgoldenrod", - "gray40", - "palegreen3", - "thistle3", - "khaki1", - "deeppink2", - "chocolate3", - "paleturquoise3", - "wheat1", - "lightsteelblue", - "sandybrown", - "darkolivegreen2", - "thistle2", - "gray85", - "orchid3", - "darkseagreen1", - "lightgoldenrod1", - "lightskyblue2", - "dodgerblue3", - "darkseagreen3", - "forestgreen", - "lightpink2", - "mediumpurple4", - "lightpink1", - "thistle", - "navajowhite", - "lemonchiffon", - "bisque2", - "mistyrose", - "gray95", - "lightcyan3", - "peachpuff2", - "lightsteelblue2", - "lightyellow2", - "moccasin", - "antiquewhite2", - "gray80", - "lightgrey" - ], - "defaultValue": "c(\"slateblue3\",\"tomato2\",\"maroon\",\"deepskyblue\",\"mediumorchid2\",\"mediumseagreen\",\"salmon\",\"dodgerblue\",\"darkgreen\",\"plum4\",\"orange\",\"yellow4\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "plot_title", - "displayName": "Plot Title", - "description": "", - "paramType": "STRING", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "PCA 3D", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "If this is `TRUE`, any plots generated during the analysis will be saved to disk.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "3D PCA Plot", - "outputs": { - "figures": { - "type": "file", - "name": "figures/pca/pca_3D.html" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_venn_diagram.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_venn_diagram.json deleted file mode 100644 index c163c04..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_venn_diagram.json +++ /dev/null @@ -1,1106 +0,0 @@ -{ - "title": "Venn Diagram", - "description": "Template generates Venn diagram of intersections across a series of sets (e.g., intersections of significant genes across tested contrasts).\nThis Venn diagram is available for up to five sets; Intersection plot is available for any number of sets. Specific sets can be selected for the visualizations and the returned dataset may include all (default) or specified intersections.\n", - "r_function": "plot_venn_diagram", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Elements Column", - "description": "Column containing the names of elements. These elements will be counted and the number displayed in each intersection of your Venn diagram. Commonly this will be the Genes column of the output of the \"Volcno Plot. -Summary\" template.", - "paramGroup": "Basic", - "sourceDataset": "Input_Dataset", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "contrasts_colname", - "displayName": "Categories Column", - "description": "Column containing the category names. These categories will be used to draw the circles of your Venn diagram. Commonly, this will be your Contrasts column from the output of the \"Volcano Plot - Summary\" template.", - "paramGroup": "Basic", - "sourceDataset": "Input_Dataset", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "DataFrame input Rds", - "description": "File path to read the summary dataframe (e.g. from plot_volcano_summary output)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "summary_dataframe.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "Venn diagram DataFrame Rds", - "description": "File path to output the venn diagram DataFrame as an Rds file", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "select_contrasts", - "displayName": "Selected Categories", - "description": "If no categories are listed then all available categories will be used; if a single category is listed only Venn diagram or Intersection table can be plotted; if more than 5 categories are listed only Intersection plot or Intersection table can be plotted", - "paramType": "VECTOR", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "plot_type", - "displayName": "Select Plot Type", - "description": "", - "paramType": "SELECT", - "paramGroup": "Advanced", - "paramValues": [ - "Venn diagram", - "Intersection plot", - "Intersection table" - ], - "defaultValue": "Venn diagram", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "intersection_ids", - "displayName": "Intersection IDs", - "description": "Enter Intersection id(s); the intersection id displayed in the Logs tab after the first run of the template or in the Intersection table if selected as the option of the Plot selection parameter above; if none entered, all intersections are returned", - "paramType": "VECTOR", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_force_unique", - "displayName": "Venn Force Unique", - "description": "If TRUE, count each element in a given category only once (ignore duplicate entries)", - "paramType": "BOOLEAN", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_numbers_format", - "displayName": "Venn Numbers Format", - "description": "The format that the numbers will be printed in", - "paramType": "SELECT", - "paramGroup": "Venn Diagram", - "paramValues": [ - "raw", - "percent", - "raw-percent", - "percent-raw" - ], - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_significant_digits", - "displayName": "Venn Significant Digits", - "description": "The number of significant digits in percent values", - "paramType": "NUMBER", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_fill_colors", - "displayName": "Venn Fill Colors", - "description": "The colour of each circle's interior. The number of colors you choose should be at least the number of input datasets.", - "paramType": "MULTISELECT", - "paramGroup": "Venn Diagram", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "c(\"darkgoldenrod2\",\"darkolivegreen2\",\"mediumpurple3\",\"darkorange2\",\"lightgreen\")", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_fill_transparency", - "displayName": "Venn Fill Transparency", - "description": "The transparency of each circle's interior. Enter a value between 0 and 1 (from transparent to opaque)", - "paramType": "STRING", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "0.2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_border_colors", - "displayName": "Venn Border Colors", - "description": "The colour of each circle's circumference; if the option 'fill colors' is chosen the same as \"Colors: fill\" above", - "paramType": "SELECT", - "paramGroup": "Venn Diagram", - "paramValues": [ - "black", - "fill colors" - ], - "defaultValue": "fill colors", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_font_size_for_category_names", - "displayName": "Venn Font Size for Category Names", - "description": "The font size for each category name", - "paramType": "NUMBER", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "3", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_category_names_distance", - "displayName": "Venn Category Names Distance", - "description": "A numeric vector giving the distance of each category name from the edge of the circle (can be negative); the default values are between 0.025 - 0.22; adjusting both the distance and position (below) may be optimal.", - "paramType": "VECTOR", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_category_names_position", - "displayName": "Venn Category Names Position", - "description": "A numeric vector giving the position (in degrees) of each category name along the circle, with 0 at 12 o'clock; adjusting both the position and distance (above) may be optimal.", - "paramType": "VECTOR", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "c()", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_font_size_for_counts", - "displayName": "Venn Font Size for Counts", - "description": "The font size for each area label", - "paramType": "NUMBER", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "6", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_outer_margin", - "displayName": "Venn Outer Margin", - "description": "The amount of whitespace around the diagram in grid units; recommended values are between 0.05 - 0.2; adding more space can help fit the category names.", - "paramType": "NUMBER", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": "0", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "intersections_order", - "displayName": "Intersections Order", - "description": "The intersections ordering; the options include degree and freq (frequency)", - "paramType": "SELECT", - "paramGroup": "Intersection Plot", - "paramValues": [ - "degree", - "freq" - ], - "defaultValue": "degree", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "display_empty_intersections", - "displayName": "Display Empty Intersections", - "description": "If FALSE (default) empty sets are not plotted", - "paramType": "BOOLEAN", - "paramGroup": "Intersection Plot", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "intersection_bar_color", - "displayName": "Intersection Bar Color", - "description": "", - "paramType": "SELECT", - "paramGroup": "Intersection Plot", - "paramValues": [ - "steelblue4", - "aquamarine3", - "salmon1", - "lightskyblue3", - "plum3", - "darkolivegreen3", - "goldenrod1", - "burlywood2", - "gray70", - "firebrick2", - "steelblue", - "palegreen4", - "orchid4", - "darkorange1", - "yellow", - "sienna", - "palevioletred1", - "gray60", - "cyan4", - "darkorange3", - "mediumpurple3", - "violetred2", - "olivedrab", - "darkgoldenrod2", - "darkgoldenrod", - "gray40", - "palegreen3", - "thistle3", - "khaki1", - "deeppink2", - "chocolate3", - "paleturquoise3", - "wheat1", - "lightsteelblue", - "salmon", - "sandybrown", - "darkolivegreen2", - "thistle2", - "gray85", - "orchid3", - "darkseagreen1", - "lightgoldenrod1", - "lightskyblue2", - "dodgerblue3", - "darkseagreen3", - "forestgreen", - "lightpink2", - "mediumpurple4", - "lightpink1", - "thistle", - "navajowhite", - "lemonchiffon", - "bisque2", - "mistyrose", - "gray95", - "lightcyan3", - "peachpuff2", - "lightsteelblue2", - "lightyellow2", - "moccasin", - "antiquewhite2", - "gray80", - "lightgrey" - ], - "defaultValue": "steelblue4", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "intersection_line_width", - "displayName": "Intersection Line Width", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Intersection Plot", - "paramValues": null, - "defaultValue": "0.7", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "intersection_point_size", - "displayName": "Intersection Point Size", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Intersection Plot", - "paramValues": null, - "defaultValue": "2.2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "table_font_size", - "displayName": "Table Font Size", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Table", - "paramValues": null, - "defaultValue": "0.7", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "table_content", - "displayName": "Table Content", - "description": "", - "paramType": "SELECT", - "paramGroup": "Table", - "paramValues": [ - "all intersections", - "returned intersections" - ], - "defaultValue": "all intersections", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "dpi", - "displayName": "Image Resolution", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "300", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "image_height", - "displayName": "Image Height", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "3000", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "image_width", - "displayName": "Image Width", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "4000", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "If this is `TRUE`, any plots generated during the analysis will be saved to disk.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "Venn Diagram", - "outputs": { - "DataFrame": { - "type": "file", - "name": "venn_diagram_dataframe.rds" - }, - "figures": { - "type": "file", - "name": "figures/diff/venn_diagram.png" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_volcano_enhanced.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_volcano_enhanced.json deleted file mode 100644 index 0ce898a..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_volcano_enhanced.json +++ /dev/null @@ -1,331 +0,0 @@ -{ - "title": "Plot Volcano - Enhanced", - "description": "Implementation of Bioconductor's Enhanced Volcano Plot (v1.6.0, https://bioconductor.org/packages/release/bioc/html/EnhancedVolcano.html). Template written by Matthew Angel and maintained by CCBR. Final Potomac Compatible Version: v52. Final Sugarloaf V1 Version: v55. Latest Sugarloaf V2 Version: v67. [View Documentation](https://nidap.nih.gov/workspace/notepad/view/ri.notepad.main.notepad.8fe3cd6c-db24-4b0a-b717-060cb77ecc5e)", - "r_function": "plot_volcano_enhanced", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Column with Feature ID", - "description": "Column from the input DEG table containing Feature ID (such as Gene Names, Isoform IDs, UniProt IDs, and so on). This is usually the first column (named \"Feature_ID\" or \"Gene\"). Only Text type columns will be allowed.", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - }, - { - "key": "signif_colname", - "displayName": "Significance Column", - "description": "Choose an unadjusted or adjusted p-value column from the input DEG table to use as the measure of significance in your Volcano plot. If your DEG analysis contained more than one contrast comparison, you will only be able to select one of these at a time. Make sure you select the same contrast that was selected for the \"Log2 Fold Change Column\" parameter.", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "defaultValue": null, - "columnType": "NUMBER", - "isMulti": true - }, - { - "key": "change_colname", - "displayName": "Log2 Fold Change Column", - "description": "Choose a log2 fold change column from the input DEG table. If your DEG analysis contained more than one contrast comparison, you will only be able to select one of these at a time. Make sure you select the same contrast that was selected for the \"Significance Column\" parameter.", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "defaultValue": null, - "columnType": "NUMBER", - "isMulti": true - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "Summary dataframe output Rds", - "description": "File path to the summary dataframe as an Rds file", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "enhanced_volcano_plot.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "signif_threshold", - "displayName": "P-Value Threshold", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "0.001", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "change_threshold", - "displayName": "Log2 Fold Change Threshold", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "1.0", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "value_to_sort_the_output_dataset", - "displayName": "How to sort the output dataset", - "description": "This selection determines how the feature (gene) list is sorted before choosing the top-N features as set by the \"Number of Features to Label\" parameter. Choose either (absolute) fold change, p-value, or t-statistic to label the top features by the selected metric. This also determines which features are labeled in the plot. This option is negated if only using custom labels.", - "paramType": "SELECT", - "paramGroup": "Label", - "paramValues": [ - "p-value", - "fold-change" - ], - "defaultValue": "p-value", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "num_features_to_label", - "displayName": "Number of Features to Label", - "description": "To minimize clutter on the volcano plot, it is inadvisable to label every feature (gene). You can choose to label any number of features or none. The value of this parameter (N) is used to label the top N features only. See the \"Choose Features To Label By\" parameter for options on how to sort the gene list before labeling the top N features. Will be negated if the option to use only additional labels is selected.", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "30", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_only_addition_labels", - "displayName": "Label Only My Feature List", - "description": "Select TRUE when you want to label ONLY a specific list of features given in the \"My Feature List\" parameter.", - "paramType": "BOOLEAN", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "additional_labels", - "displayName": "My Feature List", - "description": "Additional features (genes) to label. If the option to use only custom labels is selected, these will be the only points labeled on the plot. Otherwise, these will be plotted in addition to the other top features. This should be a comma-separated or space-delimited list.", - "paramType": "STRING", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "lab_size", - "displayName": "Label Size", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "4", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "change_sig_name", - "displayName": "Custom Significance Label", - "description": "This replaces bulky names for the p-value column.", - "paramType": "STRING", - "paramGroup": "Title and Axis labels", - "paramValues": null, - "defaultValue": "p-value", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "change_lfc_name", - "displayName": "Custom Log Fold Change Label", - "description": "This replaces bulky column names for the fold-change column.", - "paramType": "STRING", - "paramGroup": "Title and Axis labels", - "paramValues": null, - "defaultValue": "log2FC", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_custom_lab", - "displayName": "Use Custom Labels", - "description": "", - "paramType": "BOOLEAN", - "paramGroup": "Title and Axis Labels", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "title", - "displayName": "Plot Title", - "description": "", - "paramType": "STRING", - "paramGroup": "Title and Axis labels", - "paramValues": null, - "defaultValue": "Volcano Plots", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "ylim", - "displayName": "Y-Limit", - "description": "Maximum value for y-axis. Defaults to -log10(min(pval)). Set to 0 for automatic scaling.", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "0", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "custom_xlim", - "displayName": "Custom X-axis limits", - "description": "Leave empty for automatic scaling, put one number for symmetrical scale (i.e, putting \"5\" would result in a range from \"-5\" to \"5\"), or put two numbers separated by comma for \"asymmetrical\" scale (i.e, putting \"-2,4\" would result in a range from \"-2\" to \"4\")", - "paramType": "STRING", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "xlim_additional", - "displayName": "X-Limit Padding", - "description": "Add additional units to x-limit", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "0", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "ylim_additional", - "displayName": "Y-Limit Padding", - "description": "Adds additional units to y-limit.", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "0", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "axis_lab_size", - "displayName": "Axis Label Size", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "24", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "point_size", - "displayName": "Point Size", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "image_width", - "displayName": "Image Width", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "3000", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "image_height", - "displayName": "Image Height", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "3000", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "dpi", - "displayName": "Image Resolution (DPI)", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "300", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "If this is `TRUE`, any plots generated during the analysis will be saved to disk.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "Volcano Plot - Enhanced", - "outputs": { - "DataFrame": { - "type": "file", - "name": "enhanced_volcano_dataframe.rds" - }, - "figures": { - "type": "file", - "name": "figures/diff/volcano_enhanced.png" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_volcano_summary.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_volcano_summary.json deleted file mode 100644 index 2d411a5..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_volcano_summary.json +++ /dev/null @@ -1,5125 +0,0 @@ -{ - "title": "Plot Volcano - Summary", - "description": "Produces one volcano plot for each tested contrast in the input DEG table.\n\nIt can be sorted by either fold change, t-statistic, or p-value. The returned dataset includes one row for each significant gene in each contrast, and contains columns from the DEG analysis of that contrast as well as columns useful to the Venn diagram template downstream.", - "r_function": "plot_volcano_summary", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Gene Names Column", - "description": "The column from your input DEG table containing the gene names. This is usually the first column. Only columns of Text type from your DEG table will be available to select for this parameter.", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "defaultValue": null, - "columnType": "STRING", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "Summary dataframe output Rds", - "description": "File path to output summary data as an Rds file", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "signif_colname", - "displayName": "Significance column name", - "description": "Choose whether to use unadjusted or adjusted p-values in the resulting volcano plots.", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "pval", - "adjpval" - ], - "defaultValue": "pval", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "signif_threshold", - "displayName": "P-Value Threshold", - "description": "Generates a horizontal blue line at -log10 of this value on the y-axis of the volcano plot. Genes located above this threshold are considered significantly differentially expressed.", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "0.001", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "change_threshold", - "displayName": "Log2 Fold Change Threshold", - "description": "Generates two vertical red lines at +/- this value on the x-axis of the volcano plot. A value of 1 entered here will draw lines at a log2 fold change values of -1 and 1. This corresponds to unlogged fold changes of 2 and 1/2, respectively.", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "value_to_sort_the_output_dataset", - "displayName": "Choose How to sort the output dataset", - "description": "This selection determines how the gene list is sorted before choosing the top-N genes as set by the \"Number of Genes to Label\" parameter. Choose either (absolute) fold change, p-value, or t-statistic to label the top genes by the selected metric.", - "paramType": "SELECT", - "paramGroup": "Gene Name Label", - "paramValues": [ - "fold-change", - "p-value", - "t-statistic" - ], - "defaultValue": "t-statistic", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "num_features_to_label", - "displayName": "Number of Genes to Label", - "description": "To minimize clutter on the volcano plot, it is inadvisable to label every gene. You can choose to label any number of genes or none. The value of this parameter (N) is used to label the top N genes only. See the \"Choose Genes To Label By\" parameter for options on how to sort the gene list before labeling the top N genes.", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "30", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "add_features", - "displayName": "Add Custom Features List To Labels", - "description": "Set TRUE when you want to label a specific set of genes in the \"My Gene List\" parameter\" IN ADDITION to the number of genes you set in the \"Number of Genes to Label\" parameter.", - "paramType": "BOOLEAN", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_features", - "displayName": "Label Only Custom Features List", - "description": "Select TRUE when you want to label ONLY a specific list of genes given in the \"My Gene List\" parameter.", - "paramType": "BOOLEAN", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "custom_gene_list", - "displayName": "Custom Feature/Gene List", - "description": "Provide a list of genes (comma separated) to be labeled on the volcano plot. You must toggle one of the following ON to see these labels: \"Add My Gene List To Labels\" or \"Label Only My Gene List\".", - "paramType": "STRING", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "Provide list of genes-comma separated", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "default_label_color", - "displayName": "Default Feature Label Text Color", - "description": "Set the color for the text used to add gene name labels to points.", - "paramType": "SELECT", - "paramGroup": "Gene Name Label", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "black", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "custom_label_color", - "displayName": "Feature Label Text Color for custom features list", - "description": "Set the color for the specific list of genes provided in the \"Gene List\" parameter.", - "paramType": "SELECT", - "paramGroup": "Gene Name Label", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "green3", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_x_adj", - "displayName": "Label Position Adjustment (X-Axis)", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "0.2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_y_adj", - "displayName": "Label Position Adjustment (Y-Axis)", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "0.2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "line_thickness", - "displayName": "Line Segment Thickness", - "description": "Thickness of the line connecting the point and it's gene label", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "0.5", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_font_size", - "displayName": "Label Font Size", - "description": "Font size for sample labels. Set to 0 to remove labels.", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": 4, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_font_type", - "displayName": "Label Font Type", - "description": "Select the font type for the gene labels displayed in the volcano plot. The options are: 1-regular, 2-bold, 3-italic, 4-bold.italic, 5-greek alphabet.", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "displace_feature_labels", - "displayName": "Displace Feature Labels", - "description": "Set TRUE if you want to displace the gene label for a specific set of genes. Make sure to use custom x- and y- limits and give sufficient space for displacement; otherwise other labels than the desired ones will appear displaced.", - "paramType": "BOOLEAN", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "custom_gene_list_special_label_displacement", - "displayName": "Gene List Special Label Displacement", - "description": "Provide a list of features (comma separated) for which you want special displacement of the gene label.", - "paramType": "STRING", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "Provide list of genes-comma separated", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "special_label_displacement_x_axis", - "displayName": "Special Label Displacement (X-Axis)", - "description": "Choose a number to set the nudge/displacement of the gene label in the x-direction.", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "special_label_displacement_y_axis", - "displayName": "Special Label Displacement (Y-Axis)", - "description": "Choose a number (comma separated) to set the nudge/displacement of the gene label in the x-direction.", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_of_signif_threshold_line", - "displayName": "Color of P-Value Threshold Line", - "description": "The color of the horizontal p-value threshold line", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "blue", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_of_non_significant_features", - "displayName": "Color of Non-Significant Features", - "description": "", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "black", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_of_logfold_change_threshold_line", - "displayName": "Color of Log Fold Change Threshold Line", - "description": "The color of the vertical fold-change threshold lines", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "red", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_of_features_meeting_only_signif_threshold", - "displayName": "Color of Features Meeting Only P-Value Threshold", - "description": "", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "lightgoldenrod2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_for_features_meeting_pvalue_and_foldchange_thresholds", - "displayName": "Color for features meeting p-value and fold-change thresholds", - "description": "", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "red", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "flip_vplot", - "displayName": "Flip Contrast", - "description": "Select TRUE if you want to flip the contrast to opposite direction (flip the plot around the y-axis).", - "paramType": "BOOLEAN", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "FALSE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_default_x_axis_limit", - "displayName": "Use Default X-Axis Limit", - "description": "Use default x limit", - "paramType": "BOOLEAN", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "x_axis_limit", - "displayName": "X-Axis Limit", - "description": "The limits of the x-axis (symmetric about 0)", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "5", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_default_y_axis_limit", - "displayName": "Use Default Y-Axis Limit", - "description": "Use Default Y limit", - "paramType": "BOOLEAN", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "y_axis_limit", - "displayName": "Y-Axis Limit", - "description": "The upper limit of the y-axis", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": 10, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "point_size", - "displayName": "Point Size", - "description": "Size of a each data point", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "add_deg_columns", - "displayName": "Add DEG Columns to Output Table", - "description": "Select columns from input DEG results to include in the output dataset. If \"none\" is selected, then the output will contain only columns for Gene and Contrast.", - "paramType": "MULTISELECT", - "paramGroup": "Table", - "paramValues": ["FC", "logFC", "tstat", "pval", "adjpval"], - "defaultValue": ["FC", "logFC", "tstat", "pval", "adjpval"], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "image_width", - "displayName": "Image Width", - "description": "Image width in inches", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "15", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "image_height", - "displayName": "Image Height", - "description": "Image height in inches", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "15", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "dpi", - "displayName": "Image Resolution", - "description": "Image resolution in dpi (dots-per-inch) for png output", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "300", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_default_grid_layout", - "displayName": "Use Default Grid Layout", - "description": "if TRUE, an optimal number of rows in the figure grid layout is attempted; if you want to change the layout set the number of rows in the 'Number of rows in grid layout' parameter below", - "paramType": "BOOLEAN", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "TRUE", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "number_of_rows_in_grid_layout", - "displayName": "Number of Rows in Grid Layout", - "description": "", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "1", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "aspect_ratio", - "displayName": "Figure Aspect Ratio", - "description": "figure aspect ratio, expressed as y / x; if 0, the ratio is based on the image size", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": "0", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "If this is `TRUE`, any plots generated during the analysis will be saved to disk.", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "Volcano Plot - Summary", - "outputs": { - "DataFrame": { - "type": "file", - "name": "summary_dataframe.rds" - }, - "figures": { - "type": "file", - "name": "figures/diff/volcano_summary.png" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/write_multiOmicDataSet_properties.json b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/write_multiOmicDataSet_properties.json deleted file mode 100644 index d18be56..0000000 --- a/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/write_multiOmicDataSet_properties.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "title": "Write multiOmicDataSet Properties", - "description": "Export the contents of a multiOmicDataSet (sample metadata, feature annotation, counts, and analyses) to a directory of CSV/RDS files for downstream use or inspection.", - "r_function": "write_multiOmicDataSet_properties", - "columns": [], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to the input multiOmicDataSet (MOO) RDS file.", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "output_dir", - "displayName": "Output Directory", - "description": "Directory where properties will be written (sample_metadata.csv, feature_annotation.csv, counts/, analyses/).", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "moo", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputDatasetName": "multiOmicDataSet Properties", - "outputs": { - "sample_metadata": { - "type": "file", - "name": "sample_metadata.csv" - }, - "feature_annotation": { - "type": "file", - "name": "feature_annotation.csv" - }, - "counts": { - "type": "directory", - "name": "counts/" - }, - "analyses": { - "type": "directory", - "name": "analyses/" - } - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/batch_correct_counts.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/batch_correct_counts.json deleted file mode 100644 index 006f336..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/batch_correct_counts.json +++ /dev/null @@ -1,161 +0,0 @@ -{ - "r_function": "batch_correct_counts", - "title": "Batch Correction\n", - "description": "Perform batch correction using sva::ComBat()\n", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Feature ID Column", - "description": "The column from the counts data containing the Feature IDs (Usually Gene or Protein ID).\nThis is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts\nMatrix will be available to select for this parameter. (Default: `NULL` - first column in the counts matrix will be\nused.)\n", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "samples_to_include", - "displayName": "Columns to Include", - "description": "Which samples would you like to include? Usually, you will choose all sample columns, or\nyou could choose to remove certain samples. Samples excluded here will be removed in this step and from further\nanalysis downstream of this step. (Default: `NULL` - all sample IDs in `moo@sample_meta` will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "columnType": "ALL", - "isMulti": true - }, - { - "key": "sample_id_colname", - "displayName": "Sample Names Column", - "description": "The column from the sample metadata containing the sample names. The names in this column\nmust exactly match the names used as the sample column names of your input Counts Matrix. (Default: `NULL` - first\ncolumn in the sample metadata will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "covariates_colnames", - "displayName": "Covariates", - "description": "The column name(s) from the sample metadata\ncontaining variable(s) of interest, such as phenotype.\nMost commonly this will be the same column selected for your Groups Column.\nSome experimental designs may require that you add additional covariate columns here.\nDo not include the `batch_colname` here.\n", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "defaultValue": "Group", - "columnType": "ALL", - "isMulti": true - }, - { - "key": "batch_colname", - "displayName": "Batch Column", - "description": "The column from the sample metadata containing the batch information.\nSamples extracted, prepared, or sequenced at separate times or using separate materials/staff/equipment\nmay belong to different batches.\nNot all data sets have batches, in which case you do not need batch correction.\nIf your data set has no batches, you can provide a batch column with the same\nvalue in every row to skip batch correction (alternatively, simply do not run this function).\n", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "defaultValue": "Batch", - "columnType": "ALL", - "isMulti": null - }, - { - "key": "label_colname", - "displayName": "Labels Column", - "description": "The column from the sample metadata containing the sample labels as you wish them to appear in\nthe plots produced by this template. This can be the same Sample Names Column. However, you may desire different\nlabels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the\ncolumn with your preferred Labels here. The selected column should contain unique names for each sample. (Default:\n`NULL` -- `sample_id_colname` will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "sample_metadata", - "columnType": "ALL", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file at the end of the function", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "count_type", - "displayName": "Count Type", - "description": "the type of counts to use -- must be a name in the counts slot (`moo@counts`)\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "norm", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sub_count_type", - "displayName": "Sub Count Type", - "description": "if `count_type` is a list, specify the sub count type within the list. (Default: `\"voom\"`)\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "voom", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "colors_for_plots", - "displayName": "Colors for plots", - "description": "Colors for the PCA and histogram will be picked, in order, from this list.\nColors must either be names in `grDevices::colors()` or valid hex codes.\n", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "Whether to save plots to files during analysis (Defaults to `TRUE`, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - }, - "figures": { - "type": "directory", - "name": "figures/batch/" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/clean_raw_counts.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/clean_raw_counts.json deleted file mode 100644 index 7f5c144..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/clean_raw_counts.json +++ /dev/null @@ -1,156 +0,0 @@ -{ - "r_function": "clean_raw_counts", - "title": "Clean Raw Counts\n", - "description": "This function checks the input raw counts matrix for common formatting problems with feature identifiers and sample\nnames. If feature IDs contain multiple IDs separated by special characters (| - , or space) they will be split into\nmultiple columns. If duplicate feature IDs are detected the counts are summed across duplicate feature ID rows\nwithin each sample. Invalid sample names will also be reported and can be automatically\ncorrected. If your sample names are corrected here, be sure to make equivalent changes to your metadata table.\n", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Feature ID Column", - "description": "The column from the counts data containing the Feature IDs (Usually Gene or Protein ID).\nThis is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts\nMatrix will be available to select for this parameter. (Default: `NULL` - first column in the counts matrix will be\nused.)\n", - "paramGroup": "Basic", - "sourceDataset": "moo@counts", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "sample_id_colname", - "displayName": "Sample ID Column", - "description": "The column from the sample metadata containing the sample names. The names in this column\nmust exactly match the names used as the sample column names of your input Counts Matrix. (Default: `NULL` - first\ncolumn in the sample metadata will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "moo@sample_meta", - "columnType": "STRING", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file at the end of the function", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "count_type", - "displayName": "Count Type", - "description": "the type of counts to use -- must be a name in the counts slot (`moo@counts`)\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "samples_to_rename", - "displayName": "Samples to Rename", - "description": "If you do not have a Plot Labels Column in your sample metadata table, you can use this\nparameter to rename samples manually for display on the PCA plot. Use \"Add item\" to add each additional sample for\nrenaming. Use the following format to describe which old name (in your sample metadata table) you want to rename to\nwhich new name: old_name: new_name\n", - "paramType": "VECTOR", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "cleanup_column_names", - "displayName": "Cleanup Column Names", - "description": "Invalid raw counts column names can cause errors\nin the downstream analysis. If this is `TRUE`, any invalid column names\nwill be automatically altered to a correct format. These format changes\nwill include adding an \"X\" as the first character in any column name that\nbegan with a numeral and replacing some special characters (\"-,:. \") with\nunderscores (\"_\"). Invalid sample names and any changes made will be\ndetailed.\n", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "split_gene_name", - "displayName": "Split Feature ID", - "description": "If `TRUE`, split the gene name column by any of these special characters: `,|_-:`", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "aggregate_rows_with_duplicate_gene_names", - "displayName": "Aggregate Rows with Duplicate Feature Names", - "description": "If a Feature ID (from the\n\"Cleanup Column Names\" parameter above) is found to be duplicated on\nmultiple rows of the raw counts, the Log will report these Feature IDs.\nUsing the default behavior (`TRUE`), the counts for all rows with a\nduplicate Feature IDs are aggregated into a single row. Counts are summed\nacross duplicate Feature ID rows within each sample. Additional identifier\ncolumns, if present (e.g. Ensembl IDs), will be preserved and multiple\nmatching identifiers in such additional columns will appear as\ncomma-separated values in an aggregated row.\n", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "gene_name_column_to_use_for_collapsing_duplicates", - "displayName": "Column Used to Aggregate Duplicates Feature IDs", - "description": "Select the column\nwith Feature IDs to use as grouping elements to collapse the counts matrix.\nThe log output will list the columns available to identify duplicate row\nIDs in order to aggregate information.\nIf left blank your \"Feature ID\" Column will be used to Aggregate Rows. If\n\"Feature ID\" column can be split into multiple IDs the non Ensembl ID name\nwill be used to aggregate duplicate IDs. If \"Feature ID\" column does not\ncontain Ensembl IDs the split Feature IDs will be named 'Feature_id_1' and\n'Feature_id_2'. For this case an error will occur and you will have\nto manually enter the Column ID for this field.\n", - "paramType": "STRING", - "paramGroup": "Advanced", - "paramValues": [ - "Gene", - "Pepetide", - "Protein", - "Ensembl_ID", - "Ensembl_ID_version", - "Gene_id_1", - "Gene_id_2", - "Original Gene Column" - ], - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "Whether to save plots to files during analysis (Defaults to `TRUE`, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')\n", - "paramType": "BOOLEAN", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - }, - "figures": { - "type": "directory", - "name": "figures/clean/" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/create_multiOmicDataSet_from_files.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/create_multiOmicDataSet_from_files.json deleted file mode 100644 index c20d116..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/create_multiOmicDataSet_from_files.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "r_function": "create_multiOmicDataSet_from_files", - "title": "Create Multi-Omic Dataset from Files\n", - "description": "Construct a multiOmicDataSet object from text files (e.g. TSV, CSV).\n", - "columns": [], - "inputDatasets": [ - { - "key": "sample_meta_filepath", - "displayName": "", - "description": "path to text file with sample IDs and metadata for differential analysis.\n", - "paramType": "TABULAR", - "paramGroup": "basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "feature_counts_filepath", - "displayName": "", - "description": "path to text file of expected feature counts (e.g. gene counts from RSEM).\n", - "paramType": "TABULAR", - "paramGroup": "basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sample_id_colname", - "displayName": "", - "description": "name of the column in `sample_metadata` that contains the sample IDs. (Default: `NULL` -\nfirst column in the sample metadata will be used.)\n", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "feature_id_colname", - "displayName": "", - "description": "name of the column in `counts_dat` that contains feature/gene IDs. (Default: `NULL` - first\ncolumn in the count data will be used.)\n", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "delim", - "displayName": "", - "description": "Delimiter used in the input files. Any delimiter accepted by `readr::read_delim()` can be used.\nIf the files are in CSV format, set `delim = ','`; for TSV format, set `delim = '\\t'`.\n", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/diff_counts.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/diff_counts.json deleted file mode 100644 index dfbc40e..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/diff_counts.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "r_function": "diff_counts", - "title": "Differential Analysis\n", - "description": "Differential expression analysis\n", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Feature/Gene Names Column", - "description": "The column from the counts data containing the Feature IDs (Usually Gene or Protein ID).\nThis is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts\nMatrix will be available to select for this parameter. (Default: `NULL` - first column in the counts matrix will be\nused.)\n", - "paramGroup": "Basic", - "sourceDataset": "Counts_Matrix", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "sample_id_colname", - "displayName": "Sample Names Column", - "description": "The column from the sample metadata containing the sample names. The names in this column\nmust exactly match the names used as the sample column names of your input Counts Matrix. (Default: `NULL` - first\ncolumn in the sample metadata will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "columnType": "ALL", - "isMulti": null - }, - { - "key": "samples_to_include", - "displayName": "Columns to Include", - "description": "Which samples would you like to include? Usually, you will choose all sample columns, or\nyou could choose to remove certain samples. Samples excluded here will be removed in this step and from further\nanalysis downstream of this step. (Default: `NULL` - all sample IDs in `moo@sample_meta` will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "Counts_Matrix", - "columnType": "ALL", - "isMulti": true - }, - { - "key": "contrast_colname", - "displayName": "Contrast Variable Column", - "description": "The column in the metadata that contains the group variables you wish to find differential\nexpression between. Up to 2 columns (2-factor analysis) can be used.\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "columnType": "ALL", - "isMulti": true - }, - { - "key": "covariates_colnames", - "displayName": "Covariates Column(s)", - "description": "The column name(s) from the sample metadata containing variable(s) of interest, such as\nphenotype. Most commonly this will be the same column selected for your Groups Column. Some experimental designs\nmay require that you add additional covariate columns here.\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "columnType": "ALL", - "isMulti": true - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file at the end of the function", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "count_type", - "displayName": "Count Type", - "description": "the type of counts to use -- must be a name in the counts slot (`moo@counts`)\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "filt", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sub_count_type", - "displayName": "Sub Count Type", - "description": "if `count_type` is a list, specify the sub count type within the list. (Default: `NULL`)\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "contrasts", - "displayName": "Contrasts", - "description": "Specify each contrast in the format group1-group2, e.g. treated-control\n", - "paramType": "VECTOR", - "paramGroup": "Basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "input_in_log_counts", - "displayName": "Input in log Counts", - "description": "set this to `TRUE` if counts are already log2-transformed\n", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "return_mean_and_sd", - "displayName": "Return Mean and SD", - "description": "if TRUE, return Mean and Standard Deviation of groups in addition to DEG estimates for\ncontrast(s)\n", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "voom_normalization_method", - "displayName": "Normalization Method", - "description": "Normalization method to be applied to the logCPM values when using `limma::voom`", - "paramType": "SELECT", - "paramGroup": "Advanced", - "paramValues": [ - "none", - "scale", - "quantile", - "cyclicloess", - "TMM", - "TMMwzp", - "RLE", - "upperquartile" - ], - "defaultValue": "quantile", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "Whether to save plots to files during analysis (Defaults to `TRUE`, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - }, - "figures": { - "type": "directory", - "name": "figures/diff/" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/filter_counts.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/filter_counts.json deleted file mode 100644 index 58d5f49..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/filter_counts.json +++ /dev/null @@ -1,427 +0,0 @@ -{ - "r_function": "filter_counts", - "title": "Filter Low Counts\n", - "description": "This is often the first step in the QC portion of an analysis to filter out\nfeatures that have very low raw counts across most or all of your samples.\nThis function takes a multiOmicDataSet containing clean raw counts and a sample\nmetadata table, and returns the multiOmicDataSet object with filtered counts.\nIt also produces an image consisting of three QC plots.\nYou can tune the threshold for tuning how low counts for a given gene are\nbefore they are deemed \"too low\" and filtered out of downstream analysis. By\ndefault, this parameter is set to 1, meaning any raw count value less than 1\nwill count as \"too low\".\nThe QC plots are provided to help you assess: (1) PCA Plot: the within and\nbetween group variance in expression after dimensionality reduction; (2)\nCount Density Histogram: the dis/similarity of count distributions between\nsamples; and (3) Similarity Heatmap: the overall similarity of samples to one\nanother based on unsupervised clustering.\n", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Feature ID Column", - "description": "The column from the counts data containing the Feature IDs (Usually Gene or Protein ID).\nThis is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts\nMatrix will be available to select for this parameter. (Default: `NULL` - first column in the counts matrix will be\nused.)\n", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "samples_to_include", - "displayName": "Columns to Include", - "description": "Which samples would you like to include? Usually, you will choose all sample columns, or\nyou could choose to remove certain samples. Samples excluded here will be removed in this step and from further\nanalysis downstream of this step. (Default: `NULL` - all sample IDs in `moo@sample_meta` will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "columnType": "ALL", - "isMulti": true - }, - { - "key": "sample_id_colname", - "displayName": "Sample Names Column", - "description": "The column from the sample metadata containing the sample names. The names in this column\nmust exactly match the names used as the sample column names of your input Counts Matrix. (Default: `NULL` - first\ncolumn in the sample metadata will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "group_colname", - "displayName": "Groups Column", - "description": "The column from the sample metadata containing the sample group information. This is usually a\ncolumn showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal,\nBefore, After, etc.).\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": "Group", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "label_colname", - "displayName": "Labels Column", - "description": "The column from the sample metadata containing the sample labels as you wish them to appear in\nthe plots produced by this template. This can be the same Sample Names Column. However, you may desire different\nlabels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the\ncolumn with your preferred Labels here. The selected column should contain unique names for each sample. (Default:\n`NULL` -- `sample_id_colname` will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "columnType": "ALL", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file at the end of the function", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "count_type", - "displayName": "Count Type", - "description": "the type of counts to use -- must be a name in the counts slot (`moo@counts`)\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "clean", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_cpm_counts_to_filter", - "displayName": "Use CPM Counts to filter", - "description": "If no transformation has been been performed on counts matrix (eg Raw Counts) set to\nTRUE. If TRUE counts will be transformed to CPM and filtered based on given criteria. If gene counts matrix has\nbeen transformed (eg log2, CPM, FPKM or some form of Normalization) set to FALSE. If FALSE no further\ntransformation will be applied and features will be filtered as is. For RNAseq data RAW counts should be\ntransformed to CPM in order to properly filter.\n", - "paramType": "BOOLEAN", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "minimum_count_value_to_be_considered_nonzero", - "displayName": "Minimum Count Value to be Considered Nonzero", - "description": "Minimum count value to be considered non-zero for a sample\n", - "paramType": "NUMBER", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": 8, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "minimum_number_of_samples_with_nonzero_counts_in_total", - "displayName": "Minimum Number of Samples with Nonzero Counts in Total", - "description": "Minimum number of samples (total) with non-zero counts\n", - "paramType": "NUMBER", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": 7, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_group_based_filtering", - "displayName": "Use Group-Based Filtering", - "description": "If TRUE, only keeps features (e.g. genes) that have at least a certain number of\nsamples with nonzero CPM counts in at least one group\n", - "paramType": "BOOLEAN", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "minimum_number_of_samples_with_nonzero_counts_in_a_group", - "displayName": "Minimum Number of Samples with Nonzero Counts in a Group", - "description": "Only keeps genes that have at least this number of\nsamples with nonzero CPM counts in at least one group\n", - "paramType": "NUMBER", - "paramGroup": "Filtering", - "paramValues": null, - "defaultValue": 3, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "principal_component_on_x_axis", - "displayName": "Principal Component on X-axis", - "description": "The principal component to plot on the x-axis for the PCA plot. Choices include\n1, 2, 3, ... (default: 1)\n", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "principal_component_on_y_axis", - "displayName": "Principal Component on Y-axis", - "description": "The principal component to plot on the y-axis for the PCA plot. Choices include\n1, 2, 3, ... (default: 2)\n", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_position_for_pca", - "displayName": "Legend Position for PCA", - "description": "legend position for the PCA plot\n", - "paramType": "SELECT", - "paramGroup": "PCA", - "paramValues": [ - "top", - "bottom", - "left", - "right", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "point_size_for_pca", - "displayName": "Point Size for PCA", - "description": "geom point size for the PCA plot\n", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "add_label_to_pca", - "displayName": "Add Labels to PCA", - "description": "label points on the PCA plot\n", - "paramType": "BOOLEAN", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_font_size", - "displayName": "Label Font Size for PCA", - "description": "label font size for the PCA plot\n", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": 3, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_offset_x_", - "displayName": "Label Offset (x)", - "description": "label offset x for the PCA plot\n", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_offset_y_", - "displayName": "Label Offset (Y)", - "description": "label offset y for the PCA plot\n", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "samples_to_rename", - "displayName": "Samples to Rename Manually on PCA", - "description": "If you do not have a Plot Labels Column in your sample metadata table, you can use this\nparameter to rename samples manually for display on the PCA plot. Use \"Add item\" to add each additional sample for\nrenaming. Use the following format to describe which old name (in your sample metadata table) you want to rename to\nwhich new name: old_name: new_name\n", - "paramType": "VECTOR", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_histogram_by_group", - "displayName": "Color Histogram by Group", - "description": "Set to FALSE to label histogram by Sample Names, or set to TRUE to label histogram by\nthe column you select in the \"Group Column Used to Color Histogram\" parameter (below). Default is FALSE.\n", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "set_min_max_for_x_axis_for_histogram", - "displayName": "Set Min/Max for X-axis for Histogram", - "description": "whether to set min/max value for histogram x-axis\n", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "minimum_for_x_axis_for_histogram", - "displayName": "Minimum for X-axis for Histogram", - "description": "x-axis minimum for histogram plot\n", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": -1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "maximum_for_x_axis_for_histogram", - "displayName": "Maximum for X-axis for Histogram", - "description": "x-axis maximum for histogram plot\n", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_font_size_for_histogram", - "displayName": "Legend Font Size for Histogram", - "description": "legend font size for the histogram plot\n", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": 10, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_position_for_histogram", - "displayName": "Legend Position for Histogram", - "description": "legend position for the histogram plot. consider setting to 'none' for a large\nnumber of samples.\n", - "paramType": "SELECT", - "paramGroup": "Histogram", - "paramValues": [ - "right", - "bottom", - "left", - "top", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "number_of_histogram_legend_columns", - "displayName": "Number of Histogram Legend Columns", - "description": "number of columns for the histogram legend\n", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": 6, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "colors_for_plots", - "displayName": "Colors for Plots", - "description": "Colors for the PCA and histogram will be picked, in order, from this list.\nColors must either be names in `grDevices::colors()` or valid hex codes.\n", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "interactive_plots", - "displayName": "Interactive Plots", - "description": "set to TRUE to make PCA and Histogram plots interactive with `plotly`, allowing you to hover\nyour mouse over a point or line to view sample information. The similarity heat map will not display if this toggle\nis set to `TRUE`. Default is `FALSE`.\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "plot_corr_matrix_heatmap", - "displayName": "Plot Correlation Matrix Heatmap", - "description": "Datasets with a large number of samples may be too large to create a correlation\nmatrix heatmap. If this function takes longer than 5 minutes to run, Set to `FALSE` and the correlation matrix will\nnot be be created. Default is `TRUE`.\n", - "paramType": "BOOLEAN", - "paramGroup": "TCGA", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "Whether to save plots to files during analysis (Defaults to `TRUE`, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - }, - "figures": { - "type": "directory", - "name": "figures/filt/" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/filter_diff.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/filter_diff.json deleted file mode 100644 index d1756e0..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/filter_diff.json +++ /dev/null @@ -1,345 +0,0 @@ -{ - "r_function": "filter_diff", - "title": "Filter Differential Features\n", - "description": "Outputs dataset of significant genes from DEG table; filters genes based on statistical significance (p-value or\nadjusted p-value) and change (fold change, log2 fold change, or t-statistic); in addition allows for selection of DEG\nestimates and for sub-setting of contrasts and groups included in the output gene list.\n", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Gene Names Column", - "description": "The column from the counts data containing the Feature IDs (Usually Gene or Protein ID).\nThis is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts\nMatrix will be available to select for this parameter. (Default: `NULL` - first column in the counts matrix will be\nused.)\n", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "columnType": "STRING", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file at the end of the function", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "significance_column", - "displayName": "Significance Column", - "description": "Column name for significance, e.g. `\"pval\"` or `\"pvaladj\"` (default)\n", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "adjpval", - "pval" - ], - "defaultValue": "adjpval", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "significance_cutoff", - "displayName": "Significance Cutoff", - "description": "Features will only be kept if their `significance_column` is less then this cutoff\nthreshold\n", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": 0.05, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "change_column", - "displayName": "Change Column", - "description": "Column name for change, e.g. `\"logFC\"` (default)\n", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "FC", - "logFC", - "tstat" - ], - "defaultValue": "logFC", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "change_cutoff", - "displayName": "Change Cutoff", - "description": "Features will only be kept if the absolute value of their `change_column` is greater than or\nequal to this cutoff threshold\n", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "filtering_mode", - "displayName": "Filtering Mode", - "description": "Accepted values: `\"any\"` or `\"all\"` to include features that meet the criteria in *any*contrast or in *all* contrasts\n", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "any", - "all" - ], - "defaultValue": "any", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "include_estimates", - "displayName": "Include Estimates", - "description": "Column names of estimates to include. Default: `c(\"FC\", \"logFC\", \"tstat\", \"pval\", \"adjpval\")`", - "paramType": "MULTISELECT", - "paramGroup": "Advanced", - "paramValues": [ - "mean", - "sd", - "FC", - "logFC", - "tstat", - "pval", - "adjpval" - ], - "defaultValue": ["FC", "logFC", "tstat", "pval", "adjpval"], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "round_estimates", - "displayName": "Round Estimates", - "description": "Whether to round estimates. Default: `TRUE`", - "paramType": "BOOLEAN", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "contrast_filter", - "displayName": "Contrasts Filter", - "description": "Whether to filter `contrasts` in or our of analysis. If `\"keep\"`, only the contrast names\nlisted in `contrasts` will be included. If `\"remove`, the contrast names listed by `contrasts` will be removed. If\n`\"none\"`, all contrasts in the dataset are used. Options: `\"keep\"`, `\"remove\"`, or `\"none\"`", - "paramType": "SELECT", - "paramGroup": "Filter", - "paramValues": [ - "none", - "keep", - "remove" - ], - "defaultValue": "none", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "contrasts", - "displayName": "Contrasts", - "description": "Contrast names to filter by `contrast_filter`. If `contrast_filter` is `\"none\"`, this parameter has\nno effect.\n", - "paramType": "VECTOR", - "paramGroup": "Filter", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "groups_filter", - "displayName": "Groups Filter", - "description": "Whether to filter `groups` in or out of analysis. If `\"keep\"`, only the group names listed in\n`groups` will be included. If `\"remove\"`, the group names listed by `groups` will be removed. If `\"none\"`, all\ngroups in the dataset are used.\n", - "paramType": "SELECT", - "paramGroup": "Filter", - "paramValues": [ - "none", - "keep", - "remove" - ], - "defaultValue": "none", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "groups", - "displayName": "Groups", - "description": "Group names to filter by `groups_filter`. If `groups_filter` is `\"none\"`, this parameter has no effect.\nOptions: `\"keep\"`, `\"remove\"`, or `\"none\"`", - "paramType": "VECTOR", - "paramGroup": "Filter", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_font_size", - "displayName": "Label Font Size", - "description": "Font size for labels in the plot (default: 6)\n", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": 6, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_distance", - "displayName": "Label Distance", - "description": "Distance of labels from the bars (default: 1)\n", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "y_axis_expansion", - "displayName": "Y-Axis Expansion", - "description": "Expansion of the y-axis (default: 0.08)\n", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": 0.08, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "fill_colors", - "displayName": "Fill Colors ", - "description": "Fill colors for the bars (default: c(\"steelblue1\", \"whitesmoke\"))\n", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "aliceblue", - "antiquewhite4", - "darkorange", - "gold", - "red3", - "springgreen", - "steelblue1", - "blue2", - "violetred3", - "whitesmoke", - "gray60", - "gray90", - "black", - "white" - ], - "defaultValue": ["steelblue1", "whitesmoke"], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "pie_chart_in_3d", - "displayName": "Pie Chart in 3D", - "description": "Whether to draw pie charts in 3D (default: TRUE)\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "bar_width", - "displayName": "Bar Width", - "description": "Width of the bars (default: 0.4)\n", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": 0.4, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "draw_bar_border", - "displayName": "Draw Bar Border", - "description": "Whether to draw borders around bars (default: TRUE)\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "rounding_decimal_for_percent_cells", - "displayName": "Rounding Decimal for Percent Calls", - "description": "Decimal place to use when rounding Percent cells\n", - "paramType": "NUMBER", - "paramGroup": "Advanced", - "paramValues": null, - "defaultValue": 0, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "plot_titles_fontsize", - "displayName": "Font Size for Plot Titles", - "description": "Font size for plot titles (default: 12)\n", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": 12, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "Whether to save plots to files during analysis (Defaults to `TRUE`, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - }, - "figures": { - "type": "directory", - "name": "figures/diff/filt/" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/normalize_counts.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/normalize_counts.json deleted file mode 100644 index 118f7fe..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/normalize_counts.json +++ /dev/null @@ -1,408 +0,0 @@ -{ - "r_function": "normalize_counts", - "title": "Normalization\n", - "description": "Normalize counts\n", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Feature ID Column", - "description": "The column from the counts data containing the Feature IDs (Usually Gene or Protein ID).\nThis is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts\nMatrix will be available to select for this parameter. (Default: `NULL` - first column in the counts matrix will be\nused.)\n", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "samples_to_include", - "displayName": "Columns to Include", - "description": "Which samples would you like to include? Usually, you will choose all sample columns, or\nyou could choose to remove certain samples. Samples excluded here will be removed in this step and from further\nanalysis downstream of this step. (Default: `NULL` - all sample IDs in `moo@sample_meta` will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "counts_matrix", - "columnType": "ALL", - "isMulti": true - }, - { - "key": "sample_id_colname", - "displayName": "Sample Names Column", - "description": "The column from the sample metadata containing the sample names. The names in this column\nmust exactly match the names used as the sample column names of your input Counts Matrix. (Default: `NULL` - first\ncolumn in the sample metadata will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "group_colname", - "displayName": "Groups Column", - "description": "The column from the sample metadata containing the sample group information. This is usually a\ncolumn showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal,\nBefore, After, etc.).\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "defaultValue": "Group", - "columnType": "ALL", - "isMulti": null - }, - { - "key": "label_colname", - "displayName": "Labels Column", - "description": "The column from the sample metadata containing the sample labels as you wish them to appear in\nthe plots produced by this template. This can be the same Sample Names Column. However, you may desire different\nlabels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the\ncolumn with your preferred Labels here. The selected column should contain unique names for each sample. (Default:\n`NULL` -- `sample_id_colname` will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata", - "columnType": "ALL", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "MOO output Rds", - "description": "File path to output the multiOmicDataSet object (MOO) as an Rds file at the end of the function", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "count_type", - "displayName": "Count Type", - "description": "the type of counts to use -- must be a name in the counts slot (`moo@counts`)\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "filt", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "norm_type", - "displayName": "Normalization Type", - "description": "normalization type. Default: \"voom\" which uses `limma::voom`.\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "voom", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "input_in_log_counts", - "displayName": "Input in Log Counts", - "description": "set this to `TRUE` if counts are already log2-transformed\n", - "paramType": "BOOLEAN", - "paramGroup": "Normalization", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "voom_normalization_method", - "displayName": "Normalization Method", - "description": "Normalization method to be applied to the logCPM values when using `limma::voom`", - "paramType": "SELECT", - "paramGroup": "Normalization", - "paramValues": [ - "none", - "scale", - "quantile", - "cyclicloess" - ], - "defaultValue": "quantile", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "samples_to_rename", - "displayName": "Samples to Rename Manually on PCA", - "description": "If you do not have a Plot Labels Column in your sample metadata table, you can use this\nparameter to rename samples manually for display on the PCA plot. Use \"Add item\" to add each additional sample for\nrenaming. Use the following format to describe which old name (in your sample metadata table) you want to rename to\nwhich new name: old_name: new_name\n", - "paramType": "VECTOR", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "add_label_to_pca", - "displayName": "Add Labels to PCA", - "description": "label points on the PCA plot\n", - "paramType": "BOOLEAN", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "principal_component_on_x_axis", - "displayName": "Principal Component on X-axis for PCA", - "description": "The principal component to plot on the x-axis for the PCA plot. Choices include\n1, 2, 3, ... (default: 1)\n", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "principal_component_on_y_axis", - "displayName": "Principal Component on Y-axis for PCA", - "description": "The principal component to plot on the y-axis for the PCA plot. Choices include\n1, 2, 3, ... (default: 2)\n", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_position_for_pca", - "displayName": "Legend position for PCA", - "description": "legend position for the PCA plot\n", - "paramType": "SELECT", - "paramGroup": "PCA", - "paramValues": [ - "top", - "bottom", - "left", - "right", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_offset_x_", - "displayName": "Label Offset (x) for PCA", - "description": "label offset x for the PCA plot\n", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_offset_y_", - "displayName": "Label Offset (y) for PCA", - "description": "label offset y for the PCA plot\n", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_font_size", - "displayName": "Label Font Size for PCA", - "description": "label font size for the PCA plot\n", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": 3, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "point_size_for_pca", - "displayName": "Point Size for PCA", - "description": "geom point size for the PCA plot\n", - "paramType": "NUMBER", - "paramGroup": "PCA", - "paramValues": null, - "defaultValue": 8, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_histogram_by_group", - "displayName": "Color Histogram by Group", - "description": "Set to FALSE to label histogram by Sample Names, or set to TRUE to label histogram by\nthe column you select in the \"Group Column Used to Color Histogram\" parameter (below). Default is FALSE.\n", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "maximum_for_x_axis_for_histogram", - "displayName": "Maximum for X-axis in Histogram", - "description": "x-axis maximum for histogram plot\n", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "minimum_for_x_axis_for_histogram", - "displayName": "Minimum for X-axis in Histogram", - "description": "x-axis minimum for histogram plot\n", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": -1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "set_min_max_for_x_axis_for_histogram", - "displayName": "Set Min/Max for X-axis for Histogram", - "description": "whether to set min/max value for histogram x-axis\n", - "paramType": "BOOLEAN", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_font_size_for_histogram", - "displayName": "Legend Font Size for Histogram", - "description": "legend font size for the histogram plot\n", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": 10, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_position_for_histogram", - "displayName": "Legend Position for Histogram", - "description": "legend position for the histogram plot. consider setting to 'none' for a large\nnumber of samples.\n", - "paramType": "SELECT", - "paramGroup": "Histogram", - "paramValues": [ - "top", - "bottom", - "left", - "right", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "number_of_histogram_legend_columns", - "displayName": "Number of Histogram Legend Columns", - "description": "number of columns for the histogram legend\n", - "paramType": "NUMBER", - "paramGroup": "Histogram", - "paramValues": null, - "defaultValue": 6, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "colors_for_plots", - "displayName": "Colors for Plots", - "description": "Colors for the PCA and histogram will be picked, in order, from this list.\nColors must either be names in `grDevices::colors()` or valid hex codes.\n", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "interactive_plots", - "displayName": "Make Plots Interactive", - "description": "set to TRUE to make PCA and Histogram plots interactive with `plotly`, allowing you to hover\nyour mouse over a point or line to view sample information. The similarity heat map will not display if this toggle\nis set to `TRUE`. Default is `FALSE`.\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "plot_corr_matrix_heatmap", - "displayName": "Plot Correlation Matrix Heatmap", - "description": "Datasets with a large number of samples may be too large to create a correlation\nmatrix heatmap. If this function takes longer than 5 minutes to run, Set to `FALSE` and the correlation matrix will\nnot be be created. Default is `TRUE`.\n", - "paramType": "BOOLEAN", - "paramGroup": "TCGA", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "Whether to save plots to files during analysis (Defaults to `TRUE`, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "multiOmicDataSet": { - "type": "file", - "name": "moo.rds" - }, - "figures": { - "type": "directory", - "name": "figures/norm/" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_expr_heatmap.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_expr_heatmap.json deleted file mode 100644 index 5d77de0..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_expr_heatmap.json +++ /dev/null @@ -1,558 +0,0 @@ -{ - "r_function": "plot_expr_heatmap", - "title": "Plot Expression Heatmap\n", - "description": "The samples (i.e. the columns) are clustered in an unsupervised fashion based\non how similar their expression profiles are across the included genes. This\ncan help identify samples that are non clustering with their group as you\nmight expect based on the experimental design.\nBy default, the top 500 genes by variance are used, as these are\ngenerally going to include those genes that most distinguish your samples\nfrom one another. You can change this as well as many other parameters about\nthis heatmap if you explore the advanced options.\n", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Gene Column Name", - "description": "The column from the counts dataa containing the Feature IDs (Usually Gene or Protein ID).\nThis is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts\nMatrix will be available to select for this parameter. (Default: `NULL` - first column in the counts matrix will be\nused.)\n", - "paramGroup": "Data Setup", - "sourceDataset": "Counts_Matrix", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "sample_id_colname", - "displayName": "Sample Name Column", - "description": "The column from the sample metadata containing the sample names. The names in this column\nmust exactly match the names used as the sample column names of your input Counts Matrix. (Default: `NULL` - first\ncolumn in the sample metadata will be used.)\n", - "paramGroup": "Data Setup", - "sourceDataset": "Sample_Metadata", - "columnType": "ALL", - "isMulti": null - }, - { - "key": "label_colname", - "displayName": "Sample Labels Column", - "description": "The column from the sample metadata containing the sample labels as you wish them to appear in\nthe plots produced by this template. This can be the same Sample Names Column. However, you may desire different\nlabels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the\ncolumn with your preferred Labels here. The selected column should contain unique names for each sample. (Default:\n`NULL` -- `sample_id_colname` will be used.)\n", - "paramGroup": "Data Setup", - "sourceDataset": "Sample_Metadata", - "columnType": "ALL", - "isMulti": null - }, - { - "key": "samples_to_include", - "displayName": "Samples to Include", - "description": "Which samples would you like to include? Usually, you will choose all sample columns, or\nyou could choose to remove certain samples. Samples excluded here will be removed in this step and from further\nanalysis downstream of this step. (Default: `NULL` - all sample IDs in `moo@sample_meta` will be used.)\n", - "paramGroup": "Data Setup", - "sourceDataset": "Counts_Matrix", - "columnType": "NUMBER", - "isMulti": true - }, - { - "key": "reorder_dendrogram_order", - "displayName": "Reorder Sample Dendrogram Order", - "description": "Reorder the samples (columns) of the dendrogram by name, e.g.\n“sample2”,“sample3\",“sample1\".\n", - "paramGroup": "Sample", - "sourceDataset": "Counts_Matrix", - "columnType": "ALL", - "isMulti": true - }, - { - "key": "group_colname", - "displayName": "Group Columns", - "description": "The column from the sample metadata containing the sample group information. This is usually a\ncolumn showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal,\nBefore, After, etc.).\n", - "paramGroup": "Annotation", - "sourceDataset": "Sample_Metadata", - "defaultValue": "Group", - "columnType": "ALL", - "isMulti": true - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "count_type", - "displayName": "Count Type", - "description": "the type of counts to use. Must be a name in the counts slot (`names(moo@counts)`).\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sub_count_type", - "displayName": "Sub Count Type", - "description": "used if `count_type` is a list in the counts slot: specify the sub count type within the list.\nMust be a name in `names(moo@counts[[count_type]])`.\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "include_all_genes", - "displayName": "Include All Genes", - "description": "Set to TRUE if all genes are to be included. Set to FALSE if you want to filter genes by\nvariance and/or provide a list of specific genes that will appear in the heatmap.\n", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "filter_top_genes_by_variance", - "displayName": "Filter Top Genes by Variance", - "description": "Set to TRUE if you want to only include the top genes by variance. Set to FALSE\nif you do not want to filter genes by variance.\n", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "top_genes_by_variance_to_include", - "displayName": "Top Genes by Variance to Include", - "description": "The number of genes to include if filtering genes by variance. This parameter\nis ignored if \"Filter top genes by variance\" is set to FALSE.\n", - "paramType": "NUMBER", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": 500, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "specific_genes_to_include_in_heatmap", - "displayName": "Specific Genes to Include in Heatmap", - "description": "Enter the gene symbols to be included in the heatmap, with each gene\nsymbol separated with a space from the others. Alternatively, paste in a column of gene names from any spreadsheet\napplication. This parameter is ignored if \"Include all genes\" is set to TRUE.\n", - "paramType": "STRING", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": "None", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "cluster_genes", - "displayName": "Cluster Genes", - "description": "Choose whether to cluster the rows (genes). If TRUE, rows will have clustering applied. If\nFALSE, clustering will not be applied to rows.\n", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "gene_clustering_method", - "displayName": "Gene Clustering Method", - "description": "Clustering method metric to be used in clustering samples. (TODO document options)\n", - "paramType": "SELECT", - "paramGroup": "Gene", - "paramValues": [ - "ward.D", - "ward.D2", - "single", - "complete", - "average", - "mcquitty", - "median", - "centroid" - ], - "defaultValue": "average", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "gene_distance_metric", - "displayName": "Gene Distance Metric", - "description": "Distance metric to be used in clustering genes. (TODO document options)\n", - "paramType": "SELECT", - "paramGroup": "Gene", - "paramValues": [ - "euclidean", - "maximum", - "manhattan", - "canberra", - "binary", - "minkowski", - "correlation" - ], - "defaultValue": "correlation", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "display_gene_dendrograms", - "displayName": "Display Gene Dendrogram", - "description": "Set to TRUE to show gene dendrograms. Set to FALSE to hide dendrograms.\n", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "display_gene_names", - "displayName": "Display Gene Names", - "description": "Set to TRUE to display gene names on the right side of the heatmap. Set to FALSE to hide\ngene names.\n", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "center_and_rescale_expression", - "displayName": "Center and Rescale Expression", - "description": "Center and rescale expression for each gene across all included samples.\n", - "paramType": "BOOLEAN", - "paramGroup": "Gene", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "cluster_samples", - "displayName": "Cluster Samples", - "description": "Choose whether to cluster the columns (samples). If TRUE, columns will have clustering\napplied. If FALSE, clustering will not be applied to columns.\n", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "arrange_sample_columns", - "displayName": "Arrange Sample Columns", - "description": "If TRUE, arranges columns by annotation groups. If FALSE, and \"Cluster Samples\" is\nFALSE, samples will appear in the order of input (samples to include)\n", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "order_by_gene_expression", - "displayName": "Order by Gene Expression", - "description": "If TRUE, set gene name below and direction for ordering\n", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "gene_to_order_columns", - "displayName": "Gene to Order Columns", - "description": "Gene to order columns by expression levels\n", - "paramType": "STRING", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": " ", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "gene_expression_order", - "displayName": "Gene Expression Order", - "description": "Choose direction for gene order\n", - "paramType": "SELECT", - "paramGroup": "Sample", - "paramValues": [ - "low_to_high", - "high_to_low" - ], - "defaultValue": "low_to_high", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "smpl_clustering_method", - "displayName": "Sample Clustering Method", - "description": "Clustering method to be used in clustering samples. (TODO document options)\n", - "paramType": "SELECT", - "paramGroup": "Sample", - "paramValues": [ - "ward.D", - "ward.D2", - "single", - "complete", - "average", - "mcquitty", - "median", - "centroid" - ], - "defaultValue": "average", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "smpl_distance_metric", - "displayName": "Sample Distance Metric", - "description": "Distance metric to be used in clustering samples. (TODO document options)\n", - "paramType": "SELECT", - "paramGroup": "Sample", - "paramValues": [ - "euclidean", - "maximum", - "manhattan", - "canberra", - "binary", - "minkowski", - "correlation" - ], - "defaultValue": "correlation", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "display_smpl_dendrograms", - "displayName": "Display Sample Dendrograms", - "description": "Set to TRUE to show sample dendrograms. Set to FALSE to hide dendrogram.\n", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "reorder_dendrogram", - "displayName": "Reorder Sample Dendrogram", - "description": "If TRUE, set the order of the dendrogram (below)\n", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "display_sample_names", - "displayName": "Display Sample Names", - "description": "Set to TRUE if you want sample names to be displayed on the plot. Set to FALSE to hide\nsample names.\n", - "paramType": "BOOLEAN", - "paramGroup": "Sample", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "assign_group_colors", - "displayName": "Assign Group Colors", - "description": "If TRUE, set the groups assigned colors (below)\n", - "paramType": "BOOLEAN", - "paramGroup": "Annotation", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "assign_color_to_sample_groups", - "displayName": "Assign Color to Sample Groups", - "description": "Enter each sample to color in the format: group_name: color This parameter is\nignored if \"Assign Colors\" is set to FALSE.\n", - "paramType": "VECTOR", - "paramGroup": "Annotation", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "group_colors", - "displayName": "Group Colors", - "description": "Set group annotation colors.\n", - "paramType": "MULTISELECT", - "paramGroup": "Annotation", - "paramValues": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "defaultValue": ["#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "heatmap_color_scheme", - "displayName": "Heatmap Color Scheme", - "description": "color scheme (TODO document options)\n", - "paramType": "SELECT", - "paramGroup": "Visual", - "paramValues": [ - "Default", - "Blue to Red", - "Red to Vanilla", - "Violet to Pink", - "Bu Yl Rd", - "Bu Wt Rd" - ], - "defaultValue": "Default", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "autoscale_heatmap_color", - "displayName": "Autoscale Heatmap Color", - "description": "Set to TRUE to autoscale the heatmap colors between the maximum and minimum heatmap\ncolor parameters. If FALSE, set the heatmap colors between \"Set max heatmap color\" and \"Set min heatmap color\"\n(below).\n", - "paramType": "BOOLEAN", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "set_max_heatmap_color", - "displayName": "Set Max Heatmap Color", - "description": "If Autoscale heatmap color is set to FALSE, set the maximum heatmap z-score value.\n", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "set_min_heatmap_color", - "displayName": "Set Min Heatmap Color", - "description": "If Autoscale heatmap color is set to FALSE, set the minimum heatmap z-score value\n", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": -2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "aspect_ratio", - "displayName": "Aspect Ratio", - "description": "Set figure Aspect Ratio. Ratio refers to entire figure including legend. If set to Auto figure\nsize is based on number of rows and columns form counts matrix. default - Auto\n", - "paramType": "STRING", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": "Auto", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "display_numbers", - "displayName": "Display Numbers", - "description": "Setting to FALSE (default) will not display numerical value of heat on heatmap. Set to TRUE if\nyou want to see these numbers on the plot.\n", - "paramType": "BOOLEAN", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "gene_name_font_size", - "displayName": "Gene Name Font Size", - "description": "Font size for gene names. If you don't want gene labels to show, toggle \"Display Gene\nNames\" below to FALSE\n", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": 4, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_font_size", - "displayName": "Legend Font Size", - "description": "Set Font size for figure legend. Default is 10.\n", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": 10, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sample_name_font_size", - "displayName": "Sample Name Font Size", - "description": "Font size for sample names. If you don't want to display samples names, toggle \"Display\nsample names\" (below) to FALSE\n", - "paramType": "NUMBER", - "paramGroup": "Visual", - "paramValues": null, - "defaultValue": 8, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "Whether to save plots to files during analysis (Defaults to `TRUE`, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "figures": { - "type": "file", - "name": "figures/heatmap/expr_heatmap.png" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_pca_2d.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_pca_2d.json deleted file mode 100644 index 1655813..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_pca_2d.json +++ /dev/null @@ -1,275 +0,0 @@ -{ - "r_function": "plot_pca_2d", - "title": "PCA 2D\n", - "description": "Perform and plot a 2D Principal Components Analysis\nPerform and plot a 2D Principal Components Analysis\n", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "FeatureID Name Column", - "description": "The column from the counts dataa containing the Feature IDs (Usually Gene or Protein ID).\nThis is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts\nMatrix will be available to select for this parameter. (Default: `NULL` - first column in the counts matrix will be\nused.)\n", - "paramGroup": "Basic", - "sourceDataset": "Counts_Matrix", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "sample_id_colname", - "displayName": "Sample Names Column", - "description": "The column from the sample metadata containing the sample names. The names in this column\nmust exactly match the names used as the sample column names of your input Counts Matrix. (Default: `NULL` - first\ncolumn in the sample metadata will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "group_colname", - "displayName": "Group Column", - "description": "The column from the sample metadata containing the sample group information. This is usually a\ncolumn showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal,\nBefore, After, etc.).\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": "Group", - "columnType": "ALL", - "isMulti": null - }, - { - "key": "label_colname", - "displayName": "Plot Labels Column", - "description": "The column from the sample metadata containing the sample labels as you wish them to appear in\nthe plots produced by this template. This can be the same Sample Names Column. However, you may desire different\nlabels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the\ncolumn with your preferred Labels here. The selected column should contain unique names for each sample. (Default:\n`NULL` -- `sample_id_colname` will be used.)\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": "Label", - "columnType": "ALL", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "count_type", - "displayName": "Count Type", - "description": "type to assign the values of `counts_dat` to in the `counts` slot\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sub_count_type", - "displayName": "Sub Count Type", - "description": "used if `count_type` is a list in the counts slot: specify the sub count type within the list.\nMust be a name in `names(moo@counts[[count_type]])`.\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "principal_components", - "displayName": "Principal Components", - "description": "vector with numbered principal components to plot\n", - "paramType": "MULTISELECT", - "paramGroup": "Basic", - "paramValues": [ - 1, - 2, - 3, - 4, - 5 - ], - "defaultValue": [1, 2], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "point_size", - "displayName": "Point Size", - "description": "size for `ggplot2::geom_point()`", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "add_label", - "displayName": "Add Labels", - "description": "whether to add text labels for the points\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_font_size", - "displayName": "Label Font Size", - "description": "label font size for the PCA plot\n", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": 3, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "legend_position", - "displayName": "Legend Position", - "description": "passed to in `legend.position``ggplot2::theme()`", - "paramType": "SELECT", - "paramGroup": "Visualization", - "paramValues": [ - "top", - "bottom", - "left", - "right", - "none" - ], - "defaultValue": "top", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_values", - "displayName": "Color Values", - "description": "vector of colors as hex values or names recognized by R\n", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "slateblue3", - "tomato2", - "maroon", - "deepskyblue", - "mediumorchid2", - "mediumseagreen", - "salmon", - "dodgerblue", - "darkgreen", - "plum4", - "orange", - "yellow4", - "aquamarine3", - "salmon1", - "lightskyblue3", - "plum3", - "firebrick", - "darkolivegreen3", - "goldenrod1", - "burlywood2", - "gray70", - "firebrick2", - "steelblue", - "palegreen4", - "orchid4", - "darkorange1", - "yellow", - "sienna", - "palevioletred1", - "gray60", - "cyan4", - "darkorange3", - "mediumpurple3", - "violetred2", - "olivedrab", - "darkgoldenrod2", - "darkgoldenrod", - "gray40", - "palegreen3", - "thistle3", - "khaki1", - "deeppink2", - "chocolate3", - "paleturquoise3", - "wheat1", - "lightsteelblue", - "sandybrown", - "darkolivegreen2", - "thistle2", - "gray85", - "orchid3", - "darkseagreen1", - "lightgoldenrod1", - "lightskyblue2", - "dodgerblue3", - "darkseagreen3", - "forestgreen", - "lightpink2", - "mediumpurple4", - "lightpink1", - "thistle", - "navajowhite", - "lemonchiffon", - "bisque2", - "mistyrose", - "gray95", - "lightcyan3", - "peachpuff2", - "lightsteelblue2", - "lightyellow2", - "moccasin", - "antiquewhite2", - "gray80", - "lightgrey" - ], - "defaultValue": ["#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "interactive_plots", - "displayName": "Interactive Plots", - "description": "set to TRUE to make PCA and Histogram plots interactive with `plotly`, allowing you to hover\nyour mouse over a point or line to view sample information. The similarity heat map will not display if this toggle\nis set to `TRUE`. Default is `FALSE`.\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "Whether to save plots to files during analysis (Defaults to `TRUE`, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": [ - true, - false - ], - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "figures": { - "type": "file", - "name": "figures/pca/pca_2D.png" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_pca_3d.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_pca_3d.json deleted file mode 100644 index 54b06e8..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_pca_3d.json +++ /dev/null @@ -1,212 +0,0 @@ -{ - "r_function": "plot_pca_3d", - "title": "PCA 3D\n", - "description": "Perform and plot a 3D Principal Components Analysis\n3D PCA for counts dataframe\n", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "FeatureID Name Column", - "description": "The column from the counts data containing feature IDs. If `NULL`, first column is used.\n", - "paramGroup": "Basic", - "sourceDataset": "Counts_Matrix", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "sample_id_colname", - "displayName": "Sample Names Column", - "description": "The column from sample metadata containing sample names. If `NULL`, first column is used.\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "group_colname", - "displayName": "Group Column", - "description": "The column from sample metadata containing sample group information.\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": "Group", - "columnType": "ALL", - "isMulti": null - }, - { - "key": "label_colname", - "displayName": "Plot Labels Column", - "description": "The column from sample metadata containing sample labels.\n", - "paramGroup": "Basic", - "sourceDataset": "Sample_Metadata_Table", - "defaultValue": "Label", - "columnType": "ALL", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "count_type", - "displayName": "Count Type", - "description": "the type of counts to use. Ignored when `moo_counts` is already a dataframe.\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "sub_count_type", - "displayName": "Sub Count Type", - "description": "used if `count_type` is a list in the counts slot: specify the sub count type within the list.\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "point_size", - "displayName": "Point Size", - "description": "size for `ggplot2::geom_point()`", - "paramType": "NUMBER", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": 8, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_values", - "displayName": "Color Values", - "description": "vector of colors as hex values or names recognized by R.\n", - "paramType": "MULTISELECT", - "paramGroup": "Visualization", - "paramValues": [ - "slateblue3", - "tomato2", - "maroon", - "deepskyblue", - "mediumorchid2", - "mediumseagreen", - "salmon", - "dodgerblue", - "darkgreen", - "plum4", - "orange", - "yellow4", - "aquamarine3", - "salmon1", - "lightskyblue3", - "plum3", - "firebrick", - "darkolivegreen3", - "goldenrod1", - "burlywood2", - "gray70", - "firebrick2", - "steelblue", - "palegreen4", - "orchid4", - "darkorange1", - "yellow", - "sienna", - "palevioletred1", - "gray60", - "cyan4", - "darkorange3", - "mediumpurple3", - "violetred2", - "olivedrab", - "darkgoldenrod2", - "darkgoldenrod", - "gray40", - "palegreen3", - "thistle3", - "khaki1", - "deeppink2", - "chocolate3", - "paleturquoise3", - "wheat1", - "lightsteelblue", - "sandybrown", - "darkolivegreen2", - "thistle2", - "gray85", - "orchid3", - "darkseagreen1", - "lightgoldenrod1", - "lightskyblue2", - "dodgerblue3", - "darkseagreen3", - "forestgreen", - "lightpink2", - "mediumpurple4", - "lightpink1", - "thistle", - "navajowhite", - "lemonchiffon", - "bisque2", - "mistyrose", - "gray95", - "lightcyan3", - "peachpuff2", - "lightsteelblue2", - "lightyellow2", - "moccasin", - "antiquewhite2", - "gray80", - "lightgrey" - ], - "defaultValue": ["#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "plot_title", - "displayName": "Plot Title", - "description": "title for the plot\n", - "paramType": "STRING", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": "PCA 3D", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "whether to save plot to disk.\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "figures": { - "type": "file", - "name": "figures/pca/pca_3D.html" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_venn_diagram.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_venn_diagram.json deleted file mode 100644 index 9bda288..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_venn_diagram.json +++ /dev/null @@ -1,1100 +0,0 @@ -{ - "r_function": "plot_venn_diagram", - "title": "Venn Diagram\n", - "description": "Generates Venn diagram of intersections across a series of sets (e.g., intersections of significant genes across\ntested contrasts). This Venn diagram is available for up to five sets; Intersection plot is available for any number\nof sets. Specific sets can be selected for the visualizations and the returned dataset may include all (default) or\nspecified intersections.\nAn S7 generic with methods for \nlist(\"multiOmicDataSet\")\n and \nlist(\"data.frame\")\n.\n", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Elements Column", - "description": "The column from the counts data containing the Feature IDs (Usually Gene or Protein ID).\nThis is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts\nMatrix will be available to select for this parameter. (Default: `NULL` - first column in the counts matrix will be\nused.)\n", - "paramGroup": "Basic", - "sourceDataset": "Input_Dataset", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "contrasts_colname", - "displayName": "Categories Column", - "description": "Name of the column in `moo_diff_summary_dat` that contains the contrast names (default:\n\"Contrast\")\n", - "paramGroup": "Basic", - "sourceDataset": "Input_Dataset", - "defaultValue": "Contrast", - "columnType": "STRING", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "DataFrame input Rds", - "description": "File path to read the summary dataframe (e.g. from plot_volcano_summary output)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "summary_dataframe.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "Venn diagram DataFrame Rds", - "description": "File path to output the venn diagram DataFrame as an Rds file", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "select_contrasts", - "displayName": "Selected Categories", - "description": "A vector of contrast names to select for the plot. If empty, all contrasts are used.\n", - "paramType": "VECTOR", - "paramGroup": "Advanced", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "plot_type", - "displayName": "Select Plot Type", - "description": "Type of plot to generate: \"Venn diagram\" or \"Intersection plot\". Default: \"Venn diagram\"\n", - "paramType": "SELECT", - "paramGroup": "Advanced", - "paramValues": [ - "Venn diagram", - "Intersection plot", - "Intersection table" - ], - "defaultValue": "Venn diagram", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "intersection_ids", - "displayName": "Intersection IDs", - "description": "A vector of intersection IDs to select for the plot. If empty, all intersections are used.\n", - "paramType": "VECTOR", - "paramGroup": "Advanced", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_force_unique", - "displayName": "Venn Force Unique", - "description": "If TRUE, forces unique elements in the Venn diagram. Default: TRUE\n", - "paramType": "BOOLEAN", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_numbers_format", - "displayName": "Venn Numbers Format", - "description": "Format for the numbers in the Venn diagram. Options: \"raw\", \"percent\", \"raw-percent\",\n\"percent-raw\". Default: \"raw\"\n", - "paramType": "SELECT", - "paramGroup": "Venn Diagram", - "paramValues": [ - "raw", - "percent", - "raw-percent", - "percent-raw" - ], - "defaultValue": "raw", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_significant_digits", - "displayName": "Venn Significant Digits", - "description": "Number of significant digits for the Venn diagram numbers. Default: 2\n", - "paramType": "NUMBER", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_fill_colors", - "displayName": "Venn Fill Colors", - "description": "A vector of colors to fill the Venn diagram categories. Default: c(\"darkgoldenrod2\",\n\"darkolivegreen2\", \"mediumpurple3\", \"darkorange2\", \"lightgreen\")\n", - "paramType": "MULTISELECT", - "paramGroup": "Venn Diagram", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": ["darkgoldenrod2", "darkolivegreen2", "mediumpurple3", "darkorange2", "lightgreen"], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_fill_transparency", - "displayName": "Venn Fill Transparency", - "description": "Transparency level for the Venn diagram fill colors. Default: 0.2\n", - "paramType": "STRING", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": 0.2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_border_colors", - "displayName": "Venn Border Colors", - "description": "Colors for the borders of the Venn diagram categories. Default: \"fill colors\" (uses the\nsame colors as `venn_fill_colors`)\n", - "paramType": "SELECT", - "paramGroup": "Venn Diagram", - "paramValues": [ - "black", - "fill colors" - ], - "defaultValue": "fill colors", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_font_size_for_category_names", - "displayName": "Venn Font Size for Category Names", - "description": "Font size for the category names in the Venn diagram. Default: 3\n", - "paramType": "NUMBER", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": 3, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_category_names_distance", - "displayName": "Venn Category Names Distance", - "description": "Distance of the category names from the Venn diagram circles. Default: c()\n", - "paramType": "VECTOR", - "paramGroup": "Venn Diagram", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_category_names_position", - "displayName": "Venn Category Names Position", - "description": "Position of the category names in the Venn diagram. Default: c()\n", - "paramType": "VECTOR", - "paramGroup": "Venn Diagram", - "paramValues": null, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_font_size_for_counts", - "displayName": "Venn Font Size for Counts", - "description": "Font size for the counts in the Venn diagram. Default: 6\n", - "paramType": "NUMBER", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": 6, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "venn_outer_margin", - "displayName": "Venn Outer Margin", - "description": "Outer margin for the Venn diagram. Default: 0\n", - "paramType": "NUMBER", - "paramGroup": "Venn Diagram", - "paramValues": null, - "defaultValue": 0, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "intersections_order", - "displayName": "Intersections Order", - "description": "Order of the intersections in the plot. Default: \"by size\"\n", - "paramType": "SELECT", - "paramGroup": "Intersection Plot", - "paramValues": [ - "degree", - "freq" - ], - "defaultValue": "degree", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "display_empty_intersections", - "displayName": "Display Empty Intersections", - "description": "If TRUE, displays empty intersections in the plot. Default: FALSE\n", - "paramType": "BOOLEAN", - "paramGroup": "Intersection Plot", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "intersection_bar_color", - "displayName": "Intersection Bar Color", - "description": "Color for the intersection bars in the plot. Default: \"lightgray\"\n", - "paramType": "SELECT", - "paramGroup": "Intersection Plot", - "paramValues": [ - "steelblue4", - "aquamarine3", - "salmon1", - "lightskyblue3", - "plum3", - "darkolivegreen3", - "goldenrod1", - "burlywood2", - "gray70", - "firebrick2", - "steelblue", - "palegreen4", - "orchid4", - "darkorange1", - "yellow", - "sienna", - "palevioletred1", - "gray60", - "cyan4", - "darkorange3", - "mediumpurple3", - "violetred2", - "olivedrab", - "darkgoldenrod2", - "darkgoldenrod", - "gray40", - "palegreen3", - "thistle3", - "khaki1", - "deeppink2", - "chocolate3", - "paleturquoise3", - "wheat1", - "lightsteelblue", - "salmon", - "sandybrown", - "darkolivegreen2", - "thistle2", - "gray85", - "orchid3", - "darkseagreen1", - "lightgoldenrod1", - "lightskyblue2", - "dodgerblue3", - "darkseagreen3", - "forestgreen", - "lightpink2", - "mediumpurple4", - "lightpink1", - "thistle", - "navajowhite", - "lemonchiffon", - "bisque2", - "mistyrose", - "gray95", - "lightcyan3", - "peachpuff2", - "lightsteelblue2", - "lightyellow2", - "moccasin", - "antiquewhite2", - "gray80", - "lightgrey" - ], - "defaultValue": "steelblue4", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "intersection_line_width", - "displayName": "Intersection Line Width", - "description": "Width of the lines in the intersection plot. Default: 0.5\n", - "paramType": "NUMBER", - "paramGroup": "Intersection Plot", - "paramValues": null, - "defaultValue": 0.7, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "intersection_point_size", - "displayName": "Intersection Point Size", - "description": "Size of the points in the intersection plot. Default: 2\n", - "paramType": "NUMBER", - "paramGroup": "Intersection Plot", - "paramValues": null, - "defaultValue": 2.2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "table_font_size", - "displayName": "Table Font Size", - "description": "Font size for the table in the plot. Default: 3\n", - "paramType": "NUMBER", - "paramGroup": "Table", - "paramValues": null, - "defaultValue": 0.7, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "table_content", - "displayName": "Table Content", - "description": "Content of the table in the plot. Default: NULL\n", - "paramType": "SELECT", - "paramGroup": "Table", - "paramValues": [ - "all intersections", - "returned intersections" - ], - "defaultValue": "all intersections", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "dpi", - "displayName": "Image Resolution", - "description": "dots-per-inch of the output image (see `ggsave()`) - only used if save_plots is TRUE\n", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": 300, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "image_height", - "displayName": "Image Height", - "description": "output image height in pixels - only used if save_plots is TRUE\n", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": 3000, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "image_width", - "displayName": "Image Width", - "description": "output image width in pixels - only used if save_plots is TRUE\n", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": 4000, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "Whether to save plots to files during analysis (Defaults to `TRUE`, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "DataFrame": { - "type": "file", - "name": "venn_diagram_dataframe.rds" - }, - "figures": { - "type": "file", - "name": "figures/diff/venn_diagram.png" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_volcano_enhanced.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_volcano_enhanced.json deleted file mode 100644 index b9acb91..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_volcano_enhanced.json +++ /dev/null @@ -1,329 +0,0 @@ -{ - "r_function": "plot_volcano_enhanced", - "title": "Plot Volcano - Enhanced\n", - "description": "Uses \nlist(list(\"https://bioconductor.org/packages/release/bioc/html/EnhancedVolcano.html\"), list(\"Bioconductor's Enhanced Volcano Plot\"))\n.\nAn S7 generic with methods for \nlist(\"multiOmicDataSet\")\n and \nlist(\"data.frame\")\n.\n", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Column with Feature ID", - "description": "The column from the counts data containing the Feature IDs (Usually Gene or Protein ID).\nThis is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts\nMatrix will be available to select for this parameter. (Default: `NULL` - first column in the counts matrix will be\nused.)\n", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "columnType": "STRING", - "isMulti": null - }, - { - "key": "signif_colname", - "displayName": "Significance Column", - "description": "column name of significance values (e.g., adjusted p-values or FDR). This column will be used\nto determine which points are considered significant in the volcano plot.\n", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "defaultValue": ["B-A_adjpval", "B-C_adjpval"], - "columnType": "NUMBER", - "isMulti": true - }, - { - "key": "change_colname", - "displayName": "Log2 Fold Change Column", - "description": "column name of fold change values.\n", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "defaultValue": ["B-A_logFC", "B-C_logFC"], - "columnType": "NUMBER", - "isMulti": true - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "Summary dataframe output Rds", - "description": "File path to the summary dataframe as an Rds file", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "enhanced_volcano_plot.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "signif_threshold", - "displayName": "P-Value Threshold", - "description": "Numeric value specifying the significance cutoff for p-values (i.e. filters on\n`signif_colname`)\n", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": 0.05, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "change_threshold", - "displayName": "Log2 Fold Change Threshold", - "description": "Numeric value specifying the fold change cutoff for significance (i.e. filters on\n`change_colname`)\n", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "value_to_sort_the_output_dataset", - "displayName": "How to sort the output dataset", - "description": "How to sort the output dataset. Options are \"fold-change\" or \"p-value\".\n", - "paramType": "SELECT", - "paramGroup": "Label", - "paramValues": [ - "p-value", - "fold-change" - ], - "defaultValue": "p-value", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "num_features_to_label", - "displayName": "Number of Features to Label", - "description": "Number of top features/genes to label in the volcano plot. Default is 30.\n", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": 30, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_only_addition_labels", - "displayName": "Label Only My Feature List", - "description": "If `TRUE`, only the additional labels specified in `additional_labels` will be used\nfor labeling in the volcano plot, ignoring the top features.\n", - "paramType": "BOOLEAN", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "additional_labels", - "displayName": "My Feature List", - "description": "comma-separated string of feature names or IDs to include in the volcano plot.\n", - "paramType": "STRING", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "lab_size", - "displayName": "Label Size", - "description": "Size of the labels in the volcano plot.\n", - "paramType": "NUMBER", - "paramGroup": "Label", - "paramValues": null, - "defaultValue": 4, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "change_sig_name", - "displayName": "Custom Significance Label", - "description": "Name for the significance column in the plot. Default is \"p-value\".\n", - "paramType": "STRING", - "paramGroup": "Title and Axis labels", - "paramValues": null, - "defaultValue": "p-value", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "change_lfc_name", - "displayName": "Custom Log Fold Change Label", - "description": "Name for the fold change column in the plot. Default is \"log2FC\".\n", - "paramType": "STRING", - "paramGroup": "Title and Axis labels", - "paramValues": null, - "defaultValue": "log2FC", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_custom_lab", - "displayName": "Use Custom Labels", - "description": "If TRUE, uses custom labels for the plot (set by `change_sig_name` and `change_lfc_name`)\n", - "paramType": "BOOLEAN", - "paramGroup": "Title and Axis Labels", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "title", - "displayName": "Plot Title", - "description": "Title of the plot. Default is \"Volcano Plots\".\n", - "paramType": "STRING", - "paramGroup": "Title and Axis labels", - "paramValues": null, - "defaultValue": "Volcano Plots", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "ylim", - "displayName": "Y-Limit", - "description": "Y-axis limits for the plot.\n", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": 0, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "custom_xlim", - "displayName": "Custom X-axis limits", - "description": "Custom X-axis limits for the plot.\n", - "paramType": "STRING", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "xlim_additional", - "displayName": "X-Limit Padding", - "description": "Additional space to add to the X-axis limits.\n", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": 0, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "ylim_additional", - "displayName": "Y-Limit Padding", - "description": "Additional space to add to the Y-axis limits.\n", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": 0, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "axis_lab_size", - "displayName": "Axis Label Size", - "description": "Size of the axis labels.\n", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": 24, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "point_size", - "displayName": "Point Size", - "description": "Size of the points in the plot.\n", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "image_width", - "displayName": "Image Width", - "description": "output image width in pixels - only used if save_plots is TRUE\n", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": 3000, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "image_height", - "displayName": "Image Height", - "description": "output image height in pixels - only used if save_plots is TRUE\n", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": 3000, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "dpi", - "displayName": "Image Resolution (DPI)", - "description": "dots-per-inch of the output image (see `ggsave()`) - only used if save_plots is TRUE\n", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": 300, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "Whether to save plots to files during analysis (Defaults to `TRUE`, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "DataFrame": { - "type": "file", - "name": "enhanced_volcano_dataframe.rds" - }, - "figures": { - "type": "file", - "name": "figures/diff/volcano_enhanced.png" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_volcano_summary.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_volcano_summary.json deleted file mode 100644 index 9e3cf80..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_volcano_summary.json +++ /dev/null @@ -1,5129 +0,0 @@ -{ - "r_function": "plot_volcano_summary", - "title": "Plot Volcano - Summary\n", - "description": "Produces one volcano plot for each tested contrast in the input DEG table.\nIt can be sorted by either fold change, t-statistic, or p-value. The returned dataset includes one row for each\nsignificant gene in each contrast, and contains columns from the DEG analysis of that contrast as well as columns\nuseful to the Venn diagram template downstream.\nAn S7 generic with methods for \nlist(\"multiOmicDataSet\")\n and \nlist(\"data.frame\")\n.\n", - "columns": [ - { - "key": "feature_id_colname", - "displayName": "Gene Names Column", - "description": "The column from the counts data containing the Feature IDs (Usually Gene or Protein ID).\nThis is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts\nMatrix will be available to select for this parameter. (Default: `NULL` - first column in the counts matrix will be\nused.)\n", - "paramGroup": "Basic", - "sourceDataset": "DEG_Table", - "columnType": "STRING", - "isMulti": null - } - ], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to read the input multiOmicDataSet object (MOO)", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "moo_output_rds", - "displayName": "Summary dataframe output Rds", - "description": "File path to output summary data as an Rds file", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "signif_colname", - "displayName": "Significance column name", - "description": "column name of significance values (e.g., adjusted p-values or FDR). This column will be used\nto determine which points are considered significant in the volcano plot.\n", - "paramType": "SELECT", - "paramGroup": "Basic", - "paramValues": [ - "pval", - "adjpval" - ], - "defaultValue": "pval", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "signif_threshold", - "displayName": "P-Value Threshold", - "description": "Numeric value specifying the significance cutoff for p-values (i.e. filters on\n`signif_colname`)\n", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": 0.05, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "change_threshold", - "displayName": "Log2 Fold Change Threshold", - "description": "Numeric value specifying the fold change cutoff for significance (i.e. filters on\n`change_colname`)\n", - "paramType": "NUMBER", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "value_to_sort_the_output_dataset", - "displayName": "Choose How to sort the output dataset", - "description": "How to sort the output dataset. Options are \"fold-change\" or \"p-value\".\n", - "paramType": "SELECT", - "paramGroup": "Gene Name Label", - "paramValues": [ - "fold-change", - "p-value", - "t-statistic" - ], - "defaultValue": "t-statistic", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "num_features_to_label", - "displayName": "Number of Genes to Label", - "description": "Number of top features/genes to label in the volcano plot. Default is 30.\n", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": 30, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "add_features", - "displayName": "Add Custom Features List To Labels", - "description": "Add custom_gene_list To Labels. Set TRUE when you want to label a specific set of features\n(features) in the \"custom_gene_list\" parameter\" IN ADDITION to the number of features you set in the \"Number of\nFeatures to Label\" parameter.\n", - "paramType": "BOOLEAN", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_features", - "displayName": "Label Only Custom Features List", - "description": "Select TRUE when you want to label ONLY a specific list of features(features) given in the\n\"custom_gene_list\" parameter.\n", - "paramType": "BOOLEAN", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "custom_gene_list", - "displayName": "Custom Feature/Gene List", - "description": "Provide a list of features (comma separated) to be labeled on the volcano plot. You must\ntoggle one of the following ON to see these labels: \"Add features\" or \"Label Only My Feature List\".\n", - "paramType": "STRING", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "default_label_color", - "displayName": "Default Feature Label Text Color", - "description": "Set the color for the text used to add feature (gene) name labels to points.\n", - "paramType": "SELECT", - "paramGroup": "Gene Name Label", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "black", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "custom_label_color", - "displayName": "Feature Label Text Color for custom features list", - "description": "Set the color for the specific list of features (features) provided in the \"Feature List\"\nparameter.\n", - "paramType": "SELECT", - "paramGroup": "Gene Name Label", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "green3", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_x_adj", - "displayName": "Label Position Adjustment (X-Axis)", - "description": "adjust position of the labels on the x-axis. Default: 0.2\n", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": 0.2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_y_adj", - "displayName": "Label Position Adjustment (Y-Axis)", - "description": "adjust position of the labels on the y-axis. Default: 0.2\n", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": 0.2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "line_thickness", - "displayName": "Line Segment Thickness", - "description": "Set the thickness of the lines in the plot. Default: 0.5\n", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": 0.5, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_font_size", - "displayName": "Label Font Size", - "description": "Set the font size of the labels. Default: 4\n", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": 4, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "label_font_type", - "displayName": "Label Font Type", - "description": "Set the font type of the labels. Default: 1\n", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "displace_feature_labels", - "displayName": "Displace Feature Labels", - "description": "Set to TRUE to displace gene labels. Default: FALSE. Set TRUE if you want to displace\nthe feature (gene) label for a specific set of features. Make sure to use custom x- and y- limits and give\nsufficient space for displacement; otherwise other labels than the desired ones will appear displaced.\n", - "paramType": "BOOLEAN", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "custom_gene_list_special_label_displacement", - "displayName": "Gene List Special Label Displacement", - "description": "Provide a list of features (comma separated) for which you want\nspecial displacement of the feature label.\n", - "paramType": "STRING", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": "", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "special_label_displacement_x_axis", - "displayName": "Special Label Displacement (X-Axis)", - "description": "Displacement of the feature label on the x-axis. Default: 2\n", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "special_label_displacement_y_axis", - "displayName": "Special Label Displacement (Y-Axis)", - "description": "Displacement of the feature label on the y-axis. Default: 2\n", - "paramType": "NUMBER", - "paramGroup": "Gene Name Label", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_of_signif_threshold_line", - "displayName": "Color of P-Value Threshold Line", - "description": "Color of the significance threshold line. Default: \"blue\"\n", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "blue", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_of_non_significant_features", - "displayName": "Color of Non-Significant Features", - "description": "Color of the non-significant features. Default: \"black\"\n", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "black", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_of_logfold_change_threshold_line", - "displayName": "Color of Log Fold Change Threshold Line", - "description": "Color of the log fold change threshold line. Default: \"red\"\n", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "red", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_of_features_meeting_only_signif_threshold", - "displayName": "Color of Features Meeting Only P-Value Threshold", - "description": "Color of the features that meet only the significance\nthreshold. Default: \"lightgoldenrod2\"\n", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "lightgoldenrod2", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "color_for_features_meeting_pvalue_and_foldchange_thresholds", - "displayName": "Color for features meeting p-value and fold-change thresholds", - "description": "Color of the features that meet both the p-value\nand fold change thresholds. Default: \"red\"\n", - "paramType": "SELECT", - "paramGroup": "Plot", - "paramValues": [ - "white", - "aliceblue", - "antiquewhite", - "antiquewhite1", - "antiquewhite2", - "antiquewhite3", - "antiquewhite4", - "aquamarine", - "aquamarine1", - "aquamarine2", - "aquamarine3", - "aquamarine4", - "azure", - "azure1", - "azure2", - "azure3", - "azure4", - "beige", - "bisque", - "bisque1", - "bisque2", - "bisque3", - "bisque4", - "black", - "blanchedalmond", - "blue", - "blue1", - "blue2", - "blue3", - "blue4", - "blueviolet", - "brown", - "brown1", - "brown2", - "brown3", - "brown4", - "burlywood", - "burlywood1", - "burlywood2", - "burlywood3", - "burlywood4", - "cadetblue", - "cadetblue1", - "cadetblue2", - "cadetblue3", - "cadetblue4", - "chartreuse", - "chartreuse1", - "chartreuse2", - "chartreuse3", - "chartreuse4", - "chocolate", - "chocolate1", - "chocolate2", - "chocolate3", - "chocolate4", - "coral", - "coral1", - "coral2", - "coral3", - "coral4", - "cornflowerblue", - "cornsilk", - "cornsilk1", - "cornsilk2", - "cornsilk3", - "cornsilk4", - "cyan", - "cyan1", - "cyan2", - "cyan3", - "cyan4", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgoldenrod1", - "darkgoldenrod2", - "darkgoldenrod3", - "darkgoldenrod4", - "darkgray", - "darkgreen", - "darkgrey", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkolivegreen1", - "darkolivegreen2", - "darkolivegreen3", - "darkolivegreen4", - "darkorange", - "darkorange1", - "darkorange2", - "darkorange3", - "darkorange4", - "darkorchid", - "darkorchid1", - "darkorchid2", - "darkorchid3", - "darkorchid4", - "darkred", - "darksalmon", - "darkseagreen", - "darkseagreen1", - "darkseagreen2", - "darkseagreen3", - "darkseagreen4", - "darkslateblue", - "darkslategray", - "darkslategray1", - "darkslategray2", - "darkslategray3", - "darkslategray4", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deeppink1", - "deeppink2", - "deeppink3", - "deeppink4", - "deepskyblue", - "deepskyblue1", - "deepskyblue2", - "deepskyblue3", - "deepskyblue4", - "dimgray", - "dimgrey", - "dodgerblue", - "dodgerblue1", - "dodgerblue2", - "dodgerblue3", - "dodgerblue4", - "firebrick", - "firebrick1", - "firebrick2", - "firebrick3", - "firebrick4", - "floralwhite", - "forestgreen", - "gainsboro", - "ghostwhite", - "gold", - "gold1", - "gold2", - "gold3", - "gold4", - "goldenrod", - "goldenrod1", - "goldenrod2", - "goldenrod3", - "goldenrod4", - "gray", - "gray0", - "gray1", - "gray2", - "gray3", - "gray4", - "gray5", - "gray6", - "gray7", - "gray8", - "gray9", - "gray10", - "gray11", - "gray12", - "gray13", - "gray14", - "gray15", - "gray16", - "gray17", - "gray18", - "gray19", - "gray20", - "gray21", - "gray22", - "gray23", - "gray24", - "gray25", - "gray26", - "gray27", - "gray28", - "gray29", - "gray30", - "gray31", - "gray32", - "gray33", - "gray34", - "gray35", - "gray36", - "gray37", - "gray38", - "gray39", - "gray40", - "gray41", - "gray42", - "gray43", - "gray44", - "gray45", - "gray46", - "gray47", - "gray48", - "gray49", - "gray50", - "gray51", - "gray52", - "gray53", - "gray54", - "gray55", - "gray56", - "gray57", - "gray58", - "gray59", - "gray60", - "gray61", - "gray62", - "gray63", - "gray64", - "gray65", - "gray66", - "gray67", - "gray68", - "gray69", - "gray70", - "gray71", - "gray72", - "gray73", - "gray74", - "gray75", - "gray76", - "gray77", - "gray78", - "gray79", - "gray80", - "gray81", - "gray82", - "gray83", - "gray84", - "gray85", - "gray86", - "gray87", - "gray88", - "gray89", - "gray90", - "gray91", - "gray92", - "gray93", - "gray94", - "gray95", - "gray96", - "gray97", - "gray98", - "gray99", - "gray100", - "green", - "green1", - "green2", - "green3", - "green4", - "greenyellow", - "grey", - "grey0", - "grey1", - "grey2", - "grey3", - "grey4", - "grey5", - "grey6", - "grey7", - "grey8", - "grey9", - "grey10", - "grey11", - "grey12", - "grey13", - "grey14", - "grey15", - "grey16", - "grey17", - "grey18", - "grey19", - "grey20", - "grey21", - "grey22", - "grey23", - "grey24", - "grey25", - "grey26", - "grey27", - "grey28", - "grey29", - "grey30", - "grey31", - "grey32", - "grey33", - "grey34", - "grey35", - "grey36", - "grey37", - "grey38", - "grey39", - "grey40", - "grey41", - "grey42", - "grey43", - "grey44", - "grey45", - "grey46", - "grey47", - "grey48", - "grey49", - "grey50", - "grey51", - "grey52", - "grey53", - "grey54", - "grey55", - "grey56", - "grey57", - "grey58", - "grey59", - "grey60", - "grey61", - "grey62", - "grey63", - "grey64", - "grey65", - "grey66", - "grey67", - "grey68", - "grey69", - "grey70", - "grey71", - "grey72", - "grey73", - "grey74", - "grey75", - "grey76", - "grey77", - "grey78", - "grey79", - "grey80", - "grey81", - "grey82", - "grey83", - "grey84", - "grey85", - "grey86", - "grey87", - "grey88", - "grey89", - "grey90", - "grey91", - "grey92", - "grey93", - "grey94", - "grey95", - "grey96", - "grey97", - "grey98", - "grey99", - "grey100", - "honeydew", - "honeydew1", - "honeydew2", - "honeydew3", - "honeydew4", - "hotpink", - "hotpink1", - "hotpink2", - "hotpink3", - "hotpink4", - "indianred", - "indianred1", - "indianred2", - "indianred3", - "indianred4", - "ivory", - "ivory1", - "ivory2", - "ivory3", - "ivory4", - "khaki", - "khaki1", - "khaki2", - "khaki3", - "khaki4", - "lavender", - "lavenderblush", - "lavenderblush1", - "lavenderblush2", - "lavenderblush3", - "lavenderblush4", - "lawngreen", - "lemonchiffon", - "lemonchiffon1", - "lemonchiffon2", - "lemonchiffon3", - "lemonchiffon4", - "lightblue", - "lightblue1", - "lightblue2", - "lightblue3", - "lightblue4", - "lightcoral", - "lightcyan", - "lightcyan1", - "lightcyan2", - "lightcyan3", - "lightcyan4", - "lightgoldenrod", - "lightgoldenrod1", - "lightgoldenrod2", - "lightgoldenrod3", - "lightgoldenrod4", - "lightgoldenrodyellow", - "lightgray", - "lightgreen", - "lightgrey", - "lightpink", - "lightpink1", - "lightpink2", - "lightpink3", - "lightpink4", - "lightsalmon", - "lightsalmon1", - "lightsalmon2", - "lightsalmon3", - "lightsalmon4", - "lightseagreen", - "lightskyblue", - "lightskyblue1", - "lightskyblue2", - "lightskyblue3", - "lightskyblue4", - "lightslateblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightsteelblue1", - "lightsteelblue2", - "lightsteelblue3", - "lightsteelblue4", - "lightyellow", - "lightyellow1", - "lightyellow2", - "lightyellow3", - "lightyellow4", - "limegreen", - "linen", - "magenta", - "magenta1", - "magenta2", - "magenta3", - "magenta4", - "maroon", - "maroon1", - "maroon2", - "maroon3", - "maroon4", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumorchid1", - "mediumorchid2", - "mediumorchid3", - "mediumorchid4", - "mediumpurple", - "mediumpurple1", - "mediumpurple2", - "mediumpurple3", - "mediumpurple4", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "mistyrose1", - "mistyrose2", - "mistyrose3", - "mistyrose4", - "moccasin", - "navajowhite", - "navajowhite1", - "navajowhite2", - "navajowhite3", - "navajowhite4", - "navy", - "navyblue", - "oldlace", - "olivedrab", - "olivedrab1", - "olivedrab2", - "olivedrab3", - "olivedrab4", - "orange", - "orange1", - "orange2", - "orange3", - "orange4", - "orangered", - "orangered1", - "orangered2", - "orangered3", - "orangered4", - "orchid", - "orchid1", - "orchid2", - "orchid3", - "orchid4", - "palegoldenrod", - "palegreen", - "palegreen1", - "palegreen2", - "palegreen3", - "palegreen4", - "paleturquoise", - "paleturquoise1", - "paleturquoise2", - "paleturquoise3", - "paleturquoise4", - "palevioletred", - "palevioletred1", - "palevioletred2", - "palevioletred3", - "palevioletred4", - "papayawhip", - "peachpuff", - "peachpuff1", - "peachpuff2", - "peachpuff3", - "peachpuff4", - "peru", - "pink", - "pink1", - "pink2", - "pink3", - "pink4", - "plum", - "plum1", - "plum2", - "plum3", - "plum4", - "powderblue", - "purple", - "purple1", - "purple2", - "purple3", - "purple4", - "red", - "red1", - "red2", - "red3", - "red4", - "rosybrown", - "rosybrown1", - "rosybrown2", - "rosybrown3", - "rosybrown4", - "royalblue", - "royalblue1", - "royalblue2", - "royalblue3", - "royalblue4", - "saddlebrown", - "salmon", - "salmon1", - "salmon2", - "salmon3", - "salmon4", - "sandybrown", - "seagreen", - "seagreen1", - "seagreen2", - "seagreen3", - "seagreen4", - "seashell", - "seashell1", - "seashell2", - "seashell3", - "seashell4", - "sienna", - "sienna1", - "sienna2", - "sienna3", - "sienna4", - "skyblue", - "skyblue1", - "skyblue2", - "skyblue3", - "skyblue4", - "slateblue", - "slateblue1", - "slateblue2", - "slateblue3", - "slateblue4", - "slategray", - "slategray1", - "slategray2", - "slategray3", - "slategray4", - "slategrey", - "snow", - "snow1", - "snow2", - "snow3", - "snow4", - "springgreen", - "springgreen1", - "springgreen2", - "springgreen3", - "springgreen4", - "steelblue", - "steelblue1", - "steelblue2", - "steelblue3", - "steelblue4", - "tan", - "tan1", - "tan2", - "tan3", - "tan4", - "thistle", - "thistle1", - "thistle2", - "thistle3", - "thistle4", - "tomato", - "tomato1", - "tomato2", - "tomato3", - "tomato4", - "turquoise", - "turquoise1", - "turquoise2", - "turquoise3", - "turquoise4", - "violet", - "violetred", - "violetred1", - "violetred2", - "violetred3", - "violetred4", - "wheat", - "wheat1", - "wheat2", - "wheat3", - "wheat4", - "whitesmoke", - "yellow", - "yellow1", - "yellow2", - "yellow3", - "yellow4", - "yellowgreen" - ], - "defaultValue": "red", - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "flip_vplot", - "displayName": "Flip Contrast", - "description": "Set to TRUE to flip the fold change values so that the volcano plot looks like a comparison was\nB-A. Default: FALSE\n", - "paramType": "BOOLEAN", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": false, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_default_x_axis_limit", - "displayName": "Use Default X-Axis Limit", - "description": "Set to TRUE to use the default x-axis limit. Default: TRUE\n", - "paramType": "BOOLEAN", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "x_axis_limit", - "displayName": "X-Axis Limit", - "description": "Custom x-axis limit. Default: c(-5, 5)\n", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": 5, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_default_y_axis_limit", - "displayName": "Use Default Y-Axis Limit", - "description": "Set to TRUE to use the default y-axis limit. Default: TRUE\n", - "paramType": "BOOLEAN", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "y_axis_limit", - "displayName": "Y-Axis Limit", - "description": "Custom y-axis limit. Default: c(0, 10)\n", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": 10, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "point_size", - "displayName": "Point Size", - "description": "Size of the points in the plot. Default: 1\n", - "paramType": "NUMBER", - "paramGroup": "Plot", - "paramValues": null, - "defaultValue": 2, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "add_deg_columns", - "displayName": "Add DEG Columns to Output Table", - "description": "Add additional columns from the DEG analysis to the\noutput dataset. Default: `\"FC\", \"logFC\", \"tstat\", \"pval\", \"adjpval\"`", - "paramType": "MULTISELECT", - "paramGroup": "Table", - "paramValues": [ - "FC", - "logFC", - "tstat", - "pval", - "adjpval" - ], - "defaultValue": ["FC", "logFC", "tstat", "pval", "adjpval"], - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "image_width", - "displayName": "Image Width", - "description": "output image width in pixels - only used if save_plots is TRUE\n", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": 15, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "image_height", - "displayName": "Image Height", - "description": "output image height in pixels - only used if save_plots is TRUE\n", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": 15, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "dpi", - "displayName": "Image Resolution", - "description": "dots-per-inch of the output image (see `ggsave()`) - only used if save_plots is TRUE\n", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": 300, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "use_default_grid_layout", - "displayName": "Use Default Grid Layout", - "description": "Set to TRUE to use the default grid layout. Default: TRUE\n", - "paramType": "BOOLEAN", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "number_of_rows_in_grid_layout", - "displayName": "Number of Rows in Grid Layout", - "description": "Number of rows in the grid layout. Default: 1\n", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": 1, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "aspect_ratio", - "displayName": "Figure Aspect Ratio", - "description": "Aspect ratio of the output image. Default: 4/3\n", - "paramType": "NUMBER", - "paramGroup": "Image", - "paramValues": null, - "defaultValue": 0, - "condition": null, - "content": null, - "objectPropertyReference": null - }, - { - "key": "save_plots", - "displayName": "Save Plots", - "description": "Whether to save plots to files during analysis (Defaults to `TRUE`, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')\n", - "paramType": "BOOLEAN", - "paramGroup": "Visualization", - "paramValues": null, - "defaultValue": true, - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "DataFrame": { - "type": "file", - "name": "summary_dataframe.rds" - }, - "figures": { - "type": "file", - "name": "figures/diff/volcano_summary.png" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/2_blueprints/write_multiOmicDataSet_properties.json b/code/MOSuite/inst/extdata/galaxy/2_blueprints/write_multiOmicDataSet_properties.json deleted file mode 100644 index 3dd9a5f..0000000 --- a/code/MOSuite/inst/extdata/galaxy/2_blueprints/write_multiOmicDataSet_properties.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "r_function": "write_multiOmicDataSet_properties", - "title": "Write multiOmicDataSet Properties\n", - "description": "Writes the properties of a multiOmicDataSet object to disk as separate files in output_dir.\nProperties that are data frames are saved as CSV files, while all other objects are saved as RDS files.\n", - "columns": [], - "inputDatasets": [ - { - "key": "moo_input_rds", - "displayName": "MOO input Rds", - "description": "File path to the input multiOmicDataSet (MOO) RDS file.", - "paramType": "STRING", - "paramGroup": "basic", - "paramValues": null, - "defaultValue": "moo.rds", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "parameters": [ - { - "key": "output_dir", - "displayName": "Output Directory", - "description": "Directory where the properties will be saved (default: \"moo\")\n", - "paramType": "STRING", - "paramGroup": "Basic", - "paramValues": null, - "defaultValue": "moo", - "condition": null, - "content": null, - "objectPropertyReference": null - } - ], - "outputs": { - "sample_metadata": { - "type": "file", - "name": "sample_metadata.csv" - }, - "feature_annotation": { - "type": "file", - "name": "feature_annotation.csv" - }, - "counts": { - "type": "directory", - "name": "counts/" - }, - "analyses": { - "type": "directory", - "name": "analyses/" - } - } -} diff --git a/code/MOSuite/inst/extdata/galaxy/galaxy.R b/code/MOSuite/inst/extdata/galaxy/galaxy.R deleted file mode 100644 index 33df8ce..0000000 --- a/code/MOSuite/inst/extdata/galaxy/galaxy.R +++ /dev/null @@ -1,261 +0,0 @@ -library(dplyr) - -#' @keywords internal -#' @examples -#' -#' get_function_meta("batch_correct_counts", tools::Rd_db("MOSuite")) -#' -get_function_meta <- function(func_name, rd_db) { - func_db <- rd_db[[paste0(func_name, ".Rd")]] - - title <- tools:::.Rd_get_metadata(func_db, "title") |> trimws() - desc <- paste( - tools:::.Rd_get_metadata(func_db, "description"), - tools:::.Rd_get_metadata(func_db, "details"), - sep = "\n\n" - ) |> - trimws() - arg_desc <- dplyr::as_tibble( - tools:::.Rd_get_argument_table(func_db), - .name_repair = "unique_quiet" - ) - colnames(arg_desc) <- c("arg", "desc") - arg_docs <- arg_desc |> - dplyr::pull("desc") |> - trimws() |> - as.list() - names(arg_docs) <- arg_desc |> dplyr::pull("arg") - options( - moo_print_plots = TRUE, - moo_save_plots = TRUE, - moo_plots_dir = "./figures", - print_plots = TRUE, # need if this function is defined outside the package's R source directory - save_plots = TRUE, - plots_dir = "./figures" - ) - arg_defaults <- lapply( - formals(func_name, envir = getNamespace("MOSuite")), - \(x) { - if (inherits(x, "name")) { - default <- NULL - } else if (inherits(x, "call")) { - default <- eval(x, envir = getNamespace("MOSuite")) - } else { - default <- x - } - return(default) - } - ) - if ("..." %in% names(arg_defaults)) { - arg_defaults <- arg_defaults |> - within(rm("...")) # remove `...` argument - } - args_meta <- names(arg_defaults) |> - lapply(\(arg) { - return(list( - defaultValue = arg_defaults[[arg]], - description = arg_docs[[arg]] - )) - }) - names(args_meta) <- names(arg_defaults) - - return(list( - r_function = func_name, - title = title, - description = desc, - args = args_meta - )) -} - -#' @keywords internal -get_function_args <- function(func_meta) { - func_names <- Filter( - \(x) !stringr::str_starts(x, "moo"), - names(func_meta$args) - ) - func_args <- lapply(func_names, \(x) func_meta$args[[x]][["defaultValue"]]) - - if (stringr::str_starts(names(func_meta$args)[1], "moo")) { - func_names <- c("moo_input_rds", "moo_output_rds", func_names) - func_args <- c("moo.rds", "moo.rds", func_args) - } - names(func_args) <- func_names - - return(func_args) -} - -#' @keywords internal -#' @examples -#' -#' update_function_template( -#' system.file("extdata", "galaxy", "template-templates", "create_multiOmicDataSet_from_files.json", -#' package = "MOSuite" -#' ), -#' tools::Rd_db("MOSuite") -#' ) -#' -update_function_template <- function( - template, - func_meta, - keep_deprecated_args = TRUE -) { - if (!rlang::is_installed("Rd2md")) { - stop("Required pacakge {Rd2md} is not installed") - } - - safe_rd_to_md <- function(x) { - if (is.null(x) || length(x) == 0) { - return("") - } - x_chr <- as.character(x) - if (length(x_chr) == 0 || all(is.na(x_chr))) { - return("") - } - return(tryCatch( - Rd2md::rd_str_to_md(x_chr), - error = function(e) { - paste(x_chr, collapse = "\n") - } - )) - } - - new_template <- list( - r_function = template$r_function, - title = safe_rd_to_md(template$title), - description = safe_rd_to_md(func_meta$description), - columns = list(), - inputDatasets = list(), - parameters = list(), - outputs = template$outputs - ) - args_in_template <- c() - template_args_missing <- c() - for (arg_type in c("columns", "inputDatasets", "parameters")) { - for (i in seq_along(template[[arg_type]])) { - arg_name <- template[[arg_type]][[i]]$key - if (arg_name %in% names(func_meta$args)) { - arg_meta <- template[[arg_type]][[i]] - arg_meta$description <- safe_rd_to_md(func_meta$args[[arg_name]]$description) - arg_meta$defaultValue <- func_meta$args[[arg_name]]$defaultValue - args_in_template <- c(args_in_template, arg_name) - new_template[[arg_type]][[ - length(new_template[[arg_type]]) + 1 - ]] <- arg_meta - } else { - template_args_missing <- c(template_args_missing, arg_name) - if (isTRUE(keep_deprecated_args)) { - arg_meta <- template[[arg_type]][[i]] - new_template[[arg_type]][[ - length(new_template[[arg_type]]) + 1 - ]] <- arg_meta - } - } - } - } - if (length(template_args_missing) > 0) { - message(glue::glue( - "{template$r_function}: ", - "Argument(s) from template not found in R function doc: ", - "{paste(template_args_missing, collapse = ', ')}" - )) - } - - func_args_missing <- setdiff(names(func_meta$args), args_in_template) - if (length(func_args_missing) > 0) { - message( - glue::glue( - "{template$r_function}: ", - "Argument(s) from R function doc not found in template: ", - "{paste(func_args_missing, collapse = ', ')}" - ) - ) - } - return(new_template) -} - -#' @keywords internal -check_classes <- function(updated_template) { - for (p in updated_template$parameters) { - for (el in p) { - message(paste(p["key"], class(el))) - } - } - return() -} - -#' `jsonlite::write_json()` with preferred defaults -#' -#' @keywords internal -write_json <- function( - x, - filepath, - auto_unbox = TRUE, - pretty = TRUE, - null = "null", - na = "null", - ... -) { - return(invisible(jsonlite::write_json( - x, - filepath, - auto_unbox = auto_unbox, - pretty = pretty, - null = null, - na = na, - ... - ))) -} - -#' @keywords internal -write_package_json_blueprints <- - function( - input_dir = file.path("inst", "extdata", "galaxy", "1_mosuite-templates"), - blueprints_output_dir = file.path( - "inst", - "extdata", - "galaxy", - "2_blueprints" - ), - defaults_output_dir = file.path("inst", "extdata", "json_args", "defaults") - ) { - options( - moo_print_plots = TRUE, - moo_save_plots = TRUE, - moo_plots_dir = "./figures", - print_plots = TRUE, # need if this function is defined outside the package's R source directory - save_plots = TRUE, - plots_dir = "./figures" - ) - templates <- list.files( - input_dir, - pattern = ".*\\.json$", - full.names = TRUE - ) - rd_db <- tools::Rd_db("MOSuite") - for (f in templates) { - base_filename <- basename(f) - message(glue::glue("* Processing {base_filename}")) - - template <- jsonlite::read_json(f) - r_function <- template$r_function - func_meta <- get_function_meta(r_function, rd_db) - - # write default arguments - func_args <- get_function_args(func_meta) - write_json( - func_args, - file.path(defaults_output_dir, glue::glue("{r_function}.json")) - ) - - # write galaxy blueprint template - updated_template <- update_function_template( - template, - func_meta - ) - write_json( - updated_template, - file.path(blueprints_output_dir, glue::glue("{r_function}.json")) - ) - } - return(invisible()) - } diff --git a/code/MOSuite/inst/extdata/json_args/common/batch_correct_counts.json b/code/MOSuite/inst/extdata/json_args/common/batch_correct_counts.json deleted file mode 100644 index c128597..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/batch_correct_counts.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "moo_input_rds": "moo_norm.rds", - "moo_output_rds": "moo_batch.rds", - "count_type": "norm", - "sub_count_type": "voom", - "sample_id_colname": null, - "feature_id_colname": null, - "samples_to_include": null, - "covariates_colnames": "Group", - "batch_colname": "Batch", - "label_colname": "Label", - "colors_for_plots": null, - "print_plots": true, - "save_plots": true, - "plots_subdir": "batch" -} diff --git a/code/MOSuite/inst/extdata/json_args/common/clean_raw_counts.json b/code/MOSuite/inst/extdata/json_args/common/clean_raw_counts.json deleted file mode 100644 index e11a4fb..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/clean_raw_counts.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "moo_input_rds": "moo_create.rds", - "moo_output_rds": "moo_clean.rds", - "count_type": "raw", - "sample_id_colname": null, - "feature_id_colname": null, - "samples_to_rename": "", - "cleanup_column_names": true, - "split_gene_name": true, - "aggregate_rows_with_duplicate_gene_names": true, - "gene_name_column_to_use_for_collapsing_duplicates": "", - "print_plots": true, - "save_plots": true -} diff --git a/code/MOSuite/inst/extdata/json_args/common/create_multiOmicDataSet_from_files.json b/code/MOSuite/inst/extdata/json_args/common/create_multiOmicDataSet_from_files.json deleted file mode 100644 index 7fc474a..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/create_multiOmicDataSet_from_files.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "feature_counts_filepath": "Raw_Counts.csv.gz", - "sample_meta_filepath": "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", - "moo_output_rds": "moo_create.rds" -} diff --git a/code/MOSuite/inst/extdata/json_args/common/diff_counts.json b/code/MOSuite/inst/extdata/json_args/common/diff_counts.json deleted file mode 100644 index 700bf35..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/diff_counts.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "moo_input_rds": "moo_batch.rds", - "moo_output_rds": "moo_diff.rds", - "count_type": "filt", - "sub_count_type": null, - "sample_id_colname": null, - "feature_id_colname": null, - "samples_to_include": null, - "covariates_colnames": [ - "Group", - "Batch" - ], - "contrast_colname": "Group", - "contrasts": [ - "B-A", - "C-A", - "B-C" - ], - "input_in_log_counts": false, - "return_mean_and_sd": true, - "voom_normalization_method": "quantile", - "print_plots": true, - "save_plots": true, - "plots_subdir": "diff" -} diff --git a/code/MOSuite/inst/extdata/json_args/common/filter_counts.json b/code/MOSuite/inst/extdata/json_args/common/filter_counts.json deleted file mode 100644 index 0e71be4..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/filter_counts.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "moo_input_rds": "moo_clean.rds", - "moo_output_rds": "moo_filter.rds", - "count_type": "clean", - "feature_id_colname": null, - "sample_id_colname": null, - "group_colname": "Group", - "label_colname": null, - "use_cpm_counts_to_filter": true, - "minimum_count_value_to_be_considered_nonzero": 8.0, - "minimum_number_of_samples_with_nonzero_counts_in_total": 7.0, - "use_group_based_filtering": false, - "minimum_number_of_samples_with_nonzero_counts_in_a_group": 3.0, - "principal_component_on_x_axis": 1.0, - "principal_component_on_y_axis": 2.0, - "legend_position_for_pca": "top", - "point_size_for_pca": 1.0, - "add_label_to_pca": true, - "label_font_size": 3.0, - "label_offset_x_": 2.0, - "label_offset_y_": 2.0, - "samples_to_rename": null, - "color_histogram_by_group": false, - "set_min_max_for_x_axis_for_histogram": false, - "minimum_for_x_axis_for_histogram": -1.0, - "maximum_for_x_axis_for_histogram": 1.0, - "legend_font_size_for_histogram": 10.0, - "legend_position_for_histogram": "top", - "number_of_histogram_legend_columns": 6.0, - "colors_for_plots": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "interactive_plots": false, - "save_plots": true, - "plot_corr_matrix_heatmap": true, - "samples_to_include": null -} diff --git a/code/MOSuite/inst/extdata/json_args/common/filter_diff.json b/code/MOSuite/inst/extdata/json_args/common/filter_diff.json deleted file mode 100644 index bc41bd7..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/filter_diff.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "moo_input_rds": "moo_diff.rds", - "moo_output_rds": "moo_diff_filter.rds", - "feature_id_colname": null, - "significance_column": "adjpval", - "significance_cutoff": 0.05, - "change_column": "logFC", - "change_cutoff": 1, - "filtering_mode": "any", - "include_estimates": [ - "FC", - "logFC", - "tstat", - "pval", - "adjpval" - ], - "round_estimates": true, - "rounding_decimal_for_percent_cells": 0, - "contrast_filter": "none", - "contrasts": null, - "groups": null, - "groups_filter": "none", - "label_font_size": 6, - "label_distance": 1, - "y_axis_expansion": 0.08, - "fill_colors": [ - "steelblue1", - "whitesmoke" - ], - "pie_chart_in_3d": true, - "bar_width": 0.4, - "draw_bar_border": true, - "plot_type": "bar", - "plot_titles_fontsize": 12, - "print_plots": true, - "save_plots": true, - "plots_subdir": "diff/filt" -} diff --git a/code/MOSuite/inst/extdata/json_args/common/normalize_counts.json b/code/MOSuite/inst/extdata/json_args/common/normalize_counts.json deleted file mode 100644 index a5acdb5..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/normalize_counts.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "moo_input_rds": "moo_filter.rds", - "moo_output_rds": "moo_norm.rds", - "count_type": "filt", - "norm_type": "voom", - "feature_id_colname": null, - "samples_to_include": null, - "sample_id_colname": null, - "group_colname": "Group", - "label_colname": null, - "input_in_log_counts": false, - "voom_normalization_method": "quantile", - "samples_to_rename": "", - "add_label_to_pca": true, - "principal_component_on_x_axis": 1, - "principal_component_on_y_axis": 2, - "legend_position_for_pca": "top", - "label_offset_x_": 2, - "label_offset_y_": 2, - "label_font_size": 3, - "point_size_for_pca": 8, - "color_histogram_by_group": true, - "set_min_max_for_x_axis_for_histogram": false, - "minimum_for_x_axis_for_histogram": -1, - "maximum_for_x_axis_for_histogram": 1, - "legend_font_size_for_histogram": 10, - "legend_position_for_histogram": "top", - "colors_for_plots": null, - "print_plots": true, - "save_plots": true, - "interactive_plots": false, - "plots_subdir": "norm" -} diff --git a/code/MOSuite/inst/extdata/json_args/common/plot_expr_heatmap.json b/code/MOSuite/inst/extdata/json_args/common/plot_expr_heatmap.json deleted file mode 100644 index b1dc1f3..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/plot_expr_heatmap.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "moo_input_rds": "moo_norm.rds", - "count_type": "norm", - "sub_count_type": "voom", - "sample_metadata": null, - "sample_id_colname": null, - "feature_id_colname": null, - "group_colname": "Group", - "label_colname": null, - "samples_to_include": null, - "color_values": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "include_all_genes": false, - "filter_top_genes_by_variance": true, - "top_genes_by_variance_to_include": 500, - "specific_genes_to_include_in_heatmap": "None", - "cluster_genes": true, - "gene_distance_metric": "correlation", - "gene_clustering_method": "average", - "display_gene_dendrograms": true, - "display_gene_names": false, - "center_and_rescale_expression": true, - "cluster_samples": false, - "arrange_sample_columns": true, - "order_by_gene_expression": false, - "gene_to_order_columns": " ", - "gene_expression_order": "low_to_high", - "smpl_distance_metric": "correlation", - "smpl_clustering_method": "average", - "display_smpl_dendrograms": true, - "reorder_dendrogram": false, - "reorder_dendrogram_order": null, - "display_sample_names": true, - "group_columns": [ - "Group", - "Replicate", - "Batch" - ], - "assign_group_colors": false, - "assign_color_to_sample_groups": null, - "group_colors": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "heatmap_color_scheme": "Default", - "autoscale_heatmap_color": true, - "set_min_heatmap_color": -2, - "set_max_heatmap_color": 2, - "aspect_ratio": "Auto", - "legend_font_size": 10, - "gene_name_font_size": 4, - "sample_name_font_size": 8, - "display_numbers": false, - "plot_filename": "expr_heatmap.png", - "print_plots": true, - "save_plots": true, - "plots_subdir": "heatmap" -} diff --git a/code/MOSuite/inst/extdata/json_args/common/plot_pca_2d.json b/code/MOSuite/inst/extdata/json_args/common/plot_pca_2d.json deleted file mode 100644 index ab25827..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/plot_pca_2d.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "moo_input_rds": "moo_norm.rds", - "sample_metadata": null, - "feature_id_colname": null, - "sample_id_colname": null, - "samples_to_rename": null, - "group_colname": "Group", - "label_colname": "Label", - "principal_components": [ - 1, - 2 - ], - "point_size": 1, - "add_label": true, - "label_font_size": 3, - "legend_position": "top", - "color_values": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "interactive_plots": false, - "plot_filename": "pca_2D.png", - "print_plots": true, - "save_plots": true, - "plots_subdir": "pca" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/json_args/common/plot_pca_3d.json b/code/MOSuite/inst/extdata/json_args/common/plot_pca_3d.json deleted file mode 100644 index 308d197..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/plot_pca_3d.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "moo_input_rds": "moo_norm.rds", - "sample_metadata": null, - "feature_id_colname": null, - "sample_id_colname": null, - "samples_to_rename": null, - "group_colname": "Group", - "label_colname": "Label", - "principal_components": [1, 2, 3], - "point_size": 8, - "label_font_size": 24, - "color_values": [ - "#5954d6", - "#e1562c", - "#b80058", - "#00c6f8", - "#d163e6", - "#00a76c", - "#ff9287", - "#008cf9", - "#006e00", - "#796880", - "#FFA500", - "#878500" - ], - "plot_title": "PCA 3D", - "plot_filename": "pca_3D.html", - "print_plots": true, - "save_plots": true, - "plots_subdir": "pca" -} diff --git a/code/MOSuite/inst/extdata/json_args/common/plot_venn_diagram.json b/code/MOSuite/inst/extdata/json_args/common/plot_venn_diagram.json deleted file mode 100644 index 2c3b334..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/plot_venn_diagram.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "moo_input_rds": "volcano_summary_dat.rds", - "moo_output_rds": "venn_diagram_dat.rds", - "feature_id_colname": null, - "contrasts_colname": "Contrast", - "select_contrasts": null, - "plot_type": "Venn diagram", - "intersection_ids": null, - "venn_force_unique": true, - "venn_numbers_format": "raw", - "venn_significant_digits": 2, - "venn_fill_colors": [ - "darkgoldenrod2", - "darkolivegreen2", - "mediumpurple3", - "darkorange2", - "lightgreen" - ], - "venn_fill_transparency": 0.2, - "venn_border_colors": "fill colors", - "venn_font_size_for_category_names": 3, - "venn_category_names_distance": null, - "venn_category_names_position": null, - "venn_font_size_for_counts": 6, - "venn_outer_margin": 0, - "intersections_order": "degree", - "display_empty_intersections": false, - "intersection_bar_color": "steelblue4", - "intersection_point_size": 2.2, - "intersection_line_width": 0.7, - "table_font_size": 0.7, - "table_content": "all intersections", - "dpi": 300, - "image_width": 4000, - "image_height": 3000, - "plot_filename": "venn_diagram.png", - "print_plots": true, - "save_plots": true, - "plots_subdir": "diff" -} diff --git a/code/MOSuite/inst/extdata/json_args/common/plot_volcano_enhanced.json b/code/MOSuite/inst/extdata/json_args/common/plot_volcano_enhanced.json deleted file mode 100644 index 960d6be..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/plot_volcano_enhanced.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "moo_input_rds": "moo_diff_filter.rds", - "moo_output_rds": "volcano_enhanced_dat.rds", - "feature_id_colname": null, - "signif_colname": ["B-A_adjpval", "B-C_adjpval"], - "signif_threshold": 0.05, - "change_colname": ["B-A_logFC", "B-C_logFC"], - "change_threshold": 1, - "value_to_sort_the_output_dataset": "p-value", - "num_features_to_label": 30, - "use_only_addition_labels": false, - "additional_labels": "", - "is_red": true, - "lab_size": 4, - "change_sig_name": "p-value", - "change_lfc_name": "log2FC", - "title": "Volcano Plots", - "use_custom_lab": false, - "ylim": 0, - "custom_xlim": "", - "xlim_additional": 0, - "ylim_additional": 0, - "axis_lab_size": 24, - "point_size": 2, - "image_width": 3000, - "image_height": 3000, - "dpi": 300, - "interactive_plots": false, - "print_plots": true, - "save_plots": true, - "plots_subdir": "diff", - "plot_filename": "volcano_enhanced.png" -} diff --git a/code/MOSuite/inst/extdata/json_args/common/plot_volcano_summary.json b/code/MOSuite/inst/extdata/json_args/common/plot_volcano_summary.json deleted file mode 100644 index ee16ff7..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/plot_volcano_summary.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "moo_input_rds": "moo_diff_filter.rds", - "moo_output_rds": "volcano_summary_dat.rds", - "feature_id_colname": null, - "signif_colname": "pval", - "signif_threshold": 0.05, - "change_threshold": 1, - "value_to_sort_the_output_dataset": "t-statistic", - "num_features_to_label": 30, - "add_features": false, - "label_features": false, - "custom_gene_list": "", - "default_label_color": "black", - "custom_label_color": "green3", - "label_x_adj": 0.2, - "label_y_adj": 0.2, - "line_thickness": 0.5, - "label_font_size": 4, - "label_font_type": 1, - "displace_feature_labels": false, - "custom_gene_list_special_label_displacement": "", - "special_label_displacement_x_axis": 2, - "special_label_displacement_y_axis": 2, - "color_of_signif_threshold_line": "blue", - "color_of_non_significant_features": "black", - "color_of_logfold_change_threshold_line": "red", - "color_of_features_meeting_only_signif_threshold": "lightgoldenrod2", - "color_for_features_meeting_pvalue_and_foldchange_thresholds": "red", - "flip_vplot": false, - "use_default_x_axis_limit": true, - "x_axis_limit": 5, - "use_default_y_axis_limit": true, - "y_axis_limit": 10, - "point_size": 2, - "add_deg_columns": [ - "FC", - "logFC", - "tstat", - "pval", - "adjpval" - ], - "image_width": 15, - "image_height": 15, - "dpi": 300, - "use_default_grid_layout": true, - "number_of_rows_in_grid_layout": 1, - "aspect_ratio": 0, - "plot_filename": "volcano_summary.png", - "print_plots": true, - "save_plots": true, - "plots_subdir": "diff" -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/json_args/common/write_multiOmicDataSet_properties.json b/code/MOSuite/inst/extdata/json_args/common/write_multiOmicDataSet_properties.json deleted file mode 100644 index 61b1d34..0000000 --- a/code/MOSuite/inst/extdata/json_args/common/write_multiOmicDataSet_properties.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "moo_input_rds": "moo_diff_filter.rds", - "output_dir": { - "defaultValue": "moo" - } -} \ No newline at end of file diff --git a/code/MOSuite/inst/extdata/json_args/defaults/batch_correct_counts.json b/code/MOSuite/inst/extdata/json_args/defaults/batch_correct_counts.json deleted file mode 100644 index fe8d42e..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/batch_correct_counts.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "count_type": "norm", - "sub_count_type": "voom", - "sample_id_colname": null, - "feature_id_colname": null, - "samples_to_include": null, - "covariates_colnames": "Group", - "batch_colname": "Batch", - "label_colname": null, - "colors_for_plots": null, - "print_plots": true, - "save_plots": true, - "plots_subdir": "batch" -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/clean_raw_counts.json b/code/MOSuite/inst/extdata/json_args/defaults/clean_raw_counts.json deleted file mode 100644 index 43c5568..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/clean_raw_counts.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "count_type": "raw", - "sample_id_colname": null, - "feature_id_colname": null, - "samples_to_rename": "", - "cleanup_column_names": true, - "split_gene_name": true, - "aggregate_rows_with_duplicate_gene_names": true, - "gene_name_column_to_use_for_collapsing_duplicates": "", - "print_plots": true, - "save_plots": true, - "plots_subdir": "clean" -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/create_multiOmicDataSet_from_files.json b/code/MOSuite/inst/extdata/json_args/defaults/create_multiOmicDataSet_from_files.json deleted file mode 100644 index 02c0e00..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/create_multiOmicDataSet_from_files.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "sample_meta_filepath": null, - "feature_counts_filepath": null, - "count_type": "raw", - "sample_id_colname": null, - "feature_id_colname": null, - "delim": null -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/diff_counts.json b/code/MOSuite/inst/extdata/json_args/defaults/diff_counts.json deleted file mode 100644 index bc0c531..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/diff_counts.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "count_type": "filt", - "sub_count_type": null, - "sample_id_colname": null, - "feature_id_colname": null, - "samples_to_include": null, - "covariates_colnames": null, - "contrast_colname": null, - "contrasts": null, - "input_in_log_counts": false, - "return_mean_and_sd": false, - "voom_normalization_method": "quantile", - "print_plots": true, - "save_plots": true, - "plots_subdir": "diff" -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/filter_counts.json b/code/MOSuite/inst/extdata/json_args/defaults/filter_counts.json deleted file mode 100644 index 1e6feff..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/filter_counts.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "count_type": "clean", - "feature_id_colname": null, - "sample_id_colname": null, - "group_colname": "Group", - "label_colname": null, - "samples_to_include": null, - "minimum_count_value_to_be_considered_nonzero": 8, - "minimum_number_of_samples_with_nonzero_counts_in_total": 7, - "minimum_number_of_samples_with_nonzero_counts_in_a_group": 3, - "use_cpm_counts_to_filter": true, - "use_group_based_filtering": false, - "principal_component_on_x_axis": 1, - "principal_component_on_y_axis": 2, - "legend_position_for_pca": "top", - "point_size_for_pca": 1, - "add_label_to_pca": true, - "label_font_size": 3, - "label_offset_y_": 2, - "label_offset_x_": 2, - "samples_to_rename": "", - "color_histogram_by_group": false, - "set_min_max_for_x_axis_for_histogram": false, - "minimum_for_x_axis_for_histogram": -1, - "maximum_for_x_axis_for_histogram": 1, - "legend_position_for_histogram": "top", - "legend_font_size_for_histogram": 10, - "number_of_histogram_legend_columns": 6, - "colors_for_plots": null, - "plot_corr_matrix_heatmap": true, - "print_plots": true, - "save_plots": true, - "interactive_plots": false, - "plots_subdir": "filt" -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/filter_diff.json b/code/MOSuite/inst/extdata/json_args/defaults/filter_diff.json deleted file mode 100644 index d255743..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/filter_diff.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "feature_id_colname": null, - "significance_column": "adjpval", - "significance_cutoff": 0.05, - "change_column": "logFC", - "change_cutoff": 1, - "filtering_mode": "any", - "include_estimates": ["FC", "logFC", "tstat", "pval", "adjpval"], - "round_estimates": true, - "rounding_decimal_for_percent_cells": 0, - "contrast_filter": "none", - "contrasts": null, - "groups": null, - "groups_filter": "none", - "label_font_size": 6, - "label_distance": 1, - "y_axis_expansion": 0.08, - "fill_colors": ["steelblue1", "whitesmoke"], - "pie_chart_in_3d": true, - "bar_width": 0.4, - "draw_bar_border": true, - "plot_type": "bar", - "plot_titles_fontsize": 12, - "print_plots": true, - "save_plots": true, - "plots_subdir": "diff/filt" -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/normalize_counts.json b/code/MOSuite/inst/extdata/json_args/defaults/normalize_counts.json deleted file mode 100644 index 50c0e32..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/normalize_counts.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "count_type": "filt", - "norm_type": "voom", - "feature_id_colname": null, - "samples_to_include": null, - "sample_id_colname": null, - "group_colname": "Group", - "label_colname": null, - "input_in_log_counts": false, - "voom_normalization_method": "quantile", - "samples_to_rename": "", - "add_label_to_pca": true, - "principal_component_on_x_axis": 1, - "principal_component_on_y_axis": 2, - "legend_position_for_pca": "top", - "label_offset_x_": 2, - "label_offset_y_": 2, - "label_font_size": 3, - "point_size_for_pca": 8, - "color_histogram_by_group": true, - "set_min_max_for_x_axis_for_histogram": false, - "minimum_for_x_axis_for_histogram": -1, - "maximum_for_x_axis_for_histogram": 1, - "legend_font_size_for_histogram": 10, - "legend_position_for_histogram": "top", - "number_of_histogram_legend_columns": 6, - "plot_corr_matrix_heatmap": true, - "colors_for_plots": null, - "print_plots": true, - "save_plots": true, - "interactive_plots": false, - "plots_subdir": "norm" -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/plot_expr_heatmap.json b/code/MOSuite/inst/extdata/json_args/defaults/plot_expr_heatmap.json deleted file mode 100644 index c421963..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/plot_expr_heatmap.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "count_type": null, - "sub_count_type": null, - "sample_metadata": null, - "sample_id_colname": null, - "feature_id_colname": null, - "group_colname": "Group", - "label_colname": null, - "samples_to_include": null, - "color_values": ["#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"], - "include_all_genes": false, - "filter_top_genes_by_variance": true, - "top_genes_by_variance_to_include": 500, - "specific_genes_to_include_in_heatmap": "None", - "cluster_genes": true, - "gene_distance_metric": "correlation", - "gene_clustering_method": "average", - "display_gene_dendrograms": true, - "display_gene_names": false, - "center_and_rescale_expression": true, - "cluster_samples": false, - "arrange_sample_columns": true, - "order_by_gene_expression": false, - "gene_to_order_columns": " ", - "gene_expression_order": "low_to_high", - "smpl_distance_metric": "correlation", - "smpl_clustering_method": "average", - "display_smpl_dendrograms": true, - "reorder_dendrogram": false, - "reorder_dendrogram_order": null, - "display_sample_names": true, - "group_columns": ["Group", "Replicate", "Batch"], - "assign_group_colors": false, - "assign_color_to_sample_groups": null, - "group_colors": ["#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"], - "heatmap_color_scheme": "Default", - "autoscale_heatmap_color": true, - "set_min_heatmap_color": -2, - "set_max_heatmap_color": 2, - "aspect_ratio": "Auto", - "legend_font_size": 10, - "gene_name_font_size": 4, - "sample_name_font_size": 8, - "display_numbers": false, - "plot_filename": "expr_heatmap.png", - "print_plots": true, - "save_plots": true, - "plots_subdir": "heatmap" -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/plot_pca_2d.json b/code/MOSuite/inst/extdata/json_args/defaults/plot_pca_2d.json deleted file mode 100644 index edada7f..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/plot_pca_2d.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "count_type": null, - "sub_count_type": null, - "sample_metadata": null, - "sample_id_colname": null, - "feature_id_colname": null, - "group_colname": "Group", - "label_colname": "Label", - "samples_to_rename": null, - "color_values": ["#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"], - "principal_components": [1, 2], - "legend_position": "top", - "point_size": 1, - "add_label": true, - "label_font_size": 3, - "label_offset_x_": 2, - "label_offset_y_": 2, - "interactive_plots": false, - "plots_subdir": "pca", - "plot_filename": "pca_2D.png", - "print_plots": true, - "save_plots": true -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/plot_pca_3d.json b/code/MOSuite/inst/extdata/json_args/defaults/plot_pca_3d.json deleted file mode 100644 index d8e342b..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/plot_pca_3d.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "count_type": null, - "sub_count_type": null, - "sample_metadata": null, - "feature_id_colname": null, - "sample_id_colname": null, - "samples_to_rename": null, - "group_colname": "Group", - "label_colname": "Label", - "principal_components": [1, 2, 3], - "point_size": 8, - "label_font_size": 24, - "color_values": ["#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"], - "plot_title": "PCA 3D", - "plot_filename": "pca_3D.html", - "print_plots": true, - "save_plots": true, - "plots_subdir": "pca" -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/plot_venn_diagram.json b/code/MOSuite/inst/extdata/json_args/defaults/plot_venn_diagram.json deleted file mode 100644 index 10e4fb8..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/plot_venn_diagram.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "feature_id_colname": null, - "contrasts_colname": "Contrast", - "select_contrasts": null, - "plot_type": "Venn diagram", - "intersection_ids": null, - "venn_force_unique": true, - "venn_numbers_format": "raw", - "venn_significant_digits": 2, - "venn_fill_colors": ["darkgoldenrod2", "darkolivegreen2", "mediumpurple3", "darkorange2", "lightgreen"], - "venn_fill_transparency": 0.2, - "venn_border_colors": "fill colors", - "venn_font_size_for_category_names": 3, - "venn_category_names_distance": null, - "venn_category_names_position": null, - "venn_font_size_for_counts": 6, - "venn_outer_margin": 0, - "intersections_order": "degree", - "display_empty_intersections": false, - "intersection_bar_color": "steelblue4", - "intersection_point_size": 2.2, - "intersection_line_width": 0.7, - "table_font_size": 0.7, - "table_content": "all intersections", - "graphics_device": ["function (filename = \"Rplot%03d.png\", width = 480, height = 480, ", " units = \"px\", pointsize = 12, bg = \"white\", res = NA, ..., ", " type = c(\"cairo\", \"cairo-png\", \"Xlib\", \"quartz\"), antialias) ", "{", " if (!is.character(filename) || length(filename) != 1L || ", " !nzchar(filename)) ", " stop(\"'filename' must be a non-empty character string\")", " if (!checkIntFormat(filename)) ", " stop(\"invalid 'filename'\")", " g <- .geometry(width, height, units, res)", " new <- list(...)", " if (missing(type)) ", " type <- getOption(\"bitmapType\")", " type <- match.arg(type)", " if (!missing(antialias)) ", " new$antialias <- match.arg(antialias, aa.cairo)", " d <- check.options(new, name.opt = \".X11.Options\", envir = .X11env)", " antialias <- match(d$antialias, aa.cairo)", " if (type == \"quartz\") {", " if (capabilities(\"aqua\")) {", " width <- g$width/ifelse(is.na(res), 72, res)", " height <- g$height/ifelse(is.na(res), 72, res)", " invisible(.External(C_Quartz, \"png\", path.expand(filename), ", " width, height, pointsize, d$family, d$antialias != ", " \"none\", \"\", bg, \"white\", if (is.na(res)) NULL else res))", " }", " else warning(\"type = \\\"quartz\\\" is unavailable. trying \\\"Xlib\\\"\")", " }", " else if (type == \"cairo\") {", " if (capabilities(\"cairo\")) {", " invisible(.External(C_devCairo, filename, 2L, g$width, ", " g$height, pointsize, bg, res, antialias, 100L, ", " d$family, 300, optionSymbolFont(d$symbolfamily)))", " }", " else warning(\"type = \\\"cairo\\\" is unavailable. trying \\\"Xlib\\\"\")", " }", " else if (type == \"cairo-png\") {", " if (capabilities(\"cairo\")) {", " invisible(.External(C_devCairo, filename, 5L, g$width, ", " g$height, pointsize, bg, res, antialias, 100L, ", " d$family, 300, optionSymbolFont(d$symbolfamily)))", " }", " else warning(\"type = \\\"cairo-png\\\" is unavailable. trying \\\"Xlib\\\"\")", " }", " else invisible(.External2(C_X11, paste0(\"png::\", filename), ", " g$width, g$height, pointsize, d$gamma, d$colortype, d$maxcubesize, ", " bg, bg, d$fonts, res, 0L, 0L, \"\", 0, 0, d$family, optionSymbolFont(d$symbolfamily)))", "}"], - "dpi": 300, - "image_width": 4000, - "image_height": 3000, - "plot_filename": "venn_diagram.png", - "print_plots": true, - "save_plots": true, - "plots_subdir": "diff" -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/plot_volcano_enhanced.json b/code/MOSuite/inst/extdata/json_args/defaults/plot_volcano_enhanced.json deleted file mode 100644 index 6185918..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/plot_volcano_enhanced.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "feature_id_colname": null, - "signif_colname": ["B-A_adjpval", "B-C_adjpval"], - "signif_threshold": 0.05, - "change_colname": ["B-A_logFC", "B-C_logFC"], - "change_threshold": 1, - "value_to_sort_the_output_dataset": "p-value", - "num_features_to_label": 30, - "use_only_addition_labels": false, - "additional_labels": "", - "is_red": true, - "lab_size": 4, - "change_sig_name": "p-value", - "change_lfc_name": "log2FC", - "title": "Volcano Plots", - "use_custom_lab": false, - "ylim": 0, - "custom_xlim": "", - "xlim_additional": 0, - "ylim_additional": 0, - "axis_lab_size": 24, - "point_size": 2, - "image_width": 3000, - "image_height": 3000, - "dpi": 300, - "interactive_plots": false, - "print_plots": true, - "save_plots": true, - "plots_subdir": "diff", - "plot_filename": "volcano_enhanced.png" -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/plot_volcano_summary.json b/code/MOSuite/inst/extdata/json_args/defaults/plot_volcano_summary.json deleted file mode 100644 index a7cf8ea..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/plot_volcano_summary.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "feature_id_colname": null, - "signif_colname": "pval", - "signif_threshold": 0.05, - "change_threshold": 1, - "value_to_sort_the_output_dataset": "t-statistic", - "num_features_to_label": 30, - "add_features": false, - "label_features": false, - "custom_gene_list": "", - "default_label_color": "black", - "custom_label_color": "green3", - "label_x_adj": 0.2, - "label_y_adj": 0.2, - "line_thickness": 0.5, - "label_font_size": 4, - "label_font_type": 1, - "displace_feature_labels": false, - "custom_gene_list_special_label_displacement": "", - "special_label_displacement_x_axis": 2, - "special_label_displacement_y_axis": 2, - "color_of_signif_threshold_line": "blue", - "color_of_non_significant_features": "black", - "color_of_logfold_change_threshold_line": "red", - "color_of_features_meeting_only_signif_threshold": "lightgoldenrod2", - "color_for_features_meeting_pvalue_and_foldchange_thresholds": "red", - "flip_vplot": false, - "use_default_x_axis_limit": true, - "x_axis_limit": 5, - "use_default_y_axis_limit": true, - "y_axis_limit": 10, - "point_size": 2, - "add_deg_columns": ["FC", "logFC", "tstat", "pval", "adjpval"], - "graphics_device": ["function (filename = \"Rplot%03d.png\", width = 480, height = 480, ", " units = \"px\", pointsize = 12, bg = \"white\", res = NA, ..., ", " type = c(\"cairo\", \"cairo-png\", \"Xlib\", \"quartz\"), antialias) ", "{", " if (!is.character(filename) || length(filename) != 1L || ", " !nzchar(filename)) ", " stop(\"'filename' must be a non-empty character string\")", " if (!checkIntFormat(filename)) ", " stop(\"invalid 'filename'\")", " g <- .geometry(width, height, units, res)", " new <- list(...)", " if (missing(type)) ", " type <- getOption(\"bitmapType\")", " type <- match.arg(type)", " if (!missing(antialias)) ", " new$antialias <- match.arg(antialias, aa.cairo)", " d <- check.options(new, name.opt = \".X11.Options\", envir = .X11env)", " antialias <- match(d$antialias, aa.cairo)", " if (type == \"quartz\") {", " if (capabilities(\"aqua\")) {", " width <- g$width/ifelse(is.na(res), 72, res)", " height <- g$height/ifelse(is.na(res), 72, res)", " invisible(.External(C_Quartz, \"png\", path.expand(filename), ", " width, height, pointsize, d$family, d$antialias != ", " \"none\", \"\", bg, \"white\", if (is.na(res)) NULL else res))", " }", " else warning(\"type = \\\"quartz\\\" is unavailable. trying \\\"Xlib\\\"\")", " }", " else if (type == \"cairo\") {", " if (capabilities(\"cairo\")) {", " invisible(.External(C_devCairo, filename, 2L, g$width, ", " g$height, pointsize, bg, res, antialias, 100L, ", " d$family, 300, optionSymbolFont(d$symbolfamily)))", " }", " else warning(\"type = \\\"cairo\\\" is unavailable. trying \\\"Xlib\\\"\")", " }", " else if (type == \"cairo-png\") {", " if (capabilities(\"cairo\")) {", " invisible(.External(C_devCairo, filename, 5L, g$width, ", " g$height, pointsize, bg, res, antialias, 100L, ", " d$family, 300, optionSymbolFont(d$symbolfamily)))", " }", " else warning(\"type = \\\"cairo-png\\\" is unavailable. trying \\\"Xlib\\\"\")", " }", " else invisible(.External2(C_X11, paste0(\"png::\", filename), ", " g$width, g$height, pointsize, d$gamma, d$colortype, d$maxcubesize, ", " bg, bg, d$fonts, res, 0L, 0L, \"\", 0, 0, d$family, optionSymbolFont(d$symbolfamily)))", "}"], - "image_width": 15, - "image_height": 15, - "dpi": 300, - "use_default_grid_layout": true, - "number_of_rows_in_grid_layout": 1, - "aspect_ratio": 0, - "plot_filename": "volcano_summary.png", - "print_plots": true, - "save_plots": true, - "plots_subdir": "diff" -} diff --git a/code/MOSuite/inst/extdata/json_args/defaults/write_multiOmicDataSet_properties.json b/code/MOSuite/inst/extdata/json_args/defaults/write_multiOmicDataSet_properties.json deleted file mode 100644 index 123f832..0000000 --- a/code/MOSuite/inst/extdata/json_args/defaults/write_multiOmicDataSet_properties.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "moo_input_rds": "moo.rds", - "moo_output_rds": "moo.rds", - "output_dir": "moo" -} diff --git a/code/MOSuite/inst/quarto/report.qmd b/code/MOSuite/inst/quarto/report.qmd new file mode 100644 index 0000000..d5090ee --- /dev/null +++ b/code/MOSuite/inst/quarto/report.qmd @@ -0,0 +1,165 @@ +--- +title: "MOSuite analysis report" +date: today +format: html +params: + counts_csv: 'inst/extdata/nidap/Raw_Counts.csv.gz' + samplesheet_csv: 'inst/extdata/nidap/Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz' + group_colname: 'Group' + batch_colname: 'Batch' + label_colname: 'Label' + contrasts: + - B-A + - C-A + - B-C + print_plots: true +engine: knitr +--- + +```{r deps} +library(MOSuite) +library(dplyr) +library(knitr) +options(moo_print_plots = params$print_plots) +``` + +## Load data + +```{r initialize} +# create multi-omic object +counts_csv <- params$counts_csv +if (is.null(counts_csv) || !nzchar(counts_csv) || !file.exists(counts_csv)) { + counts_csv <- system.file( + "extdata", + "nidap", + "Raw_Counts.csv.gz", + package = "MOSuite" + ) +} + +samplesheet_csv <- params$samplesheet_csv +if ( + is.null(samplesheet_csv) || + !nzchar(samplesheet_csv) || + !file.exists(samplesheet_csv) +) { + samplesheet_csv <- system.file( + "extdata", + "nidap", + "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", + package = "MOSuite" + ) +} + +moo <- create_multiOmicDataSet_from_files( + sample_meta_filepath = samplesheet_csv, + feature_counts_filepath = counts_csv +) + +group_colname <- params$group_colname +batch_colname <- params$batch_colname +label_colname <- params$label_colname +contrasts_vctr <- params$contrasts +knitr::kable( + data.frame( + Parameter = names(params), + Value = sapply(params, paste, collapse = ", ") + ), + caption = "Parameter values" +) + +knitr::kable( + readr::read_csv(samplesheet_csv, n_max = 10), + caption = "Sample sheet (first 10 rows)" +) + +knitr::kable( + readr::read_csv(counts_csv, n_max = 10), + caption = "Counts data (first 10 rows)" +) +``` + +## Processing + +```{r analyze} +moo <- moo |> + clean_raw_counts() |> + filter_counts(group_colname = group_colname) |> + normalize_counts(group_colname = group_colname) |> + batch_correct_counts( + covariates_colname = group_colname, + batch_colname = batch_colname, + label_colname = label_colname + ) |> + diff_counts( + count_type = "filt", + covariates_colnames = c(group_colname, batch_colname), + contrast_colname = c(group_colname), + contrasts = contrasts_vctr, + input_in_log_counts = FALSE, + return_mean_and_sd = FALSE, + voom_normalization_method = "quantile", + ) |> + filter_diff() + +moo@analyses$diff |> + join_dfs_wide() |> + head() |> + kable() + +moo@analyses$diff_filt |> head() |> kable() +``` + +## Visualization + +### 3D PCA + +```{r pca_3D} +plot_pca( + moo@counts$batch, + moo@sample_meta, + principal_components = c(1, 2, 3), + group_colname = group_colname, + label_colname = label_colname, + color_values = moo@analyses[["colors"]][[group_colname]] +) +``` + +### Expression Heatmap + +```{r expr_heatmap} +heatmap_plot <- plot_expr_heatmap( + moo, + count_type = "norm", + sub_count_type = "voom" +) +print(heatmap_plot) +``` + +### Volcano + +#### Summary + +```{r volcano_summary} +dat_volcano_summary <- moo@analyses$diff |> + join_dfs_wide() |> + plot_volcano_summary() + +head(dat_volcano_summary) +``` + +#### Enhanced + +```{r volcano_enhanced} +dat_volcano_enhanced <- moo@analyses$diff |> + join_dfs_wide() |> + plot_volcano_enhanced() +``` + + +### Venn Diagram + +```{r venn_diagram} +venn_dat <- dat_volcano_summary |> plot_venn_diagram() +head(venn_dat) +``` diff --git a/code/MOSuite/man/batch_correct_counts.Rd b/code/MOSuite/man/batch_correct_counts.Rd index 9be8aa8..67a22c6 100644 --- a/code/MOSuite/man/batch_correct_counts.Rd +++ b/code/MOSuite/man/batch_correct_counts.Rd @@ -13,10 +13,28 @@ batch_correct_counts( samples_to_include = NULL, covariates_colnames = "Group", batch_colname = "Batch", - label_colname = NULL, + label_colname = "Label", + samples_to_rename = c(""), + add_label_to_pca = TRUE, + principal_component_on_x_axis = 1, + principal_component_on_y_axis = 2, + legend_position_for_pca = "top", + label_offset_x_ = 2, + label_offset_y_ = 2, + label_font_size = 3, + point_size_for_pca = 5, + color_histogram_by_group = TRUE, + set_min_max_for_x_axis_for_histogram = FALSE, + minimum_for_x_axis_for_histogram = -1, + maximum_for_x_axis_for_histogram = 1, + legend_font_size_for_histogram = NULL, + legend_position_for_histogram = "top", + number_of_histogram_legend_columns = 6, + plot_corr_matrix_heatmap = TRUE, colors_for_plots = NULL, print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), + interactive_plots = FALSE, plots_subdir = "batch" ) } @@ -54,18 +72,73 @@ If your data set has no batches, you can provide a batch column with the same value in every row to skip batch correction (alternatively, simply do not run this function).} \item{label_colname}{The column from the sample metadata containing the sample labels as you wish them to appear in -the plots produced by this template. This can be the same Sample Names Column. However, you may desire different -labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the -column with your preferred Labels here. The selected column should contain unique names for each sample. (Default: -\code{NULL} -- \code{sample_id_colname} will be used.)} +heatmap and PCA figures. This can be the same Sample Names Column. However, you may desire different labels to +display on your figures (e.g. shorter labels are sometimes preferred on plots). In that case, select the column with +your preferred Labels here. The selected column should contain unique names for each sample. Use \code{add_label_to_pca} +to control whether these labels are displayed on the PCA plot.} -\item{colors_for_plots}{Colors for the PCA and histogram will be picked, in order, from this list. -Colors must either be names in \code{grDevices::colors()} or valid hex codes.} +\item{samples_to_rename}{If you do not have a Plot Labels Column in your sample metadata table, you can use this +parameter to rename samples manually for display on the PCA plot. Use "Add item" to add each additional sample for +renaming. Use the following format to describe which old name (in your sample metadata table) you want to rename to +which new name: old_name: new_name} + +\item{add_label_to_pca}{If \code{TRUE}, display labels from \code{label_colname} on PCA points. If \code{FALSE}, the PCA plot uses +unlabeled points while heatmap labels still use \code{label_colname}.} + +\item{principal_component_on_x_axis}{The principal component to plot on the x-axis for the PCA plot. Choices include +1, 2, 3, ... (default: 1)} + +\item{principal_component_on_y_axis}{The principal component to plot on the y-axis for the PCA plot. Choices include +1, 2, 3, ... (default: 2)} + +\item{legend_position_for_pca}{legend position for the PCA plot} + +\item{label_offset_x_}{label offset x for the PCA plot} + +\item{label_offset_y_}{label offset y for the PCA plot} + +\item{label_font_size}{label font size for the PCA plot} + +\item{point_size_for_pca}{geom point size for the PCA plot} + +\item{color_histogram_by_group}{Set to FALSE to label histogram by Sample Names, or set to TRUE to label histogram by +the column you select in the "Group Column Used to Color Histogram" parameter (below). Default is TRUE.} + +\item{set_min_max_for_x_axis_for_histogram}{whether to set min/max value for histogram x-axis} + +\item{minimum_for_x_axis_for_histogram}{x-axis minimum for histogram plot} + +\item{maximum_for_x_axis_for_histogram}{x-axis maximum for histogram plot} + +\item{legend_font_size_for_histogram}{legend font size for the histogram plot. +If \code{NULL}, the size is scaled automatically.} + +\item{legend_position_for_histogram}{legend position for the histogram plot. consider setting to 'none' for a large +number of samples.} + +\item{number_of_histogram_legend_columns}{number of columns for the histogram legend} + +\item{plot_corr_matrix_heatmap}{Datasets with a large number of samples may be too large to create a correlation +matrix heatmap. If this function takes longer than 5 minutes to run, Set to \code{FALSE} and the correlation matrix will +not be be created. Default is \code{TRUE}.} + +\item{colors_for_plots}{Optional colors for PCA/histogram/heatmap plots. If \code{NULL}, colors are taken from +\code{moo@analyses$colors[[group_colname]]}. +Colors must either be names in \code{grDevices::colors()} or valid hex codes. +Unnamed colors are assigned by factor level order when the grouping column is a factor; +otherwise, they follow the order in which groups first appear in the metadata column. If more groups are present +than colors provided, +supplied colors are used first and additional colors are generated from the selected palette for the remaining +groups; random colors are used only if that palette returns fewer colors than the number of groups.} \item{print_plots}{Whether to print plots during analysis (Defaults to \code{FALSE}, overwritable using option 'moo_print_plots' or environment variable 'MOO_PRINT_PLOTS')} \item{save_plots}{Whether to save plots to files during analysis (Defaults to \code{TRUE}, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')} +\item{interactive_plots}{set to TRUE to make PCA and Histogram plots interactive with \code{plotly}, allowing you to hover +your mouse over a point or line to view sample information. The similarity heat map will not display if this toggle +is set to \code{TRUE}. Default is \code{FALSE}.} + \item{plots_subdir}{subdirectory in \verb{figures/} where plots will be saved if \code{save_plots} is \code{TRUE}} } \value{ diff --git a/code/MOSuite/man/clean_raw_counts.Rd b/code/MOSuite/man/clean_raw_counts.Rd index f4f580d..2d48ded 100644 --- a/code/MOSuite/man/clean_raw_counts.Rd +++ b/code/MOSuite/man/clean_raw_counts.Rd @@ -10,6 +10,8 @@ clean_raw_counts( sample_id_colname = NULL, feature_id_colname = NULL, samples_to_rename = "", + group_colname = "", + colors_for_plots = NULL, cleanup_column_names = TRUE, split_gene_name = TRUE, aggregate_rows_with_duplicate_gene_names = TRUE, @@ -38,6 +40,14 @@ parameter to rename samples manually for display on the PCA plot. Use "Add item" renaming. Use the following format to describe which old name (in your sample metadata table) you want to rename to which new name: old_name: new_name} +\item{group_colname}{sample metadata column used to color the read-depth plot. Leave blank to use the current +single-color bar fill.} + +\item{colors_for_plots}{optional colors used when \code{group_colname} is supplied. If \code{NULL}, colors are taken from +\code{moo@analyses$colors[[group_colname]]}. +Named vectors are matched to group values; +unnamed vectors follow group order and are extended with MOSuite colors when too few colors are supplied.} + \item{cleanup_column_names}{Invalid raw counts column names can cause errors in the downstream analysis. If this is \code{TRUE}, any invalid column names will be automatically altered to a correct format. These format changes diff --git a/code/MOSuite/man/diff_counts.Rd b/code/MOSuite/man/diff_counts.Rd index bf72697..e1a48c4 100644 --- a/code/MOSuite/man/diff_counts.Rd +++ b/code/MOSuite/man/diff_counts.Rd @@ -65,7 +65,7 @@ contrast(s)} \item{plots_subdir}{subdirectory in \verb{figures/} where plots will be saved if \code{save_plots} is \code{TRUE}} } \value{ -\code{multiOmicDataSet} with \code{diff} added to the \code{analyses} slot (i.e. \code{moo@analyses$diff}) +\code{multiOmicDataSet} with \code{diff} added to the \code{analyses} slot (i.e. \code{moo@analyses[["diff"]]}) } \description{ Differential expression analysis diff --git a/code/MOSuite/man/display_colors.Rd b/code/MOSuite/man/display_colors.Rd new file mode 100644 index 0000000..0512f5a --- /dev/null +++ b/code/MOSuite/man/display_colors.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/colors.R +\name{display_colors} +\alias{display_colors} +\title{Display colors for a multiOmicDataSet object} +\usage{ +display_colors(moo) +} +\arguments{ +\item{moo}{A \code{multiOmicDataSet} object (see +\code{\link[=create_multiOmicDataSet_from_dataframes]{create_multiOmicDataSet_from_dataframes()}}).} +} +\value{ +A \link[patchwork:wrap_plots]{patchwork} of \link[ggplot2:ggplot]{ggplot2::ggplot} objects, +one per group column in \code{moo@analyses$colors}. +} +\description{ +Plots a palette strip for each group column stored in \code{moo@analyses$colors}, +stacked vertically. Each strip shows the assigned hex colors and their codes. +} +\examples{ +moo <- create_multiOmicDataSet_from_dataframes(nidap_sample_metadata, nidap_raw_counts) +display_colors(moo) +} diff --git a/code/MOSuite/man/display_palette.Rd b/code/MOSuite/man/display_palette.Rd new file mode 100644 index 0000000..dbc63a4 --- /dev/null +++ b/code/MOSuite/man/display_palette.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/colors.R +\name{display_palette} +\alias{display_palette} +\title{Display the mosuite color palette} +\usage{ +display_palette(palette = mosuite_palette) +} +\arguments{ +\item{palette}{Character vector of hex color codes. Defaults to +\code{mosuite_palette}.} +} +\value{ +Invisibly returns the underlying \link[ggplot2:ggplot]{ggplot2::ggplot} object. +} +\description{ +Plots each color in \code{mosuite_palette} as a labeled tile with its hex code +displayed below. The plot is rendered at a width proportional to the number +of colors so labels remain horizontal and legible. +} +\examples{ +display_palette() +display_palette(c("#FF0000", "#00FF00", "#0000FF")) +} diff --git a/code/MOSuite/man/filter_counts.Rd b/code/MOSuite/man/filter_counts.Rd index 984545b..ce1e67d 100644 --- a/code/MOSuite/man/filter_counts.Rd +++ b/code/MOSuite/man/filter_counts.Rd @@ -10,7 +10,7 @@ filter_counts( feature_id_colname = NULL, sample_id_colname = NULL, group_colname = "Group", - label_colname = NULL, + label_colname = "Label", samples_to_include = NULL, minimum_count_value_to_be_considered_nonzero = 8, minimum_number_of_samples_with_nonzero_counts_in_total = 7, @@ -20,18 +20,18 @@ filter_counts( principal_component_on_x_axis = 1, principal_component_on_y_axis = 2, legend_position_for_pca = "top", - point_size_for_pca = 1, + point_size_for_pca = 5, add_label_to_pca = TRUE, label_font_size = 3, label_offset_y_ = 2, label_offset_x_ = 2, samples_to_rename = c(""), - color_histogram_by_group = FALSE, + color_histogram_by_group = TRUE, set_min_max_for_x_axis_for_histogram = FALSE, minimum_for_x_axis_for_histogram = -1, maximum_for_x_axis_for_histogram = 1, legend_position_for_histogram = "top", - legend_font_size_for_histogram = 10, + legend_font_size_for_histogram = NULL, number_of_histogram_legend_columns = 6, colors_for_plots = NULL, plot_corr_matrix_heatmap = TRUE, @@ -60,21 +60,24 @@ column showing to which experimental treatments each sample belongs (e.g. WildTy Before, After, etc.).} \item{label_colname}{The column from the sample metadata containing the sample labels as you wish them to appear in -the plots produced by this template. This can be the same Sample Names Column. However, you may desire different -labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the -column with your preferred Labels here. The selected column should contain unique names for each sample. (Default: -\code{NULL} -- \code{sample_id_colname} will be used.)} +heatmap and PCA figures. This can be the same Sample Names Column. However, you may desire different labels to +display on your figures (e.g. shorter labels are sometimes preferred on plots). In that case, select the column with +your preferred Labels here. The selected column should contain unique names for each sample. Use \code{add_label_to_pca} +to control whether these labels are displayed on the PCA plot.} \item{samples_to_include}{Which samples would you like to include? Usually, you will choose all sample columns, or you could choose to remove certain samples. Samples excluded here will be removed in this step and from further analysis downstream of this step. (Default: \code{NULL} - all sample IDs in \code{moo@sample_meta} will be used.)} -\item{minimum_count_value_to_be_considered_nonzero}{Minimum count value to be considered non-zero for a sample} +\item{minimum_count_value_to_be_considered_nonzero}{Minimum value in the selected filtering table required for a +sample to be considered nonzero. If \code{use_cpm_counts_to_filter} is \code{TRUE}, this threshold is applied to CPM values. +If \code{use_cpm_counts_to_filter} is \code{FALSE}, this threshold is applied directly to the selected \code{count_type} table.} -\item{minimum_number_of_samples_with_nonzero_counts_in_total}{Minimum number of samples (total) with non-zero counts} +\item{minimum_number_of_samples_with_nonzero_counts_in_total}{Minimum number of samples in total that must meet the +\code{minimum_count_value_to_be_considered_nonzero} threshold for a feature to be kept.} \item{minimum_number_of_samples_with_nonzero_counts_in_a_group}{Only keeps genes that have at least this number of -samples with nonzero CPM counts in at least one group} +samples meeting the threshold in at least one group} \item{use_cpm_counts_to_filter}{If no transformation has been been performed on counts matrix (eg Raw Counts) set to TRUE. If TRUE counts will be transformed to CPM and filtered based on given criteria. If gene counts matrix has @@ -83,7 +86,7 @@ transformation will be applied and features will be filtered as is. For RNAseq d transformed to CPM in order to properly filter.} \item{use_group_based_filtering}{If TRUE, only keeps features (e.g. genes) that have at least a certain number of -samples with nonzero CPM counts in at least one group} +samples passing the threshold in at least one group} \item{principal_component_on_x_axis}{The principal component to plot on the x-axis for the PCA plot. Choices include 1, 2, 3, ... (default: 1)} @@ -95,7 +98,8 @@ samples with nonzero CPM counts in at least one group} \item{point_size_for_pca}{geom point size for the PCA plot} -\item{add_label_to_pca}{label points on the PCA plot} +\item{add_label_to_pca}{If \code{TRUE}, display labels from \code{label_colname} on PCA points. If \code{FALSE}, the PCA plot uses +unlabeled points while heatmap labels still use \code{label_colname}.} \item{label_font_size}{label font size for the PCA plot} @@ -109,7 +113,7 @@ renaming. Use the following format to describe which old name (in your sample me which new name: old_name: new_name} \item{color_histogram_by_group}{Set to FALSE to label histogram by Sample Names, or set to TRUE to label histogram by -the column you select in the "Group Column Used to Color Histogram" parameter (below). Default is FALSE.} +the column you select in the "Group Column Used to Color Histogram" parameter (below). Default is TRUE.} \item{set_min_max_for_x_axis_for_histogram}{whether to set min/max value for histogram x-axis} @@ -120,12 +124,19 @@ the column you select in the "Group Column Used to Color Histogram" parameter (b \item{legend_position_for_histogram}{legend position for the histogram plot. consider setting to 'none' for a large number of samples.} -\item{legend_font_size_for_histogram}{legend font size for the histogram plot} +\item{legend_font_size_for_histogram}{legend font size for the histogram plot. +If \code{NULL}, the size is scaled automatically.} \item{number_of_histogram_legend_columns}{number of columns for the histogram legend} -\item{colors_for_plots}{Colors for the PCA and histogram will be picked, in order, from this list. -Colors must either be names in \code{grDevices::colors()} or valid hex codes.} +\item{colors_for_plots}{Optional colors for PCA/histogram/heatmap plots. If \code{NULL}, colors are taken from +\code{moo@analyses$colors[[group_colname]]}. +Colors must either be names in \code{grDevices::colors()} or valid hex codes. +Unnamed colors are assigned by factor level order when the grouping column is a factor; +otherwise, they follow the order in which groups first appear in the metadata column. If more groups are present +than colors provided, +supplied colors are used first and additional colors are generated from the selected palette for the remaining +groups; random colors are used only if that palette returns fewer colors than the number of groups.} \item{plot_corr_matrix_heatmap}{Datasets with a large number of samples may be too large to create a correlation matrix heatmap. If this function takes longer than 5 minutes to run, Set to \code{FALSE} and the correlation matrix will diff --git a/code/MOSuite/man/get_colors_lst.Rd b/code/MOSuite/man/get_colors_lst.Rd index fbe22fa..7cb6fed 100644 --- a/code/MOSuite/man/get_colors_lst.Rd +++ b/code/MOSuite/man/get_colors_lst.Rd @@ -4,26 +4,23 @@ \alias{get_colors_lst} \title{Create named list of default colors for plotting} \usage{ -get_colors_lst(sample_metadata, palette_fun = grDevices::palette.colors, ...) +get_colors_lst(sample_metadata, palette = mosuite_palette) } \arguments{ \item{sample_metadata}{sample metadata as a data frame or tibble. The first column is assumed to contain the sample IDs which must correspond to column names in the raw counts.} -\item{palette_fun}{Function for selecting colors. Assumed to contain \code{n} for the number of colors. Default: -\code{grDevices::palette.colors()}} - -\item{...}{additional arguments forwarded to \code{palette_fun}} +\item{palette}{Character vector of colors to assign. Defaults to +\code{mosuite_palette}.} } \value{ -named list, with each column in \code{sample_metadata} containing entry with a named vector of colors +named list, with each column in \code{sample_metadata} containing a corresponding entry with a named vector of +colors } \description{ Create named list of default colors for plotting } \examples{ get_colors_lst(nidap_sample_metadata) -\dontrun{ -get_colors_lst(nidap_sample_metadata, palette_fun = RColorBrewer::brewer.pal, name = "Set3") -} +get_colors_lst(nidap_sample_metadata, palette = RColorBrewer::brewer.pal(12, "Set3")) } diff --git a/code/MOSuite/man/get_colors_vctr.Rd b/code/MOSuite/man/get_colors_vctr.Rd index adef32e..0155194 100644 --- a/code/MOSuite/man/get_colors_vctr.Rd +++ b/code/MOSuite/man/get_colors_vctr.Rd @@ -4,21 +4,31 @@ \alias{get_colors_vctr} \title{Get vector of colors for observations in one column of a data frame} \usage{ -get_colors_vctr(dat, colname, palette_fun = grDevices::palette.colors, ...) +get_colors_vctr(dat, colname, palette = mosuite_palette, color_offset = 0L) } \arguments{ \item{dat}{data frame} \item{colname}{column name in \code{dat}} -\item{palette_fun}{Function for selecting colors. Assumed to contain \code{n} for the number of colors. Default: -\code{grDevices::palette.colors()}} +\item{palette}{Character vector of colors to assign. Defaults to +\code{mosuite_palette}.} -\item{...}{additional arguments forwarded to \code{palette_fun}} +\item{color_offset}{integer; number of palette colors to skip before +assigning colors to this column's values. Used by \code{\link[=get_colors_lst]{get_colors_lst()}} to +avoid repeating colors across columns with few unique values.} } \value{ -named vector of colors for each unique observation in \code{dat$colname} +Named character vector of hex colors, one per unique observed value +in \code{dat[[colname]]}. } \description{ -Get vector of colors for observations in one column of a data frame +Assigns one color per unique observed value in \code{dat[[colname]]}, drawn from +\code{palette} starting at \code{color_offset}. If the palette is too short, +falls back to \code{get_random_colors()}. Factor columns use factor-level order; +other columns use first-observed order. +} +\examples{ +get_colors_vctr(nidap_sample_metadata, "Group") +get_colors_vctr(nidap_sample_metadata, "Group", color_offset = 3L) } diff --git a/code/MOSuite/man/get_observed_values.Rd b/code/MOSuite/man/get_observed_values.Rd new file mode 100644 index 0000000..d16e087 --- /dev/null +++ b/code/MOSuite/man/get_observed_values.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/colors.R +\name{get_observed_values} +\alias{get_observed_values} +\title{Get observed values from a column} +\usage{ +get_observed_values(dat, colname) +} +\arguments{ +\item{dat}{data frame} + +\item{colname}{column name in \code{dat}} +} +\value{ +character vector of observed values +} +\description{ +Returns non-missing values from \code{dat[[colname]]}. For factor columns, values +are returned in factor-level order; otherwise, values keep first-observed +order. +} +\keyword{internal} diff --git a/code/MOSuite/man/get_random_colors.Rd b/code/MOSuite/man/get_random_colors.Rd index 3b6fd5a..213985b 100644 --- a/code/MOSuite/man/get_random_colors.Rd +++ b/code/MOSuite/man/get_random_colors.Rd @@ -15,8 +15,9 @@ get_random_colors(num_colors, n = 2000) vector of random colors in hex format. } \description{ -Note: this function is not guaranteed to create a color blind friendly palette. -Consider using other palettes such as \code{RColorBrewer::display.brewer.all(colorblindFriendly = TRUE)}. +Note: this function is not guaranteed to create a color blind friendly +palette. Consider using other palettes such as +\code{RColorBrewer::display.brewer.all(colorblindFriendly = TRUE)}. } \examples{ \dontrun{ diff --git a/code/MOSuite/man/log_transform_counts.Rd b/code/MOSuite/man/log_transform_counts.Rd new file mode 100644 index 0000000..33b9007 --- /dev/null +++ b/code/MOSuite/man/log_transform_counts.Rd @@ -0,0 +1,35 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/counts.R +\name{log_transform_counts} +\alias{log_transform_counts} +\title{Log-transform count columns in a data frame} +\usage{ +log_transform_counts( + counts_dat, + feature_id_colname = NULL, + sample_colnames = NULL, + pseudocount = 0.5, + base = "ln" +) +} +\arguments{ +\item{counts_dat}{data frame of feature counts.} + +\item{feature_id_colname}{name of the column in \code{counts_dat} that contains feature/gene IDs. (Default: \code{NULL} - first +column in the count data will be used.)} + +\item{sample_colnames}{optional vector of sample columns to transform. If \code{NULL}, all columns except +\code{feature_id_colname} are transformed.} + +\item{pseudocount}{value added before log transformation.} + +\item{base}{logarithm base to use for the transformation. Use a numeric value, or \code{"e"}, \code{"ln"}, or \code{"natural"} +for natural log. Default is \code{"ln"}.} +} +\value{ +count data frame with selected count columns transformed as \code{log(x + pseudocount, base)}. +} +\description{ +Log-transform count columns in a data frame +} +\keyword{internal} diff --git a/code/MOSuite/man/mosuite_palette.Rd b/code/MOSuite/man/mosuite_palette.Rd new file mode 100644 index 0000000..a3ea87b --- /dev/null +++ b/code/MOSuite/man/mosuite_palette.Rd @@ -0,0 +1,25 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{mosuite_palette} +\alias{mosuite_palette} +\title{Default MOSuite color palette} +\format{ +A character vector of length 12. +} +\usage{ +mosuite_palette +} +\description{ +A character vector of 12 hex color codes used as the default palette throughout MOSuite plots. +Colors are assigned to groups in the order they appear (or by factor level order). +Use \code{\link[=set_color_pal]{set_color_pal()}} to override the palette for a specific metadata column. +} +\examples{ +mosuite_palette +scales::show_col(mosuite_palette) +} +\seealso{ +\code{\link[=select_mosuite_colors]{select_mosuite_colors()}}, \code{\link[=set_color_pal]{set_color_pal()}} +} +\keyword{data} diff --git a/code/MOSuite/man/normalize_counts.Rd b/code/MOSuite/man/normalize_counts.Rd index 0bfd0ea..b4c362a 100644 --- a/code/MOSuite/man/normalize_counts.Rd +++ b/code/MOSuite/man/normalize_counts.Rd @@ -12,7 +12,7 @@ normalize_counts( samples_to_include = NULL, sample_id_colname = NULL, group_colname = "Group", - label_colname = NULL, + label_colname = "Label", input_in_log_counts = FALSE, voom_normalization_method = "quantile", samples_to_rename = c(""), @@ -23,12 +23,12 @@ normalize_counts( label_offset_x_ = 2, label_offset_y_ = 2, label_font_size = 3, - point_size_for_pca = 8, + point_size_for_pca = 5, color_histogram_by_group = TRUE, set_min_max_for_x_axis_for_histogram = FALSE, minimum_for_x_axis_for_histogram = -1, maximum_for_x_axis_for_histogram = 1, - legend_font_size_for_histogram = 10, + legend_font_size_for_histogram = NULL, legend_position_for_histogram = "top", number_of_histogram_legend_columns = 6, plot_corr_matrix_heatmap = TRUE, @@ -64,10 +64,10 @@ column showing to which experimental treatments each sample belongs (e.g. WildTy Before, After, etc.).} \item{label_colname}{The column from the sample metadata containing the sample labels as you wish them to appear in -the plots produced by this template. This can be the same Sample Names Column. However, you may desire different -labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the -column with your preferred Labels here. The selected column should contain unique names for each sample. (Default: -\code{NULL} -- \code{sample_id_colname} will be used.)} +heatmap and PCA figures. This can be the same Sample Names Column. However, you may desire different labels to +display on your figures (e.g. shorter labels are sometimes preferred on plots). In that case, select the column with +your preferred Labels here. The selected column should contain unique names for each sample. Use \code{add_label_to_pca} +to control whether these labels are displayed on the PCA plot.} \item{input_in_log_counts}{set this to \code{TRUE} if counts are already log2-transformed} @@ -78,7 +78,8 @@ parameter to rename samples manually for display on the PCA plot. Use "Add item" renaming. Use the following format to describe which old name (in your sample metadata table) you want to rename to which new name: old_name: new_name} -\item{add_label_to_pca}{label points on the PCA plot} +\item{add_label_to_pca}{If \code{TRUE}, display labels from \code{label_colname} on PCA points. If \code{FALSE}, the PCA plot uses +unlabeled points while heatmap labels still use \code{label_colname}.} \item{principal_component_on_x_axis}{The principal component to plot on the x-axis for the PCA plot. Choices include 1, 2, 3, ... (default: 1)} @@ -97,7 +98,7 @@ which new name: old_name: new_name} \item{point_size_for_pca}{geom point size for the PCA plot} \item{color_histogram_by_group}{Set to FALSE to label histogram by Sample Names, or set to TRUE to label histogram by -the column you select in the "Group Column Used to Color Histogram" parameter (below). Default is FALSE.} +the column you select in the "Group Column Used to Color Histogram" parameter (below). Default is TRUE.} \item{set_min_max_for_x_axis_for_histogram}{whether to set min/max value for histogram x-axis} @@ -105,7 +106,8 @@ the column you select in the "Group Column Used to Color Histogram" parameter (b \item{maximum_for_x_axis_for_histogram}{x-axis maximum for histogram plot} -\item{legend_font_size_for_histogram}{legend font size for the histogram plot} +\item{legend_font_size_for_histogram}{legend font size for the histogram plot. +If \code{NULL}, the size is scaled automatically.} \item{legend_position_for_histogram}{legend position for the histogram plot. consider setting to 'none' for a large number of samples.} @@ -116,8 +118,14 @@ number of samples.} matrix heatmap. If this function takes longer than 5 minutes to run, Set to \code{FALSE} and the correlation matrix will not be be created. Default is \code{TRUE}.} -\item{colors_for_plots}{Colors for the PCA and histogram will be picked, in order, from this list. -Colors must either be names in \code{grDevices::colors()} or valid hex codes.} +\item{colors_for_plots}{Optional colors for PCA/histogram/heatmap plots. If \code{NULL}, colors are taken from +\code{moo@analyses$colors[[group_colname]]}. +Colors must either be names in \code{grDevices::colors()} or valid hex codes. +Unnamed colors are assigned by factor level order when the grouping column is a factor; +otherwise, they follow the order in which groups first appear in the metadata column. If more groups are present +than colors provided, +supplied colors are used first and additional colors are generated from the selected palette for the remaining +groups; random colors are used only if that palette returns fewer colors than the number of groups.} \item{print_plots}{Whether to print plots during analysis (Defaults to \code{FALSE}, overwritable using option 'moo_print_plots' or environment variable 'MOO_PRINT_PLOTS')} diff --git a/code/MOSuite/man/plot_corr_heatmap-data.frame.Rd b/code/MOSuite/man/plot_corr_heatmap-data.frame.Rd index 0eec133..f027f0c 100644 --- a/code/MOSuite/man/plot_corr_heatmap-data.frame.Rd +++ b/code/MOSuite/man/plot_corr_heatmap-data.frame.Rd @@ -28,7 +28,9 @@ labels to display on your figure (e.g. shorter labels are sometimes preferred on column with your preferred Labels here. The selected column should contain unique names for each sample. (Default: \code{NULL} -- \code{sample_id_colname} will be used.)} -\item{color_values}{vector of colors as hex values or names recognized by R} +\item{color_values}{vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +level order when the grouping column is a factor; otherwise, they are assigned in the order groups first appear in +the metadata column. Defaults to \code{NULL}; when \code{NULL}, \code{mosuite_palette} is used.} } \description{ Plot correlation heatmap for counts dataframe diff --git a/code/MOSuite/man/plot_corr_heatmap-multiOmicDataSet.Rd b/code/MOSuite/man/plot_corr_heatmap-multiOmicDataSet.Rd index 0f09035..6aa3754 100644 --- a/code/MOSuite/man/plot_corr_heatmap-multiOmicDataSet.Rd +++ b/code/MOSuite/man/plot_corr_heatmap-multiOmicDataSet.Rd @@ -12,6 +12,15 @@ \item{sub_count_type}{used if \code{count_type} is a list in the counts slot: specify the sub count type within the list. Must be a name in \code{names(moo@counts[[count_type]])}.} +\item{group_colname}{The column from the sample metadata containing the sample group information. This is usually a +column showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal, +Before, After, etc.).} + +\item{color_values}{vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +level order when the grouping column is a factor; otherwise, they are assigned in the order groups first appear in +the metadata column. Defaults to \code{NULL}; when \code{NULL}, \code{mosuite_palette} is used for \code{data.frame} dispatch and +stored colors are used for \code{multiOmicDataSet} dispatch.} + \item{...}{additional arguments forwarded to \code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}} for \code{data.frame}} } \description{ diff --git a/code/MOSuite/man/plot_corr_heatmap.Rd b/code/MOSuite/man/plot_corr_heatmap.Rd index f09d191..9649791 100644 --- a/code/MOSuite/man/plot_corr_heatmap.Rd +++ b/code/MOSuite/man/plot_corr_heatmap.Rd @@ -34,10 +34,7 @@ plot_corr_heatmap(moo_counts, feature_id_colname = NULL, group_colname = "Group", label_colname = "Label", - color_values = c( - "#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500" - )) + color_values = mosuite_palette) }\if{html}{\out{}} } } diff --git a/code/MOSuite/man/plot_expr_heatmap.Rd b/code/MOSuite/man/plot_expr_heatmap.Rd index 8f8b890..e4458b5 100644 --- a/code/MOSuite/man/plot_expr_heatmap.Rd +++ b/code/MOSuite/man/plot_expr_heatmap.Rd @@ -16,8 +16,7 @@ plot_expr_heatmap( group_colname = "Group", label_colname = NULL, samples_to_include = NULL, - color_values = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), + color_values = NULL, include_all_genes = FALSE, filter_top_genes_by_variance = TRUE, top_genes_by_variance_to_include = 500, @@ -42,8 +41,6 @@ plot_expr_heatmap( group_columns = c("Group", "Replicate", "Batch"), assign_group_colors = FALSE, assign_color_to_sample_groups = c(), - group_colors = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), heatmap_color_scheme = "Default", autoscale_heatmap_color = TRUE, set_min_heatmap_color = -2, @@ -56,7 +53,8 @@ plot_expr_heatmap( plot_filename = "expr_heatmap.png", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), - plots_subdir = "heatmap" + plots_subdir = "heatmap", + ... ) ## S7 method for class @@ -70,8 +68,7 @@ plot_expr_heatmap( group_colname = "Group", label_colname = NULL, samples_to_include = NULL, - color_values = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), + color_values = NULL, include_all_genes = FALSE, filter_top_genes_by_variance = TRUE, top_genes_by_variance_to_include = 500, @@ -96,8 +93,6 @@ plot_expr_heatmap( group_columns = c("Group", "Replicate", "Batch"), assign_group_colors = FALSE, assign_color_to_sample_groups = c(), - group_colors = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), heatmap_color_scheme = "Default", autoscale_heatmap_color = TRUE, set_min_heatmap_color = -2, @@ -110,7 +105,8 @@ plot_expr_heatmap( plot_filename = "expr_heatmap.png", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), - plots_subdir = "heatmap" + plots_subdir = "heatmap", + ... ) ## S7 method for class @@ -124,8 +120,7 @@ plot_expr_heatmap( group_colname = "Group", label_colname = NULL, samples_to_include = NULL, - color_values = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), + color_values = NULL, include_all_genes = FALSE, filter_top_genes_by_variance = TRUE, top_genes_by_variance_to_include = 500, @@ -150,8 +145,6 @@ plot_expr_heatmap( group_columns = c("Group", "Replicate", "Batch"), assign_group_colors = FALSE, assign_color_to_sample_groups = c(), - group_colors = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), heatmap_color_scheme = "Default", autoscale_heatmap_color = TRUE, set_min_heatmap_color = -2, @@ -164,7 +157,8 @@ plot_expr_heatmap( plot_filename = "expr_heatmap.png", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), - plots_subdir = "heatmap" + plots_subdir = "heatmap", + ... ) } \arguments{ @@ -201,7 +195,10 @@ column with your preferred Labels here. The selected column should contain uniqu you could choose to remove certain samples. Samples excluded here will be removed in this step and from further analysis downstream of this step. (Default: \code{NULL} - all sample IDs in \code{moo@sample_meta} will be used.)} -\item{color_values}{vector of colors as hex values or names recognized by R} +\item{color_values}{vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +level order when the grouping column is a factor; otherwise, they are assigned in the order groups first appear in +the metadata column. Defaults to \code{NULL}; when \code{NULL}, \code{mosuite_palette} is used for \code{data.frame} dispatch and +stored colors are used for \code{multiOmicDataSet} dispatch.} \item{include_all_genes}{Set to TRUE if all genes are to be included. Set to FALSE if you want to filter genes by variance and/or provide a list of specific genes that will appear in the heatmap.} @@ -263,8 +260,6 @@ sample names.} \item{assign_color_to_sample_groups}{Enter each sample to color in the format: group_name: color This parameter is ignored if "Assign Colors" is set to FALSE.} -\item{group_colors}{Set group annotation colors.} - \item{heatmap_color_scheme}{color scheme (TODO document options)} \item{autoscale_heatmap_color}{Set to TRUE to autoscale the heatmap colors between the maximum and minimum heatmap @@ -296,6 +291,8 @@ you want to see these numbers on the plot.} \item{save_plots}{Whether to save plots to files during analysis (Defaults to \code{TRUE}, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')} \item{plots_subdir}{subdirectory in \verb{figures/} where plots will be saved if \code{save_plots} is \code{TRUE}} + +\item{...}{additional arguments passed to methods} } \value{ heatmap from \code{ComplexHeatmap::Heatmap()} diff --git a/code/MOSuite/man/plot_histogram.data.frame.Rd b/code/MOSuite/man/plot_histogram.data.frame.Rd index ba46275..1f94792 100644 --- a/code/MOSuite/man/plot_histogram.data.frame.Rd +++ b/code/MOSuite/man/plot_histogram.data.frame.Rd @@ -26,7 +26,9 @@ labels to display on your figure (e.g. shorter labels are sometimes preferred on column with your preferred Labels here. The selected column should contain unique names for each sample. (Default: \code{NULL} -- \code{sample_id_colname} will be used.)} -\item{color_values}{vector of colors as hex values or names recognized by R} +\item{color_values}{vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +level order when the grouping column is a factor; otherwise, they follow the order in which groups first appear in +the metadata column. Defaults to \code{NULL}; when \code{NULL}, \code{mosuite_palette} is used.} \item{color_by_group}{Set to FALSE to label histogram by Sample Names, or set to TRUE to label histogram by the column you select in the "Group Column Used to Color Histogram" parameter (below). Default is FALSE.} @@ -43,7 +45,8 @@ column you select in the "Group Column Used to Color Histogram" parameter (below \item{legend_position}{passed to in \code{legend.position} \code{ggplot2::theme()}} -\item{legend_font_size}{passed to \code{ggplot2::element_text()} via \code{ggplot2::theme()}} +\item{legend_font_size}{passed to \code{ggplot2::element_text()} via \code{ggplot2::theme()}. If \code{NULL}, the size is scaled +automatically based on the number and length of legend labels.} \item{number_of_legend_columns}{passed to \code{ncol} in \code{ggplot2::guide_legend()}} @@ -51,6 +54,12 @@ column you select in the "Group Column Used to Color Histogram" parameter (below over a point or line to view sample information. The similarity heat map will not display if this toggle is set to TRUE. Default is FALSE.} +\item{return_ggplot}{If \code{TRUE}, return the ggplot object prepared for interactive hover text before converting it to +plotly. Used when callers need to add more ggplot layers first. Default is \code{FALSE}.} + +\item{use_log2_x_axis}{If \code{TRUE}, add a display-only pseudocount to plotted values and use a log2 x-axis. Default is +\code{FALSE}.} + \item{...}{additional arguments (ignored; accepted for compatibility with the moo dispatch)} } \description{ diff --git a/code/MOSuite/man/plot_histogram.multiOmicDataSet.Rd b/code/MOSuite/man/plot_histogram.multiOmicDataSet.Rd index 75da66e..4b47fe4 100644 --- a/code/MOSuite/man/plot_histogram.multiOmicDataSet.Rd +++ b/code/MOSuite/man/plot_histogram.multiOmicDataSet.Rd @@ -10,6 +10,15 @@ the counts slot (\code{moo@counts}).} \item{sub_count_type}{Used if \code{moo_counts} is a \code{multiOmicDataSet} AND if \code{count_type} is a list, specify the sub count type within the list} + +\item{group_colname}{The column from the sample metadata containing the sample group information. This is usually a +column showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal, +Before, After, etc.).} + +\item{color_values}{vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +level order when the grouping column is a factor; otherwise, they follow the order in which groups first appear in +the metadata column. Defaults to \code{NULL}; when \code{NULL}, \code{mosuite_palette} is used for \code{data.frame} dispatch and +stored colors are used for \code{multiOmicDataSet} dispatch.} } \description{ Plot histogram for multiOmicDataSet diff --git a/code/MOSuite/man/plot_palette.Rd b/code/MOSuite/man/plot_palette.Rd new file mode 100644 index 0000000..31bddf5 --- /dev/null +++ b/code/MOSuite/man/plot_palette.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/colors.R +\name{plot_palette} +\alias{plot_palette} +\title{Plot a palette tile strip} +\usage{ +plot_palette(dat) +} +\arguments{ +\item{dat}{data frame with columns \code{hex} (hex color codes) and \code{idx} +(factor, used for faceting)} +} +\value{ +a \link[ggplot2:ggplot]{ggplot2::ggplot} object +} +\description{ +Renders a data frame with columns \code{hex} and \code{idx} as a row of colored tiles, +each labeled with its hex code. Used internally by \code{\link[=display_palette]{display_palette()}} and +\code{\link[=display_colors]{display_colors()}}. +} +\keyword{internal} diff --git a/code/MOSuite/man/plot_pca.Rd b/code/MOSuite/man/plot_pca.Rd index 6dfa47e..5fa6b6e 100644 --- a/code/MOSuite/man/plot_pca.Rd +++ b/code/MOSuite/man/plot_pca.Rd @@ -22,6 +22,12 @@ PCA plot (2D or 3D depending on the number of \code{principal_components}) Perform and plot a Principal Components Analysis } \details{ +PCA is sensitive to feature scale. For raw, cleaned, filtered, or CPM-like count data, setting +\code{log_transform = TRUE} compresses high-count features before PCA so ordination is less dominated by abundance +differences. Do not enable this for already normalized/log-scale data, such as voom/logCPM \code{norm} counts or +batch-corrected normalized counts, because that would apply a second log transform. The default PCA transform uses +the original MOSuite PCA scaling, \code{log(x + 0.5)}. + See the low-level function docs for additional arguments depending on whether you're plotting 2 or 3 PCs: \itemize{ diff --git a/code/MOSuite/man/plot_pca_2d.Rd b/code/MOSuite/man/plot_pca_2d.Rd index 244d8b2..32b343c 100644 --- a/code/MOSuite/man/plot_pca_2d.Rd +++ b/code/MOSuite/man/plot_pca_2d.Rd @@ -16,20 +16,23 @@ plot_pca_2d( group_colname = "Group", label_colname = "Label", samples_to_rename = NULL, - color_values = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), + color_values = NULL, principal_components = c(1, 2), legend_position = "top", - point_size = 1, - add_label = TRUE, + point_size = 5, + legend_font_size = NULL, label_font_size = 3, label_offset_x_ = 2, label_offset_y_ = 2, + log_transform = FALSE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", interactive_plots = FALSE, plots_subdir = "pca", plot_filename = "pca_2D.png", print_plots = options::opt("print_plots"), - save_plots = options::opt("save_plots") + save_plots = options::opt("save_plots"), + ... ) ## S7 method for class @@ -43,20 +46,23 @@ plot_pca_2d( group_colname = "Group", label_colname = "Label", samples_to_rename = NULL, - color_values = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), + color_values = NULL, principal_components = c(1, 2), legend_position = "top", - point_size = 1, - add_label = TRUE, + point_size = 5, + legend_font_size = NULL, label_font_size = 3, label_offset_x_ = 2, label_offset_y_ = 2, + log_transform = FALSE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", interactive_plots = FALSE, plots_subdir = "pca", plot_filename = "pca_2D.png", print_plots = options::opt("print_plots"), - save_plots = options::opt("save_plots") + save_plots = options::opt("save_plots"), + ... ) ## S7 method for class @@ -70,30 +76,32 @@ plot_pca_2d( group_colname = "Group", label_colname = "Label", samples_to_rename = NULL, - color_values = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), + color_values = NULL, principal_components = c(1, 2), legend_position = "top", - point_size = 1, - add_label = TRUE, + point_size = 5, + legend_font_size = NULL, label_font_size = 3, label_offset_x_ = 2, label_offset_y_ = 2, + log_transform = FALSE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", interactive_plots = FALSE, plots_subdir = "pca", plot_filename = "pca_2D.png", print_plots = options::opt("print_plots"), - save_plots = options::opt("save_plots") + save_plots = options::opt("save_plots"), + ... ) } \arguments{ \item{moo_counts}{counts dataframe or \code{multiOmicDataSet} containing \code{count_type} & \code{sub_count_type} in the counts slot} -\item{count_type}{type to assign the values of \code{counts_dat} to in the \code{counts} slot} +\item{count_type}{the type of counts to use when \code{moo_counts} is a \code{multiOmicDataSet}; ignored for data frame input.} -\item{sub_count_type}{used if \code{count_type} is a list in the counts slot: specify the sub count type within the list. -Must be a name in \code{names(moo@counts[[count_type]])}.} +\item{sub_count_type}{used when \code{count_type} refers to a list of count matrices; ignored for data frame input.} \item{sample_metadata}{sample metadata as a data frame or tibble.} @@ -110,18 +118,21 @@ used.)} column showing to which experimental treatments each sample belongs (e.g. WildType, Knockout, Tumor, Normal, Before, After, etc.).} -\item{label_colname}{The column from the sample metadata containing the sample labels as you wish them to appear in -the plots produced by this template. This can be the same Sample Names Column. However, you may desire different -labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In that case, select the -column with your preferred Labels here. The selected column should contain unique names for each sample. (Default: -\code{NULL} -- \code{sample_id_colname} will be used.)} +\item{label_colname}{The column from the sample metadata containing the sample labels as you wish them to appear on +the PCA plot. If \code{NULL}, no labels are added to PCA points. This can be the same Sample Names Column. However, you +may desire different labels to display on your figure (e.g. shorter labels are sometimes preferred on plots). In +that case, select the column with your preferred Labels here. The selected column should contain unique names for +each sample.} \item{samples_to_rename}{If you do not have a Plot Labels Column in your sample metadata table, you can use this parameter to rename samples manually for display on the PCA plot. Use "Add item" to add each additional sample for renaming. Use the following format to describe which old name (in your sample metadata table) you want to rename to which new name: old_name: new_name} -\item{color_values}{vector of colors as hex values or names recognized by R} +\item{color_values}{vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +level order when the grouping column is a factor; otherwise, they follow the order in which groups first appear in +the metadata column. Defaults to \code{NULL}; when \code{NULL}, \code{mosuite_palette} is used for \code{data.frame} dispatch and +stored colors are used for \code{multiOmicDataSet} dispatch.} \item{principal_components}{vector with numbered principal components to plot} @@ -129,25 +140,36 @@ which new name: old_name: new_name} \item{point_size}{size for \code{ggplot2::geom_point()}} -\item{add_label}{whether to add text labels for the points} +\item{legend_font_size}{font size for the PCA legend text. If \code{NULL}, the size is scaled automatically based on the +number and length of legend labels.} -\item{label_font_size}{label font size for the PCA plot} +\item{label_font_size}{font size for text labels on the PCA plot.} -\item{label_offset_x_}{label offset x for the PCA plot} +\item{label_offset_x_}{horizontal offset for text labels on the PCA plot.} -\item{label_offset_y_}{label offset y for the PCA plot} +\item{label_offset_y_}{vertical offset for text labels on the PCA plot.} -\item{interactive_plots}{set to TRUE to make PCA and Histogram plots interactive with \code{plotly}, allowing you to hover -your mouse over a point or line to view sample information. The similarity heat map will not display if this toggle -is set to \code{TRUE}. Default is \code{FALSE}.} +\item{log_transform}{If \code{TRUE}, apply \code{log(x + log_transform_pseudocount, base = log_transform_base)} to sample +count columns before PCA. Use this for count-like data such as raw, clean, filt, or CPM-like counts; leave it +\code{FALSE} for already normalized/log-scale or batch-corrected values to avoid double transformation.} -\item{plots_subdir}{subdirectory in \verb{figures/} where plots will be saved if \code{save_plots} is \code{TRUE}} +\item{log_transform_pseudocount}{Pseudocount added before log-transforming counts when \code{log_transform} is +\code{TRUE}.} -\item{plot_filename}{plot output filename - only used if save_plots is TRUE} +\item{log_transform_base}{Logarithm base to use when \code{log_transform} is \code{TRUE}. Use a numeric value, or \code{"e"}, +\code{"ln"}, or \code{"natural"} for natural log. Default is \code{"ln"} to match the original PCA transform.} + +\item{interactive_plots}{set to TRUE to make the PCA plot interactive with \code{plotly}.} + +\item{plots_subdir}{subdirectory in \verb{figures/} where PCA plots are saved.} + +\item{plot_filename}{output filename for the PCA plot image.} \item{print_plots}{Whether to print plots during analysis (Defaults to \code{FALSE}, overwritable using option 'moo_print_plots' or environment variable 'MOO_PRINT_PLOTS')} \item{save_plots}{Whether to save plots to files during analysis (Defaults to \code{TRUE}, overwritable using option 'moo_save_plots' or environment variable 'MOO_SAVE_PLOTS')} + +\item{...}{arguments forwarded to method} } \value{ ggplot object diff --git a/code/MOSuite/man/plot_pca_3d.Rd b/code/MOSuite/man/plot_pca_3d.Rd index acf569d..1dcc939 100644 --- a/code/MOSuite/man/plot_pca_3d.Rd +++ b/code/MOSuite/man/plot_pca_3d.Rd @@ -19,13 +19,16 @@ plot_pca_3d( principal_components = c(1, 2, 3), point_size = 8, label_font_size = 24, - color_values = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), + log_transform = FALSE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", + color_values = NULL, plot_title = "PCA 3D", plot_filename = "pca_3D.html", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), - plots_subdir = "pca" + plots_subdir = "pca", + ... ) ## S7 method for class @@ -42,13 +45,16 @@ plot_pca_3d( principal_components = c(1, 2, 3), point_size = 8, label_font_size = 24, - color_values = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), + log_transform = FALSE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", + color_values = NULL, plot_title = "PCA 3D", plot_filename = "pca_3D.html", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), - plots_subdir = "pca" + plots_subdir = "pca", + ... ) ## S7 method for class @@ -65,13 +71,16 @@ plot_pca_3d( principal_components = c(1, 2, 3), point_size = 8, label_font_size = 24, - color_values = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", - "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), + log_transform = FALSE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", + color_values = NULL, plot_title = "PCA 3D", plot_filename = "pca_3D.html", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), - plots_subdir = "pca" + plots_subdir = "pca", + ... ) } \arguments{ @@ -99,7 +108,20 @@ plot_pca_3d( \item{label_font_size}{font size used for labels in the interactive figure.} -\item{color_values}{vector of colors as hex values or names recognized by R.} +\item{log_transform}{If \code{TRUE}, apply \code{log(x + log_transform_pseudocount, base = log_transform_base)} to sample +count columns before PCA. Use this for count-like data such as raw, clean, filt, or CPM-like counts; leave it +\code{FALSE} for already normalized/log-scale or batch-corrected values to avoid double transformation.} + +\item{log_transform_pseudocount}{Pseudocount added before log-transforming counts when \code{log_transform} is +\code{TRUE}.} + +\item{log_transform_base}{Logarithm base to use when \code{log_transform} is \code{TRUE}. Use a numeric value, or \code{"e"}, +\code{"ln"}, or \code{"natural"} for natural log. Default is \code{"ln"} to match the original PCA transform.} + +\item{color_values}{vector of colors as hex values or names recognized by R. Unnamed colors are assigned by factor +level order when the grouping column is a factor; otherwise, they follow the order in which groups first appear in +the metadata column. Defaults to \code{NULL}; when \code{NULL}, \code{mosuite_palette} is used for \code{data.frame} dispatch and +stored colors are used for \code{multiOmicDataSet} dispatch.} \item{plot_title}{title for the plot} @@ -110,6 +132,8 @@ plot_pca_3d( \item{save_plots}{whether to save plot to disk.} \item{plots_subdir}{output subdirectory for saved plots.} + +\item{...}{additional arguments passed to methods} } \value{ \code{plotly::plot_ly} figure diff --git a/code/MOSuite/man/plot_read_depth.data.frame.Rd b/code/MOSuite/man/plot_read_depth.data.frame.Rd index 35c2689..dc490a8 100644 --- a/code/MOSuite/man/plot_read_depth.data.frame.Rd +++ b/code/MOSuite/man/plot_read_depth.data.frame.Rd @@ -5,6 +5,16 @@ \alias{plot_read_depth.data.frame} \title{Plot read depth for \code{data.frame}} \arguments{ +\item{sample_metadata}{sample metadata dataframe, required when \code{group_colname} is supplied.} + +\item{sample_id_colname}{column in sample metadata containing sample IDs.} + +\item{group_colname}{sample metadata column used to color bars. Leave blank to use the current single-color bar fill.} + +\item{color_values}{colors used when \code{group_colname} is supplied. Named vectors are matched to group values; +unnamed vectors follow group order and are extended with MOSuite colors when too few colors are supplied. +Defaults to \code{NULL}; when \code{NULL}, \code{mosuite_palette} is used.} + \item{...}{additional arguments (ignored; accepted for compatibility with the moo dispatch)} } \value{ diff --git a/code/MOSuite/man/plot_read_depth.multiOmicDataSet.Rd b/code/MOSuite/man/plot_read_depth.multiOmicDataSet.Rd index 50647ec..250c402 100644 --- a/code/MOSuite/man/plot_read_depth.multiOmicDataSet.Rd +++ b/code/MOSuite/man/plot_read_depth.multiOmicDataSet.Rd @@ -9,6 +9,15 @@ \item{sub_count_type}{used if \code{count_type} is a list in the counts slot: specify the sub count type within the list. Must be a name in \code{names(moo@counts[[count_type]])}.} + +\item{sample_id_colname}{column in sample metadata containing sample IDs.} + +\item{group_colname}{sample metadata column used to color bars. Leave blank to use the current single-color bar fill.} + +\item{color_values}{colors used when \code{group_colname} is supplied. Named vectors are matched to group values; +unnamed vectors follow group order and are extended with MOSuite colors when too few colors are supplied. +Defaults to \code{NULL}; when \code{NULL}, \code{mosuite_palette} is used for \code{data.frame} dispatch and stored colors +are used for \code{multiOmicDataSet} dispatch.} } \value{ ggplot barplot diff --git a/code/MOSuite/man/plot_venn_diagram.Rd b/code/MOSuite/man/plot_venn_diagram.Rd index 658e8c1..80ab701 100644 --- a/code/MOSuite/man/plot_venn_diagram.Rd +++ b/code/MOSuite/man/plot_venn_diagram.Rd @@ -180,7 +180,8 @@ same colors as \code{venn_fill_colors})} \item{image_height}{output image height in pixels - only used if save_plots is TRUE} -\item{plot_filename}{plot output filename - only used if save_plots is TRUE} +\item{plot_filename}{plot output filename - only used if save_plots is TRUE. When multiple comparisons are saved +separately, the comparison name is appended before the file extension.} \item{print_plots}{Whether to print plots during analysis (Defaults to \code{FALSE}, overwritable using option 'moo_print_plots' or environment variable 'MOO_PRINT_PLOTS')} diff --git a/code/MOSuite/man/plot_volcano_enhanced.Rd b/code/MOSuite/man/plot_volcano_enhanced.Rd index 9b7f238..f2d4491 100644 --- a/code/MOSuite/man/plot_volcano_enhanced.Rd +++ b/code/MOSuite/man/plot_volcano_enhanced.Rd @@ -9,29 +9,43 @@ plot_volcano_enhanced( moo_diff, feature_id_colname = NULL, - signif_colname = c("B-A_adjpval", "B-C_adjpval"), + change_colname = NULL, + signif_colname = NULL, signif_threshold = 0.05, - change_colname = c("B-A_logFC", "B-C_logFC"), change_threshold = 1, value_to_sort_the_output_dataset = "p-value", num_features_to_label = 30, - use_only_addition_labels = FALSE, - additional_labels = "", - is_red = TRUE, - lab_size = 4, + label_features = FALSE, + custom_gene_list = "", + label_significant_features_only = TRUE, + label_font_size = 7, + draw_connectors = FALSE, change_sig_name = "p-value", change_lfc_name = "log2FC", title = "Volcano Plots", + title_font_size = 24, use_custom_lab = FALSE, - ylim = 0, - custom_xlim = "", - xlim_additional = 0, - ylim_additional = 0, + use_default_x_axis_limit = TRUE, + x_axis_limit = 5, + use_default_y_axis_limit = TRUE, + y_axis_limit = 10, axis_lab_size = 24, + axis_tick_lab_size = 16, point_size = 2, + default_label_color = "black", + custom_label_color = "black", + color_of_signif_threshold_line = "black", + color_of_non_significant_features = "grey30", + color_of_logfold_change_threshold_line = "forestgreen", + color_of_features_meeting_only_signif_threshold = "royalblue", + color_for_features_meeting_pvalue_and_foldchange_thresholds = "red2", + graphics_device = grDevices::png, image_width = 3000, image_height = 3000, dpi = 300, + use_default_grid_layout = TRUE, + number_of_rows_in_grid_layout = NULL, + scale_image_to_grid = FALSE, interactive_plots = FALSE, print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), @@ -43,29 +57,43 @@ plot_volcano_enhanced( plot_volcano_enhanced( moo_diff, feature_id_colname = NULL, - signif_colname = c("B-A_adjpval", "B-C_adjpval"), + change_colname = NULL, + signif_colname = NULL, signif_threshold = 0.05, - change_colname = c("B-A_logFC", "B-C_logFC"), change_threshold = 1, value_to_sort_the_output_dataset = "p-value", num_features_to_label = 30, - use_only_addition_labels = FALSE, - additional_labels = "", - is_red = TRUE, - lab_size = 4, + label_features = FALSE, + custom_gene_list = "", + label_significant_features_only = TRUE, + label_font_size = 7, + draw_connectors = FALSE, change_sig_name = "p-value", change_lfc_name = "log2FC", title = "Volcano Plots", + title_font_size = 24, use_custom_lab = FALSE, - ylim = 0, - custom_xlim = "", - xlim_additional = 0, - ylim_additional = 0, + use_default_x_axis_limit = TRUE, + x_axis_limit = 5, + use_default_y_axis_limit = TRUE, + y_axis_limit = 10, axis_lab_size = 24, + axis_tick_lab_size = 16, point_size = 2, + default_label_color = "black", + custom_label_color = "black", + color_of_signif_threshold_line = "black", + color_of_non_significant_features = "grey30", + color_of_logfold_change_threshold_line = "forestgreen", + color_of_features_meeting_only_signif_threshold = "royalblue", + color_for_features_meeting_pvalue_and_foldchange_thresholds = "red2", + graphics_device = grDevices::png, image_width = 3000, image_height = 3000, dpi = 300, + use_default_grid_layout = TRUE, + number_of_rows_in_grid_layout = NULL, + scale_image_to_grid = FALSE, interactive_plots = FALSE, print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), @@ -77,29 +105,43 @@ plot_volcano_enhanced( plot_volcano_enhanced( moo_diff, feature_id_colname = NULL, - signif_colname = c("B-A_adjpval", "B-C_adjpval"), + change_colname = NULL, + signif_colname = NULL, signif_threshold = 0.05, - change_colname = c("B-A_logFC", "B-C_logFC"), change_threshold = 1, value_to_sort_the_output_dataset = "p-value", num_features_to_label = 30, - use_only_addition_labels = FALSE, - additional_labels = "", - is_red = TRUE, - lab_size = 4, + label_features = FALSE, + custom_gene_list = "", + label_significant_features_only = TRUE, + label_font_size = 7, + draw_connectors = FALSE, change_sig_name = "p-value", change_lfc_name = "log2FC", title = "Volcano Plots", + title_font_size = 24, use_custom_lab = FALSE, - ylim = 0, - custom_xlim = "", - xlim_additional = 0, - ylim_additional = 0, + use_default_x_axis_limit = TRUE, + x_axis_limit = 5, + use_default_y_axis_limit = TRUE, + y_axis_limit = 10, axis_lab_size = 24, + axis_tick_lab_size = 16, point_size = 2, + default_label_color = "black", + custom_label_color = "black", + color_of_signif_threshold_line = "black", + color_of_non_significant_features = "grey30", + color_of_logfold_change_threshold_line = "forestgreen", + color_of_features_meeting_only_signif_threshold = "royalblue", + color_for_features_meeting_pvalue_and_foldchange_thresholds = "red2", + graphics_device = grDevices::png, image_width = 3000, image_height = 3000, dpi = 300, + use_default_grid_layout = TRUE, + number_of_rows_in_grid_layout = NULL, + scale_image_to_grid = FALSE, interactive_plots = FALSE, print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), @@ -115,29 +157,37 @@ This is usually the first column of your input Counts Matrix. Only columns of Te Matrix will be available to select for this parameter. (Default: \code{NULL} - first column in the counts matrix will be used.)} -\item{signif_colname}{column name of significance values (e.g., adjusted p-values or FDR). This column will be used -to determine which points are considered significant in the volcano plot.} +\item{change_colname}{Character vector of logFC column names, one per +contrast (e.g. \code{c("B-A_logFC", "C-A_logFC")}). Defaults to \code{NULL}, which +auto-detects all columns ending in \verb{_logFC}.} -\item{signif_threshold}{Numeric value specifying the significance cutoff for p-values (i.e. filters on -\code{signif_colname})} +\item{signif_colname}{Character vector of significance column names, one per +contrast (e.g. \code{c("B-A_adjpval", "C-A_adjpval")}). Defaults to \code{NULL}, +which auto-detects corresponding columns by checking for \verb{_adjpval} first, +then \verb{_pval}, for each contrast in \code{change_colname}.} -\item{change_colname}{column name of fold change values.} +\item{signif_threshold}{Numeric significance threshold (p-value or adjusted p-value cutoff). Default: 0.05} \item{change_threshold}{Numeric value specifying the fold change cutoff for significance (i.e. filters on \code{change_colname})} -\item{value_to_sort_the_output_dataset}{How to sort the output dataset. Options are "fold-change" or "p-value".} +\item{value_to_sort_the_output_dataset}{How to sort the output dataset. Options are "fold-change", "p-value", or +"t-statistic".} \item{num_features_to_label}{Number of top features/genes to label in the volcano plot. Default is 30.} -\item{use_only_addition_labels}{If \code{TRUE}, only the additional labels specified in \code{additional_labels} will be used -for labeling in the volcano plot, ignoring the top features.} +\item{label_features}{If \code{TRUE}, only the features specified in \code{custom_gene_list} will be used for labeling in the +volcano plot, ignoring the top features.} -\item{additional_labels}{comma-separated string of feature names or IDs to include in the volcano plot.} +\item{custom_gene_list}{comma-separated string of feature names or IDs to include in the volcano plot.} -\item{is_red}{Logical. If TRUE, highlights points in red.} +\item{label_significant_features_only}{If \code{TRUE}, automatic labels are selected only from features that pass both +the significance and fold-change thresholds.} -\item{lab_size}{Size of the labels in the volcano plot.} +\item{label_font_size}{Size of the labels in the volcano plot.} + +\item{draw_connectors}{If \code{TRUE}, draw connector lines from labels to their points and spread labels to reduce +overlap.} \item{change_sig_name}{Name for the significance column in the plot. Default is "p-value".} @@ -145,26 +195,55 @@ for labeling in the volcano plot, ignoring the top features.} \item{title}{Title of the plot. Default is "Volcano Plots".} +\item{title_font_size}{Size of the plot title.} + \item{use_custom_lab}{If TRUE, uses custom labels for the plot (set by \code{change_sig_name} and \code{change_lfc_name})} -\item{ylim}{Y-axis limits for the plot.} +\item{use_default_x_axis_limit}{Set to TRUE to use the default x-axis limit.} -\item{custom_xlim}{Custom X-axis limits for the plot.} +\item{x_axis_limit}{Custom x-axis limit. A single value is treated symmetrically, and a two-value vector is treated +as lower and upper limits.} -\item{xlim_additional}{Additional space to add to the X-axis limits.} +\item{use_default_y_axis_limit}{Set to TRUE to use the default y-axis limit.} -\item{ylim_additional}{Additional space to add to the Y-axis limits.} +\item{y_axis_limit}{Custom y-axis limit.} \item{axis_lab_size}{Size of the axis labels.} +\item{axis_tick_lab_size}{Size of the axis tick labels.} + \item{point_size}{Size of the points in the plot.} +\item{default_label_color}{Set the color for the text used to add feature labels to points.} + +\item{custom_label_color}{Set the color for labels from \code{custom_gene_list}.} + +\item{color_of_signif_threshold_line}{Color of the significance threshold line.} + +\item{color_of_non_significant_features}{Color of the non-significant features.} + +\item{color_of_logfold_change_threshold_line}{Color of the features that meet only the log fold change threshold.} + +\item{color_of_features_meeting_only_signif_threshold}{Color of the features that meet only the significance +threshold.} + +\item{color_for_features_meeting_pvalue_and_foldchange_thresholds}{Color of the features that meet both the p-value +and fold change thresholds.} + +\item{graphics_device}{passed to \code{ggsave(device)}. Default: \code{grDevices::png}} + \item{image_width}{output image width in pixels - only used if save_plots is TRUE} \item{image_height}{output image height in pixels - only used if save_plots is TRUE} \item{dpi}{dots-per-inch of the output image (see \code{ggsave()}) - only used if save_plots is TRUE} +\item{use_default_grid_layout}{Retained for compatibility. Grid layout is handled by \code{plot_volcano_summary()}.} + +\item{number_of_rows_in_grid_layout}{Retained for compatibility. Grid layout is handled by \code{plot_volcano_summary()}.} + +\item{scale_image_to_grid}{Retained for compatibility. Grid layout is handled by \code{plot_volcano_summary()}.} + \item{interactive_plots}{set to TRUE to make PCA and Histogram plots interactive with \code{plotly}, allowing you to hover your mouse over a point or line to view sample information. The similarity heat map will not display if this toggle is set to \code{TRUE}. Default is \code{FALSE}.} @@ -175,7 +254,8 @@ is set to \code{TRUE}. Default is \code{FALSE}.} \item{plots_subdir}{subdirectory in \verb{figures/} where plots will be saved if \code{save_plots} is \code{TRUE}} -\item{plot_filename}{plot output filename - only used if save_plots is TRUE} +\item{plot_filename}{plot output filename - only used if save_plots is TRUE. When multiple comparisons are saved +separately, the comparison name is appended before the file extension.} } \description{ Uses \href{https://bioconductor.org/packages/release/bioc/html/EnhancedVolcano.html}{Bioconductor's Enhanced Volcano Plot}. diff --git a/code/MOSuite/man/plot_volcano_summary.Rd b/code/MOSuite/man/plot_volcano_summary.Rd index b6d410c..25d5054 100644 --- a/code/MOSuite/man/plot_volcano_summary.Rd +++ b/code/MOSuite/man/plot_volcano_summary.Rd @@ -9,7 +9,8 @@ plot_volcano_summary( moo_diff, feature_id_colname = NULL, - signif_colname = "pval", + change_colname = NULL, + signif_colname = NULL, signif_threshold = 0.05, change_threshold = 1, value_to_sort_the_output_dataset = "t-statistic", @@ -17,28 +18,29 @@ plot_volcano_summary( add_features = FALSE, label_features = FALSE, custom_gene_list = "", + label_significant_features_only = TRUE, default_label_color = "black", - custom_label_color = "green3", - label_x_adj = 0.2, - label_y_adj = 0.2, - line_thickness = 0.5, - label_font_size = 4, - label_font_type = 1, - displace_feature_labels = FALSE, - custom_gene_list_special_label_displacement = "", - special_label_displacement_x_axis = 2, - special_label_displacement_y_axis = 2, - color_of_signif_threshold_line = "blue", - color_of_non_significant_features = "black", - color_of_logfold_change_threshold_line = "red", - color_of_features_meeting_only_signif_threshold = "lightgoldenrod2", - color_for_features_meeting_pvalue_and_foldchange_thresholds = "red", + custom_label_color = "black", + label_font_size = 7, + draw_connectors = FALSE, + change_sig_name = "p-value", + change_lfc_name = "log2FC", + title = "Volcano Plots", + title_font_size = 24, + use_custom_lab = FALSE, + color_of_signif_threshold_line = "black", + color_of_non_significant_features = "grey30", + color_of_logfold_change_threshold_line = "forestgreen", + color_of_features_meeting_only_signif_threshold = "royalblue", + color_for_features_meeting_pvalue_and_foldchange_thresholds = "red2", flip_vplot = FALSE, use_default_x_axis_limit = TRUE, x_axis_limit = 5, use_default_y_axis_limit = TRUE, y_axis_limit = 10, point_size = 2, + axis_lab_size = 24, + axis_tick_lab_size = 16, add_deg_columns = c("FC", "logFC", "tstat", "pval", "adjpval"), graphics_device = grDevices::png, image_width = 15, @@ -46,7 +48,6 @@ plot_volcano_summary( dpi = 300, use_default_grid_layout = TRUE, number_of_rows_in_grid_layout = 1, - aspect_ratio = 0, plot_filename = "volcano_summary.png", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), @@ -57,7 +58,8 @@ plot_volcano_summary( plot_volcano_summary( moo_diff, feature_id_colname = NULL, - signif_colname = "pval", + change_colname = NULL, + signif_colname = NULL, signif_threshold = 0.05, change_threshold = 1, value_to_sort_the_output_dataset = "t-statistic", @@ -65,28 +67,29 @@ plot_volcano_summary( add_features = FALSE, label_features = FALSE, custom_gene_list = "", + label_significant_features_only = TRUE, default_label_color = "black", - custom_label_color = "green3", - label_x_adj = 0.2, - label_y_adj = 0.2, - line_thickness = 0.5, - label_font_size = 4, - label_font_type = 1, - displace_feature_labels = FALSE, - custom_gene_list_special_label_displacement = "", - special_label_displacement_x_axis = 2, - special_label_displacement_y_axis = 2, - color_of_signif_threshold_line = "blue", - color_of_non_significant_features = "black", - color_of_logfold_change_threshold_line = "red", - color_of_features_meeting_only_signif_threshold = "lightgoldenrod2", - color_for_features_meeting_pvalue_and_foldchange_thresholds = "red", + custom_label_color = "black", + label_font_size = 7, + draw_connectors = FALSE, + change_sig_name = "p-value", + change_lfc_name = "log2FC", + title = "Volcano Plots", + title_font_size = 24, + use_custom_lab = FALSE, + color_of_signif_threshold_line = "black", + color_of_non_significant_features = "grey30", + color_of_logfold_change_threshold_line = "forestgreen", + color_of_features_meeting_only_signif_threshold = "royalblue", + color_for_features_meeting_pvalue_and_foldchange_thresholds = "red2", flip_vplot = FALSE, use_default_x_axis_limit = TRUE, x_axis_limit = 5, use_default_y_axis_limit = TRUE, y_axis_limit = 10, point_size = 2, + axis_lab_size = 24, + axis_tick_lab_size = 16, add_deg_columns = c("FC", "logFC", "tstat", "pval", "adjpval"), graphics_device = grDevices::png, image_width = 15, @@ -94,7 +97,6 @@ plot_volcano_summary( dpi = 300, use_default_grid_layout = TRUE, number_of_rows_in_grid_layout = 1, - aspect_ratio = 0, plot_filename = "volcano_summary.png", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), @@ -105,7 +107,8 @@ plot_volcano_summary( plot_volcano_summary( moo_diff, feature_id_colname = NULL, - signif_colname = "pval", + change_colname = NULL, + signif_colname = NULL, signif_threshold = 0.05, change_threshold = 1, value_to_sort_the_output_dataset = "t-statistic", @@ -113,28 +116,29 @@ plot_volcano_summary( add_features = FALSE, label_features = FALSE, custom_gene_list = "", + label_significant_features_only = TRUE, default_label_color = "black", - custom_label_color = "green3", - label_x_adj = 0.2, - label_y_adj = 0.2, - line_thickness = 0.5, - label_font_size = 4, - label_font_type = 1, - displace_feature_labels = FALSE, - custom_gene_list_special_label_displacement = "", - special_label_displacement_x_axis = 2, - special_label_displacement_y_axis = 2, - color_of_signif_threshold_line = "blue", - color_of_non_significant_features = "black", - color_of_logfold_change_threshold_line = "red", - color_of_features_meeting_only_signif_threshold = "lightgoldenrod2", - color_for_features_meeting_pvalue_and_foldchange_thresholds = "red", + custom_label_color = "black", + label_font_size = 7, + draw_connectors = FALSE, + change_sig_name = "p-value", + change_lfc_name = "log2FC", + title = "Volcano Plots", + title_font_size = 24, + use_custom_lab = FALSE, + color_of_signif_threshold_line = "black", + color_of_non_significant_features = "grey30", + color_of_logfold_change_threshold_line = "forestgreen", + color_of_features_meeting_only_signif_threshold = "royalblue", + color_for_features_meeting_pvalue_and_foldchange_thresholds = "red2", flip_vplot = FALSE, use_default_x_axis_limit = TRUE, x_axis_limit = 5, use_default_y_axis_limit = TRUE, y_axis_limit = 10, point_size = 2, + axis_lab_size = 24, + axis_tick_lab_size = 16, add_deg_columns = c("FC", "logFC", "tstat", "pval", "adjpval"), graphics_device = grDevices::png, image_width = 15, @@ -142,7 +146,6 @@ plot_volcano_summary( dpi = 300, use_default_grid_layout = TRUE, number_of_rows_in_grid_layout = 1, - aspect_ratio = 0, plot_filename = "volcano_summary.png", print_plots = options::opt("print_plots"), save_plots = options::opt("save_plots"), @@ -157,16 +160,22 @@ This is usually the first column of your input Counts Matrix. Only columns of Te Matrix will be available to select for this parameter. (Default: \code{NULL} - first column in the counts matrix will be used.)} -\item{signif_colname}{column name of significance values (e.g., adjusted p-values or FDR). This column will be used -to determine which points are considered significant in the volcano plot.} +\item{change_colname}{Character vector of full logFC column names, one per +contrast (e.g. \code{c("B-A_logFC", "C-A_logFC")}). Defaults to \code{NULL}, which +auto-detects all columns ending in \verb{_logFC}.} -\item{signif_threshold}{Numeric value specifying the significance cutoff for p-values (i.e. filters on -\code{signif_colname})} +\item{signif_colname}{Character vector of full significance column names, one +per contrast (e.g. \code{c("B-A_adjpval", "C-A_adjpval")}). Defaults to \code{NULL}, +which auto-detects corresponding columns by checking for \verb{_adjpval} first, +then \verb{_pval}, for each contrast in \code{change_colname}.} + +\item{signif_threshold}{Numeric significance threshold (p-value or adjusted p-value cutoff). Default: 0.05} \item{change_threshold}{Numeric value specifying the fold change cutoff for significance (i.e. filters on \code{change_colname})} -\item{value_to_sort_the_output_dataset}{How to sort the output dataset. Options are "fold-change" or "p-value".} +\item{value_to_sort_the_output_dataset}{How to sort the output dataset. Options are "fold-change", "p-value", or +"t-statistic".} \item{num_features_to_label}{Number of top features/genes to label in the volcano plot. Default is 30.} @@ -180,43 +189,41 @@ Features to Label" parameter.} \item{custom_gene_list}{Provide a list of features (comma separated) to be labeled on the volcano plot. You must toggle one of the following ON to see these labels: "Add features" or "Label Only My Feature List".} +\item{label_significant_features_only}{If \code{TRUE}, automatic labels are selected only from features that pass both +the significance and fold-change thresholds.} + \item{default_label_color}{Set the color for the text used to add feature (gene) name labels to points.} \item{custom_label_color}{Set the color for the specific list of features (features) provided in the "Feature List" parameter.} -\item{label_x_adj}{adjust position of the labels on the x-axis. Default: 0.2} - -\item{label_y_adj}{adjust position of the labels on the y-axis. Default: 0.2} - -\item{line_thickness}{Set the thickness of the lines in the plot. Default: 0.5} +\item{label_font_size}{Set the font size of the labels. Default: 7} -\item{label_font_size}{Set the font size of the labels. Default: 4} +\item{draw_connectors}{If \code{TRUE}, draw connector lines from labels to their points and spread labels to reduce +overlap.} -\item{label_font_type}{Set the font type of the labels. Default: 1} +\item{change_sig_name}{Name for the significance column in the plot. Default is "p-value".} -\item{displace_feature_labels}{Set to TRUE to displace gene labels. Default: FALSE. Set TRUE if you want to displace -the feature (gene) label for a specific set of features. Make sure to use custom x- and y- limits and give -sufficient space for displacement; otherwise other labels than the desired ones will appear displaced.} +\item{change_lfc_name}{Name for the fold change column in the plot. Default is "log2FC".} -\item{custom_gene_list_special_label_displacement}{Provide a list of features (comma separated) for which you want -special displacement of the feature label.} +\item{title}{Title of the plot. Default is "Volcano Plots".} -\item{special_label_displacement_x_axis}{Displacement of the feature label on the x-axis. Default: 2} +\item{title_font_size}{Size of the plot title. Default: 24} -\item{special_label_displacement_y_axis}{Displacement of the feature label on the y-axis. Default: 2} +\item{use_custom_lab}{If TRUE, uses custom labels for the plot axes, set by \code{change_sig_name} and +\code{change_lfc_name}.} -\item{color_of_signif_threshold_line}{Color of the significance threshold line. Default: "blue"} +\item{color_of_signif_threshold_line}{Color of the significance threshold line. Default: "black"} -\item{color_of_non_significant_features}{Color of the non-significant features. Default: "black"} +\item{color_of_non_significant_features}{Color of the non-significant features. Default: "grey30"} -\item{color_of_logfold_change_threshold_line}{Color of the log fold change threshold line. Default: "red"} +\item{color_of_logfold_change_threshold_line}{Color of the log fold change threshold line. Default: "forestgreen"} \item{color_of_features_meeting_only_signif_threshold}{Color of the features that meet only the significance -threshold. Default: "lightgoldenrod2"} +threshold. Default: "royalblue"} \item{color_for_features_meeting_pvalue_and_foldchange_thresholds}{Color of the features that meet both the p-value -and fold change thresholds. Default: "red"} +and fold change thresholds. Default: "red2"} \item{flip_vplot}{Set to TRUE to flip the fold change values so that the volcano plot looks like a comparison was B-A. Default: FALSE} @@ -231,6 +238,10 @@ B-A. Default: FALSE} \item{point_size}{Size of the points in the plot. Default: 1} +\item{axis_lab_size}{Size of the axis labels. Default: 24} + +\item{axis_tick_lab_size}{Size of the axis tick labels. Default: 16} + \item{add_deg_columns}{Add additional columns from the DEG analysis to the output dataset. Default: \verb{"FC", "logFC", "tstat", "pval", "adjpval"}} @@ -246,8 +257,6 @@ output dataset. Default: \verb{"FC", "logFC", "tstat", "pval", "adjpval"}} \item{number_of_rows_in_grid_layout}{Number of rows in the grid layout. Default: 1} -\item{aspect_ratio}{Aspect ratio of the output image. Default: 4/3} - \item{plot_filename}{Filename for the output plot. Default: "volcano_plot.png"} \item{print_plots}{Whether to print plots during analysis (Defaults to \code{FALSE}, overwritable using option 'moo_print_plots' or environment variable 'MOO_PRINT_PLOTS')} diff --git a/code/MOSuite/man/reexports.Rd b/code/MOSuite/man/reexports.Rd index 41acbe5..b16c098 100644 --- a/code/MOSuite/man/reexports.Rd +++ b/code/MOSuite/man/reexports.Rd @@ -6,6 +6,7 @@ \alias{:=} \alias{!!} \alias{.data} +\alias{\%||\%} \title{walrus operator} \keyword{internal} \description{ @@ -13,6 +14,6 @@ These objects are imported from other packages. Follow the links below to see their documentation. \describe{ - \item{rlang}{\code{\link[rlang::=]{:=()}}, \code{\link[rlang:!!]{!!()}}, \code{\link[rlang:.data]{.data}}} + \item{rlang}{\code{\link[rlang::=]{:=()}}, \code{\link[rlang:!!]{!!()}}, \code{\link[rlang:.data]{.data}}, \code{\link[rlang:\%||\%]{\%||\%}}} }} diff --git a/code/MOSuite/man/remove_low_count_genes.Rd b/code/MOSuite/man/remove_low_count_genes.Rd index 6564ecd..0069bdc 100644 --- a/code/MOSuite/man/remove_low_count_genes.Rd +++ b/code/MOSuite/man/remove_low_count_genes.Rd @@ -7,6 +7,7 @@ remove_low_count_genes( counts_dat, sample_metadata, + sample_id_colname = NULL, feature_id_colname, group_colname, use_cpm_counts_to_filter = TRUE, @@ -17,6 +18,10 @@ remove_low_count_genes( ) } \arguments{ +\item{sample_id_colname}{The column from the sample metadata containing the sample names. The names in this column +must exactly match the names used as the sample column names of your input Counts Matrix. (Default: \code{NULL} - first +column in the sample metadata will be used.)} + \item{feature_id_colname}{The column from the counts data containing the Feature IDs (Usually Gene or Protein ID). This is usually the first column of your input Counts Matrix. Only columns of Text type from your input Counts Matrix will be available to select for this parameter. (Default: \code{NULL} - first column in the counts matrix will be @@ -33,14 +38,17 @@ transformation will be applied and features will be filtered as is. For RNAseq d transformed to CPM in order to properly filter.} \item{use_group_based_filtering}{If TRUE, only keeps features (e.g. genes) that have at least a certain number of -samples with nonzero CPM counts in at least one group} +samples passing the threshold in at least one group} -\item{minimum_count_value_to_be_considered_nonzero}{Minimum count value to be considered non-zero for a sample} +\item{minimum_count_value_to_be_considered_nonzero}{Minimum value in the selected filtering table required for a +sample to be considered nonzero. If \code{use_cpm_counts_to_filter} is \code{TRUE}, this threshold is applied to CPM values. +If \code{use_cpm_counts_to_filter} is \code{FALSE}, this threshold is applied directly to the selected \code{count_type} table.} -\item{minimum_number_of_samples_with_nonzero_counts_in_total}{Minimum number of samples (total) with non-zero counts} +\item{minimum_number_of_samples_with_nonzero_counts_in_total}{Minimum number of samples in total that must meet the +\code{minimum_count_value_to_be_considered_nonzero} threshold for a feature to be kept.} \item{minimum_number_of_samples_with_nonzero_counts_in_a_group}{Only keeps genes that have at least this number of -samples with nonzero CPM counts in at least one group} +samples meeting the threshold in at least one group} } \value{ counts matrix with low-count genes removed diff --git a/code/MOSuite/man/render_report.Rd b/code/MOSuite/man/render_report.Rd new file mode 100644 index 0000000..e826af6 --- /dev/null +++ b/code/MOSuite/man/render_report.Rd @@ -0,0 +1,54 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/render_report.R +\name{render_report} +\alias{render_report} +\title{Render the template report} +\usage{ +render_report( + qmd_template = system.file("quarto", "report.qmd", package = "MOSuite"), + qmd_src = NULL, + ... +) +} +\arguments{ +\item{qmd_template}{Path to the Quarto report file (default is the template report in the package).} + +\item{qmd_src}{Optional path to copy the Quarto report template to before +rendering. If \code{NULL} (default), the template will be copied to the current +working directory with the same filename as the template. If a file already +exists at \code{qmd_src}, it will not be overwritten.} + +\item{...}{Additional arguments passed to \code{quarto::quarto_render()}, such as +\code{execute_params} (a named list of parameters) or \code{quarto_args} (a +character vector of CLI flags, e.g. \code{c("--output-dir", "/path/to/out")}).} +} +\description{ +Copy the Quarto template to the current working directory and render it +using \code{quarto::quarto_render()}. The rendered report will be saved in the +current working directory. You can specify additional arguments to +\code{quarto::quarto_render()} to customize the rendering process. +} +\details{ +You can edit the copy of \code{report.qmd} in the current working directory to customize the report. +} +\examples{ +render_report(execute_params = list( + counts_csv = system.file("extdata", "nidap", "Raw_Counts.csv.gz", + package = "MOSuite"), + samplesheet_csv = system.file("extdata", "nidap", + "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", + package = "MOSuite") +)) + +# Render to a specific output directory +render_report( + quarto_args = c("--output-dir", "./results"), + execute_params = list( + counts_csv = system.file("extdata", "nidap", "Raw_Counts.csv.gz", + package = "MOSuite"), + samplesheet_csv = system.file("extdata", "nidap", + "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", + package = "MOSuite") + ) +) +} diff --git a/code/MOSuite/man/resolve_plot_colors.Rd b/code/MOSuite/man/resolve_plot_colors.Rd new file mode 100644 index 0000000..7ea0498 --- /dev/null +++ b/code/MOSuite/man/resolve_plot_colors.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/colors.R +\name{resolve_plot_colors} +\alias{resolve_plot_colors} +\title{Resolve plotting colors for one column} +\usage{ +resolve_plot_colors( + dat, + colname, + color_values = NULL, + palette = mosuite_palette +) +} +\arguments{ +\item{dat}{data frame} + +\item{colname}{column name in \code{dat}} + +\item{color_values}{optional named or unnamed character vector of colors} + +\item{palette}{character vector of colors used to generate defaults} +} +\value{ +named character vector of colors matching observed values in +\code{dat[[colname]]} +} +\description{ +Uses \code{color_values} when supplied; otherwise generates colors with +\code{\link[=get_colors_vctr]{get_colors_vctr()}}. If \code{color_values} is named and covers all observed +values, it is returned as-is. If too few colors are provided, missing colors +are generated and appended. +} +\keyword{internal} diff --git a/code/MOSuite/man/resolve_volcano_colnames.Rd b/code/MOSuite/man/resolve_volcano_colnames.Rd new file mode 100644 index 0000000..d9db60f --- /dev/null +++ b/code/MOSuite/man/resolve_volcano_colnames.Rd @@ -0,0 +1,32 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/volcano.R +\name{resolve_volcano_colnames} +\alias{resolve_volcano_colnames} +\title{Resolve volcano plot column names} +\usage{ +resolve_volcano_colnames(diff_dat, change_colname, signif_colname) +} +\arguments{ +\item{diff_dat}{A data frame of differential analysis results.} + +\item{change_colname}{Character vector of logFC column names, or \code{NULL} to +auto-detect columns ending in \verb{_logFC}.} + +\item{signif_colname}{Character vector of significance column names, or +\code{NULL} to auto-detect, preferring \verb{_adjpval} over \verb{_pval}.} +} +\value{ +A named list with elements \code{change_colname} and \code{signif_colname}. +} +\description{ +Auto-detects \code{change_colname} and \code{signif_colname} from a data frame when +either is \code{NULL}. Used by \code{\link[=plot_volcano_enhanced]{plot_volcano_enhanced()}} and +\code{\link[=plot_volcano_summary]{plot_volcano_summary()}}. +} +\details{ +When \code{change_colname} is \code{NULL}, all columns ending in \verb{_logFC} are used. +When \code{signif_colname} is \code{NULL}, significance columns are detected by +checking for \verb{_adjpval} columns first, then \verb{_pval}, for each contrast +derived from \code{change_colname}. +} +\keyword{internal} diff --git a/code/MOSuite/man/select_mosuite_colors.Rd b/code/MOSuite/man/select_mosuite_colors.Rd new file mode 100644 index 0000000..bce7e2f --- /dev/null +++ b/code/MOSuite/man/select_mosuite_colors.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/colors.R +\name{select_mosuite_colors} +\alias{select_mosuite_colors} +\title{Select colors from MOSuite's default palette} +\usage{ +select_mosuite_colors(n, ...) +} +\arguments{ +\item{n}{number of colors to select.} + +\item{...}{additional arguments (ignored).} +} +\value{ +vector of colors in hex format. +} +\description{ +Select colors from MOSuite's default palette +} +\examples{ +select_mosuite_colors(5) +} diff --git a/code/MOSuite/man/set_color_pal.Rd b/code/MOSuite/man/set_color_pal.Rd index c603f0e..0759700 100644 --- a/code/MOSuite/man/set_color_pal.Rd +++ b/code/MOSuite/man/set_color_pal.Rd @@ -4,20 +4,18 @@ \alias{set_color_pal} \title{Set color palette for a single group/column} \usage{ -set_color_pal(moo, colname, palette_fun = grDevices::palette.colors, ...) +set_color_pal(moo, colname, palette = mosuite_palette) } \arguments{ \item{moo}{\code{multiOmicDataSet} object (see \code{create_multiOmicDataSet_from_dataframes()})} \item{colname}{group column name to set the palette for} -\item{palette_fun}{Function for selecting colors. Assumed to contain \code{n} for the number of colors. Default: -\code{grDevices::palette.colors()}} - -\item{...}{additional arguments forwarded to \code{palette_fun}} +\item{palette}{Character vector of colors to assign. Defaults to +\code{mosuite_palette}.} } \value{ -\code{moo} with colors updated at \code{moo@analyses$colors$colname} +\code{moo} with colors updated at \code{moo@analyses$colors[[colname]]} } \description{ This allows you to set custom palettes individually for groups in the dataset @@ -28,7 +26,7 @@ moo <- create_multiOmicDataSet_from_dataframes( counts_dat = as.data.frame(nidap_raw_counts) ) moo@analyses$colors$Group -moo <- moo |> set_color_pal("Group", palette_fun = RColorBrewer::brewer.pal, name = "Set2") +moo <- moo |> set_color_pal("Group", palette = RColorBrewer::brewer.pal(3, "Set2")) moo@analyses$colors$Group } diff --git a/code/MOSuite/tests/testthat/_snaps/E2E.md b/code/MOSuite/tests/testthat/_snaps/E2E.md index b420659..ac833d9 100644 --- a/code/MOSuite/tests/testthat/_snaps/E2E.md +++ b/code/MOSuite/tests/testthat/_snaps/E2E.md @@ -42,7 +42,6 @@ no duplicated IDs in gene_id * filtering clean counts Number of features after filtering: 291 - colors_for_plots NULL * normalizing filt counts Total number of features included: 291 Sample columns: KO_S3, Sample columns: KO_S4, Sample columns: WT_S1, Sample columns: WT_S2 @@ -82,7 +81,6 @@ no duplicated IDs in GeneName * filtering clean counts Number of features after filtering: 7943 - colors_for_plots NULL * normalizing filt counts Total number of features included: 7943 Sample columns: A1, Sample columns: A2, Sample columns: A3, Sample columns: B1, Sample columns: B2, Sample columns: B3, Sample columns: C1, Sample columns: C2, Sample columns: C3 diff --git a/code/MOSuite/tests/testthat/_snaps/plot_volcano_enhanced.md b/code/MOSuite/tests/testthat/_snaps/plot_volcano_enhanced.md index 58c8804..51fa756 100644 --- a/code/MOSuite/tests/testthat/_snaps/plot_volcano_enhanced.md +++ b/code/MOSuite/tests/testthat/_snaps/plot_volcano_enhanced.md @@ -8,6 +8,22 @@ Max y: 4.60041859457819 + Condition + Warning: + Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0. + i Please use `linewidth` instead. + i The deprecated feature was likely used in the EnhancedVolcano package. + Please report the issue to the authors. + Warning: + The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0. + i Please use the `linewidth` argument instead. + i The deprecated feature was likely used in the EnhancedVolcano package. + Please report the issue to the authors. + Message + Genes in initial dataset: 7943 + + Max y: 4.76491142795451 + Genes in initial dataset: 7943 Max y: 4.32577808863472 diff --git a/code/MOSuite/tests/testthat/_snaps/plot_volcano_summary.md b/code/MOSuite/tests/testthat/_snaps/plot_volcano_summary.md index 7b248c1..bc8b6ef 100644 --- a/code/MOSuite/tests/testthat/_snaps/plot_volcano_summary.md +++ b/code/MOSuite/tests/testthat/_snaps/plot_volcano_summary.md @@ -6,14 +6,40 @@ Message Preparing table for contrast: B-A Fold change column: B-A_logFC - pval column: B-A_pval + Significance column: B-A_adjpval Total number of features included in volcano plot: 7943 Preparing table for contrast: C-A Fold change column: C-A_logFC - pval column: C-A_pval + Significance column: C-A_adjpval Total number of features included in volcano plot: 7943 Preparing table for contrast: B-C Fold change column: B-C_logFC - pval column: B-C_pval + Significance column: B-C_adjpval Total number of features included in volcano plot: 7943 + + Running Enhanced Volcano: + Genes in initial dataset: 7943 + + Max y: 4.60041859457819 + + Condition + Warning: + Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0. + i Please use `linewidth` instead. + i The deprecated feature was likely used in the EnhancedVolcano package. + Please report the issue to the authors. + Warning: + The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0. + i Please use the `linewidth` argument instead. + i The deprecated feature was likely used in the EnhancedVolcano package. + Please report the issue to the authors. + Message + Genes in initial dataset: 7943 + + Max y: 4.76491142795451 + + Genes in initial dataset: 7943 + + Max y: 4.32577808863472 + diff --git a/code/MOSuite/tests/testthat/_snaps/plots/heatmap.png b/code/MOSuite/tests/testthat/_snaps/plots/heatmap.png new file mode 100644 index 0000000000000000000000000000000000000000..92664de7d329646e403c061c66235be3c5a250ee GIT binary patch literal 23016 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 batch_correct_counts( covariates_colnames = "condition", - batch_colname = "batch" + batch_colname = "batch", + label_colname = "sample_id" ), "Batch column 'batch' contains only 1 unique value" ) @@ -62,3 +63,389 @@ test_that("batch_correction warnings & errors", { "Batch column 'batch' cannot be included in covariates." ) }) + +test_that("batch_correct_counts forwards plot settings to PCA and histogram", { + pca_args <- NULL + histogram_args <- NULL + + local_mocked_bindings( + ComBat = function(dat, ...) dat, + .package = "sva" + ) + local_mocked_bindings( + plot_pca = function(...) { + pca_args <<- list(...) + return(ggplot2::ggplot()) + }, + plot_histogram = function(...) { + histogram_args <<- list(...) + return(ggplot2::ggplot()) + }, + print_or_save_plot = function(...) invisible(NULL), + .package = "MOSuite" + ) + + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "clean" = as.data.frame(nidap_clean_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts), + "norm" = list("voom" = as.data.frame(nidap_norm_counts)) + ) + ) + + batch_correct_counts( + moo, + count_type = "norm", + sub_count_type = "voom", + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = "Group", + batch_colname = "Batch", + label_colname = "Label", + samples_to_rename = c("A1:Alpha 1"), + add_label_to_pca = FALSE, + principal_component_on_x_axis = 2, + principal_component_on_y_axis = 3, + legend_position_for_pca = "bottom", + label_offset_x_ = 4, + label_offset_y_ = 5, + label_font_size = 6, + point_size_for_pca = 7, + color_histogram_by_group = FALSE, + set_min_max_for_x_axis_for_histogram = TRUE, + minimum_for_x_axis_for_histogram = -2, + maximum_for_x_axis_for_histogram = 2, + legend_font_size_for_histogram = 11, + legend_position_for_histogram = "right", + number_of_histogram_legend_columns = 2, + colors_for_plots = c(A = "red", B = "blue", C = "green"), + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expect_equal(pca_args$samples_to_rename, c("A1:Alpha 1")) + expect_equal(pca_args$principal_components, c(2, 3)) + expect_equal(pca_args$legend_position, "bottom") + expect_equal(pca_args$point_size, 7) + expect_null(pca_args$label_colname) + expect_equal(pca_args$label_font_size, 6) + expect_equal(pca_args$label_offset_x_, 4) + expect_equal(pca_args$label_offset_y_, 5) + expect_equal(pca_args$color_values, c(A = "red", B = "blue", C = "green")) + + expect_false(histogram_args$color_by_group) + expect_true(histogram_args$set_min_max_for_x_axis) + expect_equal(histogram_args$minimum_for_x_axis, -2) + expect_equal(histogram_args$maximum_for_x_axis, 2) + expect_equal(histogram_args$x_axis_label, "Batch Corrected Counts") + expect_equal(histogram_args$legend_font_size, 11) + expect_equal(histogram_args$legend_position, "right") + expect_equal(histogram_args$number_of_legend_columns, 2) + expect_equal(histogram_args$color_values, moo@analyses[["colors"]][["Label"]]) + + pca_args <- NULL + batch_correct_counts( + moo, + count_type = "norm", + sub_count_type = "voom", + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = "Group", + batch_colname = "Batch", + label_colname = "Label", + add_label_to_pca = TRUE, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + expect_equal(pca_args$label_colname, "Label") +}) + +test_that("batch_correct_counts handles histogram label combinations", { + pca_args <- NULL + histogram_args <- NULL + group_colors <- c(A = "red", B = "blue", C = "green") + + local_mocked_bindings( + ComBat = function(dat, ...) dat, + .package = "sva" + ) + local_mocked_bindings( + plot_pca = function(...) { + pca_args <<- list(...) + return(ggplot2::ggplot()) + }, + plot_histogram = function(...) { + histogram_args <<- list(...) + return(ggplot2::ggplot()) + }, + print_or_save_plot = function(...) invisible(NULL), + .package = "MOSuite" + ) + + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "clean" = as.data.frame(nidap_clean_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts), + "norm" = list("voom" = as.data.frame(nidap_norm_counts)) + ) + ) + + combinations <- list( + list( + label_colname = NULL, + color_histogram_by_group = FALSE, + interactive_plots = FALSE + ), + list( + label_colname = NULL, + color_histogram_by_group = FALSE, + interactive_plots = TRUE + ), + list( + label_colname = NULL, + color_histogram_by_group = TRUE, + interactive_plots = FALSE + ), + list( + label_colname = NULL, + color_histogram_by_group = TRUE, + interactive_plots = TRUE + ), + list( + label_colname = "Label", + color_histogram_by_group = FALSE, + interactive_plots = FALSE + ), + list( + label_colname = "Label", + color_histogram_by_group = FALSE, + interactive_plots = TRUE + ), + list( + label_colname = "Label", + color_histogram_by_group = TRUE, + interactive_plots = FALSE + ), + list( + label_colname = "Label", + color_histogram_by_group = TRUE, + interactive_plots = TRUE + ) + ) + + for (combination in combinations) { + pca_args <- NULL + histogram_args <- NULL + batch_correct_counts( + moo, + count_type = "norm", + sub_count_type = "voom", + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = "Group", + batch_colname = "Batch", + label_colname = combination$label_colname, + color_histogram_by_group = combination$color_histogram_by_group, + interactive_plots = combination$interactive_plots, + colors_for_plots = group_colors, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expected_label_colname <- if (is.null(combination$label_colname)) { + "Sample" + } else { + combination$label_colname + } + expected_histogram_colors <- if ( + isTRUE(combination$color_histogram_by_group) + ) { + group_colors + } else { + moo@analyses[["colors"]][[expected_label_colname]] + } + + expect_equal(pca_args$label_colname, combination$label_colname) + expect_equal(histogram_args$label_colname, expected_label_colname) + expect_equal( + histogram_args$color_by_group, + combination$color_histogram_by_group + ) + expect_equal( + histogram_args$interactive_plots, + combination$interactive_plots + ) + expect_equal(histogram_args$color_values, expected_histogram_colors) + } +}) + +test_that("batch_correct_counts forwards the default MOSuite plot colors", { + pca_args <- NULL + histogram_args <- NULL + expected_colors <- c( + "1" = "#ff9287", + "2" = "#008cf9" + ) + + local_mocked_bindings( + ComBat = function(dat, ...) dat, + .package = "sva" + ) + local_mocked_bindings( + plot_pca = function(...) { + pca_args <<- list(...) + return(ggplot2::ggplot()) + }, + plot_histogram = function(...) { + histogram_args <<- list(...) + return(ggplot2::ggplot()) + }, + print_or_save_plot = function(...) invisible(NULL), + .package = "MOSuite" + ) + + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "clean" = as.data.frame(nidap_clean_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts), + "norm" = list("voom" = as.data.frame(nidap_norm_counts)) + ) + ) + + batch_correct_counts( + moo, + count_type = "norm", + sub_count_type = "voom", + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = "Group", + batch_colname = "Batch", + label_colname = "Label", + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expect_equal(pca_args$color_values, expected_colors) + expect_equal(histogram_args$color_values, expected_colors) +}) + +test_that("batch_correct_counts PCA matches standalone plot_pca on batch output", { + pca_capture <- capture_saved_pca_plot() + local_mocked_bindings( + print_or_save_plot = pca_capture$print_or_save_plot, + .package = "MOSuite" + ) + + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "clean" = as.data.frame(nidap_clean_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts), + "norm" = list("voom" = as.data.frame(nidap_norm_counts)) + ) + ) |> + batch_correct_counts( + count_type = "norm", + sub_count_type = "voom", + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = "Group", + batch_colname = "Batch", + label_colname = NULL, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expected_pca <- plot_pca( + moo@counts$batch, + sample_metadata = moo@sample_meta, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Batch", + label_colname = NULL, + samples_to_rename = c(""), + principal_components = c(1, 2), + legend_position = "top", + point_size = 5, + label_font_size = 3, + label_offset_y_ = 2, + label_offset_x_ = 2, + log_transform = FALSE, + print_plots = FALSE, + save_plots = FALSE + ) + + expect_s3_class(pca_capture$get(), "ggplot") + expect_pca_coordinates_equal(pca_capture$get(), expected_pca) +}) + +test_that("batch_correct_counts histogram matches standalone plot_histogram on batch output", { + histogram_capture <- capture_saved_histogram_plot() + local_mocked_bindings( + print_or_save_plot = histogram_capture$print_or_save_plot, + .package = "MOSuite" + ) + + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "clean" = as.data.frame(nidap_clean_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts), + "norm" = list("voom" = as.data.frame(nidap_norm_counts)) + ) + ) |> + batch_correct_counts( + count_type = "norm", + sub_count_type = "voom", + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = "Group", + batch_colname = "Batch", + label_colname = NULL, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE, + interactive_plots = FALSE + ) + + expected_histogram <- plot_histogram( + moo@counts$batch, + sample_metadata = moo@sample_meta, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Batch", + color_values = moo@analyses$colors[["Batch"]], + label_colname = NULL, + color_by_group = TRUE, + set_min_max_for_x_axis = FALSE, + minimum_for_x_axis = -1, + maximum_for_x_axis = 1, + x_axis_label = "Batch Corrected Counts", + legend_position = "top", + legend_font_size = NULL, + number_of_legend_columns = 6, + interactive_plots = FALSE + ) + + ggplot2::labs(caption = "batch-corrected counts") + + expect_s3_class(histogram_capture$get(), "ggplot") + expect_histogram_layers_equal(histogram_capture$get(), expected_histogram) +}) diff --git a/code/MOSuite/tests/testthat/test-clean.R b/code/MOSuite/tests/testthat/test-clean.R index 475c239..40197a6 100644 --- a/code/MOSuite/tests/testthat/test-clean.R +++ b/code/MOSuite/tests/testthat/test-clean.R @@ -67,6 +67,193 @@ test_that("clean_raw_counts works for RENEE data", { ) }) +test_that("clean_raw_counts plots CPM histogram after cleaning without all-zero genes", { + captured_histogram_counts <- NULL + histogram_args <- NULL + saved_filenames <- character() + group_colors <- c(A = "red", B = "blue") + + local_mocked_bindings( + plot_histogram = function(moo_counts, ...) { + captured_histogram_counts <<- moo_counts + histogram_args <<- list(...) + ggplot2::ggplot() + }, + print_or_save_plot = function(plot, filename, ...) { + saved_filenames <<- c(saved_filenames, basename(filename)) + invisible(NULL) + }, + .package = "MOSuite" + ) + + counts_dat <- data.frame( + GeneName = c("all_zero", "keep_one", "keep_one"), + S1 = c(0, 10, 5), + S2 = c(0, 0, 5), + check.names = FALSE + ) + sample_metadata <- data.frame( + Sample = c("S1", "S2"), + Group = c("A", "B"), + check.names = FALSE + ) + + create_multiOmicDataSet_from_dataframes( + sample_metadata = sample_metadata, + counts_dat = counts_dat, + sample_id_colname = "Sample", + feature_id_colname = "GeneName" + ) |> + clean_raw_counts( + sample_id_colname = "Sample", + feature_id_colname = "GeneName", + group_colname = "Group", + colors_for_plots = group_colors, + split_gene_name = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expect_true("read_depth.png" %in% saved_filenames) + expect_true("cpm_histogram.png" %in% saved_filenames) + expect_equal(captured_histogram_counts$GeneName, "keep_one") + expect_equal(captured_histogram_counts$S1, 1e6) + expect_equal(captured_histogram_counts$S2, 1e6) + expect_equal(histogram_args$group_colname, "Group") + expect_equal(histogram_args$color_values, group_colors) + expect_true(histogram_args$color_by_group) +}) + +test_that("strip_ensembl_version removes version suffix", { + ids <- c("ENSG00000121410.11", "ENSG00000268895.5", "ENSG00000148584.15") + result <- MOSuite:::strip_ensembl_version(ids) + expect_equal( + result, + c("ENSG00000121410", "ENSG00000268895", "ENSG00000148584") + ) +}) + +test_that("strip_ensembl_version is a no-op for IDs without version", { + ids <- c("ENSG00000121410", "ENSG00000268895") + result <- MOSuite:::strip_ensembl_version(ids) + expect_equal(result, ids) +}) + +test_that("separate_gene_meta_columns splits Ensembl|GeneName format", { + counts_dat <- data.frame( + `ENSG00000121410|A1BG` = c(10, 20), + sample1 = c(100, 200), + check.names = FALSE + ) + colnames(counts_dat)[1] <- "ENSG00000121410|A1BG" + # Rename so first col is the feature ID + counts_dat2 <- data.frame( + feature_id = c("ENSG00000121410|A1BG", "ENSG00000268895|A1BG-AS1"), + sample1 = c(100, 200), + stringsAsFactors = FALSE + ) + result <- MOSuite:::separate_gene_meta_columns( + counts_dat2, + split_gene_name = TRUE + ) + expect_true("Ensembl_ID" %in% colnames(result)) + expect_equal(result$Ensembl_ID, c("ENSG00000121410", "ENSG00000268895")) +}) + +test_that("separate_gene_meta_columns strips Ensembl version when present", { + counts_dat <- data.frame( + feature_id = c("ENSG00000121410.11|A1BG", "ENSG00000268895.5|A1BG-AS1"), + sample1 = c(100, 200), + stringsAsFactors = FALSE + ) + result <- MOSuite:::separate_gene_meta_columns( + counts_dat, + split_gene_name = TRUE + ) + expect_true("Ensembl_ID" %in% colnames(result)) + expect_true("Ensembl_ID_version" %in% colnames(result)) + expect_equal(result$Ensembl_ID, c("ENSG00000121410", "ENSG00000268895")) + expect_equal( + result$Ensembl_ID_version, + c("ENSG00000121410.11", "ENSG00000268895.5") + ) +}) + +test_that("separate_gene_meta_columns uses Feature_id_1/2 when format unknown", { + counts_dat <- data.frame( + feature_id = c("geneA|isoform1", "geneB|isoform2"), + sample1 = c(10, 20), + stringsAsFactors = FALSE + ) + result <- MOSuite:::separate_gene_meta_columns( + counts_dat, + split_gene_name = TRUE + ) + expect_true("Feature_id_1" %in% colnames(result)) + expect_true("Feature_id_2" %in% colnames(result)) +}) + +test_that("separate_gene_meta_columns does not split when split_gene_name = FALSE", { + counts_dat <- data.frame( + feature_id = c("ENSG00000121410|A1BG", "ENSG00000268895|other"), + sample1 = c(10, 20), + stringsAsFactors = FALSE + ) + result <- MOSuite:::separate_gene_meta_columns( + counts_dat, + split_gene_name = FALSE + ) + expect_equal(colnames(result)[1], "feature_id") + expect_equal(ncol(result), 2) +}) + +test_that("clean_raw_counts cleans column names with special characters", { + counts_dat <- data.frame( + GeneName = c("geneA", "geneB"), + `sample-1` = c(10, 20), + `sample 2` = c(30, 40), + check.names = FALSE + ) + meta <- data.frame(Sample = c("sample-1", "sample 2")) + moo <- create_multiOmicDataSet_from_dataframes( + sample_metadata = meta, + counts_dat = counts_dat, + sample_id_colname = "Sample" + ) + result <- clean_raw_counts( + moo, + sample_id_colname = "Sample", + feature_id_colname = "GeneName", + cleanup_column_names = TRUE + ) + clean_cols <- colnames(result@counts$clean) + expect_false(any(grepl("-| ", clean_cols))) +}) + +test_that("clean_raw_counts prefixes numeric-starting column names with X", { + counts_dat <- data.frame( + GeneName = c("geneA", "geneB"), + `1sample` = c(10, 20), + `2sample` = c(30, 40), + check.names = FALSE + ) + meta <- data.frame(Sample = c("1sample", "2sample")) + moo <- create_multiOmicDataSet_from_dataframes( + sample_metadata = meta, + counts_dat = counts_dat, + sample_id_colname = "Sample" + ) + result <- clean_raw_counts( + moo, + sample_id_colname = "Sample", + feature_id_colname = "GeneName", + cleanup_column_names = TRUE + ) + clean_cols <- colnames(result@counts$clean) + expect_false(any(grepl("^[0-9]", clean_cols))) + expect_true(any(grepl("^X[0-9]", clean_cols))) +}) + test_that("aggregate_duplicate_gene_names returns collapsed dfout", { counts_dat <- data.frame( gene_id = c("A", "A", "B"), diff --git a/code/MOSuite/tests/testthat/test-cli.R b/code/MOSuite/tests/testthat/test-cli.R index 8d580fb..42d57fb 100644 --- a/code/MOSuite/tests/testthat/test-cli.R +++ b/code/MOSuite/tests/testthat/test-cli.R @@ -12,14 +12,14 @@ write_example_json <- function() { ), moo_output_rds = "moo.rds" ) - return(jsonlite::write_json(j, "inst/extdata/example.json")) + return(jsonlite::write_json(j, "tests/testthat/data/example_args.json")) } test_that("mosuite cli", { command <- paste0( system.file("exec", "mosuite", package = "MOSuite"), " create_multiOmicDataSet_from_files --json=", - system.file("extdata", "example.json", package = "MOSuite") + test_path("data", "example_args.json") ) expect_snapshot(system(command)) }) @@ -37,7 +37,7 @@ test_that("cli_exec --json --debug", { "create_multiOmicDataSet_from_files", paste0( '--json="', - system.file("extdata", "example.json", package = "MOSuite"), + test_path("data", "example_args.json"), '"' ), "--debug" @@ -56,7 +56,7 @@ test_that("cli_exec --json --debug", { "filter_counts", paste0( '--json="', - system.file("extdata", "example.json", package = "MOSuite"), + test_path("data", "example_args.json"), '"' ), "--debug" @@ -82,6 +82,21 @@ test_that("mosuite --help", { expect_error(cli_exec("not_a_function"), "not a known function") }) +test_that("cli_parse handles logical-like strings", { + expect_true(cli_parse("true")) + expect_true(cli_parse("True")) + expect_true(cli_parse("TRUE")) + expect_false(cli_parse("false")) + expect_false(cli_parse("False")) + expect_false(cli_parse("FALSE")) +}) + +test_that("cli_exec_impl passes positional args", { + # Positional args are parsed via cli_parse() and appended as unnamed elements. + expect_equal(cli_exec(c("do_math", "TRUE", "FALSE")), 3) + expect_equal(cli_exec(c("do_math", "FALSE", "TRUE")), -1) +}) + test_that("cli_unknown suggests closest matching function", { # Test with a typo that has a close match result <- cli_unknown("filter_count", getNamespaceExports("MOSuite")) @@ -98,55 +113,3 @@ test_that("cli_unknown suggests closest matching function", { expect_match(result, "xyz123 is not a known function") expect_false(grepl("Did you mean", result)) }) - -test_that("mosuite cli E2E", { - new <- tempfile() - create_empty_dir(new) - # note: file paths in json files assume all files are in the current workdir - withr::with_dir(new = new, code = { - file.copy( - system.file("extdata", "nidap", "Raw_Counts.csv.gz", package = "MOSuite"), - "./" - ) - file.copy( - system.file( - "extdata", - "nidap", - "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", - package = "MOSuite" - ), - "./" - ) - json_paths <- system.file( - "extdata", - "json_args", - "common", - package = "MOSuite" - ) - Sys.glob(glue::glue("{json_paths}/*.json")) |> - lapply(function(x) { - return(file.copy(x, "./")) - }) - - run_function_cli("create_multiOmicDataSet_from_files") - run_function_cli("clean_raw_counts") - run_function_cli("filter_counts") - run_function_cli("normalize_counts") - run_function_cli("batch_correct_counts") - run_function_cli("diff_counts") - run_function_cli("filter_diff") - run_function_cli("write_multiOmicDataSet_properties") - run_function_cli("plot_expr_heatmap") - # run_function_cli("plot_pca_2d") - # run_function_cli("plot_pca_3d") - # run_function_cli("plot_volcano_enhanced") - # run_function_cli("plot_volcano_summary") - # run_function_cli("plot_venn_diagram") - - expect_true(file.exists(file.path("moo", "sample_metadata.csv"))) - expect_true(file.exists("moo_diff_filter.rds")) - moo <- readr::read_rds("moo_diff_filter.rds") - expect_equal(names(moo@counts), c("raw", "clean", "filt", "norm", "batch")) - expect_equal(names(moo@analyses), c("colors", "diff", "diff_filt")) - }) -}) diff --git a/code/MOSuite/tests/testthat/test-colors.R b/code/MOSuite/tests/testthat/test-colors.R index 3aea8b4..67b7290 100644 --- a/code/MOSuite/tests/testthat/test-colors.R +++ b/code/MOSuite/tests/testthat/test-colors.R @@ -13,65 +13,60 @@ test_that("get_colors_lst works on nidap_sample_metadata", { get_colors_lst(nidap_sample_metadata), list( Sample = c( - A1 = "#000000", - A2 = "#E69F00", - A3 = "#56B4E9", - B1 = "#009E73", - B2 = "#F0E442", - B3 = "#0072B2", - C1 = "#D55E00", - C2 = "#CC79A7", - C3 = "#999999" + A1 = "#5954d6", + A2 = "#e1562c", + A3 = "#b80058", + B1 = "#00c6f8", + B2 = "#d163e6", + B3 = "#00a76c", + C1 = "#ff9287", + C2 = "#008cf9", + C3 = "#006e00" ), Group = c( - A = "#000000", - B = "#E69F00", - C = "#56B4E9" + A = "#5954d6", + B = "#e1562c", + C = "#b80058" ), Replicate = c( - `1` = "#000000", - `2` = "#E69F00", - `3` = "#56B4E9" + `1` = "#00c6f8", + `2` = "#d163e6", + `3` = "#00a76c" ), - Batch = c(`1` = "#000000", `2` = "#E69F00"), + Batch = c(`1` = "#ff9287", `2` = "#008cf9"), Label = c( - A1 = "#000000", - A2 = "#E69F00", - A3 = "#56B4E9", - B1 = "#009E73", - B2 = "#F0E442", - B3 = "#0072B2", - C1 = "#D55E00", - C2 = "#CC79A7", - C3 = "#999999" + A1 = "#5954d6", + A2 = "#e1562c", + A3 = "#b80058", + B1 = "#00c6f8", + B2 = "#d163e6", + B3 = "#00a76c", + C1 = "#ff9287", + C2 = "#008cf9", + C3 = "#006e00" ) ) ) }) -test_that("get_colors_lst handles alternative palette functions", { +test_that("get_colors_lst handles alternative palette vectors", { sample_meta <- system.file( "extdata", "sample_metadata.tsv.gz", package = "MOSuite" ) |> readr::read_tsv() - expect_message( - expect_warning( - get_colors_lst( - sample_meta, - palette_fun = RColorBrewer::brewer.pal, - name = "Set3" - ), - "minimal value for n is 3" - ), - "Warning raised in " + result <- get_colors_lst( + sample_meta, + palette = RColorBrewer::brewer.pal(12, "Set3") ) + expect_type(result, "list") + expect_length(result, ncol(sample_meta)) }) test_that("get_colors_vctr falls back to random colors when n exceeds palette max", { - # Okabe-Ito palette has a maximum of 9 colors. When n > 9, the function + # MOSuite's default palette has 12 colors. When n > 12, the function # should fall back to get_random_colors() and emit a message. dat_many_cats <- data.frame( - group = paste0("cat", seq_len(12)) + group = paste0("cat", seq_len(13)) ) expect_no_warning( expect_message( @@ -79,8 +74,204 @@ test_that("get_colors_vctr falls back to random colors when n exceeds palette ma "exceeds the palette maximum" ) ) - expect_length(result, 12) - expect_named(result, paste0("cat", seq_len(12))) + expect_length(result, 13) + expect_named(result, paste0("cat", seq_len(13))) +}) + +test_that("get_colors_vctr retries from offset 0 when offset pushes past palette end", { + # Palette has 12 colors; offset=10, n_obs=5: 10+5=15 > 12, so retry without offset. + # The column should receive palette colors 1-5, not random colors. + dat <- data.frame(group = paste0("x", seq_len(5))) + result <- get_colors_vctr(dat, "group", color_offset = 10L) + expect_length(result, 5) + expect_named(result, paste0("x", seq_len(5))) + # Should get the first 5 palette colors (same as offset=0), not random + expected <- get_colors_vctr(dat, "group", color_offset = 0L) + expect_equal(result, expected) +}) + +test_that("get_colors_lst columns exceeding palette size fall back to random colors", { + # 13 unique values exceeds the 12-color mosuite_palette; should message and use random colors + dat_big <- data.frame(group = paste0("cat", seq_len(13))) + expect_no_warning( + expect_message( + result <- get_colors_lst(dat_big), + "exceeds the palette maximum" + ) + ) + expect_length(result$group, 13) + expect_named(result$group, paste0("cat", seq_len(13))) +}) + +test_that("resolve_plot_colors preserves named color mappings", { + dat <- data.frame(group = c("B", "A", "C", "A")) + colors <- c(A = "red", B = "blue", C = "green") + + expect_equal(resolve_plot_colors(dat, "group", colors), colors) +}) + +test_that("resolve_plot_colors names palettes by first observed category order", { + dat <- data.frame(group = c("B", "A", "C", "A")) + colors <- c("red", "blue", "green") + + expect_equal( + resolve_plot_colors(dat, "group", colors), + c(B = "red", A = "blue", C = "green") + ) +}) + +test_that("color vectors use factor level order when grouping column is a factor", { + dat <- data.frame( + group = factor(c("B", "A", "C", "A"), levels = c("C", "A", "B", "D")) + ) + + expect_equal( + get_colors_vctr(dat, "group"), + c(C = "#5954d6", A = "#e1562c", B = "#b80058") + ) + expect_equal( + resolve_plot_colors(dat, "group", c("red", "blue", "green")), + c(C = "red", A = "blue", B = "green") + ) +}) + +test_that("resolve_plot_colors generates colors when none are supplied", { + dat <- data.frame(group = c("B", "A", "C", "A")) + + expect_equal( + resolve_plot_colors(dat, "group"), + c(B = "#5954d6", A = "#e1562c", C = "#b80058") + ) +}) + +test_that("resolve_plot_colors generates additional colors for too few explicit colors", { + dat <- data.frame(group = c("B", "A", "C", "A")) + + expect_message( + result <- resolve_plot_colors(dat, "group", c("red", "blue")), + "Generating 1 additional colors" + ) + expect_named(result, c("B", "A", "C")) + expect_equal(unname(result[1:2]), c("red", "blue")) + expect_equal(unname(result[3]), "#b80058") +}) + +test_that("resolve_plot_colors uses random fallback only through get_colors_vctr", { + dat <- data.frame(group = paste0("cat", seq_len(13))) + colors <- c( + "#5954d6", + "#e1562c", + "#b80058", + "#00c6f8", + "#d163e6", + "#00a76c", + "#ff9287", + "#008cf9", + "#006e00", + "#796880", + "#FFA500", + "#878500" + ) + + expect_message( + expect_message( + result <- resolve_plot_colors(dat, "group", colors), + "Generating 1 additional colors" + ), + "exceeds the palette maximum" + ) + expect_named(result, paste0("cat", seq_len(13))) + expect_equal(unname(result[seq_along(colors)]), colors) + expect_match(unname(result[13]), "^#[0-9A-F]{6}$") +}) + +test_that("resolve_plot_colors treats non-matching names as palette labels", { + dat <- data.frame(group = c("B", "A", "C", "A")) + + expect_equal( + resolve_plot_colors( + dat, + "group", + c(indigo = "red", carrot = "blue", jade = "green") + ), + c(B = "red", A = "blue", C = "green") + ) +}) + +test_that("select_mosuite_colors returns n colors from mosuite_palette", { + result <- select_mosuite_colors(3) + expect_length(result, 3) + expect_true(all(grepl("^#", result))) +}) + +test_that("select_mosuite_colors clamps to palette length when n exceeds it", { + pal_len <- length(mosuite_palette) + result <- select_mosuite_colors(pal_len + 10) + expect_length(result, pal_len) +}) + +test_that("get_observed_values drops NAs and returns unique values in first-seen order", { + dat <- data.frame(group = c("B", NA, "A", "B", NA)) + result <- MOSuite:::get_observed_values(dat, "group") + expect_equal(result, c("B", "A")) +}) + +test_that("get_observed_values respects factor level order and excludes unseen levels", { + dat <- data.frame( + group = factor(c("B", "A", NA), levels = c("C", "A", "B", "D")) + ) + result <- MOSuite:::get_observed_values(dat, "group") + # "C" and "D" are levels but never observed; should be excluded + expect_equal(result, c("A", "B")) +}) + +test_that("get_colors_vctr returns empty character vector when column has zero observed values", { + expect_equal( + get_colors_vctr(data.frame(group = character(0)), "group"), + character(0) + ) + expect_equal( + get_colors_vctr( + data.frame(group = c(NA_character_, NA_character_)), + "group" + ), + character(0) + ) +}) + +test_that("get_colors_vctr handles a column with NA values", { + dat <- data.frame(group = c("A", NA, "B", "A")) + result <- get_colors_vctr(dat, "group") + expect_length(result, 2) + expect_named(result, c("A", "B")) +}) + +test_that("resolve_plot_colors returns color_values unchanged when column has no observations", { + dat <- data.frame(group = character(0)) + colors <- c(A = "red") + result <- MOSuite:::resolve_plot_colors(dat, "group", color_values = colors) + expect_equal(result, colors) +}) + +test_that("resolve_plot_colors returns color_values unchanged when column is all NA", { + dat <- data.frame(group = c(NA_character_, NA_character_)) + colors <- c(A = "red") + result <- MOSuite:::resolve_plot_colors(dat, "group", color_values = colors) + expect_equal(result, colors) +}) + +test_that("display_palette returns a ggplot invisibly", { + result <- display_palette(c("#FF0000", "#00FF00", "#0000FF")) + expect_s3_class(result, "gg") +}) + +test_that("display_colors returns a patchwork object", { + moo <- create_multiOmicDataSet_from_dataframes( + sample_metadata = as.data.frame(nidap_sample_metadata), + counts_dat = as.data.frame(nidap_raw_counts) + ) + result <- display_colors(moo) + expect_s3_class(result, "patchwork") }) test_that("set_color_pal overrides the color palette", { @@ -92,59 +283,58 @@ test_that("set_color_pal overrides the color palette", { moo@analyses$colors, list( Sample = c( - A1 = "#000000", - A2 = "#E69F00", - A3 = "#56B4E9", - B1 = "#009E73", - B2 = "#F0E442", - B3 = "#0072B2", - C1 = "#D55E00", - C2 = "#CC79A7", - C3 = "#999999" + A1 = "#5954d6", + A2 = "#e1562c", + A3 = "#b80058", + B1 = "#00c6f8", + B2 = "#d163e6", + B3 = "#00a76c", + C1 = "#ff9287", + C2 = "#008cf9", + C3 = "#006e00" ), Group = c( - A = "#000000", - B = "#E69F00", - C = "#56B4E9" + A = "#5954d6", + B = "#e1562c", + C = "#b80058" ), Replicate = c( - `1` = "#000000", - `2` = "#E69F00", - `3` = "#56B4E9" + `1` = "#00c6f8", + `2` = "#d163e6", + `3` = "#00a76c" ), - Batch = c(`1` = "#000000", `2` = "#E69F00"), + Batch = c(`1` = "#ff9287", `2` = "#008cf9"), Label = c( - A1 = "#000000", - A2 = "#E69F00", - A3 = "#56B4E9", - B1 = "#009E73", - B2 = "#F0E442", - B3 = "#0072B2", - C1 = "#D55E00", - C2 = "#CC79A7", - C3 = "#999999" + A1 = "#5954d6", + A2 = "#e1562c", + A3 = "#b80058", + B1 = "#00c6f8", + B2 = "#d163e6", + B3 = "#00a76c", + C1 = "#ff9287", + C2 = "#008cf9", + C3 = "#006e00" ) ) ) moo2 <- moo |> set_color_pal( colname = "Group", - palette_fun = RColorBrewer::brewer.pal, - name = "Set2" + palette = RColorBrewer::brewer.pal(3, "Set2") ) expect_equal( moo2@analyses$colors, list( Sample = c( - A1 = "#000000", - A2 = "#E69F00", - A3 = "#56B4E9", - B1 = "#009E73", - B2 = "#F0E442", - B3 = "#0072B2", - C1 = "#D55E00", - C2 = "#CC79A7", - C3 = "#999999" + A1 = "#5954d6", + A2 = "#e1562c", + A3 = "#b80058", + B1 = "#00c6f8", + B2 = "#d163e6", + B3 = "#00a76c", + C1 = "#ff9287", + C2 = "#008cf9", + C3 = "#006e00" ), Group = c( A = "#66C2A5", @@ -152,21 +342,21 @@ test_that("set_color_pal overrides the color palette", { C = "#8DA0CB" ), Replicate = c( - `1` = "#000000", - `2` = "#E69F00", - `3` = "#56B4E9" + `1` = "#00c6f8", + `2` = "#d163e6", + `3` = "#00a76c" ), - Batch = c(`1` = "#000000", `2` = "#E69F00"), + Batch = c(`1` = "#ff9287", `2` = "#008cf9"), Label = c( - A1 = "#000000", - A2 = "#E69F00", - A3 = "#56B4E9", - B1 = "#009E73", - B2 = "#F0E442", - B3 = "#0072B2", - C1 = "#D55E00", - C2 = "#CC79A7", - C3 = "#999999" + A1 = "#5954d6", + A2 = "#e1562c", + A3 = "#b80058", + B1 = "#00c6f8", + B2 = "#d163e6", + B3 = "#00a76c", + C1 = "#ff9287", + C2 = "#008cf9", + C3 = "#006e00" ) ) ) diff --git a/code/MOSuite/tests/testthat/test-filter.R b/code/MOSuite/tests/testthat/test-filter.R index aabfc78..3fccbd0 100644 --- a/code/MOSuite/tests/testthat/test-filter.R +++ b/code/MOSuite/tests/testthat/test-filter.R @@ -203,6 +203,227 @@ test_that("remove_low_count_genes works", { ) }) +test_that("remove_low_count_genes counts threshold values inclusively", { + df <- data.frame( + Gene = c("exact_keep", "below_minimum", "above_keep"), + S1 = c(4, 4, 5), + S2 = c(5, 0, 5), + S3 = c(0, 0, 0), + check.names = FALSE + ) + sample_meta <- data.frame( + Sample = c("S1", "S2", "S3"), + Group = c("A", "A", "A"), + row.names = c("S1", "S2", "S3"), + check.names = FALSE + ) + + result <- remove_low_count_genes( + counts_dat = df, + sample_metadata = sample_meta, + feature_id_colname = "Gene", + group_colname = "Group", + use_cpm_counts_to_filter = FALSE, + use_group_based_filtering = FALSE, + minimum_count_value_to_be_considered_nonzero = 4, + minimum_number_of_samples_with_nonzero_counts_in_total = 2, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 2 + ) + + expect_equal(result$Gene, c("exact_keep", "above_keep")) +}) + +test_that("remove_low_count_genes uses original filter threshold parameters", { + df <- data.frame( + Gene = c("keep", "remove"), + S1 = c(4, 4), + S2 = c(4, 0), + check.names = FALSE + ) + sample_meta <- data.frame( + Sample = c("S1", "S2"), + Group = c("A", "A"), + row.names = c("S1", "S2"), + check.names = FALSE + ) + + result <- remove_low_count_genes( + counts_dat = df, + sample_metadata = sample_meta, + feature_id_colname = "Gene", + group_colname = "Group", + use_cpm_counts_to_filter = FALSE, + use_group_based_filtering = FALSE, + minimum_count_value_to_be_considered_nonzero = 4, + minimum_number_of_samples_with_nonzero_counts_in_total = 2, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 2 + ) + + expect_equal(result$Gene, "keep") +}) + +test_that("remove_low_count_genes ignores non-numeric annotation columns", { + df <- data.frame( + Gene = c("keep", "remove"), + Symbol = c("A", "B"), + S1 = c(4, 4), + S2 = c(4, 0), + check.names = FALSE + ) + sample_meta <- data.frame( + Sample = c("S1", "S2"), + Group = c("A", "A"), + row.names = c("S1", "S2"), + check.names = FALSE + ) + + result <- remove_low_count_genes( + counts_dat = df, + sample_metadata = sample_meta, + feature_id_colname = "Gene", + group_colname = "Group", + use_cpm_counts_to_filter = FALSE, + use_group_based_filtering = FALSE, + minimum_count_value_to_be_considered_nonzero = 4, + minimum_number_of_samples_with_nonzero_counts_in_total = 2, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 2 + ) + + expect_equal(result$Gene, "keep") + expect_equal(result$Symbol, "A") +}) + +test_that("remove_low_count_genes distinguishes total sample minimum 8 from 9", { + sample_names <- paste0("S", 1:10) + df <- data.frame( + Gene = c("passes_exactly_eight", "passes_nine"), + S1 = c(4, 4), + S2 = c(4, 4), + S3 = c(4, 4), + S4 = c(4, 4), + S5 = c(4, 4), + S6 = c(4, 4), + S7 = c(4, 4), + S8 = c(4, 4), + S9 = c(0, 4), + S10 = c(0, 0), + check.names = FALSE + ) + sample_meta <- data.frame( + Sample = sample_names, + Group = rep("A", length(sample_names)), + row.names = sample_names, + check.names = FALSE + ) + + total_8 <- remove_low_count_genes( + counts_dat = df, + sample_metadata = sample_meta, + feature_id_colname = "Gene", + group_colname = "Group", + use_cpm_counts_to_filter = FALSE, + use_group_based_filtering = FALSE, + minimum_count_value_to_be_considered_nonzero = 4, + minimum_number_of_samples_with_nonzero_counts_in_total = 8, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 2 + ) + total_9 <- remove_low_count_genes( + counts_dat = df, + sample_metadata = sample_meta, + feature_id_colname = "Gene", + group_colname = "Group", + use_cpm_counts_to_filter = FALSE, + use_group_based_filtering = FALSE, + minimum_count_value_to_be_considered_nonzero = 4, + minimum_number_of_samples_with_nonzero_counts_in_total = 9, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 2 + ) + + expect_equal(total_8$Gene, c("passes_exactly_eight", "passes_nine")) + expect_equal(total_9$Gene, "passes_nine") +}) + +test_that("remove_low_count_genes applies sample minimum within groups", { + df <- data.frame( + Gene = c( + "group_exact_keep", + "split_across_groups", + "one_group_keep", + "single_sample_total_only" + ), + S1 = c(4, 4, 0, 5), + S2 = c(4, 0, 0, 0), + S3 = c(0, 4, 5, 0), + S4 = c(0, 0, 4, 0), + check.names = FALSE + ) + sample_meta <- data.frame( + Sample = c("S1", "S2", "S3", "S4"), + Group = c("A", "A", "B", "B"), + row.names = paste0("metadata_row_", 1:4), + check.names = FALSE + ) + + group_result <- remove_low_count_genes( + counts_dat = df, + sample_metadata = sample_meta, + feature_id_colname = "Gene", + group_colname = "Group", + use_cpm_counts_to_filter = FALSE, + use_group_based_filtering = TRUE, + minimum_count_value_to_be_considered_nonzero = 4, + minimum_number_of_samples_with_nonzero_counts_in_total = 1, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 2 + ) + non_group_result <- remove_low_count_genes( + counts_dat = df, + sample_metadata = sample_meta, + feature_id_colname = "Gene", + group_colname = "Group", + use_cpm_counts_to_filter = FALSE, + use_group_based_filtering = FALSE, + minimum_count_value_to_be_considered_nonzero = 4, + minimum_number_of_samples_with_nonzero_counts_in_total = 2, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 2 + ) + + expect_equal(group_result$Gene, c("group_exact_keep", "one_group_keep")) + expect_equal( + non_group_result$Gene, + c("group_exact_keep", "split_across_groups", "one_group_keep") + ) +}) + +test_that("remove_low_count_genes ignores missing group assignments", { + df <- data.frame( + Gene = c("keep", "remove"), + S1 = c(4, 4), + S2 = c(4, 0), + S3 = c(0, 4), + check.names = FALSE + ) + sample_meta <- data.frame( + Sample = c("S1", "S2", "S3"), + Group = c("A", "A", NA), + row.names = c("S1", "S2", "S3"), + check.names = FALSE + ) + + result <- remove_low_count_genes( + counts_dat = df, + sample_metadata = sample_meta, + feature_id_colname = "Gene", + group_colname = "Group", + use_cpm_counts_to_filter = FALSE, + use_group_based_filtering = TRUE, + minimum_count_value_to_be_considered_nonzero = 4, + minimum_number_of_samples_with_nonzero_counts_in_total = 1, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 2 + ) + + expect_equal(result$Gene, "keep") +}) + test_that("remove_low_count_genes works with group-based filtering (no grouped tibble crash)", { df <- data.frame( Gene = c( @@ -251,3 +472,421 @@ test_that("remove_low_count_genes works with group-based filtering (no grouped t expect_true("Gene" %in% colnames(result)) expect_true(nrow(result) > 0) }) + +test_that("filter_counts forwards plotting parameters", { + pca_args <- NULL + histogram_args <- NULL + + local_mocked_bindings( + plot_pca = function(...) { + pca_args <<- list(...) + return(ggplot2::ggplot()) + }, + plot_histogram = function(...) { + histogram_args <<- list(...) + return(ggplot2::ggplot()) + }, + print_or_save_plot = function(...) invisible(NULL), + .package = "MOSuite" + ) + + moo <- create_multiOmicDataSet_from_dataframes( + as.data.frame(nidap_sample_metadata), + as.data.frame(nidap_clean_raw_counts), + sample_id_colname = "Sample", + feature_id_colname = "Gene" + ) |> + calc_cpm(feature_id_colname = "Gene") + + filter_counts( + moo, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + label_colname = "Label", + count_type = "raw", + samples_to_rename = c("A1:Alpha 1"), + add_label_to_pca = FALSE, + principal_component_on_x_axis = 2, + principal_component_on_y_axis = 3, + legend_position_for_pca = "bottom", + label_offset_x_ = 4, + label_offset_y_ = 5, + label_font_size = 6, + point_size_for_pca = 7, + color_histogram_by_group = TRUE, + set_min_max_for_x_axis_for_histogram = TRUE, + minimum_for_x_axis_for_histogram = -2, + maximum_for_x_axis_for_histogram = 2, + legend_font_size_for_histogram = 11, + legend_position_for_histogram = "right", + number_of_histogram_legend_columns = 2, + colors_for_plots = c(A = "red", B = "blue", C = "green"), + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expect_equal(pca_args$samples_to_rename, c("A1:Alpha 1")) + expect_equal(pca_args$principal_components, c(2, 3)) + expect_equal(pca_args$legend_position, "bottom") + expect_equal(pca_args$point_size, 7) + expect_null(pca_args$label_colname) + expect_equal(pca_args$label_font_size, 6) + expect_equal(pca_args$label_offset_x_, 4) + expect_equal(pca_args$label_offset_y_, 5) + expect_equal(pca_args$color_values, c(A = "red", B = "blue", C = "green")) + + expect_true(histogram_args$color_by_group) + expect_true(histogram_args$set_min_max_for_x_axis) + expect_equal(histogram_args$minimum_for_x_axis, -2) + expect_equal(histogram_args$maximum_for_x_axis, 2) + expect_equal(histogram_args$x_axis_label, "CPM") + expect_equal(histogram_args$legend_font_size, 11) + expect_equal(histogram_args$legend_position, "right") + expect_equal(histogram_args$number_of_legend_columns, 2) + expect_equal( + histogram_args$color_values, + c(A = "red", B = "blue", C = "green") + ) + + pca_args <- NULL + filter_counts( + moo, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + label_colname = "Label", + count_type = "raw", + add_label_to_pca = TRUE, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + expect_equal(pca_args$label_colname, "Label") +}) + +test_that("filter_counts handles histogram label combinations", { + pca_args <- NULL + histogram_args <- NULL + group_colors <- c(A = "red", B = "blue", C = "green") + + local_mocked_bindings( + plot_pca = function(...) { + pca_args <<- list(...) + return(ggplot2::ggplot()) + }, + plot_histogram = function(...) { + histogram_args <<- list(...) + return(ggplot2::ggplot()) + }, + print_or_save_plot = function(...) invisible(NULL), + .package = "MOSuite" + ) + + moo <- create_multiOmicDataSet_from_dataframes( + as.data.frame(nidap_sample_metadata), + as.data.frame(nidap_clean_raw_counts), + sample_id_colname = "Sample", + feature_id_colname = "Gene" + ) |> + calc_cpm(feature_id_colname = "Gene") + + combinations <- list( + list( + label_colname = NULL, + color_histogram_by_group = FALSE, + interactive_plots = FALSE + ), + list( + label_colname = NULL, + color_histogram_by_group = FALSE, + interactive_plots = TRUE + ), + list( + label_colname = NULL, + color_histogram_by_group = TRUE, + interactive_plots = FALSE + ), + list( + label_colname = NULL, + color_histogram_by_group = TRUE, + interactive_plots = TRUE + ), + list( + label_colname = "Label", + color_histogram_by_group = FALSE, + interactive_plots = FALSE + ), + list( + label_colname = "Label", + color_histogram_by_group = FALSE, + interactive_plots = TRUE + ), + list( + label_colname = "Label", + color_histogram_by_group = TRUE, + interactive_plots = FALSE + ), + list( + label_colname = "Label", + color_histogram_by_group = TRUE, + interactive_plots = TRUE + ) + ) + + for (combination in combinations) { + pca_args <- NULL + histogram_args <- NULL + filter_counts( + moo, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + label_colname = combination$label_colname, + count_type = "raw", + color_histogram_by_group = combination$color_histogram_by_group, + interactive_plots = combination$interactive_plots, + colors_for_plots = group_colors, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expected_label_colname <- if (is.null(combination$label_colname)) { + "Sample" + } else { + combination$label_colname + } + expected_histogram_colors <- if ( + isTRUE(combination$color_histogram_by_group) + ) { + group_colors + } else { + moo@analyses[["colors"]][[expected_label_colname]] + } + + expect_equal(pca_args$label_colname, combination$label_colname) + expect_equal(histogram_args$label_colname, expected_label_colname) + expect_equal( + histogram_args$color_by_group, + combination$color_histogram_by_group + ) + expect_equal( + histogram_args$interactive_plots, + combination$interactive_plots + ) + expect_equal(histogram_args$color_values, expected_histogram_colors) + } +}) + +test_that("filter_counts forwards the default MOSuite plot colors", { + pca_args <- NULL + histogram_args <- NULL + default_colors <- c( + "A" = "#5954d6", + "B" = "#e1562c", + "C" = "#b80058" + ) + + local_mocked_bindings( + plot_pca = function(...) { + pca_args <<- list(...) + return(ggplot2::ggplot()) + }, + plot_histogram = function(...) { + histogram_args <<- list(...) + return(ggplot2::ggplot()) + }, + print_or_save_plot = function(...) invisible(NULL), + .package = "MOSuite" + ) + + moo <- create_multiOmicDataSet_from_dataframes( + as.data.frame(nidap_sample_metadata), + as.data.frame(nidap_clean_raw_counts), + sample_id_colname = "Sample", + feature_id_colname = "Gene" + ) |> + calc_cpm(feature_id_colname = "Gene") + + filter_counts( + moo, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + label_colname = "Label", + count_type = "raw", + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expect_equal(pca_args$color_values, default_colors) + expect_equal(histogram_args$color_values, default_colors) +}) + +test_that("filter_counts adds a dotted threshold line and label to the histogram", { + histogram_plot <- NULL + histogram_args <- NULL + + local_mocked_bindings( + plot_pca = function(...) { + return(ggplot2::ggplot()) + }, + plot_histogram = function(...) { + histogram_args <<- list(...) + return(ggplot2::ggplot()) + }, + print_or_save_plot = function(plot, filename, ...) { + if (basename(filename) == "histogram.png") { + histogram_plot <<- plot + } + return(invisible(NULL)) + }, + .package = "MOSuite" + ) + + moo <- create_multiOmicDataSet_from_dataframes( + as.data.frame(nidap_sample_metadata), + as.data.frame(nidap_clean_raw_counts), + sample_id_colname = "Sample", + feature_id_colname = "Gene" + ) + + filter_counts( + moo, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + label_colname = "Label", + count_type = "raw", + minimum_count_value_to_be_considered_nonzero = 4, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + histogram_data <- ggplot2::ggplot_build(histogram_plot)$data + + expect_true(histogram_args$use_log2_x_axis) + expect_true(histogram_args$return_ggplot) + expect_equal(histogram_data[[1]]$xintercept, 4 + 0.5) + expect_equal(histogram_data[[1]]$linetype, 2) + expect_equal(histogram_data[[1]]$linewidth, 1) + expect_equal(histogram_data[[2]]$x, 4 + 0.5) + expect_equal(histogram_data[[2]]$label, "CPM: 4") +}) + +test_that("filter_counts PCA matches standalone plot_pca on filtered output", { + pca_capture <- capture_saved_pca_plot() + local_mocked_bindings( + print_or_save_plot = pca_capture$print_or_save_plot, + .package = "MOSuite" + ) + + moo <- create_multiOmicDataSet_from_dataframes( + as.data.frame(nidap_sample_metadata), + as.data.frame(nidap_clean_raw_counts), + sample_id_colname = "Sample", + feature_id_colname = "Gene" + ) |> + filter_counts( + sample_id_colname = "Sample", + feature_id_colname = "Gene", + label_colname = NULL, + count_type = "raw", + use_cpm_counts_to_filter = FALSE, + minimum_count_value_to_be_considered_nonzero = 8, + minimum_number_of_samples_with_nonzero_counts_in_total = 7, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expected_pca <- plot_pca( + moo@counts$filt, + sample_metadata = moo@sample_meta, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + label_colname = NULL, + samples_to_rename = c(""), + principal_components = c(1, 2), + legend_position = "top", + point_size = 5, + label_font_size = 3, + label_offset_y_ = 2, + label_offset_x_ = 2, + log_transform = TRUE, + log_transform_pseudocount = 0.5, + log_transform_base = "ln", + print_plots = FALSE, + save_plots = FALSE + ) + + expect_s3_class(pca_capture$get(), "ggplot") + expect_pca_coordinates_equal(pca_capture$get(), expected_pca) +}) + +test_that("filter_counts histogram matches standalone plot_histogram on filtered output", { + histogram_capture <- capture_saved_histogram_plot() + local_mocked_bindings( + print_or_save_plot = histogram_capture$print_or_save_plot, + .package = "MOSuite" + ) + + moo <- create_multiOmicDataSet_from_dataframes( + as.data.frame(nidap_sample_metadata), + as.data.frame(nidap_clean_raw_counts), + sample_id_colname = "Sample", + feature_id_colname = "Gene" + ) |> + filter_counts( + sample_id_colname = "Sample", + feature_id_colname = "Gene", + label_colname = NULL, + count_type = "raw", + use_cpm_counts_to_filter = FALSE, + minimum_count_value_to_be_considered_nonzero = 8, + minimum_number_of_samples_with_nonzero_counts_in_total = 7, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE, + interactive_plots = FALSE + ) + + histogram_threshold_x <- 8 + 0.5 + expected_histogram <- plot_histogram( + moo@counts$filt, + sample_metadata = moo@sample_meta, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + label_colname = NULL, + color_by_group = TRUE, + set_min_max_for_x_axis = FALSE, + minimum_for_x_axis = -1, + maximum_for_x_axis = 1, + x_axis_label = "Count", + legend_position = "top", + legend_font_size = NULL, + number_of_legend_columns = 6, + interactive_plots = FALSE, + return_ggplot = TRUE, + use_log2_x_axis = TRUE + ) + + ggplot2::labs(caption = "filtered counts") + + ggplot2::geom_vline( + xintercept = histogram_threshold_x, + linetype = 2, + linewidth = 1 + ) + + ggplot2::annotate( + "text", + x = histogram_threshold_x, + y = Inf, + label = "Count: 8", + hjust = -0.05, + vjust = 1.5, + size = 3 + ) + + expect_s3_class(histogram_capture$get(), "ggplot") + expect_histogram_layers_equal(histogram_capture$get(), expected_histogram) +}) diff --git a/code/MOSuite/tests/testthat/test-normalize.R b/code/MOSuite/tests/testthat/test-normalize.R index 87318d4..46f7182 100644 --- a/code/MOSuite/tests/testthat/test-normalize.R +++ b/code/MOSuite/tests/testthat/test-normalize.R @@ -137,3 +137,346 @@ test_that("normalize works for RENEE", { ) ) }) + +test_that("normalize_counts forwards plotting parameters", { + pca_args <- NULL + histogram_args <- NULL + + local_mocked_bindings( + plot_pca = function(...) { + pca_args <<- list(...) + ggplot2::ggplot() + }, + plot_histogram = function(...) { + histogram_args <<- list(...) + ggplot2::ggplot() + }, + print_or_save_plot = function(...) invisible(NULL), + .package = "MOSuite" + ) + + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "clean" = as.data.frame(nidap_clean_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ) + ) + + normalize_counts( + moo, + group_colname = "Group", + label_colname = "Label", + samples_to_rename = c("A1:Alpha 1"), + add_label_to_pca = FALSE, + principal_component_on_x_axis = 2, + principal_component_on_y_axis = 3, + legend_position_for_pca = "bottom", + label_offset_x_ = 4, + label_offset_y_ = 5, + label_font_size = 6, + point_size_for_pca = 7, + color_histogram_by_group = FALSE, + set_min_max_for_x_axis_for_histogram = TRUE, + minimum_for_x_axis_for_histogram = -2, + maximum_for_x_axis_for_histogram = 2, + legend_font_size_for_histogram = 11, + legend_position_for_histogram = "right", + number_of_histogram_legend_columns = 2, + colors_for_plots = c(A = "red", B = "blue", C = "green"), + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expect_equal(pca_args$samples_to_rename, c("A1:Alpha 1")) + expect_equal(pca_args$principal_components, c(2, 3)) + expect_equal(pca_args$legend_position, "bottom") + expect_equal(pca_args$point_size, 7) + expect_null(pca_args$label_colname) + expect_equal(pca_args$label_font_size, 6) + expect_equal(pca_args$label_offset_x_, 4) + expect_equal(pca_args$label_offset_y_, 5) + expect_equal(pca_args$color_values, c(A = "red", B = "blue", C = "green")) + + expect_false(histogram_args$color_by_group) + expect_true(histogram_args$set_min_max_for_x_axis) + expect_equal(histogram_args$minimum_for_x_axis, -2) + expect_equal(histogram_args$maximum_for_x_axis, 2) + expect_equal(histogram_args$legend_font_size, 11) + expect_equal(histogram_args$legend_position, "right") + expect_equal(histogram_args$number_of_legend_columns, 2) + expect_equal(histogram_args$color_values, moo@analyses[["colors"]][["Label"]]) + + pca_args <- NULL + normalize_counts( + moo, + group_colname = "Group", + label_colname = "Label", + add_label_to_pca = TRUE, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + expect_equal(pca_args$label_colname, "Label") +}) + +test_that("normalize_counts handles histogram label combinations", { + pca_args <- NULL + histogram_args <- NULL + group_colors <- c(A = "red", B = "blue", C = "green") + + local_mocked_bindings( + plot_pca = function(...) { + pca_args <<- list(...) + ggplot2::ggplot() + }, + plot_histogram = function(...) { + histogram_args <<- list(...) + ggplot2::ggplot() + }, + print_or_save_plot = function(...) invisible(NULL), + .package = "MOSuite" + ) + + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "clean" = as.data.frame(nidap_clean_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ) + ) + + combinations <- list( + list( + label_colname = NULL, + color_histogram_by_group = FALSE, + interactive_plots = FALSE + ), + list( + label_colname = NULL, + color_histogram_by_group = FALSE, + interactive_plots = TRUE + ), + list( + label_colname = NULL, + color_histogram_by_group = TRUE, + interactive_plots = FALSE + ), + list( + label_colname = NULL, + color_histogram_by_group = TRUE, + interactive_plots = TRUE + ), + list( + label_colname = "Label", + color_histogram_by_group = FALSE, + interactive_plots = FALSE + ), + list( + label_colname = "Label", + color_histogram_by_group = FALSE, + interactive_plots = TRUE + ), + list( + label_colname = "Label", + color_histogram_by_group = TRUE, + interactive_plots = FALSE + ), + list( + label_colname = "Label", + color_histogram_by_group = TRUE, + interactive_plots = TRUE + ) + ) + + for (combination in combinations) { + pca_args <- NULL + histogram_args <- NULL + normalize_counts( + moo, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + label_colname = combination$label_colname, + color_histogram_by_group = combination$color_histogram_by_group, + interactive_plots = combination$interactive_plots, + colors_for_plots = group_colors, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expected_label_colname <- if (is.null(combination$label_colname)) { + "Sample" + } else { + combination$label_colname + } + expected_histogram_colors <- if ( + isTRUE(combination$color_histogram_by_group) + ) { + group_colors + } else { + moo@analyses[["colors"]][[expected_label_colname]] + } + + expect_equal(pca_args$label_colname, combination$label_colname) + expect_equal(histogram_args$label_colname, expected_label_colname) + expect_equal( + histogram_args$color_by_group, + combination$color_histogram_by_group + ) + expect_equal( + histogram_args$interactive_plots, + combination$interactive_plots + ) + expect_equal(histogram_args$color_values, expected_histogram_colors) + } +}) + +test_that("normalize_counts forwards the default MOSuite plot colors", { + pca_args <- NULL + histogram_args <- NULL + default_colors <- c( + "A" = "#5954d6", + "B" = "#e1562c", + "C" = "#b80058" + ) + + local_mocked_bindings( + plot_pca = function(...) { + pca_args <<- list(...) + ggplot2::ggplot() + }, + plot_histogram = function(...) { + histogram_args <<- list(...) + ggplot2::ggplot() + }, + print_or_save_plot = function(...) invisible(NULL), + .package = "MOSuite" + ) + + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "clean" = as.data.frame(nidap_clean_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ) + ) + + normalize_counts( + moo, + group_colname = "Group", + label_colname = "Label", + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expect_equal(pca_args$color_values, default_colors) + expect_equal(histogram_args$color_values, default_colors) +}) + +test_that("normalize_counts PCA matches standalone plot_pca on normalized output", { + pca_capture <- capture_saved_pca_plot() + local_mocked_bindings( + print_or_save_plot = pca_capture$print_or_save_plot, + .package = "MOSuite" + ) + + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "clean" = as.data.frame(nidap_clean_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ) + ) |> + normalize_counts( + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + label_colname = NULL, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE + ) + + expected_pca <- plot_pca( + moo@counts$norm$voom, + sample_metadata = moo@sample_meta, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + label_colname = NULL, + samples_to_rename = c(""), + principal_components = c(1, 2), + legend_position = "top", + point_size = 5, + label_font_size = 3, + label_offset_y_ = 2, + label_offset_x_ = 2, + log_transform = FALSE, + print_plots = FALSE, + save_plots = FALSE + ) + + expect_s3_class(pca_capture$get(), "ggplot") + expect_pca_coordinates_equal(pca_capture$get(), expected_pca) +}) + +test_that("normalize_counts histogram matches standalone plot_histogram on normalized output", { + histogram_capture <- capture_saved_histogram_plot() + local_mocked_bindings( + print_or_save_plot = histogram_capture$print_or_save_plot, + .package = "MOSuite" + ) + + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "clean" = as.data.frame(nidap_clean_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ) + ) |> + normalize_counts( + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + label_colname = NULL, + plot_corr_matrix_heatmap = FALSE, + print_plots = TRUE, + save_plots = FALSE, + interactive_plots = FALSE + ) + + expected_histogram <- plot_histogram( + moo@counts$norm$voom, + sample_metadata = moo@sample_meta, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + label_colname = NULL, + color_by_group = TRUE, + x_axis_label = "Normalized Counts", + set_min_max_for_x_axis = FALSE, + minimum_for_x_axis = -1, + maximum_for_x_axis = 1, + legend_position = "top", + legend_font_size = NULL, + number_of_legend_columns = 6, + interactive_plots = FALSE + ) + + ggplot2::labs(caption = "normalized counts") + + expect_s3_class(histogram_capture$get(), "ggplot") + expect_histogram_layers_equal(histogram_capture$get(), expected_histogram) +}) diff --git a/code/MOSuite/tests/testthat/test-plot_heatmap.R b/code/MOSuite/tests/testthat/test-plot_heatmap.R index ba9fb1a..6eb11f2 100644 --- a/code/MOSuite/tests/testthat/test-plot_heatmap.R +++ b/code/MOSuite/tests/testthat/test-plot_heatmap.R @@ -121,6 +121,40 @@ test_that("correlation heatmap works", { ) }) +test_that("correlation heatmap resolves annotation colors by first observed group order", { + counts_dat <- nidap_filtered_counts[, c( + "Gene", + "B1", + "B2", + "B3", + "A1", + "A2", + "A3", + "C1", + "C2", + "C3" + )] + sample_metadata <- as.data.frame(nidap_sample_metadata) + sample_metadata <- sample_metadata[ + match(colnames(counts_dat)[-1], sample_metadata$Sample), + ] + + p <- plot_corr_heatmap( + counts_dat, + sample_metadata = sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + label_colname = "Label", + group_colname = "Group", + color_values = c("#5954d6", "#e1562c", "#b80058") + ) + + expect_equal( + p@top_annotation@anno_list$Group@color_mapping@colors[c("B", "A", "C")], + c(B = "#5954D6FF", A = "#E1562CFF", C = "#B80058FF") + ) +}) + test_that("plot_corr_heatmap method dispatch works", { moo <- multiOmicDataSet( sample_metadata = as.data.frame(nidap_sample_metadata), @@ -261,3 +295,290 @@ test_that("plot_expr_heatmap works", { expect_equal(p_moo@matrix, p_dat@matrix) }) + +test_that("plot_expr_heatmap uses stored colors for all group_columns from moo@analyses$colors", { + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "norm" = list("voom" = as.data.frame(nidap_norm_counts)) + ) + ) + custom_colors <- list( + Group = c(A = "#AA0000", B = "#00AA00", C = "#0000AA"), + Replicate = c("1" = "#111111", "2" = "#222222", "3" = "#333333"), + Batch = c("1" = "#AAAAAA", "2" = "#BBBBBB") + ) + moo@analyses$colors <- custom_colors + + expect_message( + p <- plot_expr_heatmap( + moo, + count_type = "norm", + sub_count_type = "voom", + feature_id_colname = "Gene", + group_columns = c("Group", "Replicate", "Batch") + ), + "total number of genes in heatmap", + fixed = FALSE + ) + + expect_equal( + p@top_annotation@anno_list$Group@color_mapping@colors, + c(A = "#AA0000FF", B = "#00AA00FF", C = "#0000AAFF") + ) + expect_equal( + p@top_annotation@anno_list$Replicate@color_mapping@colors, + c("1" = "#111111FF", "2" = "#222222FF", "3" = "#333333FF") + ) + expect_equal( + p@top_annotation@anno_list$Batch@color_mapping@colors, + c("1" = "#AAAAAAFF", "2" = "#BBBBBBFF") + ) +}) + +test_that("plot_expr_heatmap resolves annotation colors by first observed group order", { + counts_dat <- nidap_norm_counts[, c( + "Gene", + "B1", + "B2", + "B3", + "A1", + "A2", + "A3", + "C1", + "C2", + "C3" + )] + sample_metadata <- as.data.frame(nidap_sample_metadata) + sample_metadata <- sample_metadata[ + match(colnames(counts_dat)[-1], sample_metadata$Sample), + ] + + expect_message( + p <- plot_expr_heatmap( + as.data.frame(counts_dat), + sample_metadata = sample_metadata, + feature_id_colname = "Gene", + samples_to_include = colnames(counts_dat)[-1], + group_columns = "Group", + group_colors = c("#5954d6", "#e1562c", "#b80058") + ), + "total number of genes in heatmap", + fixed = FALSE + ) + + expect_equal( + p@top_annotation@anno_list$Group@color_mapping@colors[c("B", "A", "C")], + c(B = "#5954D6FF", A = "#E1562CFF", C = "#B80058FF") + ) +}) + +test_that("plot_expr_heatmap uses selected gene distance metric", { + counts_dat <- data.frame( + Gene = paste0("g", 1:8), + s1 = c( + -0.6264538, + 0.1836433, + -0.8356286, + 1.5952808, + 0.3295078, + -0.8204684, + 0.4874291, + 0.7383247 + ), + s2 = c( + 0.57578135, + -0.30538839, + 1.51178117, + 0.38984324, + -0.62124058, + -2.21469989, + 1.12493092, + -0.04493361 + ), + s3 = c( + -0.01619026, + 0.94383621, + 0.82122120, + 0.59390132, + 0.91897737, + 0.78213630, + 0.07456498, + -1.98935170 + ), + s4 = c( + 0.61982575, + -0.05612874, + -0.15579551, + -1.47075238, + -0.47815006, + 0.41794156, + 1.35867955, + -0.10278773 + ), + s5 = c( + 0.38767161, + -0.05380504, + -1.37705956, + -0.41499456, + -0.39428995, + -0.05931340, + 1.10002537, + 0.76317575 + ), + check.names = FALSE + ) + sample_metadata <- data.frame( + Sample = paste0("s", 1:5), + Group = c("A", "A", "B", "B", "C") + ) + + common_args <- list( + moo_counts = counts_dat, + sample_metadata = sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + include_all_genes = TRUE, + filter_top_genes_by_variance = FALSE, + center_and_rescale_expression = FALSE, + cluster_genes = TRUE, + gene_clustering_method = "complete", + cluster_samples = FALSE, + arrange_sample_columns = TRUE, + group_columns = "Group", + print_plots = FALSE, + save_plots = FALSE + ) + + expect_message( + p_euclidean <- do.call( + plot_expr_heatmap, + c(common_args, list(gene_distance_metric = "euclidean")) + ), + "total number of genes in heatmap" + ) + expect_message( + p_correlation <- do.call( + plot_expr_heatmap, + c(common_args, list(gene_distance_metric = "correlation")) + ), + "total number of genes in heatmap" + ) + + expect_equal( + p_euclidean@row_dend_param$obj$order, + c(2, 5, 4, 3, 1, 7, 8, 6) + ) + expect_equal( + p_correlation@row_dend_param$obj$order, + c(2, 5, 6, 3, 4, 1, 7, 8) + ) +}) + +test_that("plot_expr_heatmap uses selected sample clustering method", { + counts_dat <- data.frame( + Gene = paste0("g", 1:8), + s1 = c( + -0.89691455, + 0.18484918, + 1.58784533, + -1.13037567, + -0.08025176, + 0.13242028, + 0.70795473, + -0.23969802 + ), + s2 = c( + 1.9844739, + -0.1387870, + 0.4176508, + 0.9817528, + -0.3926954, + -1.0396690, + 1.7822290, + -2.3110691 + ), + s3 = c( + 0.87860458, + 0.03580672, + 1.01282869, + 0.43226515, + 2.09081921, + -1.19992582, + 1.58963820, + 1.95465164 + ), + s4 = c( + 0.004937777, + -2.451706388, + 0.477237303, + -0.596558169, + 0.792203270, + 0.289636710, + 0.738938604, + 0.318960401 + ), + s5 = c( + 1.0761644, + -0.2841577, + -0.7766753, + -0.5956605, + -1.7259798, + -0.9025845, + -0.5590619, + -0.2465126 + ), + s6 = c( + -0.38358623, + -1.95910318, + -0.84170506, + 1.90354747, + 0.62249393, + 1.99092044, + -0.30548372, + -0.09084424 + ), + check.names = FALSE + ) + sample_metadata <- data.frame( + Sample = paste0("s", 1:6), + Group = c("A", "A", "B", "B", "C", "C") + ) + + common_args <- list( + moo_counts = counts_dat, + sample_metadata = sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + include_all_genes = TRUE, + filter_top_genes_by_variance = FALSE, + center_and_rescale_expression = FALSE, + cluster_genes = FALSE, + cluster_samples = TRUE, + arrange_sample_columns = FALSE, + smpl_distance_metric = "euclidean", + group_columns = "Group", + print_plots = FALSE, + save_plots = FALSE + ) + + expect_message( + p_complete <- do.call( + plot_expr_heatmap, + c(common_args, list(smpl_clustering_method = "complete")) + ), + "total number of genes in heatmap" + ) + expect_message( + p_single <- do.call( + plot_expr_heatmap, + c(common_args, list(smpl_clustering_method = "single")) + ), + "total number of genes in heatmap" + ) + + expect_equal(p_complete@column_dend_param$obj$order, c(6, 5, 2, 3, 4, 1)) + expect_equal(p_single@column_dend_param$obj$order, c(2, 3, 5, 6, 4, 1)) +}) diff --git a/code/MOSuite/tests/testthat/test-plot_histogram.R b/code/MOSuite/tests/testthat/test-plot_histogram.R index 598289d..924c7a2 100644 --- a/code/MOSuite/tests/testthat/test-plot_histogram.R +++ b/code/MOSuite/tests/testthat/test-plot_histogram.R @@ -79,6 +79,143 @@ sample_meta <- structure( row.names = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"), class = "data.frame" ) + +get_histogram_colour_guide_ncol <- function(plot) { + return(plot$guides$guides$colour$params$ncol) +} + +get_plotly_text <- function(plot) { + traces <- plotly::plotly_build(plot)$x$data + return(unlist( + lapply(traces, function(trace) trace$text), + use.names = FALSE + )) +} + +test_that("plot_histogram interactive hover text includes sample and group", { + counts_dat <- log_counts |> + as.data.frame() |> + tibble::rownames_to_column("Gene") + + plot_by_group <- suppressWarnings(plot_histogram( + counts_dat, + sample_metadata = sample_meta, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + color_by_group = TRUE, + interactive_plots = TRUE + )) + plot_by_sample <- suppressWarnings(plot_histogram( + counts_dat, + sample_metadata = sample_meta, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + color_by_group = FALSE, + interactive_plots = TRUE + )) + + hover_text_by_group <- get_plotly_text(plot_by_group) + hover_text_by_sample <- get_plotly_text(plot_by_sample) + expect_true(any(grepl("Sample: A1", hover_text_by_group, fixed = TRUE))) + expect_true(any(grepl("Group: A", hover_text_by_group, fixed = TRUE))) + expect_true(any(grepl("Sample: A1", hover_text_by_sample, fixed = TRUE))) + expect_true(any(grepl("Group: A", hover_text_by_sample, fixed = TRUE))) +}) + +test_that("plot_histogram interactive output keeps legend", { + counts_dat <- log_counts |> + as.data.frame() |> + tibble::rownames_to_column("Gene") + + plot <- suppressWarnings(plot_histogram( + counts_dat, + sample_metadata = sample_meta, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + color_by_group = TRUE, + interactive_plots = TRUE + )) + built_plot <- plotly::plotly_build(plot) + + expect_false(identical(built_plot$x$layout$showlegend, FALSE)) + expect_true(any(vapply( + built_plot$x$data, + function(trace) !is.null(trace$name) && nzchar(trace$name), + logical(1) + ))) +}) + +test_that("plot_histogram wraps long top and bottom sample-name legends", { + counts_dat <- log_counts |> + as.data.frame() |> + tibble::rownames_to_column("Gene") + sample_columns <- setdiff(colnames(counts_dat), "Gene") + long_sample_names <- stats::setNames( + sprintf("SampleName%05d", seq_along(sample_columns)), + sample_columns + ) + colnames(counts_dat) <- ifelse( + colnames(counts_dat) %in% names(long_sample_names), + unname(long_sample_names[colnames(counts_dat)]), + colnames(counts_dat) + ) + sample_metadata <- sample_meta + sample_metadata$Sample <- unname(long_sample_names[as.character( + sample_metadata$Sample + )]) + sample_metadata$Label <- sample_metadata$Sample + + for (legend_position in c("top", "bottom")) { + plot <- plot_histogram( + counts_dat, + sample_metadata = sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + color_by_group = FALSE, + legend_position = legend_position, + number_of_legend_columns = 6 + ) + + expect_equal(get_histogram_colour_guide_ncol(plot), 3) + } +}) + +test_that("plot_histogram legend columns target the colour guide", { + plot <- plot_histogram( + log_counts |> + as.data.frame() |> + tibble::rownames_to_column("Gene"), + sample_meta, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + color_by_group = FALSE, + legend_position = "top", + number_of_legend_columns = 2 + ) + + expect_equal(get_histogram_colour_guide_ncol(plot), 2) +}) + +test_that("plot_histogram uses line glyphs for density legend keys", { + plot <- plot_histogram( + nidap_filtered_counts, + sample_metadata = nidap_sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + color_by_group = TRUE + ) + + expect_equal( + plot$guides$guides$colour$params$override.aes, + list(linetype = 1, linewidth = 2, shape = NA, fill = NA) + ) + expect_s3_class(plot$theme$legend.key, "element_blank") +}) + test_that("plot_histogram works with rownames", { p <- plot_histogram( log_counts |> as.data.frame() |> tibble::rownames_to_column("Gene"), @@ -515,6 +652,165 @@ test_that("plot_histogram works with rownames", { ) }) +test_that("plot_histogram resolves group colors by first observed group order", { + color_values <- c("#5954d6", "#e1562c", "#b80058") + counts_dat <- nidap_filtered_counts[, c( + "Gene", + "B1", + "B2", + "B3", + "A1", + "A2", + "A3", + "C1", + "C2", + "C3" + )] + plot <- plot_histogram( + counts_dat, + sample_metadata = nidap_sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + color_values = color_values, + color_by_group = TRUE + ) + scales <- ggplot2::ggplot_build(plot)$plot$scales$scales + colour_scale <- scales[[which(vapply( + scales, + function(scale) "colour" %in% scale$aesthetics, + logical(1) + ))[[1]]]] + + expect_equal( + colour_scale$palette.cache, + c(B = "#5954d6", A = "#e1562c", C = "#b80058") + ) +}) + +test_that("plot_histogram resolves group colors by factor level order", { + color_values <- c("#5954d6", "#e1562c", "#b80058") + counts_dat <- nidap_filtered_counts[, c( + "Gene", + "B1", + "B2", + "B3", + "A1", + "A2", + "A3", + "C1", + "C2", + "C3" + )] + sample_metadata <- nidap_sample_metadata + sample_metadata$Group <- factor( + sample_metadata$Group, + levels = c("C", "A", "B") + ) + + plot <- plot_histogram( + counts_dat, + sample_metadata = sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + color_values = color_values, + color_by_group = TRUE + ) + scales <- ggplot2::ggplot_build(plot)$plot$scales$scales + colour_scale <- scales[[which(vapply( + scales, + function(scale) "colour" %in% scale$aesthetics, + logical(1) + ))[[1]]]] + + expect_equal( + colour_scale$palette.cache, + c(C = "#5954d6", A = "#e1562c", B = "#b80058") + ) +}) + +test_that("plot_histogram resolves sample colors by first observed sample order", { + color_values <- c("#5954d6", "#e1562c", "#b80058", "#00c6f8") + counts_dat <- nidap_filtered_counts[, c("Gene", "B1", "A1", "C1", "A2")] + plot <- plot_histogram( + counts_dat, + sample_metadata = nidap_sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + color_values = color_values, + color_by_group = FALSE + ) + scales <- ggplot2::ggplot_build(plot)$plot$scales$scales + colour_scale <- scales[[which(vapply( + scales, + function(scale) "colour" %in% scale$aesthetics, + logical(1) + ))[[1]]]] + + expect_equal( + colour_scale$palette.cache, + c(B1 = "#5954d6", A1 = "#e1562c", C1 = "#b80058", A2 = "#00c6f8") + ) +}) + +test_that("plot_histogram automatically sets log2 axis breaks when requested", { + counts_dat <- data.frame( + Gene = "gene_a", + S1 = 0, + S2 = 4, + S3 = 16, + check.names = FALSE + ) + sample_metadata <- data.frame( + Sample = c("S1", "S2", "S3"), + Group = c("A", "A", "A"), + check.names = FALSE + ) + + plot <- plot_histogram( + counts_dat, + sample_metadata = sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + color_by_group = FALSE, + use_log2_x_axis = TRUE + ) + x_scale <- plot$scales$get_scales("x") + axis_breaks <- x_scale$breaks(c(0.5, 64.5)) + + expect_equal(plot$data$count, c(0.5, 4.5, 16.5)) + expect_true(all(c(0.5, 4.5, 16.5, 64.5) %in% axis_breaks)) + expect_equal(x_scale$labels(c(0.5, 4.5, 16.5)), c("0", "4", "16")) +}) + +test_that("plot_histogram automatic log2 axis starts at zero", { + counts_dat <- data.frame( + Gene = "gene_a", + S1 = 4, + S2 = 16, + check.names = FALSE + ) + sample_metadata <- data.frame( + Sample = c("S1", "S2"), + Group = c("A", "A"), + check.names = FALSE + ) + + plot <- plot_histogram( + counts_dat, + sample_metadata = sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + color_by_group = FALSE, + use_log2_x_axis = TRUE + ) + x_scale <- plot$scales$get_scales("x") + + expect_equal(2^x_scale$limits[1], 0.5) + expect_equal(x_scale$labels(2^x_scale$limits[1]), "0") +}) + test_that("plot_histogram works with tibbles", { p <- plot_histogram( nidap_filtered_counts, diff --git a/code/MOSuite/tests/testthat/test-plot_pca.R b/code/MOSuite/tests/testthat/test-plot_pca.R index db003f3..4f5af90 100644 --- a/code/MOSuite/tests/testthat/test-plot_pca.R +++ b/code/MOSuite/tests/testthat/test-plot_pca.R @@ -178,8 +178,7 @@ test_that("plot_pca layers are expected", { "#878500" ), legend_position = "top", - point_size = 1, - add_label = TRUE, + point_size = 5, label_font_size = 3, label_offset_y_ = 2, label_offset_x_ = 2 @@ -189,6 +188,231 @@ test_that("plot_pca layers are expected", { expect_s3_class(p$layers[[1]]$geom, "GeomPoint") }) +normalize_color_values <- function(colors) { + vapply( + colors, + function(color) { + if (grepl("^rgba\\(", color)) { + color_parts <- strsplit(gsub("^rgba\\(|\\)$", "", color), ",")[[1]] + color_parts <- as.numeric(color_parts[seq_len(3)]) + grDevices::rgb( + color_parts[1], + color_parts[2], + color_parts[3], + maxColorValue = 255 + ) + } else { + rgb_value <- grDevices::col2rgb(color) + grDevices::rgb( + rgb_value[1, 1], + rgb_value[2, 1], + rgb_value[3, 1], + maxColorValue = 255 + ) + } + }, + character(1), + USE.NAMES = FALSE + ) +} + +get_colour_scale <- function(plot) { + scales <- ggplot2::ggplot_build(plot)$plot$scales$scales + scales[[which(vapply( + scales, + function(scale) "colour" %in% scale$aesthetics, + logical(1) + ))[[1]]]] +} + +get_colour_guide_ncol <- function(plot) { + plot$guides$guides$colour$params$ncol +} + +has_text_repel_layer <- function(plot) { + any(vapply( + plot$layers, + function(layer) inherits(layer$geom, "GeomTextRepel"), + logical(1) + )) +} + +get_plotly_text <- function(plot) { + traces <- plotly::plotly_build(plot)$x$data + unlist( + lapply(traces, function(trace) trace$text), + use.names = FALSE + ) +} + +test_that("2D PCA wraps long top and bottom sample-name legends", { + sample_columns <- setdiff(colnames(nidap_filtered_counts), "Gene") + long_sample_names <- stats::setNames( + sprintf("SampleName%05d", seq_along(sample_columns)), + sample_columns + ) + counts_dat <- nidap_filtered_counts + colnames(counts_dat) <- ifelse( + colnames(counts_dat) %in% names(long_sample_names), + unname(long_sample_names[colnames(counts_dat)]), + colnames(counts_dat) + ) + sample_metadata <- nidap_sample_metadata + sample_metadata$Sample <- unname(long_sample_names[as.character( + sample_metadata$Sample + )]) + sample_metadata$Label <- sample_metadata$Sample + + for (legend_position in c("top", "bottom")) { + pca_2d <- plot_pca_2d( + counts_dat, + sample_metadata = sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Sample", + label_colname = NULL, + legend_position = legend_position, + print_plots = FALSE, + save_plots = FALSE + ) + + expect_equal(get_colour_guide_ncol(pca_2d), 3) + } +}) + +test_that("2D and 3D PCA resolve unnamed colors by first observed group order", { + color_values <- c("#5954d6", "#e1562c", "#b80058") + expected_colors <- c(B = "#5954d6", A = "#e1562c", C = "#b80058") + counts_dat <- nidap_filtered_counts[, c( + "Gene", + "B1", + "B2", + "B3", + "A1", + "A2", + "A3", + "C1", + "C2", + "C3" + )] + + pca_2d <- plot_pca_2d( + counts_dat, + sample_metadata = nidap_sample_metadata, + feature_id_colname = "Gene", + color_values = color_values, + label_colname = NULL, + print_plots = FALSE, + save_plots = FALSE + ) + pca_2d_colors <- get_colour_scale(pca_2d)$palette.cache[names( + expected_colors + )] + + pca_3d <- plot_pca_3d( + counts_dat, + sample_metadata = nidap_sample_metadata, + feature_id_colname = "Gene", + color_values = color_values, + print_plots = FALSE, + save_plots = FALSE + ) + pca_3d_traces <- plotly::plotly_build(pca_3d)$x$data + pca_3d_colors <- stats::setNames( + normalize_color_values(vapply( + pca_3d_traces, + function(trace) trace$marker$color, + character(1) + )), + vapply(pca_3d_traces, function(trace) trace$name, character(1)) + )[names(expected_colors)] + + expected_colors <- stats::setNames( + normalize_color_values(expected_colors), + names(expected_colors) + ) + + expect_equal(normalize_color_values(pca_2d_colors), unname(expected_colors)) + expect_equal(pca_3d_colors, expected_colors) +}) + +test_that("2D and 3D PCA resolve unnamed colors by factor level order", { + color_values <- c("#5954d6", "#e1562c", "#b80058") + expected_colors <- c(C = "#5954d6", A = "#e1562c", B = "#b80058") + counts_dat <- nidap_filtered_counts[, c( + "Gene", + "B1", + "B2", + "B3", + "A1", + "A2", + "A3", + "C1", + "C2", + "C3" + )] + sample_metadata <- nidap_sample_metadata + sample_metadata$Group <- factor( + sample_metadata$Group, + levels = c("C", "A", "B") + ) + + pca_2d <- plot_pca_2d( + counts_dat, + sample_metadata = sample_metadata, + feature_id_colname = "Gene", + color_values = color_values, + label_colname = NULL, + print_plots = FALSE, + save_plots = FALSE + ) + pca_2d_colors <- get_colour_scale(pca_2d)$palette.cache[names( + expected_colors + )] + + pca_3d <- plot_pca_3d( + counts_dat, + sample_metadata = sample_metadata, + feature_id_colname = "Gene", + color_values = color_values, + print_plots = FALSE, + save_plots = FALSE + ) + pca_3d_traces <- plotly::plotly_build(pca_3d)$x$data + pca_3d_colors <- stats::setNames( + normalize_color_values(vapply( + pca_3d_traces, + function(trace) trace$marker$color, + character(1) + )), + vapply(pca_3d_traces, function(trace) trace$name, character(1)) + )[names(expected_colors)] + + expected_colors <- stats::setNames( + normalize_color_values(expected_colors), + names(expected_colors) + ) + + expect_equal(normalize_color_values(pca_2d_colors), unname(expected_colors)) + expect_equal(pca_3d_colors, expected_colors) +}) + +test_that("2D PCA preserves named color mappings", { + color_values <- c(C = "#5954d6", A = "#e1562c", B = "#b80058") + + pca_2d <- plot_pca_2d( + nidap_filtered_counts, + sample_metadata = nidap_sample_metadata, + feature_id_colname = "Gene", + color_values = color_values, + label_colname = NULL, + print_plots = FALSE, + save_plots = FALSE + ) + + expect_equal(get_colour_scale(pca_2d)$palette.cache, color_values) +}) + test_that("2D & 3D PCA method dispatch works", { moo <- multiOmicDataSet( @@ -327,7 +551,7 @@ test_that("plot_pca_2d works with and without labels", { moo, count_type = "filt", principal_components = c(1, 2), - add_label = TRUE, + label_colname = "Label", save_plots = FALSE, print_plots = FALSE ) @@ -337,11 +561,226 @@ test_that("plot_pca_2d works with and without labels", { moo, count_type = "filt", principal_components = c(1, 2), - add_label = FALSE, + label_colname = NULL, save_plots = FALSE, print_plots = FALSE ) - # With labels should have more layers (geom_text_repel) - expect_gt(length(p_with_labels$layers), length(p_without_labels$layers)) + expect_true(has_text_repel_layer(p_with_labels)) + expect_false(has_text_repel_layer(p_without_labels)) +}) + +test_that("plot_pca_2d interactive hover text includes label column when provided", { + sample_metadata <- as.data.frame(nidap_sample_metadata) + sample_metadata$PlotLabel <- paste0("plot-label-", sample_metadata$Sample) + moo <- multiOmicDataSet( + sample_metadata = sample_metadata, + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ) + ) + + p_with_labels <- suppressWarnings(plot_pca_2d( + moo, + count_type = "filt", + principal_components = c(1, 2), + group_colname = "Group", + label_colname = "PlotLabel", + interactive_plots = TRUE, + save_plots = FALSE, + print_plots = FALSE + )) + p_without_labels <- suppressWarnings(plot_pca_2d( + moo, + count_type = "filt", + principal_components = c(1, 2), + group_colname = "Group", + label_colname = NULL, + interactive_plots = TRUE, + save_plots = FALSE, + print_plots = FALSE + )) + + hover_text_with_labels <- get_plotly_text(p_with_labels) + hover_text_without_labels <- get_plotly_text(p_without_labels) + expect_true(any(grepl("Group: A", hover_text_with_labels, fixed = TRUE))) + expect_true(any(grepl( + "PlotLabel: plot-label-A1", + hover_text_with_labels, + fixed = TRUE + ))) + expect_false(any(grepl("Sample: A1", hover_text_with_labels, fixed = TRUE))) + expect_true(any(grepl("Sample: A1", hover_text_without_labels, fixed = TRUE))) + expect_true(any(grepl("Group: A", hover_text_without_labels, fixed = TRUE))) + expect_false(any(grepl( + "PlotLabel:", + hover_text_without_labels, + fixed = TRUE + ))) +}) + +test_that("plot_pca_3d hover text includes label column when provided", { + sample_metadata <- as.data.frame(nidap_sample_metadata) + sample_metadata$PlotLabel <- paste0("plot-label-", sample_metadata$Sample) + moo <- multiOmicDataSet( + sample_metadata = sample_metadata, + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ) + ) + + fig_with_labels <- plot_pca_3d( + moo, + count_type = "filt", + principal_components = c(1, 2, 3), + group_colname = "Group", + label_colname = "PlotLabel", + save_plots = FALSE, + print_plots = FALSE + ) + fig_without_labels <- plot_pca_3d( + moo, + count_type = "filt", + principal_components = c(1, 2, 3), + group_colname = "Group", + label_colname = NULL, + save_plots = FALSE, + print_plots = FALSE + ) + + hover_text_with_labels <- get_plotly_text(fig_with_labels) + hover_text_without_labels <- get_plotly_text(fig_without_labels) + expect_true(any(grepl("Group: A", hover_text_with_labels, fixed = TRUE))) + expect_true(any(grepl( + "PlotLabel: plot-label-A1", + hover_text_with_labels, + fixed = TRUE + ))) + expect_false(any(grepl("Sample: A1", hover_text_with_labels, fixed = TRUE))) + expect_true(any(grepl("Sample: A1", hover_text_without_labels, fixed = TRUE))) + expect_true(any(grepl("Group: A", hover_text_without_labels, fixed = TRUE))) + expect_false(any(grepl( + "PlotLabel:", + hover_text_without_labels, + fixed = TRUE + ))) +}) + +test_that("plot_pca_2d log_transform defaults to original natural-log transform", { + counts_log <- nidap_filtered_counts |> + dplyr::mutate(dplyr::across( + tidyselect::all_of(nidap_sample_metadata$Sample), + ~ log(.x + 0.5) + )) + + p_from_option <- plot_pca_2d( + nidap_filtered_counts, + sample_metadata = nidap_sample_metadata, + feature_id_colname = "Gene", + label_colname = NULL, + log_transform = TRUE, + log_transform_pseudocount = 0.5, + print_plots = FALSE, + save_plots = FALSE + ) + p_from_manual_transform <- plot_pca_2d( + counts_log, + sample_metadata = nidap_sample_metadata, + feature_id_colname = "Gene", + label_colname = NULL, + print_plots = FALSE, + save_plots = FALSE + ) + + option_points <- ggplot2::ggplot_build(p_from_option)$data[[1]][, c("x", "y")] + manual_points <- ggplot2::ggplot_build(p_from_manual_transform)$data[[1]][, c( + "x", + "y" + )] + expect_equal(option_points, manual_points, tolerance = 1e-8) +}) + +test_that("plot_pca_3d log_transform defaults to original natural-log transform", { + counts_log <- nidap_filtered_counts |> + dplyr::mutate(dplyr::across( + tidyselect::all_of(nidap_sample_metadata$Sample), + ~ log(.x + 0.5) + )) + + fig_from_option <- plot_pca_3d( + nidap_filtered_counts, + sample_metadata = nidap_sample_metadata, + feature_id_colname = "Gene", + log_transform = TRUE, + log_transform_pseudocount = 0.5, + print_plots = FALSE, + save_plots = FALSE + ) + fig_from_manual_transform <- plot_pca_3d( + counts_log, + sample_metadata = nidap_sample_metadata, + feature_id_colname = "Gene", + print_plots = FALSE, + save_plots = FALSE + ) + + option_traces <- plotly::plotly_build(fig_from_option)$x$data + manual_traces <- plotly::plotly_build(fig_from_manual_transform)$x$data + expect_equal(length(option_traces), length(manual_traces)) + for (trace_index in seq_along(option_traces)) { + expect_equal( + option_traces[[trace_index]]$x, + manual_traces[[trace_index]]$x, + tolerance = 1e-8 + ) + expect_equal( + option_traces[[trace_index]]$y, + manual_traces[[trace_index]]$y, + tolerance = 1e-8 + ) + expect_equal( + option_traces[[trace_index]]$z, + manual_traces[[trace_index]]$z, + tolerance = 1e-8 + ) + } +}) + +test_that("plot_pca_2d log_transform supports log2 base", { + counts_log <- nidap_filtered_counts |> + dplyr::mutate(dplyr::across( + tidyselect::all_of(nidap_sample_metadata$Sample), + ~ log2(.x + 0.5) + )) + + p_from_option <- plot_pca_2d( + nidap_filtered_counts, + sample_metadata = nidap_sample_metadata, + feature_id_colname = "Gene", + label_colname = NULL, + log_transform = TRUE, + log_transform_pseudocount = 0.5, + log_transform_base = 2, + print_plots = FALSE, + save_plots = FALSE + ) + p_from_manual_transform <- plot_pca_2d( + counts_log, + sample_metadata = nidap_sample_metadata, + feature_id_colname = "Gene", + label_colname = NULL, + print_plots = FALSE, + save_plots = FALSE + ) + + option_points <- ggplot2::ggplot_build(p_from_option)$data[[1]][, c("x", "y")] + manual_points <- ggplot2::ggplot_build(p_from_manual_transform)$data[[1]][, c( + "x", + "y" + )] + expect_equal(option_points, manual_points, tolerance = 1e-8) }) diff --git a/code/MOSuite/tests/testthat/test-plot_read_depth.R b/code/MOSuite/tests/testthat/test-plot_read_depth.R index df2f4e1..d7a5ae5 100644 --- a/code/MOSuite/tests/testthat/test-plot_read_depth.R +++ b/code/MOSuite/tests/testthat/test-plot_read_depth.R @@ -28,3 +28,63 @@ test_that("plot_read_depth accepts extra args via moo dispatch without error", { ) ) }) + +test_that("plot_read_depth can color samples by group", { + moo <- multiOmicDataSet( + sample_metadata = nidap_sample_metadata, + anno_dat = data.frame(), + counts_lst = list("raw" = nidap_raw_counts) + ) + plot <- plot_read_depth( + moo, + count_type = "raw", + sample_id_colname = "Sample", + group_colname = "Group", + color_values = c("A" = "blue", "B" = "green", "C" = "orange") + ) + + built <- ggplot2::ggplot_build(plot) + expect_equal( + unique(built$data[[1]]$fill), + c("blue", "green", "orange") + ) +}) + +test_that("plot_read_depth keeps single-color bars when group_colname is blank", { + moo <- multiOmicDataSet( + sample_metadata = nidap_sample_metadata, + anno_dat = data.frame(), + counts_lst = list("raw" = nidap_raw_counts) + ) + plot <- plot_read_depth( + moo, + count_type = "raw", + sample_id_colname = "Sample", + group_colname = "", + color_values = c("A" = "blue", "B" = "green", "C" = "orange") + ) + + built <- ggplot2::ggplot_build(plot) + expect_equal(unique(built$data[[1]]$fill), "blue") +}) + +test_that("plot_read_depth extends undersupplied group colors", { + moo <- multiOmicDataSet( + sample_metadata = nidap_sample_metadata, + anno_dat = data.frame(), + counts_lst = list("raw" = nidap_raw_counts) + ) + plot <- plot_read_depth( + moo, + count_type = "raw", + sample_id_colname = "Sample", + group_colname = "Group", + color_values = c("blue") + ) + + built <- ggplot2::ggplot_build(plot) + expect_equal( + unique(built$data[[1]]$fill), + c("blue", "#e1562c", "#b80058") + ) +}) diff --git a/code/MOSuite/tests/testthat/test-plot_volcano_enhanced.R b/code/MOSuite/tests/testthat/test-plot_volcano_enhanced.R index a115797..216e500 100644 --- a/code/MOSuite/tests/testthat/test-plot_volcano_enhanced.R +++ b/code/MOSuite/tests/testthat/test-plot_volcano_enhanced.R @@ -1,5 +1,4 @@ test_that("plot_volcano_enhanced works on nidap dataset", { - skip_on_ci() expect_snapshot( df_volc_enh <- plot_volcano_enhanced( nidap_deg_analysis, @@ -10,26 +9,592 @@ test_that("plot_volcano_enhanced works on nidap dataset", { }) test_that("plot_volcano_enhanced returns a data frame", { + expect_no_error( + result <- plot_volcano_enhanced( + nidap_deg_analysis, + save_plots = FALSE, + print_plots = FALSE + ) + ) + + expect_s3_class(result, "data.frame") + expect_true(ncol(result) > 0) + expect_true(nrow(result) > 0) +}) + +test_that("plot_volcano_enhanced respects num_features_to_label", { + expect_no_error( + result <- plot_volcano_enhanced( + nidap_deg_analysis, + num_features_to_label = 10, + save_plots = FALSE, + print_plots = FALSE + ) + ) + + expect_s3_class(result, "data.frame") +}) + +test_that("plot_volcano_enhanced forwards shared styling parameters", { + options(mosuite_test_volcano_args = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_volcano_args = append( + getOption("mosuite_test_volcano_args"), + list(list( + labSize = labSize, + labCol = labCol, + col = col, + cutoffLineCol = cutoffLineCol + )) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_volcano_args = NULL), add = TRUE) + + custom_label <- tail(nidap_deg_analysis$Gene, 1) + point_colors <- c("grey40", "orange", "dodgerblue", "firebrick") + result <- plot_volcano_enhanced( nidap_deg_analysis, + label_features = TRUE, + custom_gene_list = custom_label, + label_font_size = 7, + default_label_color = "purple", + custom_label_color = "darkgreen", + color_of_signif_threshold_line = "cyan", + color_of_non_significant_features = point_colors[1], + color_of_logfold_change_threshold_line = point_colors[2], + color_of_features_meeting_only_signif_threshold = point_colors[3], + color_for_features_meeting_pvalue_and_foldchange_thresholds = point_colors[ + 4 + ], save_plots = FALSE, print_plots = FALSE ) expect_s3_class(result, "data.frame") - expect_true(ncol(result) > 0) - expect_true(nrow(result) > 0) + captured_args <- getOption("mosuite_test_volcano_args")[[1]] + expect_equal(captured_args$labSize, 7) + expect_true(all(captured_args$labCol == "darkgreen")) + expect_equal(captured_args$col, point_colors) + expect_equal(captured_args$cutoffLineCol, "cyan") }) -test_that("plot_volcano_enhanced respects num_features_to_label", { +test_that("plot_volcano_enhanced uses EnhancedVolcano default colors", { + options(mosuite_test_volcano_args = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_volcano_args = append( + getOption("mosuite_test_volcano_args"), + list(list( + col = col, + cutoffLineCol = cutoffLineCol + )) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_volcano_args = NULL), add = TRUE) + + result <- plot_volcano_enhanced( + nidap_deg_analysis, + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_args <- getOption("mosuite_test_volcano_args")[[1]] + expect_equal( + captured_args$col, + c("grey30", "forestgreen", "royalblue", "red2") + ) + expect_equal(captured_args$cutoffLineCol, "black") +}) + +test_that("plot_volcano_enhanced defaults match summary-style text sizing", { + options(mosuite_test_volcano_args = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_volcano_args = append( + getOption("mosuite_test_volcano_args"), + list(list( + axisLabSize = axisLabSize, + titleLabSize = titleLabSize, + labSize = labSize, + drawConnectors = drawConnectors, + pointSize = pointSize + )) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_volcano_args = NULL), add = TRUE) + + result <- plot_volcano_enhanced( + nidap_deg_analysis, + change_colname = "B-A_logFC", + signif_colname = "B-A_pval", + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_args <- getOption("mosuite_test_volcano_args")[[1]] + expect_equal(captured_args$axisLabSize, 24) + expect_equal(captured_args$titleLabSize, 24) + expect_equal(captured_args$labSize, 7) + expect_false(captured_args$drawConnectors) + expect_equal(captured_args$pointSize, 2) + + volcano_plot <- attr(result, "plots")[[1]] + expect_equal(volcano_plot$theme$axis.text$size, 16) +}) + +test_that("plot_volcano_enhanced supports custom axis labels and padding", { + options(mosuite_test_volcano_args = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_volcano_args = append( + getOption("mosuite_test_volcano_args"), + list(list( + xlab = xlab, + ylab = ylab, + xlim = xlim, + ylim = ylim + )) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_volcano_args = NULL), add = TRUE) + + volcano_data <- data.frame( + Gene = c("left_gene", "right_gene", "not_significant"), + `B-A_logFC` = c(-1.2, 2.4, 0.2), + `B-A_pval` = c(0.001, 0.02, 0.5), + check.names = FALSE + ) + + result <- plot_volcano_enhanced( + volcano_data, + feature_id_colname = "Gene", + change_colname = "B-A_logFC", + signif_colname = "B-A_pval", + change_lfc_name = "Custom fold change", + change_sig_name = "Custom significance", + use_custom_lab = TRUE, + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_args <- getOption("mosuite_test_volcano_args")[[1]] + expect_equal(captured_args$xlab, "Custom fold change") + expect_equal(captured_args$ylab, "Custom significance") + expect_equal(captured_args$xlim, c(-2, 3)) + expect_equal(captured_args$ylim, c(0, 3)) +}) + +test_that("plot_volcano_enhanced saves defaults on a 10 inch canvas", { + options(mosuite_test_plot_output_args = list()) + trace( + ggplot2::ggsave, + tracer = quote({ + options( + mosuite_test_plot_output_args = append( + getOption("mosuite_test_plot_output_args"), + list(list( + width = width, + height = height, + units = units, + dpi = dpi + )) + ) + ) + }), + print = FALSE + ) + on.exit(untrace(ggplot2::ggsave), add = TRUE) + on.exit(options(mosuite_test_plot_output_args = NULL), add = TRUE) + + plots_dir <- tempfile("volcano-default-canvas-") + dir.create(plots_dir) + on.exit(unlink(plots_dir, recursive = TRUE), add = TRUE) + result <- plot_volcano_enhanced( nidap_deg_analysis, - num_features_to_label = 10, + change_colname = "B-A_logFC", + signif_colname = "B-A_pval", + save_plots = TRUE, + print_plots = FALSE, + plots_subdir = plots_dir + ) + + expect_s3_class(result, "data.frame") + captured_output_args <- getOption("mosuite_test_plot_output_args")[[1]] + expect_equal(captured_output_args$width, 3000) + expect_equal(captured_output_args$height, 3000) + expect_equal(captured_output_args$units, "px") + expect_equal(captured_output_args$dpi, 300) +}) + +test_that("plot_volcano_enhanced matches selected-gene summary styling", { + options(mosuite_test_volcano_args = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_volcano_args = append( + getOption("mosuite_test_volcano_args"), + list(list( + title = title, + subtitle = subtitle, + selectLab = selectLab, + labSize = labSize, + labCol = labCol + )) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_volcano_args = NULL), add = TRUE) + + volcano_data <- data.frame( + Gene = c("left_gene", "right_gene", "not_selected"), + `G2-G1_logFC` = c(-1.4, 1.5, 0.2), + `G2-G1_adjpval` = c(0.01, 0.02, 0.5), + `G2-G1_tstat` = c(-10, 9, 1), + check.names = FALSE + ) + selected_genes <- c("left_gene", "right_gene") + + result <- plot_volcano_enhanced( + volcano_data, + feature_id_colname = "Gene", + signif_colname = "G2-G1_adjpval", + change_colname = "G2-G1_logFC", + signif_threshold = 0.05, + change_threshold = 1, + value_to_sort_the_output_dataset = "t-statistic", + num_features_to_label = 20, + label_features = TRUE, + custom_gene_list = paste(selected_genes, collapse = ","), + custom_label_color = "black", save_plots = FALSE, print_plots = FALSE ) expect_s3_class(result, "data.frame") + captured_args <- getOption("mosuite_test_volcano_args")[[1]] + expect_equal(captured_args$title, "G2-G1") + expect_null(captured_args$subtitle) + expect_setequal(captured_args$selectLab, selected_genes) + expect_equal(captured_args$labSize, 7) + expect_true(all(captured_args$labCol == "black")) +}) + +test_that("plot_volcano_enhanced mimics summary contrast title and t-statistic labels", { + options(mosuite_test_volcano_args = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_volcano_args = append( + getOption("mosuite_test_volcano_args"), + list(list( + title = title, + subtitle = subtitle, + selectLab = selectLab + )) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_volcano_args = NULL), add = TRUE) + + volcano_data <- data.frame( + Gene = c("p_value_top", "tstat_top", "fold_change_top"), + `G2-G1_logFC` = c(1.2, -1.3, 2.5), + `G2-G1_pval` = c(0.0001, 0.02, 0.03), + `G2-G1_tstat` = c(2, -10, 5), + check.names = FALSE + ) + + result <- plot_volcano_enhanced( + volcano_data, + feature_id_colname = "Gene", + change_colname = "G2-G1_logFC", + signif_colname = "G2-G1_pval", + value_to_sort_the_output_dataset = "t-statistic", + num_features_to_label = 1, + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_args <- getOption("mosuite_test_volcano_args")[[1]] + expect_equal(captured_args$title, "G2-G1") + expect_null(captured_args$subtitle) + expect_equal(captured_args$selectLab, "tstat_top") +}) + +test_that("plot_volcano_enhanced displays selected genes", { + options(mosuite_test_select_labels = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_select_labels = append( + getOption("mosuite_test_select_labels"), + list(list( + selectLab = selectLab, + labCol = labCol + )) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_select_labels = NULL), add = TRUE) + + selected_genes <- nidap_deg_analysis$Gene[1:2] + result <- plot_volcano_enhanced( + nidap_deg_analysis, + label_features = TRUE, + custom_gene_list = paste(selected_genes, collapse = ","), + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_select_labels <- getOption("mosuite_test_select_labels") + expect_true(length(captured_select_labels) > 0) + expect_true(all(vapply( + captured_select_labels, + function(x) setequal(x$selectLab, selected_genes), + logical(1) + ))) + expect_true(all(vapply( + captured_select_labels, + function(x) all(x$labCol == "black"), + logical(1) + ))) +}) + +test_that("plot_volcano_enhanced offsets labels when connectors are enabled", { + volcano_data <- data.frame( + Gene = c("gene_a", "gene_b", "not_selected"), + `B-A_logFC` = c(2, -2, 0.1), + `B-A_pval` = c(0.001, 0.002, 0.5), + check.names = FALSE + ) + + result <- suppressWarnings(plot_volcano_enhanced( + volcano_data, + feature_id_colname = "Gene", + change_colname = "B-A_logFC", + signif_colname = "B-A_pval", + label_features = TRUE, + custom_gene_list = "gene_a,gene_b", + draw_connectors = TRUE, + save_plots = FALSE, + print_plots = FALSE + )) + + expect_s3_class(result, "data.frame") + volcano_plot <- attr(result, "plots")[[1]] + layer_geoms <- vapply( + volcano_plot$layers, + function(layer) class(layer$geom)[1], + character(1) + ) + expect_true("GeomTextRepel" %in% layer_geoms) + expect_false("GeomText" %in% layer_geoms) +}) + +test_that("plot_volcano_enhanced saves multiple comparisons separately", { + options(mosuite_test_plot_output_args = list()) + trace( + ggplot2::ggsave, + tracer = quote({ + options( + mosuite_test_plot_output_args = append( + getOption("mosuite_test_plot_output_args"), + list(list( + width = width, + height = height, + units = units, + dpi = dpi, + filename = filename + )) + ) + ) + }), + print = FALSE + ) + on.exit(untrace(ggplot2::ggsave), add = TRUE) + on.exit( + options(mosuite_test_plot_output_args = NULL), + add = TRUE + ) + + plots_dir <- tempfile("volcano-separate-output-") + dir.create(plots_dir) + on.exit(unlink(plots_dir, recursive = TRUE), add = TRUE) + + expect_no_error( + result <- plot_volcano_enhanced( + nidap_deg_analysis, + change_colname = c("B-A_logFC", "C-A_logFC", "B-C_logFC"), + signif_colname = c("B-A_adjpval", "C-A_adjpval", "B-C_adjpval"), + image_width = 100, + image_height = 200, + draw_connectors = FALSE, + save_plots = TRUE, + print_plots = FALSE, + plots_subdir = plots_dir + ) + ) + + expect_s3_class(result, "data.frame") + captured_output_args <- getOption("mosuite_test_plot_output_args") + expect_length(captured_output_args, 3) + expect_equal( + vapply(captured_output_args, `[[`, numeric(1), "width"), + rep(100, 3) + ) + expect_equal( + vapply(captured_output_args, `[[`, numeric(1), "height"), + rep(200, 3) + ) + expect_equal( + vapply(captured_output_args, `[[`, character(1), "units"), + rep("px", 3) + ) + expect_equal( + vapply(captured_output_args, `[[`, numeric(1), "dpi"), + rep(300, 3) + ) + output_filenames <- vapply( + captured_output_args, + `[[`, + character(1), + "filename" + ) + expect_true(all(grepl(basename(plots_dir), output_filenames, fixed = TRUE))) + expect_true(any(grepl( + "volcano_enhanced_B-A.png", + output_filenames, + fixed = TRUE + ))) + expect_true(any(grepl( + "volcano_enhanced_C-A.png", + output_filenames, + fixed = TRUE + ))) + expect_true(any(grepl( + "volcano_enhanced_B-C.png", + output_filenames, + fixed = TRUE + ))) +}) + +test_that("plot_volcano_enhanced preserves filename for one comparison", { + options(mosuite_test_plot_output_args = list()) + trace( + ggplot2::ggsave, + tracer = quote({ + options( + mosuite_test_plot_output_args = append( + getOption("mosuite_test_plot_output_args"), + list(list(filename = filename)) + ) + ) + }), + print = FALSE + ) + on.exit(untrace(ggplot2::ggsave), add = TRUE) + on.exit(options(mosuite_test_plot_output_args = NULL), add = TRUE) + + plots_dir <- tempfile("volcano-single-output-") + dir.create(plots_dir) + on.exit(unlink(plots_dir, recursive = TRUE), add = TRUE) + + expect_no_error( + result <- plot_volcano_enhanced( + nidap_deg_analysis, + change_colname = "B-A_logFC", + signif_colname = "B-A_pval", + save_plots = TRUE, + print_plots = FALSE, + plots_subdir = plots_dir, + plot_filename = "custom_volcano.png" + ) + ) + + expect_s3_class(result, "data.frame") + captured_output_args <- getOption("mosuite_test_plot_output_args") + expect_length(captured_output_args, 1) + expect_match( + captured_output_args[[1]]$filename, + basename(plots_dir), + fixed = TRUE + ) + expect_match( + captured_output_args[[1]]$filename, + "custom_volcano.png", + fixed = TRUE + ) +}) + +test_that("plot_volcano_enhanced auto-detects change_colname and signif_colname when NULL", { + # Regression test: all three contrasts in nidap_deg_analysis should be + # detected automatically, preferring _adjpval over _pval. + expect_no_error( + result <- plot_volcano_enhanced( + nidap_deg_analysis, + save_plots = FALSE, + print_plots = FALSE + ) + ) + expect_s3_class(result, "data.frame") + expect_length( + attr(result, "plots"), + length(grep("_logFC$", colnames(nidap_deg_analysis))) + ) +}) + +test_that("plot_volcano_enhanced errors when no _logFC columns and change_colname is NULL", { + bad_df <- data.frame( + Gene = letters[1:3], + `B-A_adjpval` = c(0.01, 0.02, 0.5), + check.names = FALSE + ) + expect_error( + plot_volcano_enhanced(bad_df, save_plots = FALSE, print_plots = FALSE), + regexp = "_logFC" + ) +}) + +test_that("plot_volcano_enhanced errors when no adjpval/pval columns and signif_colname is NULL", { + bad_df <- data.frame( + Gene = letters[1:3], + `B-A_logFC` = c(1, -1, 0.1), + check.names = FALSE + ) + expect_error( + plot_volcano_enhanced(bad_df, save_plots = FALSE, print_plots = FALSE), + regexp = "auto-detect" + ) }) test_that("plot_volcano_enhanced works with multiOmicDataSet", { @@ -46,11 +611,12 @@ test_that("plot_volcano_enhanced works with multiOmicDataSet", { ) ) - # Test that it returns a data frame - result <- plot_volcano_enhanced( - moo, - save_plots = FALSE, - print_plots = FALSE + expect_no_error( + result <- plot_volcano_enhanced( + moo, + save_plots = FALSE, + print_plots = FALSE + ) ) expect_s3_class(result, "data.frame") diff --git a/code/MOSuite/tests/testthat/test-plot_volcano_summary.R b/code/MOSuite/tests/testthat/test-plot_volcano_summary.R index bfaa429..0cfc92e 100644 --- a/code/MOSuite/tests/testthat/test-plot_volcano_summary.R +++ b/code/MOSuite/tests/testthat/test-plot_volcano_summary.R @@ -6,117 +6,367 @@ test_that("plot_volcano_summary works on nidap dataset", { print_plots = FALSE ) ) + expect_s3_class(df_volc_sum, "data.frame") + expect_true(nrow(df_volc_sum) > 0) + expect_true(all(c("Gene", "Contrast") %in% colnames(df_volc_sum))) +}) + +test_that("plot_volcano_summary respects non-Gene feature ID column", { + deg_analysis <- nidap_deg_analysis |> + dplyr::rename(feature_id = Gene) + + df_volc_sum <- plot_volcano_summary( + deg_analysis, + feature_id_colname = "feature_id", + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(df_volc_sum, "data.frame") + expect_true(nrow(df_volc_sum) > 0) + expect_true("feature_id" %in% colnames(df_volc_sum)) + expect_false("Gene" %in% colnames(df_volc_sum)) +}) + +test_that("plot_volcano_summary only forwards custom labels when requested", { + options(mosuite_test_select_labels = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_select_labels = append( + getOption("mosuite_test_select_labels"), + list(selectLab) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_select_labels = NULL), add = TRUE) + + custom_label <- tail(nidap_deg_analysis$Gene, 1) + + result <- plot_volcano_summary( + nidap_deg_analysis, + custom_gene_list = custom_label, + add_features = FALSE, + label_features = FALSE, + num_features_to_label = 1, + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_select_labels <- getOption("mosuite_test_select_labels") + expect_false(custom_label %in% captured_select_labels[[1]]) + + options(mosuite_test_select_labels = list()) + + result <- plot_volcano_summary( + nidap_deg_analysis, + custom_gene_list = custom_label, + add_features = TRUE, + label_features = FALSE, + num_features_to_label = 1, + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_select_labels <- getOption("mosuite_test_select_labels") + expect_true(custom_label %in% captured_select_labels[[1]]) +}) + +test_that("plot_volcano_summary forwards shared styling parameters", { + options(mosuite_test_volcano_args = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_volcano_args = append( + getOption("mosuite_test_volcano_args"), + list(list( + axisLabSize = axisLabSize, + titleLabSize = titleLabSize, + labSize = labSize, + drawConnectors = drawConnectors, + labCol = labCol, + xlab = xlab, + ylab = ylab, + xlim = xlim, + ylim = ylim, + col = col, + cutoffLineCol = cutoffLineCol + )) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_volcano_args = NULL), add = TRUE) + + custom_label <- tail(nidap_deg_analysis$Gene, 1) + point_colors <- c("grey40", "orange", "dodgerblue", "firebrick") + + result <- plot_volcano_summary( + nidap_deg_analysis, + add_features = TRUE, + custom_gene_list = custom_label, + label_font_size = 7, + draw_connectors = FALSE, + axis_lab_size = 25, + title_font_size = 26, + change_lfc_name = "Custom fold change", + change_sig_name = "Custom significance", + use_custom_lab = TRUE, + default_label_color = "purple", + custom_label_color = "darkgreen", + color_of_signif_threshold_line = "cyan", + color_of_non_significant_features = point_colors[1], + color_of_logfold_change_threshold_line = point_colors[2], + color_of_features_meeting_only_signif_threshold = point_colors[3], + color_for_features_meeting_pvalue_and_foldchange_thresholds = point_colors[ + 4 + ], + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_args <- getOption("mosuite_test_volcano_args")[[1]] + expect_equal(captured_args$axisLabSize, 25) + expect_equal(captured_args$titleLabSize, 26) + expect_equal(captured_args$labSize, 7) + expect_false(captured_args$drawConnectors) + expect_equal(captured_args$xlab, "Custom fold change") + expect_equal(captured_args$ylab, "Custom significance") + expect_equal(captured_args$xlim, c(-8, 11)) + expect_equal(captured_args$ylim, c(0, 5)) + expect_true("darkgreen" %in% captured_args$labCol) + expect_equal(captured_args$col, point_colors) + expect_equal(captured_args$cutoffLineCol, "cyan") +}) + +test_that("plot_volcano_summary uses EnhancedVolcano default colors", { + options(mosuite_test_volcano_args = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_volcano_args = append( + getOption("mosuite_test_volcano_args"), + list(list( + col = col, + cutoffLineCol = cutoffLineCol + )) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_volcano_args = NULL), add = TRUE) + + result <- plot_volcano_summary( + nidap_deg_analysis, + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_args <- getOption("mosuite_test_volcano_args")[[1]] expect_equal( - head(df_volc_sum), - structure( - list( - Gene = c("Dntt", "Tmsb4x", "Flt3", "Tspan13", "Tapt1", "Itgb7"), - Contrast = c("B-A", "B-A", "B-A", "B-A", "B-A", "B-A"), - FC = c( - -42.7465863415622, - 3.85002020608143, - -7.71439441748029, - -7.03849783123801, - -5.29181569343323, - 8.87382341151917 - ), - logFC = c( - -5.41773730869316, - 1.94486601753143, - -2.94755290920186, - -2.81526755916543, - -2.40376281543362, - 3.14955584391085 - ), - tstat = c( - -15.6879749543426, - 12.9102607749226, - -11.3808403447749, - -11.0312744854072, - -10.6584674633331, - 10.5614738819538 - ), - pval = c( - 3.15934346857821e-09, - 2.76055502226637e-08, - 1.09340538530663e-07, - 1.53110956271563e-07, - 2.21459280934843e-07, - 2.44206995658642e-07 - ), - adjpval = c( - 2.50946651709167e-05, - 0.000109635442709309, - 0.000289497299183018, - 0.000304040081416256, - 0.000323289361086099, - 0.000323289361086099 - ) - ), - row.names = c("B-A.1", "B-A.2", "B-A.3", "B-A.4", "B-A.5", "B-A.6"), - class = "data.frame" - ) + captured_args$col, + c("grey30", "forestgreen", "royalblue", "red2") + ) + expect_equal(captured_args$cutoffLineCol, "black") +}) + +test_that("plot_volcano_summary uses comparison titles without subtitles", { + options(mosuite_test_volcano_args = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_volcano_args = append( + getOption("mosuite_test_volcano_args"), + list(list( + title = title, + subtitle = subtitle + )) + ) + )), + print = FALSE ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_volcano_args = NULL), add = TRUE) + + result <- plot_volcano_summary( + nidap_deg_analysis, + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_args <- getOption("mosuite_test_volcano_args") expect_equal( - tail(df_volc_sum), - structure( - list( - Gene = c("Tecpr1", "Lap3", "Zfp952", "Tsr3", "Nbas", "Slc50a1"), - Contrast = c("B-C", "B-C", "B-C", "B-C", "B-C", "B-C"), - FC = c( - -17.6925615963148, - 2.57712293045075, - -10.2589472087027, - -3.22520189762021, - 4.43444692871868, - -2.36807519790042 - ), - logFC = c( - -4.14507103690983, - 1.36576135633674, - -3.35881078151314, - -1.68938947606405, - 2.1487541805238, - -1.24371489427577 - ), - tstat = c( - -2.19458425130448, - 2.1944817392618, - -2.19287280238278, - -2.19094226223025, - 2.19079653013039, - -2.18921321212647 - ), - pval = c( - 0.0491166107800282, - 0.0491255772255026, - 0.0492665099590459, - 0.0494361189306691, - 0.0494489447669875, - 0.0495884954830029 - ), - adjpval = c( - 0.265806852794392, - 0.265806852794392, - 0.266387943229885, - 0.26682946214958, - 0.26682946214958, - 0.26740082798472 + vapply(captured_args, `[[`, character(1), "title"), + c("B-A", "C-A", "B-C") + ) + expect_true(all(vapply( + captured_args, + function(x) is.null(x$subtitle), + logical(1) + ))) +}) + +test_that("plot_volcano_summary combines enhanced plots into one grid figure", { + options(mosuite_test_plot_output_args = list()) + trace( + ggplot2::ggsave, + tracer = quote({ + options( + mosuite_test_plot_output_args = append( + getOption("mosuite_test_plot_output_args"), + list(list( + width = width, + height = height, + units = units, + dpi = dpi, + filename = filename + )) ) - ), - row.names = c( - "B-C.957", - "B-C.958", - "B-C.959", - "B-C.960", - "B-C.961", - "B-C.962" - ), - class = "data.frame" - ) + ) + }), + print = FALSE + ) + on.exit(untrace(ggplot2::ggsave), add = TRUE) + on.exit(options(mosuite_test_plot_output_args = NULL), add = TRUE) + + plots_dir <- tempfile("volcano-summary-grid-output-") + dir.create(plots_dir) + on.exit(unlink(plots_dir, recursive = TRUE), add = TRUE) + + result <- plot_volcano_summary( + nidap_deg_analysis, + image_width = 1, + image_height = 2, + dpi = 100, + draw_connectors = FALSE, + use_default_grid_layout = FALSE, + number_of_rows_in_grid_layout = 1, + save_plots = TRUE, + print_plots = FALSE, + plots_subdir = plots_dir + ) + + expect_s3_class(result, "data.frame") + captured_output_args <- getOption("mosuite_test_plot_output_args") + expect_length(captured_output_args, 1) + expect_equal(captured_output_args[[1]]$width, 300) + expect_equal(captured_output_args[[1]]$height, 200) + expect_equal(captured_output_args[[1]]$units, "px") + expect_equal(captured_output_args[[1]]$dpi, 100) + expect_match( + captured_output_args[[1]]$filename, + basename(plots_dir), + fixed = TRUE + ) + expect_match( + captured_output_args[[1]]$filename, + "volcano_summary.png", + fixed = TRUE ) }) +test_that("plot_volcano_summary displays selected genes", { + options(mosuite_test_select_labels = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_select_labels = append( + getOption("mosuite_test_select_labels"), + list(list( + selectLab = selectLab, + labCol = labCol + )) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_select_labels = NULL), add = TRUE) + + selected_genes <- nidap_deg_analysis$Gene[1:2] + result <- plot_volcano_summary( + nidap_deg_analysis, + label_features = TRUE, + custom_gene_list = paste(selected_genes, collapse = ","), + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_select_labels <- getOption("mosuite_test_select_labels") + expect_true(length(captured_select_labels) > 0) + expect_true(all(vapply( + captured_select_labels, + function(x) setequal(x$selectLab, selected_genes), + logical(1) + ))) + expect_true(all(vapply( + captured_select_labels, + function(x) all(x$labCol == "black"), + logical(1) + ))) +}) + +test_that("plot_volcano_summary offsets labels when connectors are enabled", { + options(mosuite_test_saved_summary_plot = list()) + trace( + ggplot2::ggsave, + tracer = quote(options( + mosuite_test_saved_summary_plot = append( + getOption("mosuite_test_saved_summary_plot"), + list(list(plot = plot)) + ) + )), + print = FALSE + ) + on.exit(untrace(ggplot2::ggsave), add = TRUE) + on.exit(options(mosuite_test_saved_summary_plot = NULL), add = TRUE) + + plots_dir <- tempfile("volcano-summary-label-offset-") + dir.create(plots_dir) + on.exit(unlink(plots_dir, recursive = TRUE), add = TRUE) + + volcano_data <- data.frame( + Gene = c("gene_a", "gene_b", "not_selected"), + `B-A_logFC` = c(2, -2, 0.1), + `B-A_pval` = c(0.001, 0.002, 0.5), + `B-A_tstat` = c(8, -7, 0.5), + check.names = FALSE + ) + + result <- suppressWarnings(plot_volcano_summary( + volcano_data, + feature_id_colname = "Gene", + signif_colname = "B-A_pval", + label_features = TRUE, + custom_gene_list = "gene_a,gene_b", + draw_connectors = TRUE, + add_deg_columns = "none", + save_plots = TRUE, + print_plots = FALSE, + plots_subdir = plots_dir + )) + + expect_s3_class(result, "data.frame") + captured_plot <- getOption("mosuite_test_saved_summary_plot")[[1]]$plot + layer_geoms <- vapply( + captured_plot$layers, + function(layer) class(layer$geom)[1], + character(1) + ) + expect_true("GeomTextRepel" %in% layer_geoms) + expect_false("GeomText" %in% layer_geoms) +}) + test_that("plot_volcano_summary works with multiOmicDataSet", { # Create a multiOmicDataSet with differential analysis results moo <- multiOmicDataSet( @@ -144,3 +394,94 @@ test_that("plot_volcano_summary works with multiOmicDataSet", { expect_true("Gene" %in% colnames(result)) expect_true("Contrast" %in% colnames(result)) }) + +test_that("plot_volcano_summary auto-detects adjpval in preference to pval", { + options(mosuite_test_volcano_args = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_volcano_args = append( + getOption("mosuite_test_volcano_args"), + list(list(y = y)) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_volcano_args = NULL), add = TRUE) + + # Dataset with both pval and adjpval columns + df_both <- data.frame( + Gene = letters[1:5], + `B-A_logFC` = c(2, -2, 0.1, 1.5, -1.5), + `B-A_pval` = c(0.001, 0.002, 0.5, 0.01, 0.02), + `B-A_adjpval` = c(0.01, 0.02, 0.5, 0.05, 0.06), + `B-A_tstat` = c(8, -7, 0.5, 5, -5), + check.names = FALSE + ) + + result <- plot_volcano_summary( + df_both, + feature_id_colname = "Gene", + add_deg_columns = "none", + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_args <- getOption("mosuite_test_volcano_args")[[1]] + expect_equal(captured_args$y, "B-A_adjpval") +}) + +test_that("plot_volcano_summary change_colname restricts contrasts plotted", { + result <- plot_volcano_summary( + nidap_deg_analysis, + change_colname = "B-A_logFC", + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + expect_true(all(result$Contrast == "B-A")) +}) + +test_that("plot_volcano_summary explicit signif_colname as full column name is respected", { + options(mosuite_test_volcano_args = list()) + trace( + EnhancedVolcano::EnhancedVolcano, + tracer = quote(options( + mosuite_test_volcano_args = append( + getOption("mosuite_test_volcano_args"), + list(list(y = y)) + ) + )), + print = FALSE + ) + on.exit(untrace(EnhancedVolcano::EnhancedVolcano), add = TRUE) + on.exit(options(mosuite_test_volcano_args = NULL), add = TRUE) + + result <- plot_volcano_summary( + nidap_deg_analysis, + change_colname = "B-A_logFC", + signif_colname = "B-A_pval", + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + captured_args <- getOption("mosuite_test_volcano_args")[[1]] + expect_equal(captured_args$y, "B-A_pval") +}) + +test_that("plot_volcano_summary errors when no significance columns found", { + bad_df <- data.frame( + Gene = letters[1:3], + `B-A_logFC` = c(1, -1, 0.1), + `B-A_tstat` = c(5, -4, 0.2), + check.names = FALSE + ) + expect_error( + plot_volcano_summary(bad_df, save_plots = FALSE, print_plots = FALSE), + regexp = "auto-detect" + ) +}) diff --git a/code/MOSuite/tests/testthat/test-plots.R b/code/MOSuite/tests/testthat/test-plots.R index bb965f3..b3a7420 100644 --- a/code/MOSuite/tests/testthat/test-plots.R +++ b/code/MOSuite/tests/testthat/test-plots.R @@ -1,7 +1,7 @@ set.seed(20250225) corr_heatmap_fixture <- function() { - plot_corr_heatmap( + return(plot_corr_heatmap( nidap_filtered_counts |> as.data.frame(), sample_metadata = as.data.frame(nidap_sample_metadata), @@ -23,7 +23,7 @@ corr_heatmap_fixture <- function() { "#FFA500", "#878500" ) - ) + )) } test_that("print_or_save_plot saves ComplexHeatmap to disk without error", { @@ -77,13 +77,14 @@ test_that("print_or_save_plot prints ComplexHeatmap with caption without error", test_that("save_or_print_plot works for ComplexHeatmap", { p <- corr_heatmap_fixture() skip_on_ci() + tmp <- withr::local_tempdir() expect_snapshot_file( print_or_save_plot( p, filename = "heatmap.png", print_plots = FALSE, save_plots = TRUE, - plots_dir = "." + plots_dir = tmp ), "heatmap.png" ) @@ -91,13 +92,19 @@ test_that("save_or_print_plot works for ComplexHeatmap", { test_that("save_or_print_plot works for ggplot", { p <- plot_read_depth(nidap_clean_raw_counts) skip_on_ci() + tmp <- withr::local_tempdir() expect_snapshot_file( print_or_save_plot( p, filename = "read_depth.png", print_plots = FALSE, save_plots = TRUE, - plots_dir = "." + plots_dir = tmp, + device = grDevices::png, + width = 7, + height = 7, + units = "in", + dpi = 300 ), "read_depth.png" ) diff --git a/code/MOSuite/tests/testthat/test-render_report.R b/code/MOSuite/tests/testthat/test-render_report.R new file mode 100644 index 0000000..afdbc99 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-render_report.R @@ -0,0 +1,37 @@ +test_that("render_report runs in a temporary directory", { + skip_if_not_installed("quarto") + skip_if_not_installed("knitr") + skip_if_not_installed("rmarkdown") + + work_dir <- withr::local_tempdir() + out_dir <- withr::local_tempdir() + withr::local_dir(work_dir) + + expect_no_error( + render_report( + quarto_args = c("--output-dir", out_dir), + execute_params = list( + counts_csv = system.file( + "extdata", + "nidap", + "Raw_Counts.csv.gz", + package = "MOSuite" + ), + samplesheet_csv = system.file( + "extdata", + "nidap", + "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", + package = "MOSuite" + ), + group_colname = "Group", + label_colname = "Label", + batch_colname = "Batch", + contrasts = c("B-A", "C-A", "B-C") + ) + ) + ) + + expect_true(file.exists("report.qmd")) + expect_true(file.exists(file.path(out_dir, "report.html"))) + expect_false(file.exists("report.html")) +}) diff --git a/code/MOSuite/tests/testthat/test-volcano.R b/code/MOSuite/tests/testthat/test-volcano.R new file mode 100644 index 0000000..d67b921 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-volcano.R @@ -0,0 +1,87 @@ +df_both <- data.frame( + Gene = letters[1:3], + `B-A_logFC` = c(1, -1, 0.1), + `B-A_adjpval` = c(0.01, 0.02, 0.5), + `B-A_pval` = c(0.001, 0.002, 0.4), + `C-A_logFC` = c(2, -2, 0.2), + `C-A_adjpval` = c(0.03, 0.04, 0.6), + `C-A_pval` = c(0.003, 0.004, 0.5), + check.names = FALSE +) + +df_pval_only <- data.frame( + Gene = letters[1:3], + `B-A_logFC` = c(1, -1, 0.1), + `B-A_pval` = c(0.001, 0.002, 0.4), + check.names = FALSE +) + +df_no_signif <- data.frame( + Gene = letters[1:3], + `B-A_logFC` = c(1, -1, 0.1), + check.names = FALSE +) + +df_no_logfc <- data.frame( + Gene = letters[1:3], + `B-A_adjpval` = c(0.01, 0.02, 0.5), + check.names = FALSE +) + +test_that("resolve_volcano_colnames auto-detects both when NULL", { + result <- resolve_volcano_colnames(df_both, NULL, NULL) + expect_equal(result$change_colname, c("B-A_logFC", "C-A_logFC")) + expect_equal(result$signif_colname, c("B-A_adjpval", "C-A_adjpval")) +}) + +test_that("resolve_volcano_colnames prefers adjpval over pval", { + result <- resolve_volcano_colnames(df_both, NULL, NULL) + expect_true(all(grepl("_adjpval$", result$signif_colname))) +}) + +test_that("resolve_volcano_colnames falls back to pval when no adjpval", { + result <- resolve_volcano_colnames(df_pval_only, NULL, NULL) + expect_equal(result$change_colname, "B-A_logFC") + expect_equal(result$signif_colname, "B-A_pval") +}) + +test_that("resolve_volcano_colnames respects explicit change_colname", { + result <- resolve_volcano_colnames(df_both, "C-A_logFC", NULL) + expect_equal(result$change_colname, "C-A_logFC") + expect_equal(result$signif_colname, "C-A_adjpval") +}) + +test_that("resolve_volcano_colnames passes through explicit signif_colname", { + result <- resolve_volcano_colnames( + df_both, + c("B-A_logFC", "C-A_logFC"), + c("B-A_pval", "C-A_pval") + ) + expect_equal(result$change_colname, c("B-A_logFC", "C-A_logFC")) + expect_equal(result$signif_colname, c("B-A_pval", "C-A_pval")) +}) + +test_that("resolve_volcano_colnames errors when no _logFC columns exist", { + expect_error( + resolve_volcano_colnames(df_no_logfc, NULL, NULL), + regexp = "_logFC" + ) +}) + +test_that("resolve_volcano_colnames errors when no significance columns found", { + expect_error( + resolve_volcano_colnames(df_no_signif, NULL, NULL), + regexp = "auto-detect" + ) +}) + +test_that("resolve_volcano_colnames errors when lengths differ", { + expect_error( + resolve_volcano_colnames( + df_both, + c("B-A_logFC", "C-A_logFC"), + "B-A_adjpval" + ), + regexp = "same length" + ) +}) diff --git a/code/MOSuite/vignettes/cli.Rmd b/code/MOSuite/vignettes/cli.Rmd deleted file mode 100644 index 5de79f6..0000000 --- a/code/MOSuite/vignettes/cli.Rmd +++ /dev/null @@ -1,218 +0,0 @@ ---- -title: "Calling MOSuite from the CLI" -output: rmarkdown::html_vignette ---- - -```{r, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>", - warning = FALSE -) -``` - - -> ⚠️ **Most users do not need to use the CLI.** -> We recommend using MOSuite within R scripts, R Markdown, or Quarto documents -> for the vast majority of use-cases, as shown in the -> [**introductory vignette**](https://ccbr.github.io/MOSuite/articles/intro.html). -> The CLI is provided for a very specialized situation where MOSuite is run in -> an environment that cannot use R scripts natively. - -MOSuite includes an executable file called `mosuite`. -Any user-facing function in the MOSuite R package can be called with -`mosuite [function]` from the unix CLI. -Function arguments are passed in via a JSON file. -In addition to arguments used by the function, -the JSON file can contain the following keys: - - - `moo_input_rds` - file path to an existing MultiOmicsDataset object in RDS format. This is required if the MOSuite function has `moo` as an argument (most user-facing functions do). - - `moo_output_rds` - file path to write the result to. - -## Usage - -Run `mosuite --help` in a unix shell to see the full CLI usage: - -```{r help, echo=FALSE, results='asis'} -cat("```sh") -MOSuite:::cli_usage(con = stdout()) -cat("```") -``` - -## Installing the MOSuite CLI - -### Docker Container - -We provide a docker container with the MOSuite R package and CLI installed as of -v0.2.0 and later. - - -Running this container with docker or singularity is the recommend way to run -MOSuite in pipelines and HPC environments. - -```sh -singularity exec docker://nciccbr/mosuite:v0.2.0 bash mosuite --help -singularity exec docker://nciccbr/mosuite:v0.2.0 R -s -e \ - 'cat("MOSuite version:", installed.packages()["MOSuite",][["Version"]])' -``` - -### Installation on a personal computer - -After installing the R package, you can use `system.file()` to locate the -`mosuite` executable file with R: - -```{r install} -# remotes::install_github("CCBR/MOSuite", dependencies = TRUE) -system.file("exec", "mosuite", package = "MOSuite") -``` - -You should add this executable to your `PATH` environment variable. - -```sh -export PATH="$PATH:/path/to/exec/mosuite" -``` - -If you're using the [MOSuite docker container](#docker-container), -it is already included in the path. - -## Example end-to-end script - -You can create a shell script to run the full MOSuite pipeline. -This script assumes you have a directory `json_args/` with JSON files to set -each function's arguments. - -```{r script_e2e, echo=FALSE, results='asis'} -cat("```bash\n") -cat( - readr::read_lines(system.file( - "extdata", - "example_script.sh", - package = "MOSuite" - )), - sep = "\n" -) -cat("\n```") -``` - -The example script and accompanying JSON files are included in the package data. -You can copy them to your working directory with R: - -```{r example_data_paths, eval=FALSE} -# copy the example script -file.copy( - system.file("extdata", "example_script.sh", package = "MOSuite"), - to = "./" -) -# copy the JSON files -file.copy( - system.file("extdata", "json_args", package = "MOSuite"), - to = "./", - recursive = TRUE -) -# copy the raw counts & sample metadata -file.copy( - system.file("extdata", "nidap", "Raw_Counts.csv.gz", package = "MOSuite"), - to = "./" -) -file.copy( - system.file( - "extdata", - "nidap", - "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", - package = "MOSuite" - ), - to = "./" -) -``` - -Then run the script from the CLI: - -```bash -bash ./example_script.sh -``` - -The final multiOmicDataSet will be in `moo.rds` and figures from each step will -be in `./figures/`. - -## Writing JSON files - -Create a JSON file with arguments for `create_multiOmicDataSet_from_files()`. -You can use R code as below or write it by hand. - -```{r create_json} -j <- list( - feature_counts_filepath = system.file( - "extdata", - "RSEM.genes.expected_count.all_samples.txt.gz", - package = "MOSuite" - ), - sample_meta_filepath = system.file( - "extdata", - "sample_metadata.tsv.gz", - package = "MOSuite" - ), - moo_output_rds = "moo.rds" -) -jsonlite::write_json(j, "args_1.json") -``` - -In a unix shell, call `create_multiOmicDataSet_from_files()` and specify the path to the JSON file: - -```{bash create_moo, eval=FALSE} -mosuite create_multiOmicDataSet_from_files --json=args_1.json -``` - -This is equivalent to running the following R code: - -```{r create_moo_R} -library(MOSuite) -moo <- create_multiOmicDataSet_from_files( - feature_counts_filepath = system.file( - "extdata", - "RSEM.genes.expected_count.all_samples.txt.gz", - package = "MOSuite" - ), - sample_meta_filepath = system.file( - "extdata", - "sample_metadata.tsv.gz", - package = "MOSuite" - ) -) -readr::write_rds(moo, "moo.rds") -``` - -You can use the `moo` object you just created as input to other MOSuite functions. - -Create a JSON file of arguments for `clean_raw_counts()` with R (or write it by hand): - -```{r create_json_filter} -j <- list( - moo_input_rds = "moo.rds", - moo_output_rds = "moo.rds", - save_plots = TRUE -) -jsonlite::write_json(j, "args_2.json") -``` - -Then run `clean_raw_counts()`: - -```{bash clean_raw_counts, eval=FALSE} -mosuite clean_raw_counts --json=args_2.json -``` - -Results are saved to `moo.rds`. -Overwriting the same `moo` file is recommended to save disk space, as the -multiOmicDataset object saves intermediate results within its data structure. - -## Template JSON files - -JSON file templates with default arguments for the main functions are bundled with the package. -You can copy them to your current directory like so: - -```{r json_template} -file.copy( - system.file("extdata", "json_args", "defaults", package = "MOSuite"), - to = "./", - recursive = TRUE -) -``` diff --git a/code/MOSuite/vignettes/visualization.Rmd b/code/MOSuite/vignettes/visualization.Rmd index c46d6a0..ffa1073 100644 --- a/code/MOSuite/vignettes/visualization.Rmd +++ b/code/MOSuite/vignettes/visualization.Rmd @@ -21,7 +21,7 @@ knitr::opts_chunk$set( library(MOSuite) ``` -## Default plots from each step +## Default plots from main functions Default plots can be printed to the screen and/or saved to the disk. @@ -91,24 +91,17 @@ moo <- moo |> moo <- moo |> filter_diff() ``` -## Customize plots - -TODO - -- show how to use individual plotting functions -- how to customize & override default color palettes -- how to customize ggplot objects +## Specialized plots ### 3D PCA ```{r pca_3D} -plot_pca( - moo@counts$batch, - moo@sample_meta, +plot_pca_3d( + moo, + count_type = "batch", principal_components = c(1, 2, 3), group_colname = "Group", - label_colname = "Label", - color_values = moo@analyses[["colors"]][["Group"]] + label_colname = "Label" ) ``` @@ -118,35 +111,174 @@ plot_pca( heatmap_plot <- plot_expr_heatmap( moo, count_type = "norm", - sub_count_type = "voom" + sub_count_type = "voom", + group_colname = "Group" ) -print(heatmap_plot) +# print(heatmap_plot) ``` ### Volcano -#### Summary +#### Enhanced -```{r volcano_summary} -dat_volcano_summary <- moo@analyses$diff |> - join_dfs_wide() |> - plot_volcano_summary() +Create an enhanced volcano plot for each contrast: -head(dat_volcano_summary) +```{r volcano_enhanced, fig.height=7} +dat_volcano_enhanced <- moo |> + plot_volcano_enhanced() ``` -#### Enhanced +or plot only one contrast at a time by selecting the contrast from the `analyses` slot: -```{r volcano_enhanced} -dat_volcano_enhanced <- moo@analyses$diff |> - join_dfs_wide() |> - plot_volcano_enhanced() +```{r volcano_enhanced_single_contrast, fig.height=7} +dat_volcano_enhanced_B_A <- moo@analyses$diff[["B-A"]] |> + plot_volcano_enhanced( + feature_id_colname = "GeneName", + change_colname = "logFC", + signif_colname = "adjpval" + ) ``` +#### Summary + +Create an enhanced volcano plot for each contrast and compose them in one figure: + +```{r volcano_summary, fig.height=10, fig.width=8} +dat_volcano_summary <- moo |> + plot_volcano_summary() + +head(dat_volcano_summary) +``` ### Venn Diagram -```{r venn_diagram} +```{r venn_diagram, fig.width=7, fig.height=7} venn_dat <- dat_volcano_summary |> plot_venn_diagram() head(venn_dat) ``` + +## Customizing plots + +```{r print-plots-false, echo = FALSE} +options(moo_print_plots = FALSE) +options(moo_save_plots = FALSE) +``` + +### Plots from main functions + +You can create the plots generated by the main analysis functions directly +so you can customize them to fit your needs. + +See the [visualization reference](https://ccbr.github.io/MOSuite/reference/index.html#visualization) +for a full list of plotting functions. + +#### Examples + +Plot the read depth of the clean counts, using either the `Group` column or the `Batch` column from the metadata for the fill colors: + +```{r plot_read_depth} +plot_read_depth( + moo, + count_type = "clean", + group_colname = "Group" +) +plot_read_depth( + moo, + count_type = "clean", + group_colname = "Batch" +) +``` + + +### Customizing ggplot objects + +Plotting functions that use ggplot2 return ggplot objects. +You can customize them by adding more ggplot layers, just like any other ggplot. + +```{r ggplot2_pca_2D} +plot_pca_2d( + moo, + count_type = "batch", + principal_components = c(1, 2), + group_colname = "Batch", + label_colname = "Label" +) + + ggplot2::labs( + title = "Principle components of batch-corrected counts", + caption = "Normalized counts were batch-corrected using svg::ComBat()" + ) +``` + +### Custom colors + +MOSuite comes bundled with a default palette: +```{r display_palette, fig.height=1.5, fig.width=7} +display_palette() +``` + +When creating a multiOmicDataSet object such as with `create_multiOmicDataSet_from_dataframes()`, +default colors are automatically picked from `mosuite_palette` and set in the analyses slot. +You can access the defaults directly: + +```{r colors_slot} +moo@analyses$colors +``` + +The plotting functions access these colors by default, unless overridden +with the `color_values` argument: + +```{r plot_read_depth_custom_colors} +# color palette accessed from moo@analyses$colors[['Group']] +plot_read_depth( + moo, + count_type = "clean", + group_colname = "Group" +) + +# color palette overridden by color_values +plot_read_depth( + moo, + count_type = "clean", + group_colname = "Group", + color_values = c(A = "red", B = "green", C = "blue") +) +``` + +You can change the default colors in the multiOmicDataSet so that all plotting +functions will use your chosen color palette. + +```{r custom_palette} +moo@analyses$colors[["Batch"]] <- c("1" = "#0E7175", "2" = "#C35BCA") +moo@analyses$colors[["Replicate"]] <- c( + "1" = "#89973D", + "2" = "#E8B92F", + "3" = "#A45E41" +) +moo@analyses$colors[["Group"]] <- c(A = "#E69F00", B = "#56B4E9", C = "#009E73") +``` + +View the colors in a multiOmicDataSet with `display_colors()`: +```{r display_colors, fig.height=5, fig.width=8} +display_colors(moo) +``` + +Plotting functions will then use the custom colors set in `moo@analyses$colors`: + +```{r plots_custom_palette} +plot_read_depth( + moo, + count_type = "clean", + group_colname = "Group" +) +plot_pca_2d( + moo, + count_type = "batch", + group_colname = "Batch" +) +plot_expr_heatmap( + moo, + count_type = "norm", + sub_count_type = "voom", + group_colname = "Group" +) +``` From ffaf8eb828ae6e9705001df9e55c2f255f267a79 Mon Sep 17 00:00:00 2001 From: phoman14 Date: Fri, 31 Jul 2026 00:29:31 -0400 Subject: [PATCH 05/11] fix(diff): align covariates app panel parameter --- .codeocean/app-panel.json | 2 +- tests/testthat/test-main.R | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.codeocean/app-panel.json b/.codeocean/app-panel.json index 5e4585f..4c30324 100644 --- a/.codeocean/app-panel.json +++ b/.codeocean/app-panel.json @@ -73,7 +73,7 @@ "id": "7pRIPMdfEf1dq2CS", "category": "EzTg1ivlFDHEy9PI", "name": "Covariates column names", - "param_name": "covariates_colname", + "param_name": "covariates_colnames", "description": "Comma-separated list of columns to be used as covariates in linear modeling; must include the contrast column", "type": "text", "value_type": "string", diff --git a/tests/testthat/test-main.R b/tests/testthat/test-main.R index 668a6e9..2720d79 100644 --- a/tests/testthat/test-main.R +++ b/tests/testthat/test-main.R @@ -1,3 +1,17 @@ +test_that("app panel passes covariates_colnames to main.R", { + repo_root <- normalizePath( + file.path(testthat::test_path(), "..", ".."), + mustWork = TRUE + ) + panel <- jsonlite::fromJSON( + file.path(repo_root, ".codeocean", "app-panel.json") + ) + panel_params <- panel$parameters$param_name + + expect_true("covariates_colnames" %in% panel_params) + expect_false("covariates_colname" %in% panel_params) +}) + test_that("main.R CLI creates differential analysis output", { setup <- setup_cli_workspace("mosuite_diff_counts_test_") on.exit(unlink(setup$workspace, recursive = TRUE), add = TRUE) From 8eb09c645b541bcafcf1a601429c4686e7384531 Mon Sep 17 00:00:00 2001 From: phoman14 Date: Fri, 31 Jul 2026 06:24:08 -0400 Subject: [PATCH 06/11] docs(panel): sync parameter descriptions _commit message is ai-generated_ --- .codeocean/app-panel.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.codeocean/app-panel.json b/.codeocean/app-panel.json index 4c30324..42d5a3d 100644 --- a/.codeocean/app-panel.json +++ b/.codeocean/app-panel.json @@ -36,7 +36,7 @@ "category": "EzTg1ivlFDHEy9PI", "name": "Count type", "param_name": "count_type", - "description": "Counts slot name to use for differential expression (e.g., filt)", + "description": "The type of counts to use. This must be a name in the counts slot, moo@counts.", "type": "list", "value_type": "string", "default_value": "filt", @@ -51,7 +51,7 @@ "category": "EzTg1ivlFDHEy9PI", "name": "Contrasts column name", "param_name": "contrast_colname", - "description": "Metadata column containing group variables for differential expression (up to 2 columns for 2-factor analysis)", + "description": "The column in the metadata that contains the group variables you wish to find differential expression between. Up to 2 columns can be used for 2-factor analysis.", "type": "text", "value_type": "string", "default_value": "Group", @@ -62,7 +62,7 @@ "category": "EzTg1ivlFDHEy9PI", "name": "Contrasts for comparison", "param_name": "contrasts", - "description": "Specify contrasts in the format group1-group2,group1-group3 (comma-separated)", + "description": "Specify each contrast in the format group1-group2, for example treated-control.", "help_text": "These values must be in the contrasts column", "type": "text", "value_type": "string", @@ -74,7 +74,7 @@ "category": "EzTg1ivlFDHEy9PI", "name": "Covariates column names", "param_name": "covariates_colnames", - "description": "Comma-separated list of columns to be used as covariates in linear modeling; must include the contrast column", + "description": "The column name or names from the sample metadata containing variables of interest, such as phenotype. Most commonly this will be the same column selected for your groups column. Some experimental designs may require that you add additional covariate columns here.", "type": "text", "value_type": "string", "default_value": "Batch" @@ -84,7 +84,7 @@ "category": "FvI4Z2eb9sjL47Jt", "name": "sub count type", "param_name": "sub_count_type", - "description": "If count_type is a list, specify the sub count type within the list", + "description": "If count_type is a list, specify the sub count type within the list.", "type": "text", "value_type": "string" }, @@ -93,7 +93,7 @@ "category": "FvI4Z2eb9sjL47Jt", "name": "Sample ID Column Name", "param_name": "sample_id_colname", - "description": "Column name in sample metadata for sample IDs", + "description": "The column from the sample metadata containing the sample names. The names in this column must exactly match the names used as sample column names in the input counts matrix.", "type": "text", "value_type": "string" }, @@ -102,7 +102,7 @@ "category": "FvI4Z2eb9sjL47Jt", "name": "Feature ID column name", "param_name": "feature_id_colname", - "description": "Column name in counts table for feature IDs (e.g., gene)", + "description": "The column from the counts data containing the Feature IDs, usually Gene or Protein ID. This is usually the first column of the input counts matrix. Only columns of text type from the input counts matrix are available to select for this parameter.", "type": "text", "value_type": "string" }, @@ -111,7 +111,7 @@ "category": "FvI4Z2eb9sjL47Jt", "name": "Samples to Include", "param_name": "samples_to_include", - "description": "Comma-separated list of samples to include", + "description": "Which samples would you like to include? Usually, you will choose all sample columns, or you could choose to remove certain samples. Samples excluded here will be removed in this step and from downstream analysis.", "type": "text", "value_type": "string" }, @@ -120,7 +120,7 @@ "category": "FvI4Z2eb9sjL47Jt", "name": "Input in log counts", "param_name": "input_in_log_counts", - "description": "Set TRUE if counts are already log2-transformed", + "description": "Set this to TRUE if counts are already log2-transformed.", "type": "list", "value_type": "string", "default_value": "FALSE", @@ -134,7 +134,7 @@ "category": "FvI4Z2eb9sjL47Jt", "name": "Return mean and sd", "param_name": "return_mean_and_sd", - "description": "Return group means and standard deviations in addition to DE estimates", + "description": "Return mean and standard deviation of groups in addition to DEG estimates for contrasts.", "type": "list", "value_type": "string", "default_value": "FALSE", @@ -148,7 +148,7 @@ "category": "FvI4Z2eb9sjL47Jt", "name": "voom normalization method", "param_name": "voom_normalization_method", - "description": "Normalization method for differential expression. edgeR methods are applied with calcNormFactors before voom; limma methods are passed to voom normalize. limma options: quantile, scale, cyclicloess, none. edgeR options: TMM, TMMwzp, RLE, upperquartile.", + "description": "Normalization method to be applied to the logCPM values when using limma::voom.", "type": "list", "value_type": "string", "default_value": "quantile", From 27b27f56305644f6661e65698287bed6a71a407c Mon Sep 17 00:00:00 2001 From: phoman14 Date: Fri, 31 Jul 2026 07:07:30 -0400 Subject: [PATCH 07/11] docs(changelog): add PR entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd9185b..d036036 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Development version +- Sync Code Ocean app panel parameter descriptions with MOSuite package documentation (#7, @phoman14). - Improved the Code Ocean parameter UI for the diff counts capsule (#3, @phoman14). - Use MOSuite v0.3.2. (#4, @kelly-sovacool) From a618830c933d47133c3c3badeb58abff2fe69ce0 Mon Sep 17 00:00:00 2001 From: phoman14 Date: Fri, 31 Jul 2026 08:38:19 -0400 Subject: [PATCH 08/11] test: add syncweaver lock coverage --- tests/testthat/test-syncweaver.R | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/testthat/test-syncweaver.R diff --git a/tests/testthat/test-syncweaver.R b/tests/testthat/test-syncweaver.R new file mode 100644 index 0000000..718b32e --- /dev/null +++ b/tests/testthat/test-syncweaver.R @@ -0,0 +1,15 @@ +test_that("syncweaver lock embeds MOSuite main", { + repo_root <- normalizePath( + file.path(testthat::test_path(), "..", ".."), + mustWork = TRUE + ) + lock <- jsonlite::read_json( + file.path(repo_root, ".syncweaver-lock.json"), + simplifyVector = TRUE + ) + mosuite_source <- lock$sources[["code/MOSuite"]] + + expect_equal(mosuite_source$repo_url, "https://github.com/CCBR/MOSuite") + expect_equal(mosuite_source$ref, "main") + expect_match(mosuite_source$git_sha, "^[0-9a-f]{40}$") +}) From 78680fc3a3729863ea6dc8cb3825e8ead26cf75b Mon Sep 17 00:00:00 2001 From: phoman14 Date: Mon, 3 Aug 2026 08:37:14 -0400 Subject: [PATCH 09/11] test: remove syncweaver lock tests --- tests/testthat/test-syncweaver.R | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 tests/testthat/test-syncweaver.R diff --git a/tests/testthat/test-syncweaver.R b/tests/testthat/test-syncweaver.R deleted file mode 100644 index 718b32e..0000000 --- a/tests/testthat/test-syncweaver.R +++ /dev/null @@ -1,15 +0,0 @@ -test_that("syncweaver lock embeds MOSuite main", { - repo_root <- normalizePath( - file.path(testthat::test_path(), "..", ".."), - mustWork = TRUE - ) - lock <- jsonlite::read_json( - file.path(repo_root, ".syncweaver-lock.json"), - simplifyVector = TRUE - ) - mosuite_source <- lock$sources[["code/MOSuite"]] - - expect_equal(mosuite_source$repo_url, "https://github.com/CCBR/MOSuite") - expect_equal(mosuite_source$ref, "main") - expect_match(mosuite_source$git_sha, "^[0-9a-f]{40}$") -}) From 45867e57db2ba0bfe53023421ad60337f9c8f499 Mon Sep 17 00:00:00 2001 From: phoman14 Date: Mon, 3 Aug 2026 14:43:22 -0400 Subject: [PATCH 10/11] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d036036..3f488cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Development version -- Sync Code Ocean app panel parameter descriptions with MOSuite package documentation (#7, @phoman14). +- Sync Code Ocean app panel parameter descriptions with MOSuite package documentation for MOSuite v0.4.1 (#7, @phoman14). - Improved the Code Ocean parameter UI for the diff counts capsule (#3, @phoman14). - Use MOSuite v0.3.2. (#4, @kelly-sovacool) From 1642b0d4c6bf837616edf8e6db29f18d886d1a3a Mon Sep 17 00:00:00 2001 From: Kelly Sovacool Date: Mon, 3 Aug 2026 18:45:55 -0400 Subject: [PATCH 11/11] test: use dynamic parameters, not hard-coded --- tests/testthat/test-main.R | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test-main.R b/tests/testthat/test-main.R index 2720d79..2a96975 100644 --- a/tests/testthat/test-main.R +++ b/tests/testthat/test-main.R @@ -1,4 +1,4 @@ -test_that("app panel passes covariates_colnames to main.R", { +test_that("every app panel parameter is accepted and used by main.R", { repo_root <- normalizePath( file.path(testthat::test_path(), "..", ".."), mustWork = TRUE @@ -6,10 +6,28 @@ test_that("app panel passes covariates_colnames to main.R", { panel <- jsonlite::fromJSON( file.path(repo_root, ".codeocean", "app-panel.json") ) - panel_params <- panel$parameters$param_name + main_text <- paste( + readLines(file.path(repo_root, "code", "main.R"), warn = FALSE), + collapse = "\n" + ) + + param_names <- panel$parameters$param_name + expect_true(length(param_names) > 0) - expect_true("covariates_colnames" %in% panel_params) - expect_false("covariates_colname" %in% panel_params) + for (param_name in param_names) { + expect_match( + main_text, + sprintf('"--%s"', param_name), + fixed = TRUE, + info = sprintf("main.R should define a --%s CLI argument", param_name) + ) + expect_match( + main_text, + sprintf("args$%s", param_name), + fixed = TRUE, + info = sprintf("main.R should read args$%s", param_name) + ) + } }) test_that("main.R CLI creates differential analysis output", {