diff --git a/.codeocean/environment.json b/.codeocean/environment.json index 8d79df0..ab54a1a 100644 --- a/.codeocean/environment.json +++ b/.codeocean/environment.json @@ -1,6 +1,6 @@ { "version": 1, - "base_image": "codeocean/mosuite:v0.3.0", + "base_image": "codeocean/mosuite-minimal:v0.3.1", "post_install": true, "options": { "registry_host_arg": true, diff --git a/.github/workflows/pull-subtree.yml b/.github/workflows/pull-subtree.yml new file mode 100644 index 0000000..ecfd060 --- /dev/null +++ b/.github/workflows/pull-subtree.yml @@ -0,0 +1,41 @@ +name: pull-subtree + +on: + repository_dispatch: + types: [release] + workflow_dispatch: + +jobs: + pull-subtree: + runs-on: ubuntu-latest + strategy: + matrix: + config: + - { remote: CCBR/MOSuite, local: code/MOSuite } + steps: + - name: Generate a token + id: generate-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ vars.CCBR_BOT_APP_ID }} + private-key: ${{ secrets.CCBR_BOT_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + - uses: actions/checkout@v6 + with: + token: ${{ steps.generate-token.outputs.token }} + - name: git config + run: | + git config --global user.name "CCBR-bot" + git config --global user.email "258092125+ccbr-bot@users.noreply.github.com" + - name: Pull subtree + env: + local_branch_name: pull/${{ matrix.config.remote }} + remote_branch_name: main # TODO use release ref from repo dispatch payload + run: | + git switch -c ${{ env.local_branch_name }} + git remote add -f subtree-remote ${{ matrix.config.remote }} + git fetch subtree-remote main + git subtree pull --prefix ${{ matrix.config.local }} subtree-remote ${{ env.remote_branch_name }} --squash + git add ${{ matrix.config.local }} + git commit -m 'chore: pull subtree from ${{ matrix.config.remote}} @ ${{ env.remote_branch_name}}' + gh pr create --fill-first diff --git a/.github/workflows/push-subtree.yml b/.github/workflows/push-subtree.yml new file mode 100644 index 0000000..1e687a4 --- /dev/null +++ b/.github/workflows/push-subtree.yml @@ -0,0 +1,9 @@ +name: push-subtree + +on: + repository_dispatch: + workflow_dispatch: + +jobs: + push-subtree: + runs-on: ubuntu-latest diff --git a/.github/workflows/sync-code-ocean.yml b/.github/workflows/sync-code-ocean.yml new file mode 100644 index 0000000..22d5f93 --- /dev/null +++ b/.github/workflows/sync-code-ocean.yml @@ -0,0 +1,9 @@ +name: sync-code-ocean + +on: + repository_dispatch: + workflow_dispatch: + +jobs: + sync-code-ocean: + runs-on: ubuntu-latest diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index ac25f8b..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: test - -on: - push: - branches: [main, dev] - pull_request: - branches: [main, dev] - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - - name: Parse environment.json and set Docker image - id: docker_image - run: | - IMAGE=$(jq -r '.base_image' .codeocean/environment.json) - IMAGE=${IMAGE//codeocean/nciccbr} - echo "image=$IMAGE" >> $GITHUB_OUTPUT - echo "Using Docker image: $IMAGE" - - - name: Run tests in Docker - run: | - docker run --rm \ - -v ${{ github.workspace }}:/workspace \ - -w /workspace \ - ${{ steps.docker_image.outputs.image }} \ - Rscript tests/testthat.R diff --git a/CHANGELOG.md b/CHANGELOG.md index 5026b15..d6c9b40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## development version +- The MOSuite package is now available in `code/MOSuite`. (#1) +- Use MOSuite v0.3.1. + ## v2.0 - Use MOSuite v0.3.0. diff --git a/code/MOSuite/.Rbuildignore b/code/MOSuite/.Rbuildignore new file mode 100644 index 0000000..7ee19e0 --- /dev/null +++ b/code/MOSuite/.Rbuildignore @@ -0,0 +1,37 @@ +^renv$ +^renv\.lock$ +^_pkgdown\.yml$ +^\.github$ +^\.lintr$ +^\.pre-commit-config\.yaml$ +^\.prettierignore$ +^\.prettierrc$ +^\.Rproj\.user$ +^CITATION\.cff$ +^codemeta\.json$ +^data-raw$ +^doc$ +^Dockerfile$ +^docker$ +^docs$ +^figures$ +^LICENSE\.md$ +^Meta$ +^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$ +^tests/figures$ +^vignettes/figures/$ +^vignettes/memory\.Rmd$ +^vignettes/cli\.Rmd$ +VennDiagram.*\.log +^[.]?air[.]toml$ +^\.vscode$ diff --git a/code/MOSuite/.gitattributes b/code/MOSuite/.gitattributes new file mode 100644 index 0000000..ed0ce76 --- /dev/null +++ b/code/MOSuite/.gitattributes @@ -0,0 +1,4 @@ +CITATION.cff linguist-generated +codemeta.json linguist-generated +NAMESPACE linguist-generated +man/ linguist-generated diff --git a/code/MOSuite/.github/.Rprofile b/code/MOSuite/.github/.Rprofile new file mode 100644 index 0000000..f993fcf --- /dev/null +++ b/code/MOSuite/.github/.Rprofile @@ -0,0 +1 @@ +rlang::global_entrace() diff --git a/code/MOSuite/.github/.gitignore b/code/MOSuite/.github/.gitignore new file mode 100644 index 0000000..2d19fc7 --- /dev/null +++ b/code/MOSuite/.github/.gitignore @@ -0,0 +1 @@ +*.html diff --git a/code/MOSuite/.github/CONTRIBUTING.md b/code/MOSuite/.github/CONTRIBUTING.md new file mode 100644 index 0000000..b476770 --- /dev/null +++ b/code/MOSuite/.github/CONTRIBUTING.md @@ -0,0 +1,292 @@ +# Contributing to MOSuite + +## Proposing changes with issues + +If you want to make a change, it's a good idea to first +[open an issue](https://github.com/CCBR/MOSuite/issues) +and make sure someone from the team agrees that it’s needed. +Before opening an issue, check the existing issues to make sure you're not +opening a duplicate, and follow these guidelines to ensure your issue will be +high-quality: +. + +If you've decided to work on an issue, +[assign yourself to the issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/assigning-issues-and-pull-requests-to-other-github-users#assigning-an-individual-issue-or-pull-request) +so others will know you're working on it. + +## Pull request process + +We use [GitHub Flow](https://docs.github.com/en/get-started/using-github/github-flow) +as our collaboration process. +Follow the steps below for detailed instructions on contributing changes to +MOSuite. + +![GitHub Flow diagram](https://raw.githubusercontent.com/CCBR/CCBR_NextflowTemplate/main/.github/img/GitHub-Flow_bg-white.png) + + +### Clone the repo + +If you are a member of [CCBR](https://github.com/CCBR), +you can clone this repository to your computer or development environment. +Otherwise, you will first need to +[fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo) +the repo and clone your fork. You only need to do this step once. + +```sh +git clone https://github.com/CCBR/MOSuite +``` + +> Cloning into 'MOSuite'...
+> remote: Enumerating objects: 1136, done.
+> remote: Counting objects: 100% (463/463), done.
+> remote: Compressing objects: 100% (357/357), done.
+> remote: Total 1136 (delta 149), reused 332 (delta 103), pack-reused 673
+> Receiving objects: 100% (1136/1136), 11.01 MiB | 9.76 MiB/s, done.
+> Resolving deltas: 100% (530/530), done.
+ +```sh +cd MOSuite +``` + +### If this is your first time cloning the repo, install dependencies + +- In an R console, install the R development dependencies with + `devtools::install_dev_deps()`, and then make sure the package passes R CMD + check by running `devtools::check()`. If R CMD check doesn't pass cleanly, + it's a good idea to ask for help before continuing. + +- Install [`pre-commit`](https://pre-commit.com/#install) if you don't already + have it. Then from the repo's root directory, run + + ```sh + pre-commit install + ``` + + This will install the repo's pre-commit hooks. + You'll only need to do this step the first time you clone the repo. + +### Create a branch + + Create a Git branch for your pull request (PR). Give the branch a descriptive + name for the changes you will make, such as `iss-10` if it is for a specific + issue. + + ```sh + # create a new branch and switch to it + git branch iss-10 + git switch iss-10 + ``` + + > Switched to a new branch 'iss-10' + +### Make your changes + +Edit the code, write unit tests, and update the documentation as needed. + +#### style + +New code should follow the [tidyverse style guide](https://style.tidyverse.org). +You can use the [styler](https://CRAN.R-project.org/package=styler) package to +apply these styles, but please don't restyle code that has nothing to do with +your PR. + +A brief overview of conventions according to the tidyverse style guide: + +- most object names (variables and functions) should be in [snake_case](https://style.tidyverse.org/syntax.html#sec-objectnames) +- function names should use [verbs](https://style.tidyverse.org/functions.html#naming) where possible +- use `<-` for assignment +- use [pipes](https://style.tidyverse.org/pipes.html) to chain operations on a single object + +Please see the [tidyverse style guide](https://style.tidyverse.org) for more details. + +#### test + +Most changes to the code will also need unit tests to demonstrate that the +changes work as intended. +Use [`testthat`](https://testthat.r-lib.org/) to create your unit tests and test +the code. +Test files are organized as described in +. +Take a look at the existing code in this package for examples. + +#### document + +If you have written a new function or changed the API of an existing function, +you will need to update the function's documentation using +[roxygen2](https://cran.r-project.org/package=roxygen2) with +[Markdown syntax](https://roxygen2.r-lib.org/articles/rd-formatting.html). +See instructions on writing roxygen2 comments here: +. +If the function is used in a vignette, you may also need to update the vignette. + +#### check + +After making your changes, run `devtools::check()` from an R console to make +sure the package still passes R CMD check. + +### Commit and push your changes + +If you're not sure how often you should commit or what your commits should +consist of, we recommend following the "atomic commits" principle where each +commit contains one new feature, fix, or task. +Learn more about atomic commits here: + + +First, add the files that you changed to the staging area: + +```sh +git add path/to/changed/files/ +``` + +Then make the commit. +Your commit message should follow the +[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) +specification. +Briefly, each commit should start with one of the approved types such as +`feat`, `fix`, `docs`, etc. followed by a description of the commit. +Take a look at the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/#summary) +for more detailed information about how to write commit messages. + + +```sh +git commit -m 'feat: create function for awesome feature' +``` + +pre-commit will enforce that your commit message and the code changes are +styled correctly and will attempt to make corrections if needed. + +> Check for added large files..............................................Passed
+> Fix End of Files.........................................................Passed
+> Trim Trailing Whitespace.................................................Failed
+> - hook id: trailing-whitespace
+> - exit code: 1
+> - files were modified by this hook
+>
+> Fixing path/to/changed/files/file.txt
+>
+> codespell................................................................Passed
+> style-files..........................................(no files to check)Skipped
+> readme-rmd-rendered..................................(no files to check)Skipped
+> use-tidy-description.................................(no files to check)Skipped
+ +In the example above, one of the hooks modified a file in the proposed commit, +so the pre-commit check failed. You can run `git diff` to see the changes that +pre-commit made and `git status` to see which files were modified. To proceed +with the commit, re-add the modified file(s) and re-run the commit command: + +```sh +git add path/to/changed/files/file.txt +git commit -m 'feat: create function for awesome feature' +``` + +This time, all the hooks either passed or were skipped +(e.g. hooks that only run on R code will not run if no R files were +committed). +When the pre-commit check is successful, the usual commit success message +will appear after the pre-commit messages showing that the commit was created. + +> Check for added large files..............................................Passed
+> Fix End of Files.........................................................Passed
+> Trim Trailing Whitespace.................................................Passed
+> codespell................................................................Passed
+> style-files..........................................(no files to check)Skipped
+> readme-rmd-rendered..................................(no files to check)Skipped
+> use-tidy-description.................................(no files to check)Skipped
+> Conventional Commit......................................................Passed
+> [iss-10 9ff256e] feat: create function for awesome feature
+> 1 file changed, 22 insertions(+), 3 deletions(-)
+ +Finally, push your changes to GitHub: + +```sh +git push +``` + +If this is the first time you are pushing this branch, you may have to +explicitly set the upstream branch: + +```sh +git push --set-upstream origin iss-10 +``` + +> Enumerating objects: 7, done.
+> Counting objects: 100% (7/7), done.
+> Delta compression using up to 10 threads
+> Compressing objects: 100% (4/4), done.
+> Writing objects: 100% (4/4), 648 bytes | 648.00 KiB/s, done.
+> Total 4 (delta 3), reused 0 (delta 0), pack-reused 0
+> remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
+> remote:
+> remote: Create a pull request for 'iss-10' on GitHub by visiting:
+> remote: https://github.com/CCBR/MOSuite/pull/new/iss-10
+> remote:
+> To https://github.com/CCBR/MOSuite
+>
+> [new branch] iss-10 -> iss-10
+> branch 'iss-10' set up to track 'origin/iss-10'.
+ +We recommend pushing your commits often so they will be backed up on GitHub. +You can view the files in your branch on GitHub at +`https://github.com/CCBR/MOSuite/tree/` +(replace `` with the actual name of your branch). + +### Create the PR + +Once your branch is ready, create a PR on GitHub: + + +Select the branch you just pushed: + +![Create a new PR from your branch](https://raw.githubusercontent.com/CCBR/CCBR_NextflowTemplate/main/.github/img/new-PR.png) + +Edit the PR title and description. +The title should briefly describe the change. +Follow the comments in the template to fill out the body of the PR, and +you can delete the comments (everything between ``) as you go. +When you're ready, click 'Create pull request' to open it. + +![Open the PR after editing the title and description](https://raw.githubusercontent.com/CCBR/CCBR_NextflowTemplate/main/.github/img/create-PR.png) + +Optionally, you can mark the PR as a draft if you're not yet ready for it to +be reviewed, then change it later when you're ready. + +### Wait for a maintainer to review your PR + +We will do our best to follow the tidyverse code review principles: +. +The reviewer may suggest that you make changes before accepting your PR in +order to improve the code quality or style. +If that's the case, continue to make changes in your branch and push them to +GitHub, and they will appear in the PR. + +Once the PR is approved, the maintainer will merge it and the issue(s) the PR +links will close automatically. +Congratulations and thank you for your contribution! + +### After your PR has been merged + +After your PR has been merged, update your local clone of the repo by +switching to the main branch and pulling the latest changes: + +```sh +git checkout main +git pull +``` + +It's a good idea to run `git pull` before creating a new branch so it will +start from the most recent commits in main. + +## Helpful links for more information + +- This contributing guide was adapted from the [tidyverse contributing guide](https://github.com/tidyverse/tidyverse/blob/main/.github/CONTRIBUTING.md) +- [GitHub Flow](https://docs.github.com/en/get-started/using-github/github-flow) +- [tidyverse style guide](https://style.tidyverse.org) +- [tidyverse code review principles](https://code-review.tidyverse.org) +- [reproducible examples](https://www.tidyverse.org/help/#reprex) +- [R packages book](https://r-pkgs.org/) +- packages: + - [usethis](https://usethis.r-lib.org/) + - [devtools](https://devtools.r-lib.org/) + - [testthat](https://testthat.r-lib.org/) + - [styler](https://styler.r-lib.org/) + - [roxygen2](https://roxygen2.r-lib.org) diff --git a/code/MOSuite/.github/ISSUE_TEMPLATE/bug_report.yml b/code/MOSuite/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..13b961e --- /dev/null +++ b/code/MOSuite/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,45 @@ +name: Bug report +description: Report something that is broken or incorrect +labels: bug +body: + - type: markdown + attributes: + value: | + Before you submit this issue, please check the documentation: + + - type: textarea + id: description + attributes: + label: Description of the bug + description: A clear and concise description of what the bug is. + validations: + required: true + + - type: textarea + id: reprex + attributes: + label: Code and output + description: Please include a minimal reproducible example (AKA a reprex). If you've never heard of a [reprex](http://reprex.tidyverse.org/) before, start by reading . + render: console + placeholder: | + library(MOSuite) + ... insert_your_code_here() ... + + Paste some output where something broke + + - type: textarea + id: files + attributes: + label: Relevant files + description: | + Please drag and drop any relevant files here if applicable. Create a `.zip` archive if the extension is not allowed. + + - type: textarea + id: system + attributes: + label: System information + description: | + * Version of R + * Version of CCBR/MOSuite + * OS _(eg. Ubuntu Linux, macOS)_ + * Hardware _(eg. HPC, Desktop)_ diff --git a/code/MOSuite/.github/ISSUE_TEMPLATE/config.yml b/code/MOSuite/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..d1dde83 --- /dev/null +++ b/code/MOSuite/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,4 @@ +contact_links: + - name: Discussions + url: https://github.com/CCBR/MOSuite/discussions + about: Please ask and answer questions here. diff --git a/code/MOSuite/.github/ISSUE_TEMPLATE/feature_request.yml b/code/MOSuite/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..73a08f5 --- /dev/null +++ b/code/MOSuite/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,11 @@ +name: Feature request +description: Suggest an idea for the package +labels: enhancement +body: + - type: textarea + id: description + attributes: + label: Description of feature + description: Please describe your suggestion for a new feature. It might help to describe a problem or use case, plus any alternatives that you have considered. + validations: + required: true diff --git a/code/MOSuite/.github/PULL_REQUEST_TEMPLATE.md b/code/MOSuite/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..bc679fa --- /dev/null +++ b/code/MOSuite/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,24 @@ +## Changes + + + +## Issues + + + +## PR Checklist + +(~Strikethrough~ any points that are not applicable.) + +- [ ] This comment contains a description of changes with justifications, with any relevant issues linked. +- [ ] Write unit tests for any new features, bug fixes, or other code changes. +- [ ] Update the docs if there are any API changes (roxygen2 comments, vignettes, readme, etc.). +- [ ] Update `NEWS.md` with a short description of any user-facing changes and reference the PR number. Follow the style described in +- [ ] Run `devtools::check()` locally and fix all notes, warnings, and errors. diff --git a/code/MOSuite/.github/WORDLIST.txt b/code/MOSuite/.github/WORDLIST.txt new file mode 100644 index 0000000..273d91e --- /dev/null +++ b/code/MOSuite/.github/WORDLIST.txt @@ -0,0 +1,3 @@ +Bu +entrace +metadat diff --git a/code/MOSuite/.github/assets/user-labels.yml b/code/MOSuite/.github/assets/user-labels.yml new file mode 100644 index 0000000..3ba7ab0 --- /dev/null +++ b/code/MOSuite/.github/assets/user-labels.yml @@ -0,0 +1,2 @@ +"POC: Kelly": kelly-sovacool +"POC: Phil": phoman14 diff --git a/code/MOSuite/.github/copilot-instructions.md b/code/MOSuite/.github/copilot-instructions.md new file mode 100644 index 0000000..ab79ac9 --- /dev/null +++ b/code/MOSuite/.github/copilot-instructions.md @@ -0,0 +1,164 @@ +# CoPilot Instructions for CCBR Repositories + +## Reviewer guidance (what to look for in PRs) + +- Reviewers must validate enforcement rules: no secrets, container specified, and reproducibility pins. +- If code is AI-generated, reviewers must ensure the author documents what was changed and why, and that the PR is labeled `generated-by-AI`. +- Reviewers should verify license headers and ownership metadata (for example, `CODEOWNERS`) are present. +- Reviews must read the code and verify that it adheres to the project's coding standards, guidelines, and best practices in software engineering. + +## CI & enforcement suggestions (automatable) + +1. **PR template**: include optional AI-assistance disclosure fields (model used, high-level prompt intent, manual review confirmation). +2. **Pre-merge check (GitHub Action)**: verify `.github/copilot-instructions.md` is present in the repository and that new pipeline files include a `# CRAFT:` header. +3. **Lint jobs**: `ruff` for Python, `shellcheck` for shell, `lintr` for R, and `nf-core lint` or Snakemake lint checks where applicable. +4. **Secrets scan**: run `TruffleHog` or `Gitleaks` on PRs to detect accidental credentials. +5. **AI usage label**: if AI usage is declared, an Action should add `generated-by-AI` label (create this label if it does not exist); the PR body should end with the italicized Markdown line: _Generated using AI_, and any associated commit messages should end with the plain footer line: `Generated using AI`. + +_Sample GH Action check (concept): if AI usage is declared, require an AI-assistance disclosure field in the PR body._ + +## Security & compliance (mandatory) + +- Developers must not send PHI or sensitive NIH internal identifiers to unapproved external AI services; use synthetic examples. +- Repository content must only be sent to model providers approved by NCI/NIH policy (for example, Copilot for Business or approved internal proxies). +- For AI-assisted actions, teams must keep an auditable record including: user, repository, action, timestamp, model name, and endpoint. +- If using a server wrapper (Option C), logs must include the minimum metadata above and follow institutional retention policy. +- If policy forbids external model use for internal code, teams must use approved local/internal LLM workflows. + +## Operational notes (practical) + +- `copilot-instructions.md` should remain concise and prescriptive; keep only high-value rules and edge-case examples. +- Developers should include the CRAFT block in edited files when requesting substantial generated code to improve context quality. +- CoPilot must ask the user for permission before deleting any file unless the file was created by CoPilot for a temporary run or test. +- CoPilot must not edit any files outside of the current open workspace. + +## Code authoring guidance + +- Code must not include hard-coded secrets, credentials, or sensitive absolute paths on disk. +- Code should be designed for modularity, reusability, and maintainability. It should ideally be platform-agnostic, with special support for running on the Biowulf HPC. +- Use pre-commit to enforce code style and linting during the commit process. + +### Pipelines + +- Authors must review existing CCBR pipelines first: . +- New pipelines should follow established CCBR conventions for folder layout, rule/process naming, config structure, and test patterns. +- Pipelines must define container images and pin tool/image versions for reproducibility. +- Contributions should include a test dataset and a documented example command. + +#### Snakemake + +- In general, new pipelines should be created with Nextflow rather than Snakemake, unless there is a compelling reason to use Snakemake. +- Generate new pipelines from the CCBR_SnakemakeTemplate repo: +- For Snakemake, run `snakemake --lint` and a dry-run before PR submission. + +#### Nextflow + +- Generate new pipelines from the CCBR_NextflowTemplate repo: +- For Nextflow pipelines, authors must follow nf-core patterns and references: . +- Nextflow code must use DSL2 only (DSL1 is not allowed). +- For Nextflow, run `nf-core lint` (or equivalent checks) before PR submission. +- Where possible, reuse modules and subworkflows from CCBR/nf-modules or nf-core/modules. +- New modules and subworkflows should be tested with `nf-test`. + +### Python scripts and packages + +- Python scripts must include module and function/class docstrings. +- Where a standard CLI framework is adopted, Python CLIs should use `click` or `typer` for consistency with existing components. +- Scripts must support `--help` and document required/optional arguments. +- Python code must follow [PEP 8](https://peps.python.org/pep-0008/), use `snake_case`, and include type hints for public functions. +- Scripts must raise descriptive error messages on failure and warnings when applicable. Prefer raising an exception over printing an error message, and over returning an error code. +- Python code should pass `ruff`; +- Each script must include a documented example usage in comments or README. +- Tests should be written with `pytest`. Other testing frameworks may be used if justified. +- Do not catch bare exceptions. The exception type must always be specified. +- Only include one return statement at the end of a function. + +### R scripts and packages + +- R scripts must include function and class docstrings via roxygen2. +- CLIs must be defined using the `argparse` package. +- CLIs must support `--help` and document required/optional arguments. +- R code should pass `lintr` and `air`. +- Tests should be written with `testthat`. +- Packages should 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, if a return statement is used at all. Explicit returns are preferred but not required for R functions. + +## AI-generated commit messages (Conventional Commits) + +- 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_ + +Suggested prompt for AI tools: + +```text +Create a Conventional Commit message from this staged diff. +Rules: +1) Use one of: feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert. +2) Keep subject <= 72 chars, imperative mood, no trailing period. +3) Include optional scope when clear. +4) Add a short body only if needed (why/impact), wrapped at ~72 chars. +5) Output only the final commit message. +``` + +## Pull Requests + +When opening a pull request, use the repository's pull request template (usually it is `.github/PULL_REQUEST_TEMPLATE.md`). +Different repos have different PR templates depending on their needs. +Ensure that the pull request follows the repository's PR template and includes all required information. +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. + +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 docstrings and long-form docs in the `docs/` or `vignettes/` directory. + +When a repo contains a build workflow (i.e. a workflow file in `.github/workflows` starting with `build` or named `R-CMD-check`), +the build workflow must pass before the PR can be approved. + +### Changelog + +The changelog for the repository should be maintained in a `CHANGELOG.md` file +(or `NEWS.md` for R packages) 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) +``` + +## Onboarding checklist for new developers + +- [ ] Read `.github/CONTRIBUTING.md` and `.github/copilot-instructions.md`. +- [ ] Configure VSCode workspace to open `copilot-instructions.md` by default (so Copilot Chat sees it). +- [ ] Install pre-commit and run `pre-commit install`. + +## Appendix: VSCode snippet (drop into `.vscode/snippets/craft.code-snippets`) + +```json +{ + "Insert CRAFT prompt": { + "prefix": "craft", + "body": [ + "/* C: Context: Repo=${workspaceFolderBasename}; bioinformatics pipelines; NIH HPC (Biowulf/Helix); containers: quay.io/ccbr */", + "/* R: Rules: no PHI, no secrets, containerize, pin versions, follow style */", + "/* F: Flow: inputs/ -> results/, conf/, tests/ */", + "/* T: Tests: provide a one-line TEST_CMD and expected output */", + "", + "A: $1" + ], + "description": "Insert CRAFT prompt and place cursor at Actions" + } +} +``` diff --git a/code/MOSuite/.github/img/GitHub-Flow_bg-white.png b/code/MOSuite/.github/img/GitHub-Flow_bg-white.png new file mode 100644 index 0000000..03696c2 Binary files /dev/null and b/code/MOSuite/.github/img/GitHub-Flow_bg-white.png differ diff --git a/code/MOSuite/.github/img/create-PR.png b/code/MOSuite/.github/img/create-PR.png new file mode 100644 index 0000000..d0f8765 Binary files /dev/null and b/code/MOSuite/.github/img/create-PR.png differ diff --git a/code/MOSuite/.github/img/new-PR.png b/code/MOSuite/.github/img/new-PR.png new file mode 100644 index 0000000..1c6173f Binary files /dev/null and b/code/MOSuite/.github/img/new-PR.png differ diff --git a/code/MOSuite/.github/package-versions.txt b/code/MOSuite/.github/package-versions.txt new file mode 100644 index 0000000..8d99fc0 --- /dev/null +++ b/code/MOSuite/.github/package-versions.txt @@ -0,0 +1 @@ +any::ggplot2@3.5.2 diff --git a/code/MOSuite/.github/workflows/R-CMD-check.yaml b/code/MOSuite/.github/workflows/R-CMD-check.yaml new file mode 100644 index 0000000..97d3f32 --- /dev/null +++ b/code/MOSuite/.github/workflows/R-CMD-check.yaml @@ -0,0 +1,71 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +name: R-CMD-check + +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: read + +jobs: + R-CMD-check: + strategy: + fail-fast: false + matrix: + config: + - { os: ubuntu-latest, r: 'release' } + - { os: ubuntu-latest, r: 'oldrel-1' } + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_KEEP_PKG_SOURCE: yes + steps: + - uses: actions/checkout@v6 + - uses: CCBR/actions/install-r-pak@main + with: + versions-file: .github/package-versions.txt + extra-packages: local::. + needs: dev + r-version: ${{ matrix.config.r }} + http-user-agent: ${{ matrix.config.http-user-agent }} + - uses: r-lib/actions/check-r-package@v2 + with: + upload-snapshots: true + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: CCBR/actions/install-r-pak@main + with: + r-version: 4.5 + versions-file: .github/package-versions.txt + needs: dev + - name: Lint + shell: Rscript {0} + run: lintr::lint_package() + env: + LINTR_ERROR_ON_LINT: false + + check: # make sure all check jobs pass. https://github.com/orgs/community/discussions/4324#discussioncomment-3477871 + runs-on: ubuntu-latest + needs: [R-CMD-check, lint] + if: always() + steps: + - name: Successful build + if: ${{ !(contains(needs.*.result, 'failure')) }} + run: exit 0 + - name: Failing build + if: ${{ contains(needs.*.result, 'failure') }} + run: exit 1 diff --git a/code/MOSuite/.github/workflows/assign-from-label.yml b/code/MOSuite/.github/workflows/assign-from-label.yml new file mode 100644 index 0000000..a8efb9c --- /dev/null +++ b/code/MOSuite/.github/workflows/assign-from-label.yml @@ -0,0 +1,33 @@ +name: assign-from-label +run-name: "assign-from-label: '${{ github.event.label.name }}'" + +on: + issues: + types: + - labeled + pull_request: + types: + - labeled + +env: + GH_TOKEN: ${{ github.token }} + +permissions: + issues: write + pull-requests: write + +jobs: + assign-from-label: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: pietrobolcato/action-read-yaml@1.1.0 + id: metadata + with: + config: .github/assets/user-labels.yml + + - name: assign + if: ${{ steps.metadata.outputs[github.event.label.name] != '' }} + run: | + gh issue edit ${{ github.event.issue.number }} --add-assignee ${{ steps.metadata.outputs[github.event.label.name] }} diff --git a/code/MOSuite/.github/workflows/auto-format.yml b/code/MOSuite/.github/workflows/auto-format.yml new file mode 100644 index 0000000..bc5d53b --- /dev/null +++ b/code/MOSuite/.github/workflows/auto-format.yml @@ -0,0 +1,87 @@ +name: auto-format + +on: + workflow_dispatch: + pull_request: + branches: [ main, master ] + +permissions: + contents: write + pull-requests: write + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + auto-format: + runs-on: ubuntu-latest + + steps: + - name: Generate a token + id: generate-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ vars.CCBR_BOT_APP_ID }} + private-key: ${{ secrets.CCBR_BOT_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + + - uses: actions/checkout@v6 + with: + token: ${{ steps.generate-token.outputs.token }} + fetch-depth: 0 + ref: ${{ github.event_name == 'pull_request' && github.head_ref || + github.ref_name }} + + - name: git config + run: | + git config --global user.name "CCBR-bot" + git config --global user.email "258092125+ccbr-bot@users.noreply.github.com" + + - uses: CCBR/actions/install-r-pak@main + with: + r-version: 4.5 + versions-file: .github/package-versions.txt + 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: | + rmarkdown::render("README.Rmd") + roxygen2::roxygenize() + + - name: update citation + shell: Rscript {0} + run: | + # See https://docs.ropensci.org/cffr/articles/cffr.html + library(cffr) + mykeys <- list(identifiers = list(list( + description = "Archived snapshots of all versions", + type = "doi", + value = "10.5281/zenodo.16371580" + ))) + cf <- cff_create(keys = mykeys) + # Create your CITATION.cff file + cff_write(cf) + + - name: update codemeta + uses: citation-file-format/cffconvert-github-action@2.0.0 + with: + args: "--format codemeta --outfile codemeta.json" + + - name: format + uses: pre-commit/action@v3.0.1 + continue-on-error: true + + - name: commit & push + run: | + git add . + git commit -m "ci: 🤖 auto-format" || echo "nothing to commit" + git push || echo "nothing to push" diff --git a/code/MOSuite/.github/workflows/check-links.yml b/code/MOSuite/.github/workflows/check-links.yml new file mode 100644 index 0000000..3b9493e --- /dev/null +++ b/code/MOSuite/.github/workflows/check-links.yml @@ -0,0 +1,30 @@ +name: links + +on: + repository_dispatch: + workflow_dispatch: + schedule: + - cron: "12 11 2 3,9 *" + +jobs: + linkChecker: + runs-on: ubuntu-latest + permissions: + issues: write # required for peter-evans/create-issue-from-file + steps: + - uses: actions/checkout@v4 + + - name: Link Checker + id: lychee + uses: lycheeverse/lychee-action@v2 + with: + fail: false + + - name: Create Issue From File + if: steps.lychee.outputs.exit_code != 0 + uses: peter-evans/create-issue-from-file@v5 + with: + title: Link Checker Report + content-filepath: ./lychee/out.md + labels: automated issue + assignees: kelly-sovacool diff --git a/code/MOSuite/.github/workflows/docker.yml b/code/MOSuite/.github/workflows/docker.yml new file mode 100644 index 0000000..ceb8f50 --- /dev/null +++ b/code/MOSuite/.github/workflows/docker.yml @@ -0,0 +1,78 @@ +name: docker + +on: + workflow_dispatch: + inputs: + docker_image_tag: + description: "Tag to apply to the built docker image (e.g. 'v0.3.0'). If not + specified, it will be determined from the DESCRIPTION file." + required: false + default: "" + release: + types: [ published ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + R_VERSION: 4.4 + CONTEXT: "./" + NAMESPACE: "nciccbr" +jobs: + build-docker: + runs-on: ubuntu-latest + permissions: + contents: read + strategy: + fail-fast: false + matrix: + config: + - { dockerfile_path: "docker/Dockerfile", image_name: "mosuite" } + - { dockerfile_path: "docker/Dockerfile_minimal", image_name: "mosuite-minimal" } + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ github.ref_name }} + - name: prepare variables + id: vars + run: | + image_name="${{ matrix.config.image_name }}" + + if [ "${{ github.event_name }}" = "release" ]; then + version="${{ github.ref_name }}" + elif [ -n "${{ github.event.inputs.docker_image_tag }}" ]; then + version="${{ github.event.inputs.docker_image_tag }}" + else + version="$(grep 'Version:' ./DESCRIPTION | sed 's/Version: /v/')" + fi + + docker_tags="${NAMESPACE}/${image_name}:${version}" + if [ "${{ github.event_name }}" = "release" ]; then + docker_tags="${docker_tags},${NAMESPACE}/${image_name}:latest" + fi + + echo "date=$(date +"%Y-%m-%d")" >> "$GITHUB_OUTPUT" + echo "dockerfile_path=${{ matrix.config.dockerfile_path }}" >> "$GITHUB_OUTPUT" + echo "image_name=${image_name}" >> "$GITHUB_OUTPUT" + echo "version=${version}" >> "$GITHUB_OUTPUT" + echo "docker_tags=${docker_tags}" >> "$GITHUB_OUTPUT" + + - name: Login to DockerHub + if: ${{ github.event_name != 'pull_request' }} + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push + uses: docker/build-push-action@v6 + with: + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.vars.outputs.docker_tags }} + context: ${{ env.CONTEXT }} + file: ${{ steps.vars.outputs.dockerfile_path }} + build-args: | + BUILD_DATE=${{ steps.vars.outputs.date }} + BUILD_TAG=${{ steps.vars.outputs.version }} + REPONAME=${{ steps.vars.outputs.image_name }} + R_VERSION=${{ env.R_VERSION }} diff --git a/code/MOSuite/.github/workflows/label-issues-repo-name.yml b/code/MOSuite/.github/workflows/label-issues-repo-name.yml new file mode 100644 index 0000000..5c6d15d --- /dev/null +++ b/code/MOSuite/.github/workflows/label-issues-repo-name.yml @@ -0,0 +1,21 @@ +name: label-issues-repo-name + +on: + issues: + types: + - opened + pull_request: + types: + - opened + +permissions: + issues: write + pull-requests: write + +jobs: + add-label: + runs-on: ubuntu-latest + steps: + - uses: CCBR/actions/label-issue-repo-name@v0.5 + with: + github-token: ${{ github.token }} diff --git a/code/MOSuite/.github/workflows/pkgdown.yaml b/code/MOSuite/.github/workflows/pkgdown.yaml new file mode 100644 index 0000000..ac57479 --- /dev/null +++ b/code/MOSuite/.github/workflows/pkgdown.yaml @@ -0,0 +1,47 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + release: + types: [ published ] + workflow_dispatch: + +name: pkgdown + +permissions: + contents: write + pages: write + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + pkgdown: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v6 + + - uses: CCBR/actions/install-r-pak@main + with: + r-version: 4.5 + versions-file: .github/package-versions.txt + extra-packages: local::. + needs: dev + + - name: Build site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) + shell: Rscript {0} + + - name: Deploy to GitHub pages 🚀 + if: github.event_name != 'pull_request' + uses: JamesIves/github-pages-deploy-action@v4.4.1 + with: + clean: false + branch: gh-pages + folder: docs diff --git a/code/MOSuite/.github/workflows/techdev-project.yml b/code/MOSuite/.github/workflows/techdev-project.yml new file mode 100644 index 0000000..7dd5d21 --- /dev/null +++ b/code/MOSuite/.github/workflows/techdev-project.yml @@ -0,0 +1,53 @@ +name: TechDev-project + +on: + issues: + types: + - opened + - reopened + pull_request: + types: + - opened + +permissions: + issues: write + pull-requests: write + contents: read + +jobs: + add-to-project-ccbr: + runs-on: ubuntu-latest + steps: + - name: Generate a token + id: generate-token + if: ${{ inputs.github-token == '' }} + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ vars.CCBR_BOT_APP_ID }} + private-key: ${{ secrets.CCBR_BOT_PRIVATE_KEY }} + owner: CCBR + + - name: Add to CCBR techdev project + uses: actions/add-to-project@v1.0.2 + with: + project-url: https://github.com/orgs/CCBR/projects/17 + github-token: ${{ steps.generate-token.outputs.token }} + + add-to-project-nidap: + runs-on: ubuntu-latest + if: github.event_name == 'issues' + steps: + - name: Generate a token + id: generate-token + if: ${{ inputs.github-token == '' }} + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ vars.CCBR_BOT_APP_ID }} + private-key: ${{ secrets.CCBR_BOT_PRIVATE_KEY }} + owner: NIDAP-Community + + - name: Add to NIDAP MOSuite project + uses: actions/add-to-project@v1.0.2 + with: + project-url: https://github.com/orgs/NIDAP-Community/projects/3 + github-token: ${{ steps.generate-token.outputs.token }} diff --git a/code/MOSuite/.github/workflows/test-coverage.yaml b/code/MOSuite/.github/workflows/test-coverage.yaml new file mode 100644 index 0000000..6531d6f --- /dev/null +++ b/code/MOSuite/.github/workflows/test-coverage.yaml @@ -0,0 +1,74 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +name: test-coverage + +on: + push: + branches: [main, master] + paths: + - "R/**" + - "tests/**" + - "DESCRIPTION" + - "NAMESPACE" + - ".github/workflows/test-coverage.yaml" + pull_request: + branches: [main, master] + paths: + - "R/**" + - "tests/**" + - "DESCRIPTION" + - "NAMESPACE" + - ".github/workflows/test-coverage.yaml" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: read-all + +jobs: + test-coverage: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + steps: + - uses: actions/checkout@v4 + + - uses: CCBR/actions/install-r-pak@main + with: + r-version: 4.5 + versions-file: .github/package-versions.txt + needs: dev + + - name: Test coverage + run: | + cov <- covr::package_coverage( + quiet = FALSE, + clean = FALSE, + install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") + ) + covr::to_cobertura(cov) + shell: Rscript {0} + + - uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: ${{ github.event_name != 'pull_request' && true || false }} + file: ./cobertura.xml + plugin: noop + disable_search: true + token: ${{ secrets.CODECOV_TOKEN }} + + - name: Show testthat output + if: always() + run: | + ## -------------------------------------------------------------------- + find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true + shell: bash + + - name: Upload test results + if: failure() + uses: actions/upload-artifact@v4 + with: + name: coverage-test-failures + path: ${{ runner.temp }}/package diff --git a/code/MOSuite/.github/workflows/user-projects.yml b/code/MOSuite/.github/workflows/user-projects.yml new file mode 100644 index 0000000..c189ef6 --- /dev/null +++ b/code/MOSuite/.github/workflows/user-projects.yml @@ -0,0 +1,23 @@ +name: user-projects + +on: + issues: + types: + - assigned + pull_request: + types: + - assigned + +permissions: + issues: write + pull-requests: write + +jobs: + add-to-project: + runs-on: ubuntu-latest + steps: + - uses: CCBR/actions/user-projects@main + with: + app-id: ${{ vars.CCBR_BOT_APP_ID }} + app-private-key: ${{ secrets.CCBR_BOT_PRIVATE_KEY }} + token-owner: "CCBR" diff --git a/code/MOSuite/.gitignore b/code/MOSuite/.gitignore new file mode 100644 index 0000000..a7f1be5 --- /dev/null +++ b/code/MOSuite/.gitignore @@ -0,0 +1,21 @@ +.Rproj.user +.Rhistory +.Rdata +.httr-oauth +.DS_Store +.quarto +docs +inst/doc +/doc/ +/Meta/ +/README.html +**/figures/ +VennDiagram.*.log +*_files/ +tests/testthat/Rplots.pdf +/tmp +vignettes/args*.json +Rplots.pdf +moo_input.rds +plot-volc-enh.json +volc-sum-params.json diff --git a/code/MOSuite/.lintr b/code/MOSuite/.lintr new file mode 100644 index 0000000..e636784 --- /dev/null +++ b/code/MOSuite/.lintr @@ -0,0 +1,10 @@ +linters: linters_with_defaults( + line_length_linter = line_length_linter(120L), + commented_code_linter = NULL, + object_name_linter = NULL, + object_length_linter = object_length_linter(60L), + return_linter = return_linter( + return_style = "explicit" + ), + indentation_linter = NULL + ) diff --git a/code/MOSuite/.pre-commit-config.yaml b/code/MOSuite/.pre-commit-config.yaml new file mode 100644 index 0000000..7331cb1 --- /dev/null +++ b/code/MOSuite/.pre-commit-config.yaml @@ -0,0 +1,47 @@ +default_install_hook_types: [pre-commit, commit-msg] +default_stages: [pre-commit] +exclude: | + (?x)( + ^assets/| + ^docs/.*.html| + ^inst/extdata| + ^man/| + ^tests/testthat/_snaps/| + ^CITATION.cff| + ^renv* + ) +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: check-added-large-files + args: ["--maxkb=12000"] + - id: end-of-file-fixer + - id: trailing-whitespace + # spell check + - repo: https://github.com/codespell-project/codespell + rev: v2.4.2 + hooks: + - id: codespell + args: ["-I=.github/WORDLIST.txt"] + # R formatting + - repo: https://github.com/posit-dev/air-pre-commit + rev: 0.9.0 + hooks: + - id: air-format + - repo: https://github.com/lorenzwalthert/precommit + rev: v0.4.3.9021 + hooks: + - id: parsable-R + - id: readme-rmd-rendered + - id: use-tidy-description + - id: lintr + args: [--warn_only] + verbose: true + # enforce commit format + - repo: https://github.com/compilerla/conventional-pre-commit + rev: v4.4.0 + hooks: + - id: conventional-pre-commit + stages: [commit-msg] + args: [] diff --git a/code/MOSuite/.prettierignore b/code/MOSuite/.prettierignore new file mode 100644 index 0000000..63da1a4 --- /dev/null +++ b/code/MOSuite/.prettierignore @@ -0,0 +1,10 @@ +# gitignore +.nextflow* +work/ +data/ +results/ +.DS_Store +*.code-workspace +assets/*.html +data-raw/*.txt +man/* diff --git a/code/MOSuite/.prettierrc b/code/MOSuite/.prettierrc new file mode 100644 index 0000000..6385d00 --- /dev/null +++ b/code/MOSuite/.prettierrc @@ -0,0 +1,7 @@ +overrides: + - files: + - "*.md" + - "citation.cff" + - ".prettierrc" + options: + tabWidth: 2 diff --git a/code/MOSuite/.vscode/extensions.json b/code/MOSuite/.vscode/extensions.json new file mode 100644 index 0000000..344f76e --- /dev/null +++ b/code/MOSuite/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "Posit.air-vscode" + ] +} diff --git a/code/MOSuite/.vscode/settings.json b/code/MOSuite/.vscode/settings.json new file mode 100644 index 0000000..61ac215 --- /dev/null +++ b/code/MOSuite/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + "[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/CITATION.cff b/code/MOSuite/CITATION.cff new file mode 100644 index 0000000..541c136 --- /dev/null +++ b/code/MOSuite/CITATION.cff @@ -0,0 +1,1046 @@ +# -------------------------------------------- +# CITATION file created with {cffr} R package +# See also: https://docs.ropensci.org/cffr/ +# -------------------------------------------- + +cff-version: 1.2.0 +message: 'To cite package "MOSuite" in publications use:' +type: software +license: MIT +title: 'MOSuite: R package for differential multi-omics analysis' +version: 0.3.1 +doi: 10.5281/zenodo.16371580 +identifiers: +- description: Archived snapshots of all versions + type: doi + value: 10.5281/zenodo.16371580 +abstract: Multi-Omics Suite provides a suite of functions to clean, filter, batch-correct, + normalize, visualize, and perform differential analysis. While the package is designed + for differential RNA-seq analysis and multi-omics datasets, it can be used for any + data represented in a counts table. See the website for more information, documentation, + and examples at . +authors: +- family-names: Sovacool + given-names: Kelly + email: kelly.sovacool@nih.gov + orcid: https://orcid.org/0000-0003-3283-829X +- family-names: Homan + given-names: Philip + email: philip.homan@nih.gov +- family-names: Koparde + given-names: Vishal + email: vishal.koparde@nih.gov + orcid: https://orcid.org/0000-0001-8978-8495 +- family-names: Chill + given-names: Samantha + email: samantha.chill@nih.gov + orcid: https://orcid.org/0000-0002-8734-9875 +preferred-citation: + type: manual + title: 'MOSuite: R package for differential multi-omics analysis' + authors: + - family-names: Sovacool + given-names: Kelly + email: kelly.sovacool@nih.gov + orcid: https://orcid.org/0000-0003-3283-829X + - family-names: Homan + given-names: Philip + email: philip.homan@nih.gov + - family-names: Koparde + given-names: Vishal + email: vishal.koparde@nih.gov + orcid: https://orcid.org/0000-0001-8978-8495 + - family-names: Chill + given-names: Samantha + email: samantha.chill@nih.gov + orcid: https://orcid.org/0000-0002-8734-9875 + year: '2025' + doi: 10.5281/zenodo.16371580 + url: https://ccbr.github.io/MOSuite/ +repository-code: https://github.com/CCBR/MOSuite +url: https://ccbr.github.io/MOSuite/ +contact: +- family-names: Sovacool + given-names: Kelly + email: kelly.sovacool@nih.gov + orcid: https://orcid.org/0000-0003-3283-829X +references: +- type: software + title: 'R: A Language and Environment for Statistical Computing' + notes: Depends + url: https://www.R-project.org/ + authors: + - name: R Core Team + institution: + name: R Foundation for Statistical Computing + address: Vienna, Austria + year: '2026' + version: '>= 4.0.0' +- type: software + title: assertthat + abstract: 'assertthat: Easy Pre and Post Assertions' + notes: Imports + repository: https://CRAN.R-project.org/package=assertthat + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@rstudio.com + year: '2026' + doi: 10.32614/CRAN.package.assertthat +- type: software + title: dendextend + abstract: 'dendextend: Extending ''dendrogram'' Functionality in R' + notes: Imports + url: https://talgalili.github.io/dendextend/ + repository: https://CRAN.R-project.org/package=dendextend + authors: + - family-names: Galili + given-names: Tal + email: tal.galili@gmail.com + - family-names: Jefferis + given-names: Gregory + email: jefferis@gmail.com + year: '2026' + doi: 10.32614/CRAN.package.dendextend +- type: software + title: DESeq2 + abstract: 'DESeq2: Differential gene expression analysis based on the negative binomial + distribution' + notes: Imports + url: https://github.com/thelovelab/DESeq2 + repository: https://bioconductor.org/ + authors: + - family-names: Love + given-names: Michael + email: michaelisaiahlove@gmail.com + - family-names: Anders + given-names: Simon + - family-names: Huber + given-names: Wolfgang + year: '2026' + doi: 10.18129/B9.bioc.DESeq2 +- type: software + title: dplyr + abstract: 'dplyr: A Grammar of Data Manipulation' + notes: Imports + url: https://dplyr.tidyverse.org + repository: https://CRAN.R-project.org/package=dplyr + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + orcid: https://orcid.org/0000-0003-4757-117X + - family-names: François + given-names: Romain + orcid: https://orcid.org/0000-0002-2444-4226 + - family-names: Henry + given-names: Lionel + - family-names: Müller + given-names: Kirill + orcid: https://orcid.org/0000-0002-1416-3412 + - family-names: Vaughan + given-names: Davis + email: davis@posit.co + orcid: https://orcid.org/0000-0003-4777-038X + year: '2026' + doi: 10.32614/CRAN.package.dplyr +- type: software + title: edgeR + abstract: 'edgeR: Empirical Analysis of Digital Gene Expression Data in R' + notes: Imports + url: https://bioinf.wehi.edu.au/edgeR/ + repository: https://bioconductor.org/ + authors: + - family-names: Chen + given-names: Yunshun + - family-names: Chen + given-names: Lizhong + - family-names: Lun + given-names: Aaron TL + - family-names: McCarthy + given-names: Davis J + - family-names: Baldoni + given-names: Pedro + - family-names: Ritchie + given-names: Matthew E + - family-names: Phipson + given-names: Belinda + - family-names: Hu + given-names: Yifang + - family-names: Zhou + given-names: Xiaobei + - family-names: Robinson + given-names: Mark D + - family-names: Smyth + given-names: Gordon K + year: '2026' + doi: 10.18129/B9.bioc.edgeR +- type: software + title: ggplot2 + abstract: 'ggplot2: Create Elegant Data Visualisations Using the Grammar of Graphics' + notes: Imports + url: https://ggplot2.tidyverse.org + repository: https://CRAN.R-project.org/package=ggplot2 + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + orcid: https://orcid.org/0000-0003-4757-117X + - family-names: Chang + given-names: Winston + orcid: https://orcid.org/0000-0002-1576-2126 + - family-names: Henry + given-names: Lionel + - family-names: Pedersen + given-names: Thomas Lin + email: thomas.pedersen@posit.co + orcid: https://orcid.org/0000-0002-5147-4711 + - family-names: Takahashi + given-names: Kohske + - family-names: Wilke + given-names: Claus + orcid: https://orcid.org/0000-0002-7470-9261 + - family-names: Woo + given-names: Kara + orcid: https://orcid.org/0000-0002-5125-4188 + - family-names: Yutani + given-names: Hiroaki + orcid: https://orcid.org/0000-0002-3385-7233 + - family-names: Dunnington + given-names: Dewey + orcid: https://orcid.org/0000-0002-9415-4582 + - family-names: Brand + given-names: Teun + name-particle: van den + orcid: https://orcid.org/0000-0002-9335-7468 + year: '2026' + doi: 10.32614/CRAN.package.ggplot2 + version: < 4.0.0 +- type: software + title: glue + abstract: 'glue: Interpreted String Literals' + notes: Imports + url: https://glue.tidyverse.org/ + repository: https://CRAN.R-project.org/package=glue + authors: + - family-names: Hester + given-names: Jim + orcid: https://orcid.org/0000-0002-2739-7082 + - family-names: Bryan + given-names: Jennifer + email: jenny@posit.co + orcid: https://orcid.org/0000-0002-6983-2759 + year: '2026' + doi: 10.32614/CRAN.package.glue +- type: software + title: htmlwidgets + abstract: 'htmlwidgets: HTML Widgets for R' + notes: Imports + url: https://github.com/ramnathv/htmlwidgets + repository: https://CRAN.R-project.org/package=htmlwidgets + authors: + - family-names: Vaidyanathan + given-names: Ramnath + - family-names: Xie + given-names: Yihui + - family-names: Allaire + given-names: JJ + - family-names: Cheng + given-names: Joe + email: joe@posit.co + - family-names: Sievert + given-names: Carson + email: carson@posit.co + orcid: https://orcid.org/0000-0002-4958-2844 + - family-names: Russell + given-names: Kenton + year: '2026' + doi: 10.32614/CRAN.package.htmlwidgets +- type: software + title: jsonlite + abstract: 'jsonlite: A Simple and Robust JSON Parser and Generator for R' + notes: Imports + url: https://jeroen.r-universe.dev/jsonlite + repository: https://CRAN.R-project.org/package=jsonlite + authors: + - family-names: Ooms + given-names: Jeroen + email: jeroenooms@gmail.com + orcid: https://orcid.org/0000-0002-4035-0289 + year: '2026' + doi: 10.32614/CRAN.package.jsonlite +- type: software + title: limma + abstract: 'limma: Linear Models for Microarray and Omics Data' + notes: Imports + url: https://bioinf.wehi.edu.au/limma/ + repository: https://bioconductor.org/ + authors: + - family-names: Smyth + given-names: Gordon + - 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 + title: matrixStats + abstract: 'matrixStats: Functions that Apply to Rows and Columns of Matrices (and + to Vectors)' + notes: Imports + url: https://github.com/HenrikBengtsson/matrixStats + repository: https://CRAN.R-project.org/package=matrixStats + authors: + - family-names: Bengtsson + given-names: Henrik + email: henrikb@braju.com + year: '2026' + doi: 10.32614/CRAN.package.matrixStats +- type: software + title: methods + 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: options + abstract: 'options: Simple, Consistent Package Options' + notes: Imports + url: https://dgkf.github.io/options/ + repository: https://CRAN.R-project.org/package=options + authors: + - family-names: Kelkhoff + given-names: Doug + email: doug.kelkhoff@gmail.com + year: '2026' + doi: 10.32614/CRAN.package.options +- type: software + title: plotly + abstract: 'plotly: Create Interactive Web Graphics via ''plotly.js''' + notes: Imports + url: https://plotly-r.com + repository: https://CRAN.R-project.org/package=plotly + authors: + - family-names: Sievert + given-names: Carson + email: cpsievert1@gmail.com + orcid: https://orcid.org/0000-0002-4958-2844 + - family-names: Parmer + given-names: Chris + email: chris@plot.ly + - family-names: Hocking + given-names: Toby + email: tdhock5@gmail.com + - family-names: Chamberlain + given-names: Scott + email: myrmecocystus@gmail.com + - family-names: Ram + given-names: Karthik + email: karthik.ram@gmail.com + - family-names: Corvellec + given-names: Marianne + email: marianne.corvellec@igdore.org + orcid: https://orcid.org/0000-0002-1994-3581 + - family-names: Despouy + given-names: Pedro + email: pedro@plot.ly + year: '2026' + doi: 10.32614/CRAN.package.plotly +- type: software + title: purrr + abstract: 'purrr: Functional Programming Tools' + notes: Imports + url: https://purrr.tidyverse.org/ + repository: https://CRAN.R-project.org/package=purrr + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + orcid: https://orcid.org/0000-0003-4757-117X + - family-names: Henry + given-names: Lionel + email: lionel@posit.co + year: '2026' + doi: 10.32614/CRAN.package.purrr +- type: software + title: reshape2 + abstract: 'reshape2: Flexibly Reshape Data: A Reboot of the Reshape Package' + notes: Imports + url: https://github.com/hadley/reshape + repository: https://CRAN.R-project.org/package=reshape2 + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + year: '2026' + doi: 10.32614/CRAN.package.reshape2 +- type: software + title: rlang + abstract: 'rlang: Functions for Base Types and Core R and ''Tidyverse'' Features' + notes: Imports + url: https://rlang.r-lib.org + repository: https://CRAN.R-project.org/package=rlang + authors: + - family-names: Henry + given-names: Lionel + email: lionel@posit.co + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + year: '2026' + doi: 10.32614/CRAN.package.rlang +- type: software + title: S7 + abstract: 'S7: An Object Oriented System Meant to Become a Successor to S3 and S4' + notes: Imports + url: https://rconsortium.github.io/S7/ + repository: https://CRAN.R-project.org/package=S7 + authors: + - family-names: Vaughan + given-names: Davis + - family-names: Hester + given-names: Jim + orcid: https://orcid.org/0000-0002-2739-7082 + - family-names: Kalinowski + given-names: Tomasz + - family-names: Landau + given-names: Will + - family-names: Lawrence + given-names: Michael + - family-names: Maechler + given-names: Martin + orcid: https://orcid.org/0000-0002-8685-9910 + - family-names: Tierney + given-names: Luke + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + orcid: https://orcid.org/0000-0003-4757-117X + year: '2026' + doi: 10.32614/CRAN.package.S7 +- type: software + title: stats + 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: stringr + abstract: 'stringr: Simple, Consistent Wrappers for Common String Operations' + notes: Imports + url: https://stringr.tidyverse.org + repository: https://CRAN.R-project.org/package=stringr + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + year: '2026' + doi: 10.32614/CRAN.package.stringr +- type: software + title: tibble + abstract: 'tibble: Simple Data Frames' + notes: Imports + url: https://tibble.tidyverse.org/ + repository: https://CRAN.R-project.org/package=tibble + authors: + - family-names: Müller + given-names: Kirill + email: kirill@cynkra.com + orcid: https://orcid.org/0000-0002-1416-3412 + - family-names: Wickham + given-names: Hadley + email: hadley@rstudio.com + year: '2026' + doi: 10.32614/CRAN.package.tibble +- type: software + title: tidyr + abstract: 'tidyr: Tidy Messy Data' + notes: Imports + url: https://tidyr.tidyverse.org + repository: https://CRAN.R-project.org/package=tidyr + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + - family-names: Vaughan + given-names: Davis + email: davis@posit.co + - family-names: Girlich + given-names: Maximilian + year: '2026' + doi: 10.32614/CRAN.package.tidyr +- type: software + title: tidyselect + abstract: 'tidyselect: Select from a Set of Strings' + notes: Imports + url: https://tidyselect.r-lib.org + repository: https://CRAN.R-project.org/package=tidyselect + authors: + - family-names: Henry + given-names: Lionel + email: lionel@posit.co + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + year: '2026' + doi: 10.32614/CRAN.package.tidyselect +- type: software + title: amap + abstract: 'amap: Another Multidimensional Analysis Package' + notes: Suggests + repository: https://CRAN.R-project.org/package=amap + authors: + - family-names: Lucas + given-names: Antoine + email: antoinelucas@gmail.com + year: '2026' + doi: 10.32614/CRAN.package.amap +- type: software + title: argparse + abstract: 'argparse: Command Line Optional and Positional Argument Parser' + notes: Suggests + url: https://trevorldavis.com/R/argparse/ + repository: https://CRAN.R-project.org/package=argparse + authors: + - family-names: Davis + given-names: Trevor L. + email: trevor.l.davis@gmail.com + orcid: https://orcid.org/0000-0001-6341-4639 + year: '2026' + doi: 10.32614/CRAN.package.argparse +- type: software + title: broom + abstract: 'broom: Convert Statistical Objects into Tidy Tibbles' + notes: Suggests + url: https://broom.tidymodels.org/ + repository: https://CRAN.R-project.org/package=broom + authors: + - family-names: Robinson + given-names: David + email: admiral.david@gmail.com + - family-names: Hayes + given-names: Alex + email: alexpghayes@gmail.com + orcid: https://orcid.org/0000-0002-4985-5160 + - family-names: Couch + given-names: Simon + email: simon.couch@posit.co + orcid: https://orcid.org/0000-0001-5676-5107 + - family-names: Hvitfeldt + given-names: Emil + email: emil.hvitfeldt@posit.co + orcid: https://orcid.org/0000-0002-0679-1945 + year: '2026' + doi: 10.32614/CRAN.package.broom +- type: software + title: cffr + abstract: 'cffr: Generate Citation File Format (''cff'') Metadata for R Packages' + notes: Suggests + url: https://docs.ropensci.org/cffr/ + repository: https://CRAN.R-project.org/package=cffr + authors: + - family-names: Hernangómez + given-names: Diego + email: diego.hernangomezherrero@gmail.com + orcid: https://orcid.org/0000-0001-8457-4658 + year: '2026' + doi: 10.32614/CRAN.package.cffr +- type: software + title: colorspace + abstract: 'colorspace: A Toolbox for Manipulating and Assessing Colors and Palettes' + notes: Suggests + url: https://colorspace.R-Forge.R-project.org/ + repository: https://CRAN.R-project.org/package=colorspace + authors: + - family-names: Ihaka + given-names: Ross + email: ihaka@stat.auckland.ac.nz + - family-names: Murrell + given-names: Paul + email: paul@stat.auckland.ac.nz + orcid: https://orcid.org/0000-0002-3224-8858 + - family-names: Hornik + given-names: Kurt + email: Kurt.Hornik@R-project.org + orcid: https://orcid.org/0000-0003-4198-9911 + - family-names: Fisher + given-names: Jason C. + email: jfisher@usgs.gov + orcid: https://orcid.org/0000-0001-9032-8912 + - family-names: Stauffer + given-names: Reto + email: Reto.Stauffer@uibk.ac.at + orcid: https://orcid.org/0000-0002-3798-5507 + - family-names: Wilke + given-names: Claus O. + email: wilke@austin.utexas.edu + orcid: https://orcid.org/0000-0002-7470-9261 + - family-names: McWhite + given-names: Claire D. + email: claire.mcwhite@utmail.utexas.edu + orcid: https://orcid.org/0000-0001-7346-3047 + - family-names: Zeileis + given-names: Achim + email: Achim.Zeileis@R-project.org + orcid: https://orcid.org/0000-0003-0918-3766 + year: '2026' + doi: 10.32614/CRAN.package.colorspace +- type: software + title: ComplexHeatmap + abstract: 'ComplexHeatmap: Make Complex Heatmaps' + notes: Suggests + url: https://jokergoo.github.io/ComplexHeatmap-reference/book/ + repository: https://bioconductor.org/ + authors: + - family-names: Gu + given-names: Zuguang + email: guzuguang@suat-sz.edu.cn + orcid: https://orcid.org/0000-0002-7395-8709 + year: '2026' + doi: 10.18129/B9.bioc.ComplexHeatmap +- type: software + title: dendsort + abstract: 'dendsort: Modular Leaf Ordering Methods for Dendrogram Nodes' + notes: Suggests + url: https://github.com/evanbiederstedt/dendsort + repository: https://CRAN.R-project.org/package=dendsort + authors: + - family-names: Sakai + given-names: Ryo + email: ryo@vda-lab.be + - family-names: Biederstedt + given-names: Evan + email: evan.biederstedt@gmail.com + year: '2026' + doi: 10.32614/CRAN.package.dendsort +- type: software + title: docopt + abstract: 'docopt: Command-Line Interface Specification Language' + notes: Suggests + url: https://github.com/docopt/docopt.R + repository: https://CRAN.R-project.org/package=docopt + authors: + - family-names: Jonge + given-names: Edwin + name-particle: de + email: edwindjonge@gmail.com + orcid: https://orcid.org/0000-0002-6580-4718 + year: '2026' + doi: 10.32614/CRAN.package.docopt +- type: software + title: EnhancedVolcano + abstract: 'EnhancedVolcano: Publication-ready volcano plots with enhanced colouring + and labeling' + notes: Suggests + url: https://github.com/kevinblighe/EnhancedVolcano + repository: https://bioconductor.org/ + authors: + - family-names: Blighe + given-names: Kevin + - family-names: Rana + given-names: Sharmila + - family-names: Lewis + given-names: Myles + year: '2026' + doi: 10.18129/B9.bioc.EnhancedVolcano +- type: software + title: ggrepel + abstract: 'ggrepel: Automatically Position Non-Overlapping Text Labels with ''ggplot2''' + notes: Suggests + url: https://ggrepel.slowkow.com/ + repository: https://CRAN.R-project.org/package=ggrepel + authors: + - family-names: Slowikowski + given-names: Kamil + email: kslowikowski@gmail.com + orcid: https://orcid.org/0000-0002-2843-6370 + year: '2026' + doi: 10.32614/CRAN.package.ggrepel +- type: software + title: gridExtra + abstract: 'gridExtra: Miscellaneous Functions for "Grid" Graphics' + notes: Suggests + repository: https://CRAN.R-project.org/package=gridExtra + authors: + - family-names: Auguie + given-names: Baptiste + email: baptiste.auguie@gmail.com + year: '2026' + doi: 10.32614/CRAN.package.gridExtra +- type: software + title: knitr + abstract: 'knitr: A General-Purpose Package for Dynamic Report Generation in R' + notes: Suggests + url: https://yihui.org/knitr/ + repository: https://CRAN.R-project.org/package=knitr + authors: + - family-names: Xie + given-names: Yihui + email: xie@yihui.name + orcid: https://orcid.org/0000-0003-0645-5666 + year: '2026' + doi: 10.32614/CRAN.package.knitr +- type: software + title: lobstr + abstract: 'lobstr: Visualize R Data Structures with Trees' + notes: Suggests + url: https://lobstr.r-lib.org/ + repository: https://CRAN.R-project.org/package=lobstr + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + year: '2026' + doi: 10.32614/CRAN.package.lobstr +- type: software + title: patchwork + abstract: 'patchwork: The Composer of Plots' + notes: Suggests + url: https://patchwork.data-imaginist.com + repository: https://CRAN.R-project.org/package=patchwork + authors: + - family-names: Pedersen + given-names: Thomas Lin + email: thomasp85@gmail.com + orcid: https://orcid.org/0000-0002-5147-4711 + year: '2026' + doi: 10.32614/CRAN.package.patchwork +- type: software + title: plotrix + abstract: 'plotrix: Various Plotting Functions' + notes: Suggests + url: https://plotrix.github.io/plotrix/ + repository: https://CRAN.R-project.org/package=plotrix + authors: + - family-names: Lemon + given-names: Jim + year: '2026' + doi: 10.32614/CRAN.package.plotrix +- type: software + title: RColorBrewer + abstract: 'RColorBrewer: ColorBrewer Palettes' + notes: Suggests + repository: https://CRAN.R-project.org/package=RColorBrewer + authors: + - family-names: Neuwirth + given-names: Erich + email: erich.neuwirth@univie.ac.at + year: '2026' + doi: 10.32614/CRAN.package.RColorBrewer +- type: software + title: Rd2md + abstract: 'Rd2md: Markdown Reference Manuals' + notes: Suggests + url: https://github.com/quantsch/rd2md + repository: https://CRAN.R-project.org/package=Rd2md + authors: + - family-names: Busch + given-names: Julian + email: jb@quants.ch + year: '2026' + doi: 10.32614/CRAN.package.Rd2md +- type: software + title: readr + abstract: 'readr: Read Rectangular Text Data' + notes: Suggests + url: https://readr.tidyverse.org + repository: https://CRAN.R-project.org/package=readr + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + - family-names: Hester + given-names: Jim + - family-names: Bryan + given-names: Jennifer + email: jenny@posit.co + orcid: https://orcid.org/0000-0002-6983-2759 + year: '2026' + doi: 10.32614/CRAN.package.readr +- type: software + title: rmarkdown + abstract: 'rmarkdown: Dynamic Documents for R' + notes: Suggests + url: https://pkgs.rstudio.com/rmarkdown/ + repository: https://CRAN.R-project.org/package=rmarkdown + authors: + - family-names: Allaire + given-names: JJ + email: jj@posit.co + - family-names: Xie + given-names: Yihui + email: xie@yihui.name + orcid: https://orcid.org/0000-0003-0645-5666 + - family-names: Dervieux + given-names: Christophe + email: cderv@posit.co + orcid: https://orcid.org/0000-0003-4474-2498 + - family-names: McPherson + given-names: Jonathan + email: jonathan@posit.co + - family-names: Luraschi + given-names: Javier + - family-names: Ushey + given-names: Kevin + email: kevin@posit.co + - family-names: Atkins + given-names: Aron + email: aron@posit.co + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + - family-names: Cheng + given-names: Joe + email: joe@posit.co + - family-names: Chang + given-names: Winston + email: winston@posit.co + - family-names: Iannone + given-names: Richard + email: rich@posit.co + orcid: https://orcid.org/0000-0003-3925-190X + year: '2026' + doi: 10.32614/CRAN.package.rmarkdown +- type: software + title: roxygen2 + abstract: 'roxygen2: In-Line Documentation for R' + notes: Suggests + url: https://roxygen2.r-lib.org/ + repository: https://CRAN.R-project.org/package=roxygen2 + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + orcid: https://orcid.org/0000-0003-4757-117X + - family-names: Danenberg + given-names: Peter + email: pcd@roxygen.org + - family-names: Csárdi + given-names: Gábor + email: csardi.gabor@gmail.com + - family-names: Eugster + given-names: Manuel + year: '2026' + doi: 10.32614/CRAN.package.roxygen2 + version: '>= 8.0.0' +- type: software + title: scales + abstract: 'scales: Scale Functions for Visualization' + notes: Suggests + url: https://scales.r-lib.org + repository: https://CRAN.R-project.org/package=scales + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + - family-names: Pedersen + given-names: Thomas Lin + email: thomas.pedersen@posit.co + orcid: https://orcid.org/0000-0002-5147-4711 + - family-names: Seidel + given-names: Dana + year: '2026' + doi: 10.32614/CRAN.package.scales +- type: software + title: styler + abstract: 'styler: Non-Invasive Pretty Printing of R Code' + notes: Suggests + url: https://styler.r-lib.org + repository: https://CRAN.R-project.org/package=styler + authors: + - family-names: Müller + given-names: Kirill + email: kirill@cynkra.com + orcid: https://orcid.org/0000-0002-1416-3412 + - family-names: Walthert + given-names: Lorenz + email: lorenz.walthert@icloud.com + - family-names: Patil + given-names: Indrajeet + email: patilindrajeet.science@gmail.com + orcid: https://orcid.org/0000-0003-1995-6531 + year: '2026' + doi: 10.32614/CRAN.package.styler +- type: software + title: sva + abstract: 'sva: Surrogate Variable Analysis' + notes: Suggests + repository: https://bioconductor.org/ + authors: + - family-names: Leek + given-names: Jeffrey T. + email: jtleek@gmail.com + - family-names: Johnson + given-names: W. Evan + email: wej@bu.edu + - family-names: Parker + given-names: Hilary S. + email: hiparker@jhsph.edu + - family-names: Fertig + given-names: Elana J. + email: ejfertig@jhmi.edu + - family-names: Jaffe + given-names: Andrew E. + email: ajaffe@jhsph.edu + - family-names: Zhang + given-names: Yuqing + email: zhangyuqing.pkusms@gmail.com + - family-names: Storey + given-names: John D. + email: jstorey@princeton.edu + - family-names: Torres + given-names: Leonardo Collado + email: lcolladotor@gmail.com + year: '2026' + doi: 10.18129/B9.bioc.sva +- type: software + title: testthat + abstract: 'testthat: Unit Testing for R' + notes: Suggests + url: https://testthat.r-lib.org + repository: https://CRAN.R-project.org/package=testthat + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + year: '2026' + doi: 10.32614/CRAN.package.testthat + version: '>= 3.0.0' +- type: software + title: UpSetR + abstract: 'UpSetR: A More Scalable Alternative to Venn and Euler Diagrams for Visualizing + Intersecting Sets' + notes: Suggests + url: http://github.com/hms-dbmi/UpSetR + repository: https://CRAN.R-project.org/package=UpSetR + authors: + - family-names: Gehlenborg + given-names: Nils + email: nils@hms.harvard.edu + year: '2026' + doi: 10.32614/CRAN.package.UpSetR +- type: software + title: usethis + abstract: 'usethis: Automate Package and Project Setup' + notes: Suggests + url: https://usethis.r-lib.org + repository: https://CRAN.R-project.org/package=usethis + authors: + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + orcid: https://orcid.org/0000-0003-4757-117X + - family-names: Bryan + given-names: Jennifer + email: jenny@posit.co + orcid: https://orcid.org/0000-0002-6983-2759 + - family-names: Barrett + given-names: Malcolm + email: malcolmbarrett@gmail.com + orcid: https://orcid.org/0000-0003-0299-5825 + - family-names: Teucher + given-names: Andy + email: andy.teucher@posit.co + orcid: https://orcid.org/0000-0002-7840-692X + year: '2026' + doi: 10.32614/CRAN.package.usethis +- type: software + title: V8 + abstract: 'V8: Embedded JavaScript and WebAssembly Engine for R' + notes: Suggests + url: https://jeroen.r-universe.dev/V8 + repository: https://CRAN.R-project.org/package=V8 + authors: + - family-names: Ooms + given-names: Jeroen + email: jeroenooms@gmail.com + orcid: https://orcid.org/0000-0002-4035-0289 + year: '2026' + doi: 10.32614/CRAN.package.V8 +- type: software + title: VennDiagram + abstract: 'VennDiagram: Generate High-Resolution Venn and Euler Plots' + notes: Suggests + url: https://github.com/uclahs-cds/package-VennDiagram + repository: https://CRAN.R-project.org/package=VennDiagram + authors: + - family-names: Chen + given-names: Hanbo + year: '2026' + doi: 10.32614/CRAN.package.VennDiagram +- type: software + title: withr + abstract: 'withr: Run Code ''With'' Temporarily Modified Global State' + notes: Suggests + url: https://withr.r-lib.org + repository: https://CRAN.R-project.org/package=withr + authors: + - family-names: Hester + given-names: Jim + - family-names: Henry + given-names: Lionel + email: lionel@posit.co + - family-names: Müller + given-names: Kirill + email: krlmlr+r@mailbox.org + - family-names: Ushey + given-names: Kevin + email: kevinushey@gmail.com + - family-names: Wickham + given-names: Hadley + email: hadley@posit.co + - family-names: Chang + given-names: Winston + year: '2026' + doi: 10.32614/CRAN.package.withr + diff --git a/code/MOSuite/DESCRIPTION b/code/MOSuite/DESCRIPTION new file mode 100644 index 0000000..9f48d10 --- /dev/null +++ b/code/MOSuite/DESCRIPTION @@ -0,0 +1,92 @@ +Package: MOSuite +Title: R package for differential multi-omics analysis +Version: 0.3.1 +Authors@R: c( + person("Kelly", "Sovacool", , "kelly.sovacool@nih.gov", role = c("aut", "cre"), + comment = c(ORCID = "0000-0003-3283-829X")), + person("Philip", "Homan", , "philip.homan@nih.gov", role = "aut"), + person("Vishal", "Koparde", , "vishal.koparde@nih.gov", role = "aut", + comment = c(ORCID = "0000-0001-8978-8495")), + person("Samantha", "Chill", , "samantha.chill@nih.gov", role = "aut", + comment = c(ORCID = "0000-0002-8734-9875")), + person("T. Joshua", "Meyer", , "thomas.meyer@nih.gov", role = "ctb"), + person("CCR Collaborative Bioinformatics Resource", role = "cph") + ) +Description: Multi-Omics Suite provides a suite of functions to clean, + filter, batch-correct, normalize, visualize, and perform differential + analysis. While the package is designed for differential RNA-seq + analysis and multi-omics datasets, it can be used for any data + represented in a counts table. See the website for more information, + documentation, and examples at . +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) +Imports: + assertthat, + dendextend, + DESeq2, + dplyr, + edgeR, + ggplot2 (< 4.0.0), + glue, + htmlwidgets, + jsonlite, + limma, + matrixStats, + methods, + options, + plotly, + purrr, + reshape2, + rlang, + S7, + stats, + stringr, + tibble, + tidyr, + tidyselect +Suggests: + amap, + argparse, + broom, + cffr, + colorspace, + ComplexHeatmap, + dendsort, + docopt, + EnhancedVolcano, + ggrepel, + gridExtra, + knitr, + lobstr, + patchwork, + plotrix, + RColorBrewer, + Rd2md, + readr, + rmarkdown, + roxygen2 (>= 8.0.0), + scales, + styler, + sva, + testthat (>= 3.0.0), + UpSetR, + usethis, + V8, + VennDiagram, + withr +VignetteBuilder: + knitr +biocViews: +Config/Needs/dev: cffr, covr, here, lintr, pkgdown, + rcmdcheck, xml2 +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/LICENSE b/code/MOSuite/LICENSE new file mode 100644 index 0000000..73e9360 --- /dev/null +++ b/code/MOSuite/LICENSE @@ -0,0 +1,2 @@ +YEAR: 2023 +COPYRIGHT HOLDER: CCR Collaborative Bioinformatics Resource diff --git a/code/MOSuite/LICENSE.md b/code/MOSuite/LICENSE.md new file mode 100644 index 0000000..f8e9903 --- /dev/null +++ b/code/MOSuite/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2023 CCR Collaborative Bioinformatics Resource + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/code/MOSuite/MOSuite.Rproj b/code/MOSuite/MOSuite.Rproj new file mode 100644 index 0000000..ccfa15d --- /dev/null +++ b/code/MOSuite/MOSuite.Rproj @@ -0,0 +1,23 @@ +Version: 1.0 +ProjectId: 8ebbd9db-482e-4f6c-a523-b56383cc5b59 + +RestoreWorkspace: No +SaveWorkspace: No +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX + +AutoAppendNewline: Yes +StripTrailingWhitespace: Yes +LineEndingConversion: Posix + +BuildType: Package +PackageUseDevtools: Yes +PackageInstallArgs: --no-multiarch --with-keep.source +PackageRoxygenize: rd,collate,namespace diff --git a/code/MOSuite/NAMESPACE b/code/MOSuite/NAMESPACE new file mode 100644 index 0000000..dcdf57a --- /dev/null +++ b/code/MOSuite/NAMESPACE @@ -0,0 +1,51 @@ +# Generated by roxygen2: do not edit by hand + +export("!!") +export(":=") +export(.data) +export(batch_correct_counts) +export(bind_dfs_long) +export(calc_cpm) +export(calc_pca) +export(clean_raw_counts) +export(cli_exec) +export(cli_from_json) +export(create_multiOmicDataSet_from_dataframes) +export(create_multiOmicDataSet_from_files) +export(diff_counts) +export(do_math) +export(extract_counts) +export(filter_counts) +export(filter_diff) +export(get_colors_lst) +export(get_colors_vctr) +export(join_dfs_wide) +export(load_moo_from_data_dir) +export(multiOmicDataSet) +export(normalize_counts) +export(parse_optional_vector) +export(parse_samples_to_rename) +export(parse_vector_with_default) +export(plot_corr_heatmap) +export(plot_expr_heatmap) +export(plot_histogram) +export(plot_pca) +export(plot_pca_2d) +export(plot_pca_3d) +export(plot_read_depth) +export(plot_venn_diagram) +export(plot_volcano_enhanced) +export(plot_volcano_summary) +export(print_or_save_plot) +export(read_multiOmicDataSet) +export(set_color_pal) +export(setup_capsule_environment) +export(write_multiOmicDataSet) +export(write_multiOmicDataSet_properties) +if (getRversion() < "4.3.0") importFrom("S7", "@") +importFrom(DESeq2,DESeq) +importFrom(dendextend,rotate) +importFrom(matrixStats,rowVars) +importFrom(rlang,"!!") +importFrom(rlang,":=") +importFrom(rlang,.data) diff --git a/code/MOSuite/NEWS.md b/code/MOSuite/NEWS.md new file mode 100644 index 0000000..24d05da --- /dev/null +++ b/code/MOSuite/NEWS.md @@ -0,0 +1,84 @@ +## MOSuite 0.3.1 + +- Fix recursion error in `plot_venn_diagram()`. (#188, @kelly-sovacool) +- Fix S7 dispatch argument mismatch in `plot_read_depth()` and `plot_histogram()`. (#200, @copilot, @kelly-sovacool) +- Fix crash in `remove_low_count_genes()` when `use_group_based_filtering = TRUE`. (#200, @copilot, @kelly-sovacool) +- Fix color palette selection to fall back to random colors with a message when the number of categories exceeds the palette maximum. (#204, @copilot, @kelly-sovacool) +- Update S7 class, generic, and method documentation to use roxygen2 v8.0.0. (#206, #212, @copilot, @kelly-sovacool) +- A docker container with only MOSuite's dependencies, not MOSuite itself, is now available: . (#209, @kelly-sovacool) +- Minor bug fixes in `calc_cpm_df()`, `create_multiOmicDataSet_from_dataframes()`, and `diff_counts()` docstring. (#214, @kelly-sovacool) + +## MOSuite 0.3.0 + +### New features + +- New function `write_multiOmicDataSet_properties()`. (#173, @kelly-sovacool) + - Extracts all the properties from a multiOmicDataSet and writes any data frames as csv files, other objects are written as rds files. +- New utility functions to reduce code duplication across Code Ocean capsules: (#185, @kelly-sovacool) + `setup_capsule_environment()`, `load_moo_from_data_dir()`, `parse_optional_vector()`, `parse_vector_with_default()`, and `parse_samples_to_rename()`. + +### Bug fixes + +- Fixed bug in `clean_raw_counts()` where duplicate gene rows were not being aggregated correctly. (#162, @TJoshMeyer) +- Fixed `batch_correct_counts()` to gracefully skip batch correction when only a single batch level exists; the function now warns without erroring. (#158, @TJoshMeyer) +- Fixed `multiOmicDataSet` validator to return character vector instead of using `stop()` per S7 documentation. (#177, @copilot, @kelly-sovacool) +- Fixed duplicate PCA figure files in `filter_counts()`, `normalize_counts()`, and `batch_correct_counts()`. (#180, @kelly-sovacool) +- Bug fixes: (#174, @kelly-sovacool) + - Fixed bugs in `plot_volcano_summary()`, `plot_volcano_enhanced()`, and `plot_pca_3d()` when used with multiOmicDataSet objects. + - Fixed bug in `filter_diff()` when `filtering_mode = "all"` that was causing plot rendering errors. + - Fixed `plot_pca_2d()` to save plots to disk correctly. +- Replaced deprecated `arrange_()` with `arrange()` in `plot_expr_heatmap()`. (#182, @kelly-sovacool) +- Improvements for use with Galaxy. (#168, #170, #171, #174, @kelly-sovacool) + +## MOSuite 0.2.1 + +- A docker image is now available. (#134) + - +- Minor documentation improvements. (#135) +- Improvements for use with Galaxy. (#149) +- Fixed bug where 3D PCA plots were not being saved. (#149) + +## MOSuite 0.2.0 + +- Any user-facing function can now be called from the unix command line to support Galaxy. (#126, #127) + Usage: `mosuite [function] --json=path/to/args` + - It is not recommended for most users to run MOSuite via the CLI; this is only intended for the Galaxy workflow. +- MOSuite is now archived in Zenodo with a DOI: [10.5281/zenodo.16371580](http://doi.org/10.5281/zenodo.16371580) + +## MOSuite 0.1.0 + +This is the first release of MOSuite 🎉 + +- Note: at the start of development, this package was called reneeTools. + Later it was renamed to MOSuite. (#76) + +### Main functions & classes + +- `multiOmicDataSet` (#16, #28) + - `create_multiOmicDataSet_from_files()` + - `create_multiOmicDataSet_from_dataframes()` +- `run_deseq2()` +- `calc_cpm()` (#38) +- `filter_counts()` (#38) +- `clean_raw_counts()` (#79) +- `normalize_counts()` (#82) +- `batch_correct_counts()` (#87) +- `diff_counts()` (#102) +- `filter_diff()` (#110) + +#### visualization + +- `plot_histogram()` (#96) +- `plot_corr_heatmap()` (#96) +- `plot_expr_heatmap()` (#90, #96) +- `plot_pca()` (#88, #96) +- `plot_volcano_enhanced()` (#112) +- `plot_volcano_summary()` (#112) +- `plot_venn_diagram()` (#111) + +### vignettes + +- `intro` +- `visualization` +- `memory` +- `renee` diff --git a/code/MOSuite/R/0_mo-class.R b/code/MOSuite/R/0_mo-class.R new file mode 100644 index 0000000..631e753 --- /dev/null +++ b/code/MOSuite/R/0_mo-class.R @@ -0,0 +1,504 @@ +#' multiOmicDataSet class +#' +#' @param 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. +#' @param anno_dat data frame of feature annotations, such as gene symbols or any other information about the features +#' in `counts_lst`. +#' @param counts_lst named list of data frames containing counts, e.g. expected feature counts from RSEM. Each data +#' frame is expected to contain a `feature_id` column as the first column, and all remaining columns are sample IDs in +#' the `sample_meta`. +#' @param analyses_lst named list of analysis results, e.g. DESeq results object +#' +#' @prop sample_meta 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. +#' @prop annotation data frame of feature annotations, such as gene symbols or any other information about the +#' features in the counts list. +#' @prop counts named list of counts data frames (e.g. `raw`, `clean`, `cpm`, `filt`, `norm`, `batch`). Each data +#' frame is expected to contain a feature ID column as the first column, and all remaining columns are sample IDs. +#' @prop analyses named list of analysis results (e.g. DESeq2 results, colors). +#' +#' @returns A `multiOmicDataSet` S7 object. +#' @export +#' +#' @family moo constructors +multiOmicDataSet <- S7::new_class( + "multiOmicDataSet", + properties = list( + sample_meta = S7::class_data.frame, + annotation = S7::class_data.frame, + counts = S7::class_list, + # list of data frames + analyses = S7::class_list + ), + constructor = function( + sample_metadata, + anno_dat, + counts_lst, + analyses_lst = list() + ) { + if (!("colors" %in% names(analyses_lst))) { + analyses_lst[["colors"]] <- get_colors_lst(sample_metadata) + } + return(S7::new_object( + S7::S7_object(), + sample_meta = sample_metadata, + annotation = anno_dat, + counts = counts_lst, + analyses = analyses_lst + )) + }, + validator = function(self) { + errors <- character(0) + + # counts must only contain approved names + approved_counts <- c("raw", "clean", "cpm", "filt", "norm", "batch") + if (!all(names(self@counts) %in% approved_counts)) { + errors <- c( + errors, + glue::glue( + "@counts can only contain these names:\n\t{paste(approved_counts, collapse = ', ')}" + ) + ) + } + + if (!("raw" %in% names(self@counts))) { + errors <- c(errors, "@counts must contain at least 'raw' counts") + } else { + # Only validate sample IDs if raw counts exist + meta_sample_colnames <- self@sample_meta |> dplyr::pull(1) + feature_sample_colnames <- self@counts$raw |> + dplyr::select(-1) |> + colnames() + + # all sample IDs in sample_meta must also be in raw counts, & vice versa + in_meta_not_in_counts <- setdiff( + meta_sample_colnames, + feature_sample_colnames + ) + if (length(in_meta_not_in_counts) > 0) { + errors <- c( + errors, + glue::glue( + "Not all sample IDs in the @sample_meta are in the @counts$raw data:\n\t", + "{glue::glue_collapse(in_meta_not_in_counts, sep = ', ')}" + ) + ) + } + in_counts_not_in_meta <- setdiff( + feature_sample_colnames, + meta_sample_colnames + ) + if (length(in_counts_not_in_meta) > 0) { + errors <- c( + errors, + glue::glue( + "Not all columns after the first column in the @counts$raw data are sample IDs in the @sample_meta:\n\t", + "{glue::glue_collapse(in_counts_not_in_meta, sep = ', ')}" + ) + ) + } + + # sample IDs must be in the same order + if (!all(feature_sample_colnames == meta_sample_colnames)) { + errors <- c( + errors, + glue::glue( + "The sample IDs in the @sample_meta do not equal the columns in the @counts$raw data. ", + "Sample IDs must be in the same order." + ) + ) + } + } + + # TODO any sample ID in filt or norm_cpm counts must also be in sample_meta + # TODO counts can only contain 1 feature name column, and all other columns are sample counts + + if (length(errors) > 0) { + return(errors) + } + return(NULL) + } +) + +#' Construct a multiOmicDataSet object from data frames +#' +#' @inheritParams multiOmicDataSet +#' @param counts_dat data frame of feature counts (e.g. expected feature counts from RSEM). +#' @param count_type type to assign the values of `counts_dat` to in the `counts` slot +#' @param sample_id_colname name of the column in `sample_metadata` that contains the sample IDs. (Default: `NULL` - +#' first column in the sample metadata will be used.) +#' @param feature_id_colname name of the column in `counts_dat` that contains feature/gene IDs. (Default: `NULL` - first +#' column in the count data will be used.) +#' +#' @return [multiOmicDataSet] object +#' @export +#' +#' @examples +#' sample_meta <- data.frame( +#' sample_id = c("KO_S3", "KO_S4", "WT_S1", "WT_S2"), +#' condition = factor( +#' c("knockout", "knockout", "wildtype", "wildtype"), +#' levels = c("wildtype", "knockout") +#' ) +#' ) +#' moo <- create_multiOmicDataSet_from_dataframes(sample_meta, gene_counts) +#' head(moo@sample_meta) +#' head(moo@counts$raw) +#' head(moo@annotation) +#' +#' sample_meta_nidap <- readr::read_csv(system.file("extdata", "nidap", +#' "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", +#' package = "MOSuite" +#' )) +#' raw_counts_nidap <- readr::read_csv(system.file("extdata", "nidap", "Raw_Counts.csv.gz", +#' package = "MOSuite" +#' )) +#' moo_nidap <- create_multiOmicDataSet_from_dataframes(sample_meta_nidap, raw_counts_nidap) +#' +#' @family moo constructors +create_multiOmicDataSet_from_dataframes <- function( + sample_metadata, + counts_dat, + sample_id_colname = NULL, + feature_id_colname = NULL, + count_type = "raw" +) { + # move sample & feature ID columns to first + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } else { + sample_metadata <- sample_metadata |> + dplyr::relocate(!!rlang::sym(sample_id_colname)) + } + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(counts_dat)[1] + } else { + counts_dat <- counts_dat |> + dplyr::relocate(!!rlang::sym(feature_id_colname)) + } + + meta_sample_colnames <- sample_metadata |> dplyr::pull(sample_id_colname) + if (!all(meta_sample_colnames %in% colnames(counts_dat))) { + stop( + glue::glue( + "Not all sample IDs in the sample metadata are in the count data. Samples missing in count data:\n\t", + glue::glue_collapse( + meta_sample_colnames[ + !(meta_sample_colnames %in% colnames(counts_dat)) + ], + sep = ", " + ) + ) + ) + } + + # create anno_dat out of excess columns in count dat + anno_dat <- counts_dat |> + dplyr::select(-tidyselect::all_of(meta_sample_colnames)) + counts_dat <- counts_dat |> + dplyr::select( + !!rlang::sym(feature_id_colname), + tidyselect::all_of(meta_sample_colnames) + ) + + counts <- list() + counts[[count_type]] <- counts_dat + + return(multiOmicDataSet(sample_metadata, anno_dat, counts)) +} + +#' Construct a multiOmicDataSet object from text files (e.g. TSV, CSV). +#' +#' @inheritParams multiOmicDataSet +#' @inheritParams create_multiOmicDataSet_from_dataframes +#' @param sample_meta_filepath path to text file with sample IDs and metadata for differential analysis. +#' @param feature_counts_filepath path to text file of expected feature counts (e.g. gene counts from RSEM). +#' @param delim Delimiter used in the input files. Any delimiter accepted by `readr::read_delim()` can be used. +#' If the files are in CSV format, set `delim = ','`; for TSV format, set `delim = '\t'`. +#' @param ... additional arguments forwarded to `readr::read_delim()`. +#' +#' @return [multiOmicDataSet] object +#' @export +#' +#' @examples +#' moo <- create_multiOmicDataSet_from_files( +#' sample_meta_filepath = system.file("extdata", +#' "sample_metadata.tsv.gz", +#' package = "MOSuite" +#' ), +#' feature_counts_filepath = system.file("extdata", +#' "RSEM.genes.expected_count.all_samples.txt.gz", +#' package = "MOSuite" +#' ), +#' delim = "\t" +#' ) +#' moo@counts$raw |> head() +#' moo@sample_meta +#' +#' moo_nidap <- create_multiOmicDataSet_from_files( +#' system.file("extdata", "nidap", +#' "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", +#' package = "MOSuite" +#' ), +#' system.file("extdata", "nidap", "Raw_Counts.csv.gz", package = "MOSuite"), +#' delim = "," +#' ) +#' +#' @family moo constructors +create_multiOmicDataSet_from_files <- function( + sample_meta_filepath, + feature_counts_filepath, + count_type = "raw", + sample_id_colname = NULL, + feature_id_colname = NULL, + delim = NULL, + ... +) { + counts_dat <- readr::read_delim(feature_counts_filepath, delim = delim, ...) + sample_metadata <- readr::read_delim(sample_meta_filepath, delim = delim, ...) + return( + create_multiOmicDataSet_from_dataframes( + sample_metadata = sample_metadata, + counts_dat = counts_dat, + count_type = count_type, + sample_id_colname = sample_id_colname, + feature_id_colname = feature_id_colname + ) + ) +} + +#' Extract count data +#' +#' @usage +#' extract_counts(moo, count_type, sub_count_type = NULL) +#' +#' @param moo multiOmicDataSet containing `count_type` & `sub_count_type` in the counts slot +#' @param count_type the type of counts to use -- must be a name in the counts slot (`moo@counts[[count_type]]`) +#' @param sub_count_type if `count_type` is a list, specify the sub count type within the list +#' (`moo@counts[[count_type]][[sub_count_type]]`). (Default: `NULL`) +#' +#' @export +#' @examples +#' 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) +#' ) +#' ) +#' ) +#' +#' moo |> +#' extract_counts("filt") |> +#' head() +#' +#' moo |> +#' extract_counts("norm", "voom") |> +#' head() +#' +extract_counts <- S7::new_generic( + "extract_counts", + "moo", + function(moo, count_type, sub_count_type = NULL) { + return(S7::S7_dispatch()) + } +) + +#' @rdname extract_counts +S7::method(extract_counts, multiOmicDataSet) <- function( + moo, + count_type, + sub_count_type = NULL +) { + # select correct counts matrix + if (!(count_type %in% names(moo@counts))) { + stop( + glue::glue( + "count_type {count_type} not in moo@counts. Count types: {glue::glue_collapse(names(moo@counts), sep = ', ')}" + ) + ) + } + counts_dat <- moo@counts[[count_type]] + if (!is.null(sub_count_type)) { + if (!(inherits(counts_dat, "list"))) { + stop( + glue::glue( + "{count_type} counts does not contain subtypes. To use {count_type} counts, set sub_count_type to NULL" + ) + ) + } else if (!(sub_count_type %in% names(counts_dat))) { + stop( + glue::glue( + "sub_count_type {sub_count_type} is not in moo@counts[[{count_type}]]" + ) + ) + } + counts_dat <- moo@counts[[count_type]][[sub_count_type]] + } else if (inherits(counts_dat, "list")) { + stop( + glue::glue( + "{count_type} counts contains subtypes. You must set sub_count_type to extract a subtype" + ) + ) + } + return(counts_dat) +} + +#' Write a multiOmicDataSet to disk as an RDS file +#' +#' @param moo [multiOmicDataSet] object to serialize +#' @param filepath Path to the RDS file to write (default: "moo.rds") +#' +#' @return Invisibly returns `filepath` +#' @export +write_multiOmicDataSet <- function(moo, filepath = "moo.rds") { + if (!inherits(moo, multiOmicDataSet)) { + stop("moo must be a multiOmicDataSet") + } + readr::write_rds(moo, filepath) + return(invisible(filepath)) +} + +#' Read a multiOmicDataSet from disk +#' +#' @param filepath Path to an RDS file produced by [write_multiOmicDataSet()] +#' +#' @return [multiOmicDataSet] +#' @export +read_multiOmicDataSet <- function(filepath) { + moo <- readr::read_rds(filepath) + if (!inherits(moo, multiOmicDataSet)) { + stop("RDS does not contain a multiOmicDataSet") + } + return(moo) +} + +#' Write multiOmicDataSet properties to disk as CSV files +#' +#' Writes the properties of a multiOmicDataSet object to disk as separate files in output_dir. +#' Properties that are data frames are saved as CSV files, while all other objects are saved as RDS files. +#' +#' @param moo `multiOmicDataSet` object to write properties from +#' @param output_dir Directory where the properties will be saved (default: "moo") +#' @return Invisibly returns the `output_dir` where the files were saved +#' @export +#' +write_multiOmicDataSet_properties <- S7::new_generic( + "write_multiOmicDataSet_properties", + "moo", + function(moo, output_dir = "moo") { + return(S7::S7_dispatch()) + } +) + +#' @rdname write_multiOmicDataSet_properties +S7::method(write_multiOmicDataSet_properties, multiOmicDataSet) <- function( + moo, + output_dir = "moo" +) { + if (!dir.exists(output_dir)) { + dir.create(output_dir, recursive = TRUE) + } + + # write sample metadata + readr::write_csv( + moo@sample_meta, + file = file.path(output_dir, "sample_metadata.csv") + ) + + # write annotation data + readr::write_csv( + moo@annotation, + file = file.path(output_dir, "feature_annotation.csv") + ) + + # write counts + counts_dir <- file.path(output_dir, "counts") + if (!dir.exists(counts_dir)) { + dir.create(counts_dir) + } + for (count_type in names(moo@counts)) { + counts_dat <- moo@counts[[count_type]] + if (inherits(counts_dat, "list")) { + sub_counts_dir <- file.path(counts_dir, count_type) + if (!dir.exists(sub_counts_dir)) { + dir.create(sub_counts_dir) + } + for (sub_count_type in names(counts_dat)) { + readr::write_csv( + counts_dat[[sub_count_type]], + file = file.path( + sub_counts_dir, + paste0(sub_count_type, "_counts.csv") + ) + ) + } + } else { + readr::write_csv( + counts_dat, + file = file.path( + counts_dir, + paste0(count_type, "_counts.csv") + ) + ) + } + } + + # write analyses + analyses_dir <- file.path(output_dir, "analyses") + if (!dir.exists(analyses_dir)) { + dir.create(analyses_dir) + } + + for (analysis_name in names(moo@analyses)) { + analysis_dat <- moo@analyses[[analysis_name]] + if (inherits(analysis_dat, "data.frame")) { + readr::write_csv( + analysis_dat, + file = file.path( + analyses_dir, + paste0(analysis_name, ".csv") + ) + ) + } else if (inherits(analysis_dat, "list")) { + for (sub_analysis_name in names(analysis_dat)) { + # make sub directory for sub analysis + sub_analysis_dir <- file.path(analyses_dir, analysis_name) + if (!dir.exists(sub_analysis_dir)) { + dir.create(sub_analysis_dir) + } + if (inherits(analysis_dat[[sub_analysis_name]], "data.frame")) { + readr::write_csv( + analysis_dat[[sub_analysis_name]], + file = file.path( + sub_analysis_dir, + paste0(analysis_name, "_", sub_analysis_name, ".csv") + ) + ) + } else { + saveRDS( + analysis_dat[[sub_analysis_name]], + file = file.path( + sub_analysis_dir, + paste0(analysis_name, "_", sub_analysis_name, ".rds") + ) + ) + } + } + } else { + saveRDS( + analysis_dat, + file = file.path( + analyses_dir, + paste0(analysis_name, ".rds") + ) + ) + } + } + + return(invisible(output_dir)) +} diff --git a/code/MOSuite/R/MOSuite-package.R b/code/MOSuite/R/MOSuite-package.R new file mode 100644 index 0000000..2869fd4 --- /dev/null +++ b/code/MOSuite/R/MOSuite-package.R @@ -0,0 +1,14 @@ +#' MOSuite: R package for downstream multi-omics analysis +#' +#' Designed for differential [RNA-seq](https://github.com/CCBR/RENEE) analysis +#' or any data represented in a counts table. +#' +#' See the website for more information, documentation, and examples: +#' \url{https://ccbr.github.io/MOSuite} +#' +#' @keywords internal +"_PACKAGE" + +## usethis namespace: start +## usethis namespace: end +NULL diff --git a/code/MOSuite/R/batch-correction.R b/code/MOSuite/R/batch-correction.R new file mode 100644 index 0000000..7e18183 --- /dev/null +++ b/code/MOSuite/R/batch-correction.R @@ -0,0 +1,216 @@ +#' Perform batch correction +#' +#' Perform batch correction using sva::ComBat() +#' +#' @inheritParams filter_counts +#' @inheritParams option_params +#' +#' @param sub_count_type if `count_type` is a list, specify the sub count type within the list. (Default: `"voom"`) +#' @param covariates_colnames The column name(s) from the sample metadata +#' containing variable(s) 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. +#' Do not include the `batch_colname` here. +#' @param batch_colname The column from the sample metadata 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 data sets have batches, in which case you do not need batch correction. +#' 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). +#' +#' @return `multiOmicDataSet` with batch-corrected counts +#' @export +#' +#' @examples +#' 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", +#' covariates_colnames = "Group", +#' batch_colname = "Batch", +#' label_colname = "Label" +#' ) +#' +#' head(moo@counts[["batch"]]) +#' +#' @family moo methods +batch_correct_counts <- function( + moo, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "batch" +) { + abort_packages_not_installed("sva") + # select correct counts matrix + if (!(count_type %in% names(moo@counts))) { + stop(glue::glue("count_type {count_type} not in moo@counts")) + } + counts_dat <- moo@counts[[count_type]] + if (!is.null(sub_count_type)) { + if (!(inherits(counts_dat, "list"))) { + stop( + glue::glue( + "{count_type} counts is not a named list. To use {count_type} counts, set sub_count_type to NULL" + ) + ) + } else if (!(sub_count_type %in% names(counts_dat))) { + stop( + glue::glue( + "sub_count_type {sub_count_type} is not in moo@counts[[{count_type}]]" + ) + ) + } + counts_dat <- moo@counts[[count_type]][[sub_count_type]] + } + # sva::ComBat() can't handle tibbles + counts_dat <- counts_dat |> as.data.frame() + sample_metadata <- moo@sample_meta |> as.data.frame() + batch_vctr <- sample_metadata |> dplyr::pull(batch_colname) + message( + glue::glue( + "* batch-correcting {glue::glue_collapse(c(count_type, sub_count_type),sep='-')} counts" + ) + ) + + covariates_colnames <- covariates_colnames |> unlist() + + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(counts_dat)[1] + } + if (is.null(samples_to_include)) { + samples_to_include <- sample_metadata |> dplyr::pull(sample_id_colname) + } + if (is.null(label_colname)) { + label_colname <- sample_id_colname + } + + if (batch_colname %in% covariates_colnames) { + stop(glue::glue( + "Batch column '{batch_colname}' cannot be included in covariates." + )) + } + if (length(unique(batch_vctr)) <= 1) { + combat_edata <- counts_dat + warning( + glue::glue( + "Batch column '{batch_colname}' contains only 1 unique value; skipping batch correction" + ) + ) + } else { + counts_matr <- counts_dat |> + counts_dat_to_matrix(feature_id_colname = feature_id_colname) + # coerce covariate columns to factors + sample_metadata <- sample_metadata |> + dplyr::mutate(dplyr::across( + tidyselect::all_of(covariates_colnames), + ~ as.factor(.x) + )) + # run batch correction + combat_edata <- sva::ComBat( + counts_matr, + batch = batch_vctr, + mod = stats::model.matrix( + stats::as.formula(paste( + "~", + paste(covariates_colnames, sep = "+", collapse = "+") + )), + data = sample_metadata + ), + par.prior = TRUE, + prior.plots = FALSE + ) |> + as.data.frame() |> + tibble::rownames_to_column(feature_id_colname) + } + + if (isTRUE(print_plots) || isTRUE(save_plots)) { + if (is.null(colors_for_plots)) { + colors_for_plots <- moo@analyses[["colors"]][[batch_colname]] + } + pca_plot <- plot_pca( + 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, + save_plots = FALSE + ) + + ggplot2::labs(caption = "batch-corrected counts") + + hist_plot <- plot_histogram( + combat_edata, + 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_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 + ) + + ggplot2::labs(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 + ) + print_or_save_plot( + hist_plot, + filename = file.path(plots_subdir, "histogram.png"), + 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 + ) + } + + message(glue::glue( + "The total number of features in output: {nrow(combat_edata)}" + )) + message(glue::glue( + "Number of samples after batch correction: {ncol(combat_edata)}" + )) + + moo@counts[["batch"]] <- combat_edata + return(moo) +} diff --git a/code/MOSuite/R/clean.R b/code/MOSuite/R/clean.R new file mode 100644 index 0000000..d14b2ca --- /dev/null +++ b/code/MOSuite/R/clean.R @@ -0,0 +1,463 @@ +#' Clean Raw Counts +#' +#' This function checks the input raw counts matrix for common formatting problems with feature identifiers and sample +#' names. If feature IDs contain multiple IDs separated by special characters (| - , or space) they will be split into +#' multiple columns. If duplicate feature IDs are detected the counts are summed across duplicate feature ID rows +#' within each sample. Invalid sample names will also be reported and can be automatically +#' corrected. If your sample names are corrected here, be sure to make equivalent changes to your metadata table. +#' +#' @inheritParams filter_counts +#' @inheritParams option_params +#' +#' @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 +#' 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. +#' @param split_gene_name If `TRUE`, split the gene name column by any of these special characters: `,|_-:` +#' @param aggregate_rows_with_duplicate_gene_names 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. +#' Using the default behavior (`TRUE`), 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. +#' @param gene_name_column_to_use_for_collapsing_duplicates Select the column +#' with Feature IDs to use as grouping elements to collapse the counts matrix. +#' The log output will list the columns available to identify duplicate row +#' IDs in order to aggregate information. +#' If left blank your "Feature ID" Column will be used to Aggregate Rows. If +#' "Feature ID" column can be split into multiple IDs the non Ensembl ID name +#' will be used to aggregate duplicate IDs. If "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 an error will occur and you will have +#' to manually enter the Column ID for this field. +#' +#' @returns `multiOmicDataSet` with cleaned counts +#' @export +#' +#' @examples +#' moo <- create_multiOmicDataSet_from_dataframes( +#' as.data.frame(nidap_sample_metadata), +#' as.data.frame(nidap_raw_counts), +#' sample_id_colname = "Sample", +#' ) |> +#' clean_raw_counts(sample_id_colname = "Sample", feature_id_colname = "GeneName") +#' head(moo@counts$clean) +#' @family moo methods +clean_raw_counts <- function( + moo, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "clean" +) { + counts_dat <- moo@counts[[count_type]] |> as.data.frame() + sample_metadata <- moo@sample_meta |> as.data.frame() + + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(counts_dat)[1] + } + # Sample Read Counts Plot + if (isTRUE(print_plots) || isTRUE(save_plots)) { + read_plot <- plot_read_depth(counts_dat) + print_or_save_plot( + read_plot, + filename = file.path(plots_subdir, "read_depth.png"), + print_plots = print_plots, + save_plots = save_plots + ) + } + + message(glue::glue("* cleaning {count_type} counts")) + # Manually rename samples + counts_dat <- rename_samples(counts_dat, samples_to_rename) + + ### PH: START Clean up Sample Name columns + ################################## + ##### Cleanup Columns + ################################## + ## Look for any non standard Characters or automatic formatting introduced when Table is read included + ## done after Rename step so that names do not automatically change before using names in Metadata. + + if (cleanup_column_names) { + # cl_og <- colnames(counts_dat) + ## convert special charchers to _ + cl2 <- gsub("-| |\\:", "_", colnames(counts_dat)) + if (length(cl2[(cl2) != colnames(counts_dat)]) > 0) { + message( + glue::glue( + "Columns had special characters replaced with underscore: ", + glue::glue_collapse( + colnames(counts_dat)[(colnames(counts_dat)) != cl2], + sep = ", " + ) + ) + ) + colnames(counts_dat) <- cl2 + } + + ## if names begin with number add X + cl2 <- sub("^(\\d)", "X\\1", colnames(counts_dat)) + if (length(cl2[(cl2) != colnames(counts_dat)]) > 0) { + message("Columns started with numbers and an X was added to colname :") + colnames(counts_dat) <- cl2 + } + } else { + ## invalid name format + if (any(make.names(colnames(counts_dat)) != colnames(counts_dat))) { + message( + paste( + "Error: The following counts matrix column names are not valid:", + paste( + colnames(counts_dat)[ + make.names(colnames(counts_dat)) != colnames(counts_dat) + ], + collapse = ", " + ), + "Likely causes are columns starting with numbers or other special characters eg spaces.", + .sep = "\n" + ) + ) + } + ## Names Contain dashes + if (sum(grepl("-", colnames(counts_dat))) != 0) { + message(paste( + "The sample names cannot contain dashes:", + paste( + colnames(counts_dat)[grepl("-", colnames(counts_dat))], + collapse = ", " + ) + )) + } + } + ### PH: END Clean up Sample Name columns + + # Split Ensemble + Gene name + counts_dat <- separate_gene_meta_columns( + counts_dat, + split_gene_name = split_gene_name + ) + + # Aggregate duplicate gene names + counts_dat <- aggregate_duplicate_gene_names( + counts_dat, + gene_name_column_to_use_for_collapsing_duplicates = gene_name_column_to_use_for_collapsing_duplicates, + aggregate_rows_with_duplicate_gene_names = aggregate_rows_with_duplicate_gene_names, + split_gene_name = split_gene_name + ) + + moo@counts[["clean"]] <- counts_dat + return(moo) +} + +#' Remove version number from ENSEMBLE IDs +#' +#' @param x vector of IDs +#' +#' @return IDs without version numbers +#' +#' @keywords internal +#' +strip_ensembl_version <- function(x) { + return(unlist(lapply(stringr::str_split(x, "[.]"), "[[", 1))) +} + +#' Separate gene metadata column +#' +#' @param counts_dat dataframe with raw counts data +#' @inheritParams clean_raw_counts +#' +#' @returns dataframe with metadata separated +#' @keywords internal +separate_gene_meta_columns <- function(counts_dat, split_gene_name = TRUE) { + ## Identify and separate Gene Name Columns into multiple Gene Metadata columns + ################################## + ## Split Ensemble + Gene name + ################################## + ## First check if Feature ID column can be split by ",|_-:" + ## Then check if one column contains Ensemble (regex '^ENS[A-Z]+[0-9]+') + ## check if Ensemble ID has version info and remove version + ## If one column contains Ensemble ID Assume other column is Gene names + ## If Column does not contain Ensmeble ID name split columns Gene_ID_1 and Gene_ID_2 + + ## if split_Gene_name ==F then will rename feature_id_colname column to either Gene(Bulk RNAseq) or + ## FeatureID(Proteomics) + + feature_id_colname <- colnames(counts_dat)[1] + out_colname <- feature_id_colname + + if (split_gene_name == TRUE) { + Ensembl_ID <- stringr::str_split_fixed( + counts_dat[, feature_id_colname], + "_|-|:|\\|", + n = 2 + ) |> + data.frame() + EnsCol <- apply(Ensembl_ID, c(1, 2), function(x) { + return(grepl("^ENS[A-Z]+[0-9]+", x)) + }) + + if ("" %in% Ensembl_ID[, 1] || "" %in% Ensembl_ID[, 2]) { + message(glue::glue( + "\nNot able to identify multiple id's in {feature_id_colname}" + )) + # colnames(df)[colnames(df)%in%clm]=gene_col + colnames(counts_dat)[ + colnames(counts_dat) %in% feature_id_colname + ] <- out_colname + } else { + ## at least one column must have all ensemble ids found in EnsCol + if ( + any( + nrow(EnsCol[EnsCol[, 1] == TRUE, ]) == nrow(Ensembl_ID), + nrow(EnsCol[EnsCol[, 2] == TRUE, ]) == nrow(Ensembl_ID) + ) + ) { + colnames(Ensembl_ID)[colSums(EnsCol) != nrow(Ensembl_ID)] <- out_colname + + ## check if Ensmble column has version information + if ( + grepl( + "^ENS[A-Z]+[0-9]+\\.[0-9]+$", + Ensembl_ID[, colSums(EnsCol) == nrow(Ensembl_ID)] + ) |> + sum() == + nrow(Ensembl_ID) + ) { + colnames(Ensembl_ID)[ + colSums(EnsCol) == nrow(Ensembl_ID) + ] <- "Ensembl_ID_version" + Ensembl_ID$Ensembl_ID <- strip_ensembl_version( + Ensembl_ID$Ensembl_ID_version + ) + } else { + colnames(Ensembl_ID)[ + colSums(EnsCol) == nrow(Ensembl_ID) + ] <- "Ensembl_ID" + } + } else { + colnames(Ensembl_ID) <- c("Feature_id_1", "Feature_id_2") + message("Could not determine ID formats from split feature ID column") + } + counts_dat <- cbind( + Ensembl_ID, + counts_dat[, !colnames(counts_dat) %in% feature_id_colname] + ) + } + } else { + colnames(counts_dat)[ + colnames(counts_dat) %in% feature_id_colname + ] <- out_colname + } + return(counts_dat) +} + +#' Aggregate duplicate gene names +#' +#' @inheritParams clean_raw_counts +#' @inheritParams separate_gene_meta_columns +#' +#' @returns data frame with columns separated if possible +#' @keywords internal +aggregate_duplicate_gene_names <- function( + counts_dat, + gene_name_column_to_use_for_collapsing_duplicates, + aggregate_rows_with_duplicate_gene_names, + split_gene_name +) { + ################################## + ## If duplicate gene, aggregate information to single row + ################################## + + feature_id_colname <- colnames(counts_dat)[1] + dfout <- counts_dat + + ## If user uses "Feature ID" column then switch to empty for appropriate behavior based on other parameters + if (gene_name_column_to_use_for_collapsing_duplicates == feature_id_colname) { + gene_name_column_to_use_for_collapsing_duplicates <- "" + } + if ( + gene_name_column_to_use_for_collapsing_duplicates == "" && + ("Feature_id_1" %in% colnames(counts_dat)) == FALSE + ) { + gene_name_column_to_use_for_collapsing_duplicates <- feature_id_colname + } + + ## Error Check if Column is Numeric + nums <- unlist(lapply(counts_dat, is.numeric)) + nums <- names(nums[nums]) + message(paste( + "Columns that can be used to aggregate gene information", + paste( + counts_dat[, !names(counts_dat) %in% nums, drop = FALSE] |> + colnames(), + sep = ", " + ) + )) + + ########## + ## This section will Print duplicate row names when Aggregation column is not Specified. + ## Purpose is to Identify Row Annotation columns and show user that rows may duplicated + ####### + ## Print what rows are duplicated in selected annotation column + ## if no column name given default to Gene(Bulk RNAseq) or FeatureID(Proteomics) + ## Options: 1 Use default RowName for data_type + ## 2 Use default Row name when Split Gene name recognizes Annotation name type + ## 3 show duplicate rows for all row annotations columns when + ## Split Gene name does not recognize Annotation name type + if (gene_name_column_to_use_for_collapsing_duplicates == "") { + if (split_gene_name == FALSE) { + ## If no Column name given for Aggregation then display Feature ID duplicates + message(paste0("genes with duplicate IDs in ", feature_id_colname)) + + ## if Gene Name column is split then select Column Names generated from "Split Ensemble + Gene name" Raw If + ## Feature_id_1 is generated it means that "Split Ensemble + Gene name" could not recognize Gene name format + ## (EnsembleID or GeneName) and so default is to identify duplicicates in Feature_id_1 column + } else if ( + split_gene_name == TRUE && + grepl("Feature_id_1", colnames(counts_dat)) == FALSE + ) { + x <- counts_dat[ + duplicated(counts_dat[, + gene_name_column_to_use_for_collapsing_duplicates + ]), + gene_name_column_to_use_for_collapsing_duplicates + ] |> + unique() |> + as.character() |> + glue::glue_collapse(sep = ", ") + message(glue::glue( + "genes with duplicate IDs in {feature_id_colname}: {x}" + )) + } else if ( + split_gene_name == TRUE && + grepl("Feature_id_1", colnames(counts_dat)) == TRUE + ) { + x <- counts_dat[ + duplicated(counts_dat[, "Feature_id_1"]), + "Feature_id_1" + ] |> + unique() |> + as.character() |> + glue::glue_collapse(sep = ", ") + message(glue::glue("genes with duplicate IDs in {Feature_id_1}: {x}")) + + x <- counts_dat[ + duplicated(counts_dat[, "Feature_id_2"]), + "Feature_id_2" + ] |> + unique() |> + as.character() |> + glue::glue_collapse(sep = ", ") + message(glue::glue("genes with duplicate IDs in {Feature_id_2}: {x}")) + } + } + + ########## + ## This section Aggregates duplicate Row names based on selected Annotation Column name + ####### + if (aggregate_rows_with_duplicate_gene_names == TRUE) { + message( + glue::glue( + "Aggregating the counts for the same ID in different chromosome locations.", + "Column used to Aggregate duplicate IDs: {gene_name_column_to_use_for_collapsing_duplicates}", + "Number of rows before Collapse: {nrow(counts_dat)}", + .sep = "\n" + ) + ) + + if ( + sum(duplicated(counts_dat[, + gene_name_column_to_use_for_collapsing_duplicates + ])) != + 0 + ) { + x <- counts_dat[ + duplicated(counts_dat[, + gene_name_column_to_use_for_collapsing_duplicates + ]), + gene_name_column_to_use_for_collapsing_duplicates + ] |> + as.character() |> + unique() |> + glue::glue_collapse(sep = ", ") + message(glue::glue("Duplicate IDs: {x}")) + + dfagg <- counts_dat[, c( + gene_name_column_to_use_for_collapsing_duplicates, + nums + )] |> + dplyr::group_by_at( + gene_name_column_to_use_for_collapsing_duplicates + ) |> + dplyr::summarise_all(sum) + + if (ncol(counts_dat[, !names(counts_dat) %in% nums, drop = FALSE]) > 1) { + ## collapse non-numeric columns + dfagg2 <- counts_dat[, !names(counts_dat) %in% nums] |> + dplyr::group_by_at( + gene_name_column_to_use_for_collapsing_duplicates + ) |> + dplyr::summarise_all(paste, collapse = ",") + + dfagg <- merge( + dfagg2, + dfagg, + by = eval(gene_name_column_to_use_for_collapsing_duplicates), + sort = FALSE + ) |> + as.data.frame() + } + dfout <- dfagg + message(glue::glue("Number of rows after Collapse: {nrow(dfout)}")) + } else { + message( + glue::glue( + "no duplicated IDs in {gene_name_column_to_use_for_collapsing_duplicates}" + ) + ) + dfout <- counts_dat + } + } else { + if (gene_name_column_to_use_for_collapsing_duplicates != "") { + message( + glue::glue( + "Duplicate IDs in {gene_name_column_to_use_for_collapsing_duplicates} Column:", + glue::glue_collapse( + counts_dat[ + duplicated(counts_dat[, + gene_name_column_to_use_for_collapsing_duplicates + ]), + gene_name_column_to_use_for_collapsing_duplicates + ] |> + as.character() |> + unique(), + sep = ", " + ), + .sep = "\n" + ) + ) + } + + message( + "If you desire to Aggregate row feature information select appropriate Column to use for collapsing duplicates" + ) + } + + return(dfout) +} diff --git a/code/MOSuite/R/cli.R b/code/MOSuite/R/cli.R new file mode 100644 index 0000000..4dcaf41 --- /dev/null +++ b/code/MOSuite/R/cli.R @@ -0,0 +1,205 @@ +# These functions were inspired by and adapted from renv: +# https://github.com/rstudio/renv/blob/d0eb86349d35679eb6920ca59072bd7369fe620f/R/cli.R + +#' Execute MOSuite from the CLI +#' +#' @export +#' @keywords internal +cli_exec <- function(clargs = commandArgs(trailingOnly = TRUE)) { + return(invisible(cli_exec_impl(clargs))) +} + +cli_exec_impl <- function(clargs) { + # check for tool called without arguments, or called with '--help' + usage <- length(clargs) == 0 || clargs[1L] %in% c("help", "--help") + + if (usage) { + return(cli_usage()) + } + + # extract method + method <- clargs[1L] + + # check request for help on requested method + help <- + clargs[2L] %in% c("help", "--help") + + if (help) { + return(cli_help(method)) + } + + # check for known function in MOSuite + exports <- getNamespaceExports("MOSuite") + if (!method %in% exports) { + return(stop(cli_unknown(method, exports))) + } + + # begin building call + # if --json in arguments, call cli_from_json() + if (any(stringr::str_detect(clargs, "^--json"))) { + f <- getExportedValue("MOSuite", "cli_from_json") + args <- list(f) + args$method <- method + } else { + # otherwise call the method directly + f <- getExportedValue("MOSuite", method) + args <- list(f) + } + + for (clarg in clargs[-1L]) { + # convert '--no-' into a FALSE parameter + if (grepl("^--no-", clarg)) { + key <- substring(clarg, 6L) + args[[key]] <- FALSE + } else if (grepl("^--[^=]+=", clarg)) { + # convert '--param=value' flags + index <- regexpr("=", clarg, fixed = TRUE) + key <- substring(clarg, 3L, index - 1L) + val <- substring(clarg, index + 1L) + args[[key]] <- cli_parse(val) + } else if (grepl("^--", clarg)) { + # convert '--flag' into a TRUE parameter + key <- substring(clarg, 3L) + args[[key]] <- TRUE + } else if (grepl("=", clarg, fixed = TRUE)) { + # convert 'param=value' flags + index <- regexpr("=", clarg, fixed = TRUE) + key <- substring(clarg, 1L, index - 1L) + val <- substring(clarg, index + 1L) + args[[key]] <- cli_parse(val) + } else { + # take other parameters as-is + args[[length(args) + 1L]] <- cli_parse(clarg) + } + } + + # invoke method with parsed arguments + return(do.call(args[[1L]], args[-1L], envir = globalenv())) +} + +cli_usage <- function(con = stderr()) { + usage <- " +Usage: mosuite [function] [--json=path/to/args.json] + +[function] should be the name of a function exported from MOSuite. +[--json] should specify the path to a JSON file with arguments accepted by that function. + The equals sign (=) is required to separate --json from the path. + +Additionally, 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 `method` has `moo` as an argument. + - moo_output_rds: file path to write the result to. + +Use `mosuite [function] --help` for more information about the associated function. + +Main functions: + mosuite create_multiOmicDataSet_from_files + mosuite filter_counts + mosuite clean_raw_counts + mosuite normalize_counts + mosuite batch_correct_counts + mosuite diff_counts + mosuite filter_diff +" + return(writeLines(usage, con = con)) +} + +cli_help <- function(method) { + return(print(utils::help(method, package = "MOSuite"))) +} + +cli_unknown <- function(method, exports) { + # report unknown command + msg <- glue::glue("MOSuite: {method} is not a known function.") + + # check for similar commands + distance <- c(utils::adist(method, exports)) + names(distance) <- exports + n <- min(distance) + if (n < 4) { + msg <- glue::glue( + msg, + "\n Did you mean {paste(shQuote(names(distance)[distance == n]), collapse = ' or ')}?" + ) + } + return(msg) +} + +cli_parse <- function(text) { + # handle logical-like values up-front + if (text %in% c("true", "True", "TRUE")) { + return(TRUE) + } else if (text %in% c("false", "False", "FALSE")) { + return(FALSE) + } + + # parse the expression + value <- parse(text = text)[[1L]] + return(if (is.language(value)) text else value) +} + +#' Call an MOSuite function with arguments specified in a json file +#' +#' @param method function in MOSuite to call +#' @param json path to a JSON file containing arguments for the function. +#' Additionally, the JSON can contain the following keys: +#' - `moo_input_rds` - filepath to an existing MultiOmicsDataset object in RDS format. +#' This is required if the MOSuite function contains `moo` as an argument. +#' - `moo_output_rds` - filepath to write the result to. +#' @param debug when TRUE, do not call the command, just return the expression. +#' +#' @returns invisible returns the function call +#' @export +#' @keywords internal +#' +cli_from_json <- function(method, json, debug = FALSE) { + # begin building function call + f <- getExportedValue("MOSuite", method) + fcn_args <- list(f) + # get function arguments from json + json_args <- jsonlite::read_json(json) + + # if needed, get moo from moo_input_rds + accepted_args <- formals(method, envir = getNamespace("MOSuite")) + first_arg <- names(accepted_args)[1] + if (stringr::str_detect(first_arg, "^moo")) { + assertthat::assert_that( + "moo_input_rds" %in% names(json_args), + msg = glue::glue( + "moo_input_rds must be included in the JSON because `{first_arg}` is required for {method}()" + ) + ) + fcn_args[[first_arg]] <- readr::read_rds(json_args[["moo_input_rds"]]) + } + # all other json keys should be arguments for the method + json_args <- json_args |> + purrr::map(\(x) { + if (is.list(x)) { + return(unlist(x)) # convert lists to vectors + } else { + return(x) + } + }) + fcn_args <- c( + fcn_args, + json_args[!stringr::str_detect(names(json_args), "moo_.*_rds")] + ) + + # construct call expression for debug (non-evaluated) + call_head <- call("::", as.symbol("MOSuite"), as.symbol(method)) + call_expr <- as.call(c(list(call_head), fcn_args[-1L])) + + # invoke method with parsed arguments from json + if (isTRUE(debug)) { + return(invisible(call_expr)) + } else { + result <- do.call(fcn_args[[1L]], fcn_args[-1L], envir = globalenv()) + + # save result to output_rds + if ("moo_output_rds" %in% names(json_args)) { + readr::write_rds(result, json_args[["moo_output_rds"]]) + } + } + + return(invisible(call_expr)) +} diff --git a/code/MOSuite/R/colors.R b/code/MOSuite/R/colors.R new file mode 100644 index 0000000..291901f --- /dev/null +++ b/code/MOSuite/R/colors.R @@ -0,0 +1,164 @@ +#' 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)`. +#' +#' @param num_colors number of colors to select. +#' @param n number of random RGB values to generate in the color space. +#' +#' @return vector of random colors in hex format. +#' @keywords internal +#' +#' @examples +#' \dontrun{ +#' set.seed(10) +#' get_random_colors(5) +#' } +get_random_colors <- function(num_colors, n = 2e3) { + abort_packages_not_installed("colorspace") + if (num_colors < 1) { + stop("num_colors must be at least 1") + } + n <- 2e3 + ourColorSpace <- colorspace::RGB( + stats::runif(n), + stats::runif(n), + stats::runif(n) + ) + ourColorSpace <- methods::as(ourColorSpace, "LAB") + currentColorSpace <- ourColorSpace@coords + # Set iter.max to 20 to avoid convergence warnings. + km <- stats::kmeans(currentColorSpace, num_colors, iter.max = 20) + return(unname(colorspace::hex(colorspace::LAB(km$centers)))) +} + + +#' 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` +#' +#' @returns named list, with each column in `sample_metadata` containing 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 <- function( + sample_metadata, + palette_fun = grDevices::palette.colors, + ... +) { + dat_colnames <- colnames(sample_metadata) + color_lists <- dat_colnames |> + purrr::map( + .f = get_colors_vctr, + dat = sample_metadata, + palette_fun = palette_fun, + ... + ) + names(color_lists) <- dat_colnames + return(color_lists) +} + +#' Get vector of colors for observations in one column of a data frame +#' +#' @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` +#' @export +#' +get_colors_vctr <- function( + dat, + colname, + palette_fun = grDevices::palette.colors, + ... +) { + obs <- dat |> + dplyr::pull(colname) |> + unique() + n_obs <- length(obs) + + warned_cnd <- NULL + colors_vctr <- withCallingHandlers( + warning = function(cnd) { + warned_cnd <<- cnd + invokeRestart("muffleWarning") + }, + palette_fun(n = n_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 + message(glue::glue( + 'Warning raised in get_color_vctr() for column "{colname}"' + )) + warning(conditionMessage(warned_cnd)) + } + + # 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)] + + names(colors_vctr) <- obs + return(colors_vctr) +} + +#' Set color palette for a single group/column +#' +#' This allows you to set custom palettes individually for groups in the dataset +#' +#' @inheritParams get_colors_lst +#' +#' @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` +#' @export +#' +#' @examples +#' moo <- create_multiOmicDataSet_from_dataframes( +#' sample_metadata = as.data.frame(nidap_sample_metadata), +#' 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@analyses$colors$Group +#' +#' @family moo methods +set_color_pal <- S7::new_generic( + "set_color_pal", + "moo", + function(moo, colname, palette_fun = grDevices::palette.colors, ...) { + return(S7::S7_dispatch()) + } +) + +S7::method(set_color_pal, multiOmicDataSet) <- function( + moo, + colname, + palette_fun = grDevices::palette.colors, + ... +) { + moo@analyses[["colors"]][[colname]] <- get_colors_vctr( + dat = moo@sample_meta, + colname = colname, + palette_fun = palette_fun, + ... + ) + return(moo) +} diff --git a/code/MOSuite/R/counts.R b/code/MOSuite/R/counts.R new file mode 100644 index 0000000..039bded --- /dev/null +++ b/code/MOSuite/R/counts.R @@ -0,0 +1,110 @@ +#' Calculate counts-per-million (CPM) on raw counts in a multiOmicDataSet +#' +#' @param moo multiOmicDataSet object +#' @param ... additional arguments to pass to edgeR::cpm() +#' +#' @return multiOmicDataSet with cpm-transformed counts +#' @export +#' +#' @examples +#' sample_meta <- data.frame( +#' sample_id = c("KO_S3", "KO_S4", "WT_S1", "WT_S2"), +#' condition = factor( +#' c("knockout", "knockout", "wildtype", "wildtype"), +#' levels = c("wildtype", "knockout") +#' ) +#' ) +#' moo <- create_multiOmicDataSet_from_dataframes(sample_meta, gene_counts) |> +#' calc_cpm() +#' head(moo@counts$cpm) +calc_cpm <- S7::new_generic("calc_cpm", "moo", function(moo, ...) { + return(S7::S7_dispatch()) +}) + +S7::method(calc_cpm, multiOmicDataSet) <- function( + moo, + feature_id_colname = "gene_id", + ... +) { + moo@counts$cpm <- moo@counts$raw |> + calc_cpm_df(feature_id_colname = feature_id_colname) + return(moo) +} + +#' Calculate CPM on a data frame +#' +#' @inheritParams create_multiOmicDataSet_from_dataframes +#' @param dat data frame of counts with a gene column +#' @param ... additional arguments to pass to edger::cpm() +#' +#' @return cpm-transformed counts as a data frame +#' @keywords internal +#' +calc_cpm_df <- function(dat, feature_id_colname = "gene_id", ...) { + gene_ids <- dat |> dplyr::pull(feature_id_colname) + row_names <- rownames(dat) + dat_cpm <- dat |> + dplyr::select(-tidyselect::any_of(feature_id_colname)) |> + as.matrix() |> + edgeR::cpm(...) |> + as.data.frame() + dat_cpm[[feature_id_colname]] <- gene_ids + rownames(dat_cpm) <- if ( + suppressWarnings(all(!is.na(as.integer(row_names)))) + ) { + as.integer(row_names) + } else { + row_names + } + return(dat_cpm |> dplyr::relocate(tidyselect::all_of(feature_id_colname))) +} + +#' Convert a data frame of gene counts to a matrix +#' +#' @inheritParams create_multiOmicDataSet_from_dataframes +#' @param counts_tbl expected feature counts as a dataframe or tibble, with all columns except `feature_id_colname` +#' +#' @return matrix of gene counts with rows as gene IDs +#' @keywords internal +#' +#' @examples +#' \dontrun{ +#' counts_dat_to_matrix(head(gene_counts)) +#' } +counts_dat_to_matrix <- function(counts_tbl, feature_id_colname = NULL) { + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(counts_tbl)[1] + } + counts_dat <- counts_tbl |> + as.data.frame() + row.names(counts_dat) <- counts_dat |> + dplyr::pull(feature_id_colname) + # convert counts tibble to matrix + counts_mat <- counts_dat |> + dplyr::select(-tidyselect::any_of(feature_id_colname)) |> + as.matrix() + return(counts_mat) +} + +#' Convert all numeric columns in a dataframe to integers +#' +#' Round doubles to integers and convert to integer type +#' +#' @param counts_tbl data frame with numeric columns +#' +#' @return data frame with any numeric columns as integers +#' @keywords internal +#' +#' @examples +#' \dontrun{ +#' data.frame(a = c(0, 0.1, 2.3, 5L, 6.9)) |> as_integer_df() +#' } +as_integer_df <- function(counts_tbl) { + counts_tbl <- counts_tbl |> + # deseq2 requires integer counts + dplyr::mutate(dplyr::across( + dplyr::where(is.numeric), + \(x) as.integer(round(x, 0)) + )) + return(counts_tbl) +} diff --git a/code/MOSuite/R/data.R b/code/MOSuite/R/data.R new file mode 100644 index 0000000..f27fb3b --- /dev/null +++ b/code/MOSuite/R/data.R @@ -0,0 +1,66 @@ +#' RSEM expected gene counts +#' +#' @format ## `gene_counts` +#' A data frame with columns 'gene_id', 'GeneName', and a column for each sample's expected count. +#' @keywords data +#' @source Generated by running RENEE v2.5.8 on the +#' [test dataset](https://github.com/CCBR/RENEE/tree/e08f7db6c6e638cfd330caa182f64665d2ef37fa/.tests) +"gene_counts" + +#' Sample metadata for the NIDAP test dataset +#' @keywords data +"nidap_sample_metadata" + +#' Raw counts for the NIDAP test dataset +#' Pairs with `nidap_sample_metadata`. +#' @keywords data +"nidap_raw_counts" + +#' Clean raw counts for the NIDAP test dataset. +#' The result of running `clean_raw_counts()` on `nidap_raw_counts`. +#' @keywords data +"nidap_clean_raw_counts" + +#' Filtered counts for the NIDAP test dataset. +#' The result of running `filter_counts()` on `nidap_clean_raw_counts`. +#' @keywords data +"nidap_filtered_counts" + +#' Normalized counts for the NIDAP test dataset. +#' The result of running `normalize_counts()` on `nidap_filtered_counts`. +#' @keywords data +"nidap_norm_counts" + +#' Batch-corrected counts for the NIDAP test dataset. +#' @keywords data +"nidap_batch_corrected_counts" + +#' Batch-corrected counts for the NIDAP test dataset. +#' The result of running `batch_correct_counts()` on `nidap_norm_counts`. +#' @keywords data +"nidap_batch_corrected_counts_2" + + +#' Differential gene expression analysis for the NIDAP test dataset. +#' @keywords data +"nidap_deg_analysis" + + +#' Differential gene expression analysis for the NIDAP test dataset. +#' The result of running `diff_counts()` on `nidap_filtered_counts`. +#' @keywords data +"nidap_deg_analysis_2" + +#' List of differentially expressed genes from the NIDAP test dataset using +#' default parameters with `filter_diff()`. +#' @keywords data +"nidap_deg_gene_list" + +#' Summarized differential expression analysis for input to venn diagram +#' @keywords data +"nidap_volcano_summary_dat" + +#' Output data from venn diagram. +#' The result of running `plot_venn_diagram()` on `nidap_volcano_summary_dat` +#' @keywords data +"nidap_venn_diagram_dat" diff --git a/code/MOSuite/R/deseq2.R b/code/MOSuite/R/deseq2.R new file mode 100644 index 0000000..8cc4f22 --- /dev/null +++ b/code/MOSuite/R/deseq2.R @@ -0,0 +1,50 @@ +#' Run DESeq2 on a multiOmicDataSet +#' +#' @param moo multiOmicDataSet object +#' @param design model formula for experimental design. Columns must exist in `meta_dat`. +#' @param ... remaining variables are forwarded to `DESeq2::DESeq()`. +#' +#' @return multiOmicDataSet object with DESeq2 slot filled +#' @keywords internal +#' +#' @examples +#' \dontrun{ +#' moo <- create_multiOmicDataSet_from_files( +#' system.file("extdata", "sample_metadata.tsv.gz", +#' package = "MOSuite" +#' ), +#' system.file("extdata", +#' "RSEM.genes.expected_count.all_samples.txt.gz", +#' package = "MOSuite" +#' ) +#' ) |> filter_counts() +#' moo <- run_deseq2(moo, ~condition) +#' } +#' @family moo methods +run_deseq2 <- S7::new_generic("run_deseq2", "moo", function(moo, design, ...) { + return(S7::S7_dispatch()) +}) + +S7::method(run_deseq2, multiOmicDataSet) <- function( + moo, + design, + feature_id_colname = "gene_id", + min_count = 10, + ... +) { + if (is.null(moo@counts$filt)) { + stop( + "moo must contain filtered counts for DESeq2. Hint: Did you forget to run filter_counts()?" + ) + } + dds <- DESeq2::DESeqDataSetFromMatrix( + countData = moo@counts$filt |> + dplyr::mutate(dplyr::across(dplyr::where(is.numeric), round)) |> # DESeq2 requires integer counts + counts_dat_to_matrix(feature_id_colname = feature_id_colname), + colData = moo@sample_meta, + design = design + ) + moo@analyses$deseq2_ds <- DESeq2::DESeq(dds, ...) + moo@analyses$deseq2_results <- DESeq2::results(moo@analyses$deseq2_ds) + return(moo) +} diff --git a/code/MOSuite/R/differential.R b/code/MOSuite/R/differential.R new file mode 100644 index 0000000..3adf34c --- /dev/null +++ b/code/MOSuite/R/differential.R @@ -0,0 +1,1039 @@ +#' Differential expression analysis +#' +#' @inheritParams filter_counts +#' @inheritParams batch_correct_counts +#' @inheritParams normalize_counts +#' @inheritParams option_params +#' +#' @param sub_count_type if `count_type` is a list, specify the sub count type within the list. (Default: `NULL`) +#' @param covariates_colnames The column name(s) from the sample metadata containing variable(s) 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. +#' @param contrast_colname The column in the metadata that contains the group variables you wish to find differential +#' expression between. Up to 2 columns (2-factor analysis) can be used. +#' @param contrasts Specify each contrast in the format group1-group2, e.g. treated-control +#' @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`) +#' @export +#' +#' @family moo methods +#' +#' @examples +#' 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) +#' ) +#' ) |> +#' diff_counts( +#' count_type = "filt", +#' sub_count_type = NULL, +#' sample_id_colname = "Sample", +#' feature_id_colname = "Gene", +#' covariates_colnames = c("Group", "Batch"), +#' contrast_colname = c("Group"), +#' contrasts = c("B-A", "C-A", "B-C"), +#' voom_normalization_method = "quantile", +#' ) +#' head(moo@analyses$diff) +diff_counts <- function( + moo, + 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, + # return_normalized_counts = FALSE, + voom_normalization_method = "quantile", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" +) { + final_res <- group <- . <- NULL + return_normalized_counts <- FALSE + sample_metadata <- moo@sample_meta + message(glue::glue("* differential counts")) + # select correct counts matrix + if (!(count_type %in% names(moo@counts))) { + stop(glue::glue("count_type {count_type} not in moo@counts")) + } + counts_dat <- moo@counts[[count_type]] + if (!is.null(sub_count_type)) { + if (!(inherits(counts_dat, "list"))) { + stop( + glue::glue( + "{count_type} counts is not a named list. To use {count_type} counts, set sub_count_type to NULL" + ) + ) + } else if (!(sub_count_type %in% names(counts_dat))) { + stop( + glue::glue( + "sub_count_type {sub_count_type} is not in moo@counts[[{count_type}]]" + ) + ) + } + counts_dat <- moo@counts[[count_type]][[sub_count_type]] + } + if (is.null(covariates_colnames)) { + stop("covariates_colnames vector cannot be NULL") + } + if (is.null(contrast_colname)) { + stop("contrast_colname cannot be NULL") + } + if (is.null(contrasts)) { + stop("contrasts vector cannot be NULL") + } + # ensure these are vectors, not lists. needed when using cli with JSON for args + covariates_colnames <- covariates_colnames |> unlist() + contrast_colname <- contrast_colname |> unlist() + contrasts <- contrasts |> unlist() + + # TODO support tibbles + counts_dat <- counts_dat |> as.data.frame() + + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(counts_dat)[1] + } + ## --------------- ## + ## Main Code Block ## + ## --------------- ## + + ### PH: START Check Rownames - from Filtering + Normalization Template + ## create unique rownames to correctly add back Annocolumns at end of template + counts_dat[, feature_id_colname] <- paste0( + counts_dat[, feature_id_colname], + "_", + seq_len(nrow(counts_dat)) + ) + + df.m <- counts_dat + gene_names <- NULL + gene_names$GeneID <- counts_dat[, feature_id_colname] + ### PH: END Check Rownames - from Filtering + Normalization Template + + ### PH: START Input Data Validation - from Filtering + Normalization Template + ### This code block does input data validation + # Remove samples that are not in the contrast groups: + groups <- unique(unlist(strsplit(contrasts, "-"))) + sample_metadata <- sample_metadata |> + dplyr::filter(.data[[contrast_colname]] %in% groups) + df.m <- df.m |> + dplyr::select(tidyr::all_of(c( + feature_id_colname, + sample_metadata |> dplyr::pull(sample_id_colname) + ))) + ### PH: END Input Data Validation - from Filtering + Normalization Template + + #################################### + ### Computational Functions + ################################ + ### PH: START Create Design Formula/Table + # Put covariates in order + covariates_colnames <- covariates_colnames[order( + covariates_colnames != contrast_colname + )] + + # TODO: refactor - function to sub spaces with underscores + for (ocv in covariates_colnames) { + sample_metadata[[ocv]] <- gsub( + " ", + "_", + sample_metadata |> dplyr::pull(ocv) + ) + } + contrasts <- gsub(" ", "_", contrasts) + cov <- covariates_colnames[!covariates_colnames %in% contrast_colname] + + # Combine columns if 2-factor analysis + if (length(contrast_colname) > 1) { + sample_metadata <- sample_metadata |> + dplyr::mutate( + contmerge = paste0( + .data[[contrast_colname[1]]], + ".", + .data[[contrast_colname[2]]] + ) + ) + } else { + sample_metadata <- sample_metadata |> + dplyr::mutate(contmerge = .data[[contrast_colname]]) + } + + contrast_var <- factor(sample_metadata$contmerge) + + ## create Design table + if (length(cov) > 0) { + dm.formula <- stats::as.formula(paste( + "~0 +", + paste( + "contmerge", + paste(cov, sep = "+", collapse = "+"), + sep = "+" + ) + )) + design <- stats::model.matrix(dm.formula, sample_metadata) + colnames(design) <- gsub("contmerge", "", colnames(design)) + } else { + dm.formula <- stats::as.formula(~ 0 + contmerge) + design <- stats::model.matrix(dm.formula, sample_metadata) + colnames(design) <- levels(contrast_var) + } + ### PH: End Create Design Formula/Table + + ### PH: START Limma Normalization - Same as in Normalize Counts + # Create DGEList object from counts - counts should not be Log scale + if (input_in_log_counts == TRUE) { + df_unlog <- df.m |> + dplyr::mutate(dplyr::across(dplyr::where(is.numeric), ~ 2^.x)) + x <- edgeR::DGEList(counts = df_unlog, genes = gene_names) + } else { + x <- edgeR::DGEList(counts = df.m, genes = gene_names) + } + + # TODO add this to existing norm function & document options + if ( + voom_normalization_method %in% c("TMM", "TMMwzp", "RLE", "upperquartile") + ) { + x <- edgeR::calcNormFactors(x, method = voom_normalization_method) + rownames(x) <- x$genes$GeneID + v <- limma::voom(x, design = design, normalize = "none") + } else { + v <- limma::voom( + x, + design = design, + normalize = voom_normalization_method, + save.plot = TRUE + ) + } + ### PH: END Limma Normalization - Same as in Normalize Counts + + ### PH: START Linear Fit and and extract df.voom table. Could be added to Limma Normalization function above with an + ### option to run lmFit + rownames(v$E) <- v$genes$GeneID + # df.voom <- as.data.frame(v$E) |> tibble::rownames_to_column(feature_id_colname) + fit <- limma::lmFit(v, design) + cm <- limma::makeContrasts(contrasts = contrasts, levels = design) + ### PH: END Linear Fit and and extract df.voom table. + + ### PH: START Run Contrasts (eBays) input: + # -fit from LMfit + # -cm from Make Contrasts + # Run Contrasts + fit2 <- limma::contrasts.fit(fit, cm) + fit2 <- limma::eBayes(fit2) + logFC <- fit2$coefficients + colnames(logFC) <- paste(colnames(logFC), "logFC", sep = "_") + tstat <- fit2$t + colnames(tstat) <- paste(colnames(tstat), "tstat", sep = "_") + FC <- 2^fit2$coefficients + FC <- ifelse(FC < 1, -1 / FC, FC) + colnames(FC) <- paste(colnames(FC), "FC", sep = "_") + pvalall <- fit2$p.value + colnames(pvalall) <- paste(colnames(pvalall), "pval", sep = "_") + pvaladjall <- apply(pvalall, 2, function(x) { + return(stats::p.adjust(x, "BH")) + }) + colnames(pvaladjall) <- paste( + colnames(fit2$coefficients), + "adjpval", + sep = "_" + ) + + ### PH: END Run Contrasts (eBays) input: + + #################################### + ### Create Output Functions + ################################ + ### PH: START Create DEG Table + # -VoomObject from Limma Normalization + # -pvalall from Run Contrasts (eBays) + # -pvaladjall from Run Contrasts (eBays) + # -FC from Run Contrasts (eBays) + # -logFC from Run Contrasts (eBays) + # -tstat from Run Contrasts (eBays) + # OUTPUT: DEG Table + if (return_mean_and_sd == TRUE) { + tve <- t(v$E) + mean.df <- as.data.frame(tve) |> + tibble::rownames_to_column(sample_id_colname) |> + dplyr::left_join( + sample_metadata |> + dplyr::select(tidyr::all_of( + c(sample_id_colname, contrast_colname) + )), + by = sample_id_colname + ) |> + dplyr::rename(group = tidyr::all_of(contrast_colname)) |> + dplyr::group_by(group) |> + dplyr::summarise(dplyr::across( + dplyr::where(is.numeric), + ~ base::mean(.x) + )) |> + as.data.frame() + mat_mean <- mean.df[, -c(1, 2)] |> + as.matrix() |> + t() + colnames(mat_mean) <- mean.df[, 1] + colnames(mat_mean) <- paste(colnames(mat_mean), "mean", sep = "_") + colnames(mat_mean) <- gsub("\\.", "_", colnames(mat_mean)) + # mat_mean <- mat_mean |> as.data.frame() |> tibble::rownames_to_column(feature_id_colname) + + sd.df <- as.data.frame(tve) |> + tibble::rownames_to_column(sample_id_colname) |> + dplyr::left_join( + sample_metadata |> + dplyr::select(tidyr::all_of( + c(sample_id_colname, contrast_colname) + )), + by = sample_id_colname + ) |> + dplyr::rename(group = tidyr::all_of(contrast_colname)) |> + dplyr::group_by(group) |> + dplyr::summarise(dplyr::across( + dplyr::where(is.numeric), + ~ stats::sd(.x) + )) |> + as.data.frame() + mat_sd <- sd.df[, -c(1, 2)] |> + as.matrix() |> + t() + colnames(mat_sd) <- sd.df[, 1] + colnames(mat_sd) <- paste(colnames(mat_sd), "sd", sep = "_") + colnames(mat_sd) <- gsub("\\.", "_", colnames(mat_sd)) + # mat_sd <- mat_sd |> as.data.frame() |> tibble::rownames_to_column(feature_id_colname) + + finalres <- purrr::map( + list(mat_mean, mat_sd, FC, logFC, tstat, pvalall, pvaladjall), + \(mat) { + result <- mat |> + as.data.frame() |> + tibble::rownames_to_column(feature_id_colname) + return(result) + } + ) |> + purrr::reduce(dplyr::left_join, by = feature_id_colname) + } else { + finalres <- purrr::map(list(FC, logFC, tstat, pvalall, pvaladjall), \(mat) { + result <- mat |> + as.data.frame() |> + tibble::rownames_to_column(feature_id_colname) + return(result) + }) |> + purrr::reduce(dplyr::left_join, by = feature_id_colname) + } + + if (return_normalized_counts == TRUE) { + finalres <- final_res |> + dplyr::left_join( + v$E |> + as.data.frame() |> + tibble::rownames_to_column(feature_id_colname), + by = feature_id_colname + ) + } + + message(paste0("Total number of genes included: ", nrow(finalres))) + + ### add back Anno columns and Remove row number from Feature Column + finalres[, feature_id_colname] <- gsub( + "_[0-9]+$", + "", + finalres[, feature_id_colname] + ) + call_me_alias <- colnames(finalres) + colnames(finalres) <- gsub("\\(|\\)", "", call_me_alias) + ### PH: END Create DEG Table + + ### PH: START contrast summary table input: + # -design from create Design table + # -cm from Make Contrasts + ## Output is table showing contrasts used + + # Print out sample numbers: + # + sampsize <- colSums(design) + # titleval <- "Please note Sample size:" + # titletext <- paste(names(sampsize), + # sampsize, + # sep = "=", + # collapse = " \n ") + # titleall <- paste(titleval, "\n", titletext, "\n\n\n") + + contrast <- colnames(cm) + connames <- strsplit(contrast, "-") + connames <- lapply(connames, function(x) { + return(gsub("\\(", "", gsub("\\)", "", x))) + }) + contrastsize <- lapply(connames, function(x) { + return(sampsize[unlist(x)]) + }) + footnotetext <- paste(contrast, contrastsize, sep = " : ", collapse = "\n") + footnotetext <- paste("\n\n\nContrasts:\n", footnotetext) + ### PH: END contrast summary table + + ### PH: START Identify DEG genes input: + # -finalres from Create DEG Table + ## Output should be table With # of DEGs per contrast with different cutoffs + # TODO: currently these are not used anywhere downstream + # FCpval1 <- get_gene_lists( + # finalres, + # FC, + # pvalall, + # pvaladjall, + # contrasts, + # FClimit = 1.2, + # pvallimit = 0.05, + # pval = "pval", + # feature_id_colname = feature_id_colname + # ) + # FCpval2 <- get_gene_lists( + # finalres, + # FC, + # pvalall, + # pvaladjall, + # contrasts, + # FClimit = 1.2, + # pvallimit = 0.01, + # pval = "pval", + # feature_id_colname = feature_id_colname + # ) + # FCadjpval1 <- get_gene_lists( + # finalres, + # FC, + # pvalall, + # pvaladjall, + # contrasts, + # FClimit = 1.2, + # pvallimit = 0.05, + # pval = "adjpval", + # feature_id_colname = feature_id_colname + # ) + # FCadjpval2 <- get_gene_lists( + # finalres, + # FC, + # pvalall, + # pvaladjall, + # contrasts, + # FClimit = 1.2, + # pvallimit = 0.01, + # pval = "adjpval", + # feature_id_colname = feature_id_colname + # ) + ### PH: END Identify DEG genes + + # Mean-variance Plot. + mv_plot <- plot_mean_variance(voom_elist = v) + print_or_save_plot( + mv_plot, + filename = file.path(plots_subdir, "mean-variance.png"), + print_plots = print_plots, + save_plots = save_plots + ) + + df_list <- contrasts |> + purrr::map(\(contrast) { + result <- finalres |> + dplyr::select( + tidyselect::all_of(feature_id_colname), + tidyselect::all_of( + purrr::map( + contrast |> + stringr::str_split("-") |> + unlist() |> + paste0(., "_"), + tidyselect::starts_with, + vars = colnames(.) + ) |> + unlist() + ), + tidyselect::all_of(tidyselect::starts_with(contrast)) + ) |> + dplyr::rename_with(~ gsub(paste0(contrast, "_"), "", .x)) + return(result) + }) + + names(df_list) <- contrasts + + moo@analyses[["diff"]] <- df_list + return(moo) +} + + +get_gene_lists <- function( + finalres, + FC, + pvalall, + pvaladjall, + contrasts, + FClimit, + pvallimit, + pval, + feature_id_colname = "Gene" +) { + upreg_genes <- list() + downreg_genes <- list() + for (i in seq_len(length(contrasts))) { + if (pval == "pval") { + upreg_genes[[i]] <- finalres |> + dplyr::filter( + .data[[colnames(FC)[i]]] > FClimit & + .data[[colnames(pvalall)[i]]] < pvallimit + ) |> + dplyr::pull(tidyselect::all_of(feature_id_colname)) |> + length() + downreg_genes[[i]] <- finalres |> + dplyr::filter( + .data[[colnames(FC)[i]]] < -FClimit & + .data[[colnames(pvalall)[i]]] < pvallimit + ) |> + dplyr::pull(tidyselect::all_of(feature_id_colname)) |> + length() + } else { + upreg_genes[[i]] <- finalres |> + dplyr::filter( + .data[[colnames(FC)[i]]] > FClimit & + .data[[colnames(pvaladjall)[i]]] < pvallimit + ) |> + dplyr::pull(tidyselect::all_of(feature_id_colname)) |> + length() + downreg_genes[[i]] <- finalres |> + dplyr::filter( + .data[[colnames(FC)[i]]] < -FClimit & + .data[[colnames(pvaladjall)[i]]] < pvallimit + ) |> + dplyr::pull(tidyselect::all_of(feature_id_colname)) |> + length() + } + } + names(upreg_genes) <- contrasts + names(downreg_genes) <- contrasts + allreggenes <- rbind(unlist(upreg_genes), unlist(downreg_genes)) + rownames(allreggenes) <- c( + paste0("upreg>", FClimit, ", ", pval, "<", pvallimit), + paste0("downreg<-", FClimit, ", ", pval, "<", pvallimit) + ) + return(allreggenes) +} + + +plot_mean_variance <- function(voom_elist) { + x <- y <- NULL + v <- voom_elist + sx <- v$voom.xy$x + sy <- v$voom.xy$y + xyplot <- as.data.frame(cbind(sx, sy)) + voomline <- as.data.frame(cbind(x = v$voom.line$x, y = v$voom.line$y)) + + g <- ggplot2::ggplot() + + ggplot2::geom_point(data = xyplot, ggplot2::aes(x = sx, y = sy), size = 1) + + ggplot2::theme_bw() + + ggplot2::geom_smooth( + data = voomline, + ggplot2::aes(x = x, y = y), + color = "red" + ) + + ggplot2::ggtitle("voom: Mean-variance trend") + + ggplot2::xlab(v$voom.xy$xlab) + + ggplot2::ylab(v$voom.xy$ylab) + + ggplot2::theme( + axis.title = ggplot2::element_text(size = 12), + plot.title = ggplot2::element_text( + size = 14, + face = "bold", + hjust = 0.5 + ) + ) + return(g) +} + +#' Filter features from differential analysis based on statistical significance +#' +#' 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. +#' +#' @inheritParams option_params +#' @inheritParams filter_counts +#' @param significance_column Column name for significance, e.g. `"pval"` or `"pvaladj"` (default) +#' @param significance_cutoff Features will only be kept if their `significance_column` is less then this cutoff +#' threshold +#' @param change_column Column name for change, e.g. `"logFC"` (default) +#' @param change_cutoff Features will only be kept if the absolute value of their `change_column` is greater than or +#' equal to this cutoff threshold +#' @param filtering_mode Accepted values: `"any"` or `"all"` to include features that meet the criteria in _any_ +#' contrast or in _all_ contrasts +#' @param include_estimates Column names of estimates to include. Default: `c("FC", "logFC", "tstat", "pval", +#' "adjpval")` +#' @param round_estimates Whether to round estimates. Default: `TRUE` +#' @param rounding_decimal_for_percent_cells Decimal place to use when rounding Percent cells +#' @param contrast_filter Whether to filter `contrasts` in or our of analysis. If `"keep"`, only the contrast names +#' listed in `contrasts` will be included. If `"remove`, the contrast names listed by `contrasts` will be removed. If +#' `"none"`, all contrasts in the dataset are used. Options: `"keep"`, `"remove"`, or `"none"` +#' @param contrasts Contrast names to filter by `contrast_filter`. If `contrast_filter` is `"none"`, this parameter has +#' no effect. +#' @param groups Group names to filter by `groups_filter`. If `groups_filter` is `"none"`, this parameter has no effect. +#' Options: `"keep"`, `"remove"`, or `"none"` +#' @param groups_filter Whether to filter `groups` in or out of analysis. If `"keep"`, only the group names listed in +#' `groups` will be included. If `"remove"`, the group names listed by `groups` will be removed. If `"none"`, all +#' groups in the dataset are used. +#' @param label_font_size Font size for labels in the plot (default: 6) +#' @param label_distance Distance of labels from the bars (default: 1) +#' @param y_axis_expansion Expansion of the y-axis (default: 0.08) +#' @param fill_colors Fill colors for the bars (default: c("steelblue1", "whitesmoke")) +#' @param pie_chart_in_3d Whether to draw pie charts in 3D (default: TRUE) +#' @param bar_width Width of the bars (default: 0.4) +#' @param draw_bar_border Whether to draw borders around bars (default: TRUE) +#' @param plot_type "bar" or "pie" +#' @param plot_titles_fontsize Font size for plot titles (default: 12) +#' @param plots_subdir subdirectory in where plots will be saved if `save_plots` is `TRUE` +#' +#' @family moo methods +#' +#' @export +#' +#' @examples +#' 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) +#' ) +#' ) |> +#' diff_counts( +#' count_type = "filt", +#' sub_count_type = NULL, +#' sample_id_colname = "Sample", +#' feature_id_colname = "Gene", +#' covariates_colnames = c("Group", "Batch"), +#' contrast_colname = c("Group"), +#' contrasts = c("B-A", "C-A", "B-C"), +#' voom_normalization_method = "quantile", +#' ) |> +#' filter_diff() +#' head(moo@analyses$diff_filt) +filter_diff <- function( + moo, + feature_id_colname = NULL, + significance_column = "adjpval", + significance_cutoff = 0.05, + change_column = "logFC", + change_cutoff = 1, + filtering_mode = "any", + include_estimates = c("FC", "logFC", "tstat", "pval", "adjpval"), + round_estimates = TRUE, + rounding_decimal_for_percent_cells = 0, + contrast_filter = "none", + contrasts = c(), + groups = c(), + groups_filter = "none", + label_font_size = 6, + label_distance = 1, + y_axis_expansion = 0.08, + fill_colors = c("steelblue1", "whitesmoke"), + pie_chart_in_3d = TRUE, + bar_width = 0.4, + draw_bar_border = TRUE, + plot_type = "bar", + plot_titles_fontsize = 12, + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = file.path("diff", "filt") +) { + Count <- Count_format <- L1 <- Label <- Percent <- Significant <- Var1 <- Var2 <- value <- NULL + + # from NIDAP DEG_Gene_List template - filters DEG table + diff_dat <- moo@analyses$diff |> + join_dfs_wide() |> + as.data.frame() + + message("* filtering differential features") + + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(diff_dat)[1] + } + if (!(filtering_mode %in% c("any", "all"))) { + stop(glue::glue("filtering_mode not recognized: {filtering_mode}")) + } + if (!(plot_type %in% c("bar", "pie"))) { + stop(glue::glue("plot_type not recognized: {plot_type}")) + } + if (!(contrast_filter %in% c("keep", "remove", "none"))) { + stop(glue::glue("contrast_filter not recognized: {contrast_filter}")) + } + # ensure these are vectors, not lists. needed for reading args from JSON + include_estimates <- include_estimates |> unlist() + contrasts <- contrasts |> unlist() + groups <- groups |> unlist() + fill_colors <- fill_colors |> unlist() + + # If include_estimates param is empty, then fill it with default values. + if (length(include_estimates) == 0) { + include_estimates <- c("FC", "logFC", "tstat", "pval", "adjpval") + } + ## select DEG stat columns + estimates <- paste0("_", include_estimates) + signif <- paste0("_", significance_column) + change <- paste0("_", change_column) + diff_dat <- diff_dat |> + dplyr::select( + tidyselect::all_of(feature_id_colname), + tidyselect::ends_with(c(estimates, signif, change)) + ) + + contrasts_name <- diff_dat |> + dplyr::select(tidyselect::ends_with(signif)) |> + colnames() + contrasts_name <- unlist(strsplit(contrasts_name, signif)) + if (contrast_filter == "keep") { + contrasts_name <- intersect(contrasts_name, contrasts) + } else if (contrast_filter == "remove") { + contrasts_name <- setdiff(contrasts_name, contrasts) + } + contrasts_name <- paste0(contrasts_name, "_") + + groups_name <- diff_dat |> + dplyr::select(tidyselect::ends_with(c("_mean", "_sd"))) |> + colnames() + groups_name <- unique(gsub("_mean|_sd", "", groups_name)) + if (groups_filter == "keep") { + groups_name <- intersect(groups_name, groups) + } else if (contrast_filter == "remove") { + groups_name <- setdiff(groups_name, groups) + } + groups_name <- paste0(groups_name, "_") + + ### PH: END Set parameters + + ### PH: START Subset DEG table + + diff_dat <- diff_dat |> + dplyr::select( + tidyselect::all_of(feature_id_colname), + tidyselect::starts_with(c(groups_name, contrasts_name)) + ) + + ## select filter variables + datsignif <- diff_dat |> + dplyr::select( + tidyselect::all_of(feature_id_colname), + tidyselect::ends_with(signif) + ) |> + tibble::column_to_rownames(feature_id_colname) + datchange <- diff_dat |> + dplyr::select( + tidyselect::all_of(feature_id_colname), + tidyselect::ends_with(change) + ) |> + tibble::column_to_rownames(feature_id_colname) + genes <- diff_dat[, feature_id_colname] + + ## filter genes + significant <- datsignif < significance_cutoff + changed <- abs(datchange) >= change_cutoff + if (filtering_mode == "any") { + selgenes <- apply(significant & changed, 1, any) + select_genes <- genes[selgenes] + } else if (filtering_mode == "all") { + selgenes <- apply(significant & changed, 1, all) + select_genes <- genes[selgenes] + } + + # stop if 0 genes selected with the selection criteria + if (length(select_genes) == 0) { + stop(glue::glue( + "ERROR: Selection criteria selected no genes - change stringency of the Significance cutoff", + " and/or Change cutoff parameters" + )) + } + message( + glue::glue( + "Total number of genes selected with {significance_column} < {significance_cutoff}", + " and \u007c {change_column} \u007c \u2265 {change_cutoff} is sum(selgenes)" + ) + ) + + ## .output dataset + out <- diff_dat |> dplyr::filter(get(feature_id_colname) %in% select_genes) + if (round_estimates) { + out <- out |> dplyr::mutate_if(is.numeric, ~ signif(., 3)) + } + + ### PH: END Subset DEG table + + ### PH: START Create DEG summary Barplot + ## do plot + significant <- apply(datsignif, 2, function(x) x <= significance_cutoff) + changed <- apply(datchange, 2, function(x) abs(x) >= change_cutoff) + dd <- significant & changed + if (draw_bar_border) { + bar_border <- "black" + } else { + bar_border <- NA + } + + ## If fill_colors is blank, then + ## give it default values. + if (length(fill_colors) == 0) { + fill_colors <- c("steelblue1", "whitesmoke") + } + + if (filtering_mode == "any") { + say_contrast <- paste(colnames(dd), collapse = " | ") + say_contrast <- gsub("_pval|_adjpval", "", say_contrast) + + Var2df <- reshape2::melt(apply(dd, 2, table)) + if ("L1" %in% names(Var2df)) { + Var2df <- Var2df |> + dplyr::rename(Var2 = L1) + } + + tab <- Var2df |> + dplyr::mutate(Significant = ifelse(Var1, "TRUE", "FALSE")) |> + dplyr::mutate( + Significant = factor(Significant, levels = c("TRUE", "FALSE")), + Count = value, + Count_format = format(round(value, 1), nsmall = 0, big.mark = ",") + ) |> + dplyr::mutate(Var2 = gsub("_pval|_adjpval", "", Var2)) |> + dplyr::group_by(Var2) |> + dplyr::mutate( + Percent = round( + Count / sum(Count) * 100, + rounding_decimal_for_percent_cells + ) + ) |> + dplyr::mutate(Label = sprintf("%s (%g%%)", Count_format, Percent)) + + pp <- ggplot2::ggplot( + tab, + ggplot2::aes( + x = "", + y = Count, + labels = Significant, + fill = Significant + ) + ) + + ggplot2::geom_col( + width = bar_width, + position = "dodge", + col = bar_border + ) + + ggplot2::facet_wrap(~Var2) + + ggplot2::scale_fill_manual(values = fill_colors) + + ggplot2::theme_bw(base_size = 20) + + ggplot2::xlab("") + + ggplot2::ylab("Number of Genes") + + ggplot2::geom_text( + ggplot2::aes(label = Label), + color = c("black"), + size = label_font_size, + position = ggplot2::position_dodge(width = bar_width), + vjust = -label_distance + ) + + ggplot2::ggtitle( + sprintf( + "%s<%g & |%s|>%g %s", + significance_column, + significance_cutoff, + change_column, + change_cutoff, + filtering_mode + ) + ) + + ggplot2::theme( + axis.ticks.x = ggplot2::element_blank(), + axis.text.x = ggplot2::element_blank(), + legend.key.size = ggplot2::unit(3, "line"), + legend.position = "top", + panel.grid.major.x = ggplot2::element_blank(), + panel.grid.minor.x = ggplot2::element_blank(), + strip.background = ggplot2::element_blank(), + strip.text = ggplot2::element_text(size = plot_titles_fontsize) + ) + + ggplot2::scale_y_continuous(name = "", expand = c(y_axis_expansion, 0)) + print_or_save_plot( + pp, + filename = file.path(plots_subdir, glue::glue("{plot_type}chart.png")), + print_plots = print_plots, + save_plots = save_plots + ) + } else if (filtering_mode == "all") { + say_contrast <- paste(colnames(dd), collapse = " & ") + say_contrast <- gsub("_pval|_adjpval", "", say_contrast) + dd <- apply(dd, 1, function(x) all(x == TRUE)) + + if (plot_type == "bar") { + dd <- data.frame(dd) + colnames(dd) <- say_contrast + Var2df <- reshape2::melt(apply(dd, 2, table)) + if ("L1" %in% names(Var2df)) { + Var2df <- Var2df |> + dplyr::rename(Var2 = L1) + } + + tab <- Var2df |> + dplyr::mutate(Significant = ifelse(Var1, "TRUE", "FALSE")) |> + dplyr::mutate( + Significant = factor(Significant, levels = c("TRUE", "FALSE")), + Count = value, + Count_format = format(round(value, 1), nsmall = 0, big.mark = ",") + ) |> + dplyr::mutate(Var2 = gsub("_pval|_adjpval", "", Var2)) |> + dplyr::group_by(Var2) |> + dplyr::mutate( + Percent = round( + Count / sum(Count) * 100, + rounding_decimal_for_percent_cells + ) + ) |> + dplyr::mutate(Label = sprintf("%s (%g%%)", Count_format, Percent)) + + pp <- ggplot2::ggplot( + tab, + ggplot2::aes( + x = "", + y = Count, + labels = Significant, + fill = Significant + ) + ) + + ggplot2::geom_col( + width = bar_width, + position = "dodge", + col = bar_border + ) + + ggplot2::facet_wrap(~Var2) + + ggplot2::scale_fill_manual(values = fill_colors) + + ggplot2::theme_bw(base_size = 20) + + ggplot2::xlab("") + + ggplot2::ylab("Number of Genes") + + ggplot2::geom_text( + ggplot2::aes(label = Label), + color = c("black"), + size = label_font_size, + position = ggplot2::position_dodge(width = bar_width), + vjust = -label_distance + ) + + ggplot2::ggtitle( + sprintf( + "%s<%g & |%s|>%g %s", + significance_column, + significance_cutoff, + change_column, + change_cutoff, + filtering_mode + ) + ) + + ggplot2::theme( + axis.ticks.x = ggplot2::element_blank(), + axis.text.x = ggplot2::element_blank(), + legend.key.size = ggplot2::unit(3, "line"), + legend.position = "top", + panel.grid.major.x = ggplot2::element_blank(), + panel.grid.minor.x = ggplot2::element_blank(), + strip.background = ggplot2::element_blank(), + strip.text = ggplot2::element_text(size = plot_titles_fontsize) + ) + + ggplot2::scale_y_continuous(name = "", expand = c(y_axis_expansion, 0)) + print_or_save_plot( + pp, + filename = file.path(plots_subdir, glue::glue("{plot_type}chart.png")), + print_plots = print_plots, + save_plots = save_plots + ) + ### PH: END Create DEG summary Barplot + } else if (plot_type == "pie") { + ### PH: START Create DEG summary PieChart + abort_packages_not_installed("plotrix") + N <- c(sum(dd), length(dd) - sum(dd)) + Nk <- format(round(as.numeric(N), 1), nsmall = 0, big.mark = ",") + P <- round(N / sum(N) * 100, rounding_decimal_for_percent_cells) + if (label_font_size > 0) { + labs <- c( + sprintf("Significant\n%s (%g%%)", Nk[1], P[1]), + sprintf("Non-Significant\n%s (%g%%)", Nk[2], P[2]) + ) + } else { + labs <- NULL + } + # TODO: how to print_or_save base R plot? + if (pie_chart_in_3d) { + plotrix::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 + ) + graphics::title( + main = sprintf( + "%s<%g & |%s|>%g %s: %s", + significance_column, + significance_cutoff, + change_column, + change_cutoff, + filtering_mode, + say_contrast + ), + cex.main = plot_titles_fontsize / 3, + line = -2 + ) + } else { + labs <- gsub("\n", ": ", labs) + plotrix::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 + ) + graphics::title( + main = sprintf( + "%s<%g & |%s|>%g %s: %s", + significance_column, + significance_cutoff, + change_column, + change_cutoff, + filtering_mode, + say_contrast + ), + cex.main = plot_titles_fontsize / 3, + line = -2 + ) + } + ### PH: END Create DEG summary PieChart + } + } + + moo@analyses$diff_filt <- out + return(moo) +} diff --git a/code/MOSuite/R/filter.R b/code/MOSuite/R/filter.R new file mode 100644 index 0000000..7e0625f --- /dev/null +++ b/code/MOSuite/R/filter.R @@ -0,0 +1,359 @@ +#' Filter low counts +#' +#' This is often the first step in the QC portion of an analysis to filter out +#' features that have very low raw counts across most or all of your samples. +#' +#' This function takes a multiOmicDataSet containing clean raw counts and a sample +#' metadata table, and returns the multiOmicDataSet object with filtered counts. +#' It also produces an image consisting of three QC plots. +#' +#' You can tune the threshold for tuning how low counts for a given gene are +#' before they are deemed "too low" and filtered out of downstream analysis. By +#' default, this parameter is set to 1, meaning any raw count value less than 1 +#' will count as "too low". +#' +#' The 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. +#' +#' @inheritParams option_params +#' +#' @param moo multiOmicDataSet object (see `create_multiOmicDataSet_from_dataframes()`) +#' @param count_type the type of counts to use -- must be a name in the counts slot (`moo@counts`) +#' @param 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: `NULL` - first column in the counts matrix will be +#' used.) +#' @param 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: `NULL` - first +#' column in the sample metadata will be used.) +#' @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 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.) +#' @param 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 +#' 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 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 +#' @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 +#' @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 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 +#' @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_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. +#' @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 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. +#' Colors must either be names in `grDevices::colors()` or valid hex codes. +#' @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`. +#' @param interactive_plots set to TRUE to make PCA and Histogram plots 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 plots_subdir subdirectory in `figures/` where plots will be saved if `save_plots` is `TRUE` +#' +#' @return `multiOmicDataSet` with filtered counts +#' @export +#' +#' @examples +#' 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( +#' count_type = "raw" +#' ) +#' head(moo@counts$filt) +#' +#' @family moo methods +filter_counts <- function( + moo, + 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 = c(""), + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + interactive_plots = FALSE, + plots_subdir = "filt" +) { + if (!(count_type %in% names(moo@counts))) { + stop(glue::glue("count_type {count_type} not in moo@counts")) + } + counts_dat <- moo@counts[[count_type]] |> as.data.frame() # currently, this function requires data frames + sample_metadata <- moo@sample_meta |> as.data.frame() + + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(counts_dat)[1] + } + if (is.null(samples_to_include)) { + samples_to_include <- sample_metadata |> dplyr::pull(sample_id_colname) + } + if (is.null(label_colname)) { + label_colname <- sample_id_colname + } + message(glue::glue("* filtering {count_type} counts")) + + samples_to_include <- samples_to_include |> unlist() + + df <- counts_dat |> + dplyr::select( + tidyselect::all_of(feature_id_colname), + tidyselect::all_of(samples_to_include) + ) + + # filter out low count genes + df_filt <- remove_low_count_genes( + counts_dat = df, + sample_metadata = sample_metadata, + feature_id_colname = feature_id_colname, + group_colname = group_colname, + use_cpm_counts_to_filter = use_cpm_counts_to_filter, + use_group_based_filtering = use_group_based_filtering, + 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, + 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 (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) + } + if (isTRUE(color_histogram_by_group)) { + colors_for_histogram <- colors_for_plots + } else { + 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, + 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, + 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, + add_label = add_label_to_pca, + label_font_size = label_font_size, + label_offset_y_ = label_offset_y_, + label_offset_x_ = label_offset_x_, + save_plots = FALSE + ) + + ggplot2::labs(caption = "filtered counts") + + hist_plot <- plot_histogram( + log_counts, + sample_metadata, + sample_id_colname = sample_id_colname, + feature_id_colname = feature_id_colname, + group_colname = group_colname, + label_colname = label_colname, + 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, + 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 = "filtered counts") + if (isTRUE(plot_corr_matrix_heatmap)) { + corHM <- plot_corr_heatmap( + df_filt[, samples_to_include], + sample_metadata = sample_metadata, + sample_id_colname = sample_id_colname, + feature_id_colname = feature_id_colname, + label_colname = label_colname, + group_colname = group_colname, + color_values = colors_for_plots + ) + + ggplot2::labs(caption = "filtered counts") + print_or_save_plot( + corHM, + filename = file.path(plots_subdir, "corr_heatmap.png"), + print_plots = print_plots, + save_plots = save_plots + ) + } + + 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")) + 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 + ) + print_or_save_plot( + hist_plot, + filename = file.path(plots_subdir, glue::glue("histogram.{plot_ext}")), + print_plots = print_plots, + save_plots = save_plots + ) + } + df_final <- df |> + dplyr::filter( + !!rlang::sym(feature_id_colname) %in% df_filt[, feature_id_colname] + ) + + moo@counts[["filt"]] <- df_final + + return(moo) +} + +#' Remove low-count genes +#' +#' TODO this function also transforms raw counts to CPM, but that should be a separate function before this step, before +#' filter_counts function() +#' +#' @inheritParams filter_counts +#' +#' @return counts matrix with low-count genes removed +#' @keywords internal +#' +remove_low_count_genes <- function( + counts_dat, + sample_metadata, + feature_id_colname, + group_colname, + use_cpm_counts_to_filter = TRUE, + use_group_based_filtering = FALSE, + 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 +) { + # TODO refactor with tidyverse + value <- isexpr1 <- NULL + df <- counts_dat + + df <- df[stats::complete.cases(df), ] + + # USE CPM Transformation + trans_df <- df + if (use_cpm_counts_to_filter == TRUE) { + trans_df[, -1] <- edgeR::cpm(as.matrix(df[, -1])) + } + + 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) + ) + tcounts.group <- tcounts.tot |> + tidyr::pivot_wider(names_from = "variable", values_from = "sum") |> + as.data.frame() + tcounts.keep <- colSums( + tcounts.group[(1:colnum + 1)] >= + minimum_number_of_samples_with_nonzero_counts_in_a_group + ) >= + 1 + df_filt <- trans_df[tcounts.keep, ] |> + tibble::rownames_to_column(feature_id_colname) + } else { + 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) + df_filt <- trans_df |> + dplyr::filter(isexpr1) |> + dplyr::select(-isexpr1) + } + + message(paste0("Number of features after filtering: ", nrow(df_filt))) + return(df_filt) +} diff --git a/code/MOSuite/R/metadata.R b/code/MOSuite/R/metadata.R new file mode 100644 index 0000000..c8a6f3f --- /dev/null +++ b/code/MOSuite/R/metadata.R @@ -0,0 +1,26 @@ +#' Convert sample metadata from a tibble to a dataframe with sample IDs as row names +#' +#' @param meta_tbl tibble with `sample_id` column +#' +#' @inheritParams create_multiOmicDataSet_from_files +#' +#' @return dataframe where row names are the sample IDs +#' @keywords internal +#' +#' @examples +#' \dontrun{ +#' sample_meta_tbl <- readr::read_tsv(system.file("extdata", +#' "sample_metadata.tsv.gz", +#' package = "MOSuite" +#' )) +#' head(sample_meta_tbl) +#' meta_tbl_to_dat(sample_meta_tbl) +#' } +meta_tbl_to_dat <- function(meta_tbl, sample_id_colname = sample_id) { + sample_id <- NULL + meta_dat <- meta_tbl |> + as.data.frame() |> + dplyr::select({{ sample_id_colname }}) + rownames(meta_dat) <- meta_tbl |> dplyr::pull({{ sample_id_colname }}) + return(meta_dat) +} diff --git a/code/MOSuite/R/normalize.R b/code/MOSuite/R/normalize.R new file mode 100644 index 0000000..e6ebd76 --- /dev/null +++ b/code/MOSuite/R/normalize.R @@ -0,0 +1,194 @@ +#' Normalize counts +#' +#' @inheritParams filter_counts +#' @inheritParams option_params +#' +#' @param norm_type normalization type. Default: "voom" which uses `limma::voom`. +#' @param input_in_log_counts set this to `TRUE` if counts are already log2-transformed +#' @param voom_normalization_method Normalization method to be applied to the logCPM values when using `limma::voom` +#' +#' @return `multiOmicDataSet` with normalized counts +#' @export +#' +#' @examples +#' 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( +#' group_colname = "Group", +#' label_colname = "Label" +#' ) +#' head(moo@counts[["norm"]][["voom"]]) +#' @family moo methods +normalize_counts <- function( + moo, + 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 = 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 = 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + interactive_plots = FALSE, + plots_subdir = "norm" +) { + counts_dat <- moo@counts[[count_type]] |> as.data.frame() + sample_metadata <- moo@sample_meta |> as.data.frame() + plots_subdir <- file.path(plots_subdir, norm_type) + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(counts_dat)[1] + } + if (is.null(samples_to_include)) { + samples_to_include <- sample_metadata |> dplyr::pull(sample_id_colname) + } + if (is.null(label_colname)) { + label_colname <- sample_id_colname + } + message(glue::glue("* normalizing {count_type} counts")) + df.filt <- counts_dat |> + dplyr::select(tidyselect::all_of(samples_to_include)) + + ## --------------- ## + ## Main Code Block ## + ## --------------- ## + gene_names <- NULL + gene_names$feature_id <- counts_dat |> dplyr::pull(feature_id_colname) + + ### PH: START Limma Normalization + ############################## + #### Limma Normalization + ############################## + + # If input is in log space, linearize + if (input_in_log_counts == TRUE) { + x <- edgeR::DGEList(counts = 2^df.filt, genes = gene_names) + } else { + x <- edgeR::DGEList(counts = df.filt, genes = gene_names) + } + v <- limma::voom(x, normalize = voom_normalization_method) + rownames(v$E) <- v$genes$feature_id + df.voom <- as.data.frame(v$E) |> + tibble::rownames_to_column(feature_id_colname) + 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]] + } + 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( + df.voom, + sample_metadata = sample_metadata, + sample_id_colname = sample_id_colname, + samples_to_rename = samples_to_rename, + group_colname = group_colname, + label_colname = label_colname, + 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, + add_label = add_label_to_pca, + label_font_size = label_font_size, + label_offset_y_ = label_offset_y_, + label_offset_x_ = label_offset_x_, + save_plots = FALSE + ) + + ggplot2::labs(caption = "normalized counts") + hist_plot <- plot_histogram( + df.voom, + sample_metadata = sample_metadata, + sample_id_colname = sample_id_colname, + feature_id_colname = feature_id_colname, + group_colname = group_colname, + label_colname = label_colname, + color_values = colors_for_histogram, + color_by_group = color_histogram_by_group, + x_axis_label = "Normalized Counts", + 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") + if (isTRUE(plot_corr_matrix_heatmap)) { + corHM_plot <- plot_corr_heatmap( + df.filt, + sample_metadata = sample_metadata, + sample_id_colname = sample_id_colname, + feature_id_colname = feature_id_colname, + group_colname = group_colname, + label_colname = label_colname, + color_values = colors_for_plots + ) + + ggplot2::labs(caption = "normalized counts") + print_or_save_plot( + corHM_plot, + filename = file.path(plots_subdir, "corr_heatmap.png"), + print_plots = print_plots, + save_plots = save_plots + ) + } + + print_or_save_plot( + pca_plot, + filename = file.path(plots_subdir, "pca.png"), + print_plots = print_plots, + save_plots = save_plots + ) + print_or_save_plot( + hist_plot, + filename = file.path(plots_subdir, "histogram.png"), + print_plots = print_plots, + save_plots = save_plots + ) + } + + message(paste( + "Sample columns:", + paste(colnames(df.voom)[!colnames(df.voom) %in% feature_id_colname]), + collapse = ", " + )) + + if (isFALSE("norm" %in% names(moo@counts))) { + moo@counts[["norm"]] <- list() + } + moo@counts[["norm"]][[norm_type]] <- df.voom + return(moo) +} diff --git a/code/MOSuite/R/options.R b/code/MOSuite/R/options.R new file mode 100644 index 0000000..0cc8d7d --- /dev/null +++ b/code/MOSuite/R/options.R @@ -0,0 +1,40 @@ +options::set_option_name_fn(function(package, name) { + return(tolower(paste0("moo_", name))) +}) + +options::set_envvar_name_fn(function(package, name) { + return(gsub("[^A-Z0-9]", "_", toupper(paste0("moo_", name)))) +}) + +options::define_option( + option = "print_plots", + default = FALSE, + desc = "Whether to print plots during analysis", + option_name = "moo_print_plots", + envvar_name = "MOO_PRINT_PLOTS" +) +options::define_option( + option = "save_plots", + default = TRUE, + desc = "Whether to save plots to files during analysis", + option_name = "moo_save_plots", + envvar_name = "MOO_SAVE_PLOTS" +) +options::define_option( + option = "plots_dir", + default = "figures/", + desc = "Path where plots are saved when `moo_save_plots` is `TRUE`", + option_name = "moo_plots_dir", + envvar_name = "MOO_PLOTS_DIR" +) + + +#' @eval options::as_roxygen_docs() +NULL + +#' @title Option parameters +#' @eval options::as_params() +#' @name option_params +#' @keywords internal +#' +NULL diff --git a/code/MOSuite/R/plot_heatmap.R b/code/MOSuite/R/plot_heatmap.R new file mode 100644 index 0000000..879f0ee --- /dev/null +++ b/code/MOSuite/R/plot_heatmap.R @@ -0,0 +1,1107 @@ +#' Plot correlation heatmap +#' +#' @param moo_counts counts dataframe or `multiOmicDataSet` containing `count_type` & `sub_count_type` in the counts +#' slot +#' @param ... arguments forwarded to method +#' +#' @export +#' @returns heatmap from `ComplexHeatmap::Heatmap()` +#' @examples +#' # plot correlation heatmap for a counts slot in a multiOmicDataset Object +#' moo <- multiOmicDataSet( +#' sample_metadata = as.data.frame(nidap_sample_metadata), +#' anno_dat = data.frame(), +#' counts_lst = list("raw" = as.data.frame(nidap_raw_counts)) +#' ) +#' p <- plot_corr_heatmap(moo, count_type = "raw") +#' +#' # plot correlation heatmap for a counts dataframe +#' plot_corr_heatmap( +#' moo@counts$raw, +#' sample_metadata = moo@sample_meta, +#' sample_id_colname = "Sample", +#' feature_id_colname = "Gene", +#' group_colname = "Group", +#' label_colname = "Label" +#' ) +#' @details +#' +#' ## Method Usage +#' +#' ``` +#' # multiOmicDataSet +#' plot_corr_heatmap(moo_counts, +#' count_type, +#' sub_count_type = NULL, +#' ...) +#' +#' # dataframe +#' plot_corr_heatmap(moo_counts, +#' sample_metadata, +#' sample_id_colname = NULL, +#' 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" +#' )) +#' ``` +#' +#' @seealso +#' - [plot_corr_heatmap.multiOmicDataSet()] +#' - [plot_corr_heatmap.data.frame()] +#' +#' @family plotters +#' @family heatmaps +#' @keywords plotters +#' @family moo methods +plot_corr_heatmap <- S7::new_generic("plot_corr_heatmap", "moo_counts") + +#' Plot correlation heatmap for multiOmicDataSet +#' +#' @param moo_counts a `multiOmicDataSet` object +#' @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 ... additional arguments forwarded to [plot_corr_heatmap()] for `data.frame` +#' +#' @rdname plot_corr_heatmap-multiOmicDataSet +#' @aliases plot_corr_heatmap.multiOmicDataSet +#' @usage NULL +#' +#' @seealso [plot_corr_heatmap()] generic +#' @family plotters for multiOmicDataSets +S7::method(plot_corr_heatmap, multiOmicDataSet) <- function( + moo_counts, + count_type, + sub_count_type = NULL, + ... +) { + counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) + return(plot_corr_heatmap( + counts_dat, + sample_metadata = moo_counts@sample_meta, + ... + )) +} + +#' Plot correlation heatmap for counts dataframe +#' +#' @param moo_counts a `data.frame` of counts +#' @param sample_metadata sample metadata as a data frame or tibble (**Required**) +#' @param 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: `NULL` - first +#' column in the sample metadata will be used.) +#' @param 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: `NULL` - first column in the counts matrix will be +#' used.) +#' @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 color_values vector of colors as hex values or names recognized by R +#' +#' @rdname plot_corr_heatmap-data.frame +#' @aliases plot_corr_heatmap.data.frame +#' @usage NULL +#' +#' @seealso [plot_corr_heatmap()] generic +#' @family plotters for counts dataframes +S7::method(plot_corr_heatmap, S7::class_data.frame) <- function( + moo_counts, + sample_metadata, + sample_id_colname = NULL, + 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" + ) +) { + abort_packages_not_installed("amap", "ComplexHeatmap", "dendsort") + counts_dat <- moo_counts + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } + if ( + !is.null(feature_id_colname) && + feature_id_colname %in% colnames(counts_dat) + ) { + counts_dat <- counts_dat |> + tibble::column_to_rownames(var = feature_id_colname) + } + # drop non-numeric columns + counts_dat <- counts_dat |> dplyr::select(tidyselect::where(is.numeric)) + + ## Annotate + # 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 + + cols <- lapply(group_colname, function(x) { + ax <- as.factor(sample_metadata |> dplyr::pull(x)) |> levels() + out <- col[ax] + return(out) + }) + names(cols) <- (group_colname) + + anno <- ComplexHeatmap::columnAnnotation( + df = sample_metadata[, group_colname, drop = FALSE], + col = cols + ) + + ## Create Correlation Matrix + + old <- sample_metadata[[sample_id_colname]] + new <- sample_metadata[[label_colname]] + names(old) <- new + counts_dat <- counts_dat |> dplyr::rename(tidyselect::any_of(old)) + + mat <- as.matrix(counts_dat) + tcounts <- t(mat) + + ## calculate correlation + d <- amap::Dist(tcounts, method = "correlation", diag = TRUE) + m <- as.matrix(d) + + ## create dendogram + dend <- d |> + stats::hclust(method = "average") |> + stats::as.dendrogram() |> + dendsort::dendsort() |> + rev() + + ### plot + new.palette <- grDevices::colorRampPalette(c("blue", "green", "yellow")) + # lgd <- ComplexHeatmap::Legend(new.palette(20), + # title = "Correlation", + # title_position = "lefttop-rot") + hm <- ComplexHeatmap::Heatmap( + m, + heatmap_legend_param = list( + title = "Correlation", + title_position = "leftcenter-rot" + ), + cluster_rows = dend, + cluster_columns = dend, + top_annotation = anno, + row_names_gp = grid::gpar(fontsize = 15), + column_names_gp = grid::gpar(fontsize = 15), + col = new.palette(20) + ) + + return(hm) +} + +#' Plot expression heatmap +#' +#' The samples (i.e. the columns) are clustered 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. +#' +#' 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. +#' +#' @inheritParams option_params +#' @inheritParams filter_counts +#' +#' @param moo_counts counts dataframe or `multiOmicDataSet` containing `count_type` & `sub_count_type` in the counts +#' slot +#' @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_metadata sample metadata as a data frame or tibble (only required if `moo_counts` is a dataframe) +#' @param 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: `NULL` - first +#' column in the sample metadata will be used.) +#' @param feature_id_colname The column from the counts dataa 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: `NULL` - first column in the counts matrix will be +#' used.) +#' @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 color_values vector of colors as hex values or names recognized by R +#' @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.) +#' @param 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. +#' @param filter_top_genes_by_variance 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. +#' @param top_genes_by_variance_to_include 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. +#' @param specific_genes_to_include_in_heatmap 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. +#' @param cluster_genes Choose whether to cluster the rows (genes). If TRUE, rows will have clustering applied. If +#' FALSE, clustering will not be applied to rows. +#' @param gene_distance_metric Distance metric to be used in clustering genes. (TODO document options) +#' @param gene_clustering_method Clustering method metric to be used in clustering samples. (TODO document options) +#' @param display_gene_dendrograms Set to TRUE to show gene dendrograms. Set to FALSE to hide dendrograms. +#' @param display_gene_names Set to TRUE to display gene names on the right side of the heatmap. Set to FALSE to hide +#' gene names. +#' @param center_and_rescale_expression Center and rescale expression for each gene across all included samples. +#' @param cluster_samples Choose whether to cluster the columns (samples). If TRUE, columns will have clustering +#' applied. If FALSE, clustering will not be applied to columns. +#' @param arrange_sample_columns If TRUE, arranges columns by annotation groups. If FALSE, and "Cluster Samples" is +#' FALSE, samples will appear in the order of input (samples to include) +#' @param order_by_gene_expression If TRUE, set gene name below and direction for ordering +#' @param gene_to_order_columns Gene to order columns by expression levels +#' @param gene_expression_order Choose direction for gene order +#' @param smpl_distance_metric Distance metric to be used in clustering samples. (TODO document options) +#' @param smpl_clustering_method Clustering method to be used in clustering samples. (TODO document options) +#' @param display_smpl_dendrograms Set to TRUE to show sample dendrograms. Set to FALSE to hide dendrogram. +#' @param reorder_dendrogram If TRUE, set the order of the dendrogram (below) +#' @param reorder_dendrogram_order Reorder the samples (columns) of the dendrogram by name, e.g. +#' “sample2”,“sample3",“sample1". +#' @param display_sample_names Set to TRUE if you want sample names to be displayed on the plot. Set to FALSE to hide +#' sample names. +#' @param group_columns Columns containing the sample groups for annotation tracks +#' @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" +#' (below). +#' @param set_min_heatmap_color If Autoscale heatmap color is set to FALSE, set the minimum heatmap z-score value +#' @param set_max_heatmap_color If Autoscale heatmap color is set to FALSE, set the maximum heatmap z-score value. +#' @param aspect_ratio 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 +#' @param legend_font_size Set Font size for figure legend. Default is 10. +#' @param gene_name_font_size Font size for gene names. If you don't want gene labels to show, toggle "Display Gene +#' Names" below to FALSE +#' @param sample_name_font_size Font size for sample names. If you don't want to display samples names, toggle "Display +#' sample names" (below) to FALSE +#' @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 +#' +#' @export +#' @returns heatmap from `ComplexHeatmap::Heatmap()` +#' +#' @examples +#' # plot expression heatmap for a counts slot in a multiOmicDataset Object +#' moo <- multiOmicDataSet( +#' sample_metadata = as.data.frame(nidap_sample_metadata), +#' anno_dat = data.frame(), +#' counts_lst = list( +#' "raw" = nidap_raw_counts, +#' "norm" = list( +#' "voom" = as.data.frame(nidap_norm_counts) +#' ) +#' ) +#' ) +#' p <- plot_expr_heatmap(moo, count_type = "norm", sub_count_type = "voom") +#' +#' # customize the plot +#' plot_expr_heatmap(moo, +#' count_type = "norm", sub_count_type = "voom", +#' top_genes_by_variance_to_include = 100 +#' ) +#' +#' # plot expression heatmap for a counts dataframe +#' counts_dat <- moo@counts$norm$voom +#' plot_expr_heatmap( +#' counts_dat, +#' sample_metadata = nidap_sample_metadata, +#' sample_id_colname = "Sample", +#' feature_id_colname = "Gene", +#' group_colname = "Group", +#' label_colname = "Label", +#' top_genes_by_variance_to_include = 100 +#' ) +#' +#' @family plotters +#' @family heatmaps +#' @family moo methods +#' @keywords plotters +plot_expr_heatmap <- S7::new_generic( + "plot_expr_heatmap", + "moo_counts", + function( + moo_counts, + count_type, + 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 = c( + "#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 = c(), + display_sample_names = TRUE, + 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, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "heatmap" + ) { + return(S7::S7_dispatch()) + } +) + + +#' @rdname plot_expr_heatmap +S7::method(plot_expr_heatmap, multiOmicDataSet) <- function( + moo_counts, + count_type, + 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 = c( + "#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 = c(), + display_sample_names = TRUE, + 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, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "heatmap" +) { + counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) + 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, + plot_filename = plot_filename, + print_plots, + save_plots, + plots_subdir + ) + return(heatmap_plot) +} + +#' @rdname plot_expr_heatmap +S7::method(plot_expr_heatmap, S7::class_data.frame) <- function( + moo_counts, + count_type, + 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 = c( + "#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 = c(), + display_sample_names = TRUE, + 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, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "heatmap" +) { + ## This function uses pheatmap to draw a heatmap, scaling first by rows + ## (with samples in columns and genes in rows) + Gene <- NULL + # TODO support tibbles; currently these must be dataframes + counts_dat <- as.data.frame(moo_counts) + sample_metadata <- as.data.frame(sample_metadata) + + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(counts_dat)[1] + } + if (is.null(label_colname)) { + label_colname <- sample_id_colname + } + if (is.null(samples_to_include)) { + samples_to_include <- sample_metadata |> dplyr::pull(sample_id_colname) + } + + ## --------------- ## + ## Error Messages ## + ## -------------- ## + + if ( + include_all_genes == TRUE && + filter_top_genes_by_variance == TRUE + ) { + stop( + "ERROR: Choose only one of 'Include all genes' or 'Filter top genes by variance' as TRUE" + ) + } + + if ( + any( + all(cluster_samples == TRUE, arrange_sample_columns == TRUE), + all( + arrange_sample_columns == TRUE, + order_by_gene_expression == TRUE + ), + all(arrange_sample_columns == TRUE, cluster_samples == TRUE), + all( + cluster_samples == FALSE, + arrange_sample_columns == FALSE, + order_by_gene_expression == FALSE + ) + ) + ) { + stop( + "ERROR: Choose only one of 'Cluster Samples', 'Arrange sample columns', or 'order by gene expression' as TRUE" + ) + } + + ### PH: START palette function for heatmap scale + ## Begin pal() color palette function∂: + pal <- function( + n, + h = c(237, 43), + c = 100, + l = c(70, 90), + power = 1, + fixup = TRUE, + gamma = NULL, + alpha = 1, + ... + ) { + if (n < 1L) { + return(character(0L)) + } + h <- rep(h, length.out = 2L) + c <- c[1L] + l <- rep(l, length.out = 2L) + power <- rep(power, length.out = 2L) + rval <- seq(1, -1, length = n) + rval <- colorspace::hex( + colorspace::polarLUV( + L = l[2L] - diff(l) * abs(rval)^power[2L], + C = c * abs(rval)^power[1L], + H = ifelse(rval > 0, h[1L], h[2L]) + ), + fixup = fixup, + ... + ) + if (!missing(alpha)) { + alpha <- pmax(pmin(alpha, 1), 0) + alpha <- format( + as.hexmode(round(alpha * 255 + 1e-04)), + width = 2L, + upper.case = TRUE + ) + rval <- paste(rval, alpha, sep = "") + } + return(rval) + } + ### PH: END palette function for heatmap scale + + ### PH: START SET up heatmap function for do.call + ## Stratagy is to use Pheatmap to create heatmap then output as Complex Heatmap to add Annotations + + ## Begin doheatmap() function: + doheatmap <- function(dat, clus, clus2, ht, rn, cn, col, dispnum) { + col.pal <- np[[col]] + # 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) { + breaks <- seq(minx, maxx, length = 100) + legbreaks <- seq(minx, maxx, length = 5) + } else { + breaks <- seq(set_min_heatmap_color, set_max_heatmap_color, length = 100) + legbreaks <- seq(set_min_heatmap_color, set_max_heatmap_color, length = 5) + } + 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) + + if (FALSE) { + sort_hclust <- function(...) { + return(stats::as.hclust(rev( + dendsort::dendsort(stats::as.dendrogram(...)) + ))) + } + } else { + sort_hclust <- function(...) { + return(stats::as.hclust(dendsort::dendsort(stats::as.dendrogram(...)))) + } + } + # if (clus) { + # colclus <- sort_hclust(hc) + # } else { + # colclus <- FALSE + # } + if (clus2) { + rowclus <- sort_hclust(hcrow) + } else { + rowclus <- FALSE + } + if (display_smpl_dendrograms) { + smpl_treeheight <- 25 + } else { + smpl_treeheight <- 0 + } + if (display_gene_dendrograms) { + gene_treeheight <- 25 + } else { + gene_treeheight <- 0 + } + hm.parameters <- list( + dat, + color = col.pal, + legend_breaks = legbreaks, + legend = TRUE, + scale = "none", + treeheight_col = smpl_treeheight, + treeheight_row = gene_treeheight, + kmeans_k = NA, + breaks = breaks, + display_numbers = dispnum, + number_color = "black", + fontsize_number = 8, + cellwidth = NA, + cellheight = NA, + fontsize = legend_font_size, + fontsize_row = gene_name_font_size, + fontsize_col = sample_name_font_size, + show_rownames = rn, + show_colnames = cn, + cluster_rows = rowclus, + cluster_cols = clus, + clustering_distance_rows = drows1, + clustering_distance_cols = dcols1, + 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 + return(do.call( + ComplexHeatmap::pheatmap, + c( + hm.parameters, + list(clustering_callback = callback) + ) + )) + } + # End doheatmap() function. + + ## --------------- ## + ## Main Code Block ## + ## --------------- ## + + ### PH: START Build different color spectra options for heatmap: + np0 <- pal(100) + np1 <- colorspace::diverge_hcl(100, c = 100, l = c(30, 80), power = 1) # Blue to Red + np2 <- colorspace::heat_hcl( + 100, + c = c(80, 30), + l = c(30, 90), + power = c(1 / 5, 2) + ) # Red to Vanilla + np3 <- rev(colorspace::heat_hcl( + 100, + h = c(0, -100), + c = c(40, 80), + l = c(75, 40), + power = 1 + )) # Violet to Pink + np4 <- rev(grDevices::colorRampPalette(RColorBrewer::brewer.pal( + 10, + "RdYlBu" + ))(100)) # Red to yellow to blue + np5 <- grDevices::colorRampPalette(c("steelblue", "white", "red"))(100) # Steelblue to White to Red + + ## Gather list of color spectra and give them names for the GUI to show. + np <- list(np0, np1, np2, np3, np4, np5) + names(np) <- c( + "Default", + "Blue to Red", + "Red to Vanilla", + "Violet to Pink", + "Bu Yl Rd", + "Bu Wt Rd" + ) + + ### PH: END Build different color spectra options for heatmap: + + ### PH: START Build Counts Table for HM + + ############## + ### Select Samples + ############## + + ## Parse input counts matrix. Subset by samples. + df1 <- counts_dat + # Swap out Gene Name column name, if it's not 'Gene'. + # TODO: refactor to avoid renaming gene column + if (feature_id_colname != "Gene") { + # Drop original Gene column + df1 <- df1[, !(colnames(df1) %in% c("Gene"))] + # Rename column to Gene + colnames(df1)[which(colnames(df1) == feature_id_colname)] <- "Gene" + } + # Build new counts matrix containing only sample subset chosen by user. + df.orig <- df1 + df <- df.orig |> + dplyr::group_by(Gene) |> + dplyr::summarise_all(mean) + df.mat <- df[, (colnames(df) != "Gene")] |> as.data.frame() + # df |> dplyr::mutate(Gene = stringr::str_replace_all(Gene, "_", " ")) -> df + row.names(df.mat) <- df$Gene + rownames(df.mat) <- stringr::str_wrap(rownames(df.mat), 30) # for really long geneset names + df.mat <- as.data.frame(df.mat) + + ############## + ## Subset counts matrix by genes. + ############## + + # Toggle to include all genes in counts matrix (in addition to any user-submitted gene list). + if (include_all_genes == FALSE) { + # Add user-submitted gene list (optional). + genes_to_include_parsed <- c() + genes_to_include_parsed <- strsplit( + specific_genes_to_include_in_heatmap, + " " + )[[1]] + # genes_to_include_parsed = gsub("_"," ",genes_to_include_parsed) + df.final.extra.genes <- df.mat[genes_to_include_parsed, ] + + # filter all genes by variance + user-submitted gene list + if (filter_top_genes_by_variance == TRUE) { + df.final <- as.matrix(df.mat) + var <- matrixStats::rowVars(df.final) + df <- as.data.frame(df.final) + rownames(df) <- rownames(df.final) + df.final <- df + df.final$var <- var + df.final <- df.final |> + tibble::rownames_to_column("Gene") + df.final <- df.final |> + dplyr::arrange(dplyr::desc(var)) + df.final.extra.genes <- dplyr::filter( + df.final, + Gene %in% genes_to_include_parsed + ) + df.final <- df.final[1:top_genes_by_variance_to_include, ] + df.final <- df.final[stats::complete.cases(df.final), ] + # Rbind user gene list to variance-filtered gene list and deduplicate. + df.final <- rbind(df.final, df.final.extra.genes) + df.final <- df.final[!duplicated(df.final), ] + rownames(df.final) <- df.final$Gene + df.final$Gene <- NULL + df.final$var <- NULL + } else { + # filter ONLY user-provided gene list. + df.final <- df.final.extra.genes + df.final <- df.final[!duplicated(df.final), ] + # Order genes in heatmap by user-submitted order of gene names. + df.final <- df.final[genes_to_include_parsed, ] + # df.final$Gene <- NULL + } + } else { + df.final <- df.mat + df.final$Gene <- NULL + } + + ############## + ## Center and Rescale Counts + ############## + ## Optionally apply centering and rescaling (default TRUE). + if (center_and_rescale_expression == TRUE) { + tmean.scale <- t(scale(t(df.final))) + tmean.scale <- tmean.scale[!is.infinite(rowSums(tmean.scale)), ] + tmean.scale <- stats::na.omit(tmean.scale) + } else { + tmean.scale <- df.final + } + + ############## + ## Order rows by Gene Expression + ############## + if (order_by_gene_expression == TRUE) { + gene_to_order_columns <- gsub(" ", "", gene_to_order_columns) + if (gene_expression_order == "low_to_high") { + tmean.scale <- tmean.scale[, order(tmean.scale[gene_to_order_columns, ])] # order from low to high + } else { + tmean.scale <- tmean.scale[, order(-tmean.scale[gene_to_order_columns, ])] # order from high to low + } + } + + df.final <- as.data.frame(tmean.scale) + ### PH: END Build Counts Table for HM + + ### PH: START Build Annotation Columns + + ## Parse input sample metadata and add annotation tracks to top of heatmap. + annot <- sample_metadata + # Filter to only samples user requests. + annot <- annot |> + dplyr::filter(.data[[sample_id_colname]] %in% samples_to_include) + + # Arrange sample options. + if (arrange_sample_columns) { + annot <- annot[match(samples_to_include, annot[[sample_id_colname]]), ] + for (x in group_columns) { + annot[, x] <- factor(annot[, x], levels = unique(annot[, x])) + } + annot <- annot |> + dplyr::arrange( + dplyr::across(tidyselect::all_of(group_columns)), + .by_group = TRUE + ) + df.final <- df.final[, match( + annot[[sample_id_colname]], + colnames(df.final) + )] + } + + # Build subsetted sample metadata table to use for figure. + + annotation_col <- annot |> dplyr::select(tidyselect::all_of(group_columns)) + 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) + } + 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 + } + + if (assign_group_colors == TRUE) { + colassign <- assign_color_to_sample_groups + groupname <- c() + groupcol <- c() + for (i in seq_along(colassign)) { + groupname[i] <- strsplit(colassign[i], ": ?")[[1]][1] + groupcol[i] <- strsplit(colassign[i], ": ?")[[1]][2] + } + annot_col[[1]][groupname] <- groupcol + } + ### PH: End Build Annotation Columns + + old <- annot[[sample_id_colname]] + new <- annot[[label_colname]] + names(old) <- new + df.final <- dplyr::rename(df.final, tidyselect::any_of(old)) + labels_col <- colnames(df.final) + + ## Print number of genes to log. + message(paste0("The total number of genes in heatmap: ", nrow(df.final))) + + ## PH: Make the heatmap. + p <- doheatmap( + dat = as.matrix(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 + ) + p@matrix_color_mapping@name <- " " + p@matrix_legend_param$at <- as.numeric(formatC(p@matrix_legend_param$at, 2)) + p@column_title_param$gp$fontsize <- 10 + # print(p) + + ## PH: Output heatmap counts table. + ## If user sets toggle to TRUE, return Z-scores. + ## Else return input counts matrix by default (toggle FALSE). + ## Returned matrix includes only genes & samples used in heatmap. + # if (return_z_scores) { + # df.new <- data.frame(tmean.scale) # Convert to Z-scores. + # df.new |> tibble::rownames_to_column("Gene") -> df.new + # return(df.new) + # } else { + # df.final |> tibble::rownames_to_column("Gene") -> df.new + # return(df.new) + # } + + print_or_save_plot( + p, + filename = file.path(plots_subdir, plot_filename), + print_plots = print_plots, + save_plots = save_plots + ) + + return(p) +} diff --git a/code/MOSuite/R/plot_histogram.R b/code/MOSuite/R/plot_histogram.R new file mode 100644 index 0000000..8dd3087 --- /dev/null +++ b/code/MOSuite/R/plot_histogram.R @@ -0,0 +1,277 @@ +#' Plot histogram +#' +#' @param moo_counts counts dataframe or `multiOmicDataSet` containing `count_type` & `sub_count_type` in the counts +#' slot +#' @param ... arguments forwarded to method +#' +#' @returns ggplot object +#' @export +#' +#' @examples +#' # plot histogram for a counts slot in a multiOmicDataset Object +#' moo <- multiOmicDataSet( +#' sample_metadata = nidap_sample_metadata, +#' anno_dat = data.frame(), +#' counts_lst = list("raw" = nidap_raw_counts) +#' ) +#' p <- plot_histogram(moo, count_type = "raw") +#' +#' # customize the plot +#' plot_histogram(moo, +#' count_type = "raw", +#' group_colname = "Group", color_by_group = TRUE +#' ) +#' +#' # plot histogram for a counts dataframe directly +#' counts_dat <- moo@counts$raw +#' plot_histogram( +#' counts_dat, +#' sample_metadata = nidap_sample_metadata, +#' sample_id_colname = "Sample", +#' feature_id_colname = "GeneName", +#' label_colname = "Label" +#' ) +#' +#' @seealso +#' - [plot_histogram.multiOmicDataSet()] +#' - [plot_histogram.data.frame()] +#' +#' @family plotters +#' @keywords plotters +#' @family moo methods +plot_histogram <- S7::new_generic( + "plot_histogram", + dispatch_args = "moo_counts" +) + +#' Plot histogram for multiOmicDataSet +#' +#' @rdname plot_histogram.multiOmicDataSet +#' @aliases plot_histogram.multiOmicDataSet +#' @usage NULL +#' +#' @param count_type Required if `moo_counts` is a `multiOmicDataSet`: the type of counts to use -- must be a name in +#' 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 +#' @examples +#' # plot histogram for a counts slot in a multiOmicDataset Object +#' moo <- multiOmicDataSet( +#' sample_metadata = nidap_sample_metadata, +#' anno_dat = data.frame(), +#' counts_lst = list("raw" = nidap_raw_counts) +#' ) +#' p <- plot_histogram(moo, count_type = "raw") +#' +#' # customize the plot +#' plot_histogram(moo, +#' count_type = "raw", +#' group_colname = "Group", color_by_group = TRUE +#' ) +#' +#' @seealso [plot_histogram()] generic +#' @family plotters for multiOmicDataSets +S7::method(plot_histogram, multiOmicDataSet) <- function( + moo_counts, + count_type, + sub_count_type = NULL, + ... +) { + counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) + return(plot_histogram( + counts_dat, + sample_metadata = moo_counts@sample_meta, + ... + )) +} + +#' Plot histogram for counts dataframe +#' +#' @rdname plot_histogram.data.frame +#' @aliases plot_histogram.data.frame +#' @usage NULL +#' +#' @param sample_metadata sample metadata as a data frame or tibble (**required**) +#' @param 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: `NULL` - first +#' column in the sample metadata will be used.) +#' @param feature_id_colname The column from the counts dataa 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: `NULL` - first column in the counts matrix will be +#' used.) +#' @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 color_values vector of colors as hex values or names recognized by R +#' @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`) +#' @param minimum_for_x_axis value to override default `min` for `ggplot2::xlim()` +#' @param maximum_for_x_axis value to override default `max` for `ggplot2::xlim()` +#' @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 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 ... additional arguments (ignored; accepted for compatibility with the moo dispatch) +#' @examples +#' +#' # plot histogram for a counts dataframe directly +#' plot_histogram( +#' nidap_clean_raw_counts, +#' sample_metadata = nidap_sample_metadata, +#' sample_id_colname = "Sample", +#' feature_id_colname = "Gene", +#' label_colname = "Label" +#' ) +#' +#' # customize the plot +#' plot_histogram( +#' nidap_clean_raw_counts, +#' sample_metadata = nidap_sample_metadata, +#' sample_id_colname = "Sample", +#' feature_id_colname = "Gene", +#' group_colname = "Group", +#' color_by_group = TRUE +#' ) +#' +#' @seealso [plot_histogram()] generic +#' +#' @family plotters for counts dataframes +S7::method(plot_histogram, S7::class_data.frame) <- function( + moo_counts, + sample_metadata, + sample_id_colname = NULL, + 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_by_group = FALSE, + set_min_max_for_x_axis = FALSE, + minimum_for_x_axis = -1, + maximum_for_x_axis = 1, + x_axis_label = "Counts", + y_axis_label = "Density", + legend_position = "top", + legend_font_size = 10, + number_of_legend_columns = 6, + interactive_plots = FALSE, + ... +) { + count <- NULL + counts_dat <- moo_counts + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(counts_dat)[1] + } + + df_long <- counts_dat |> + tidyr::pivot_longer( + -tidyselect::all_of(feature_id_colname), + names_to = sample_id_colname, + values_to = "count" + ) |> + dplyr::left_join(sample_metadata, by = sample_id_colname) + + if (set_min_max_for_x_axis == TRUE) { + 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)) + } + + if (color_by_group == TRUE) { + 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() + + # plot Density + hist_plot <- df_long |> + ggplot2::ggplot(ggplot2::aes( + x = count, + group = !!rlang::sym(sample_id_colname) + )) + + ggplot2::geom_density( + ggplot2::aes(colour = !!rlang::sym(group_colname)), + linewidth = 1 + ) + } else { + n <- df_long |> + dplyr::pull(sample_id_colname) |> + unique() |> + length() + + 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 + ) + } + + hist_plot <- hist_plot + + ggplot2::xlab(x_axis_label) + + ggplot2::ylab(y_axis_label) + + ggplot2::theme_bw() + + ggplot2::theme( + legend.position = legend_position, + legend.text = ggplot2::element_text(size = legend_font_size), + legend.title = ggplot2::element_blank(), + panel.background = ggplot2::element_blank(), + axis.text = ggplot2::element_text(size = 18), + axis.title = ggplot2::element_text(size = 20), + panel.border = ggplot2::element_rect( + colour = "black", + fill = NA, + linewidth = 0 + ), + axis.line = ggplot2::element_line(linewidth = .5), + axis.ticks = ggplot2::element_line(linewidth = 1) + ) + + ggplot2::ggtitle("Frequency Histogram") + + ggplot2::xlim(xmin, xmax) + + # 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) + ) + + if (isTRUE(interactive_plots)) { + hist_plot <- (hist_plot + ggplot2::theme(legend.position = "none")) |> + plotly::ggplotly(tooltip = c(sample_id_colname)) + } + return(hist_plot) +} diff --git a/code/MOSuite/R/plot_pca.R b/code/MOSuite/R/plot_pca.R new file mode 100644 index 0000000..d419b80 --- /dev/null +++ b/code/MOSuite/R/plot_pca.R @@ -0,0 +1,718 @@ +#' Perform and plot a Principal Components Analysis +#' +#' @param moo_counts counts dataframe or `multiOmicDataSet` containing `count_type` & `sub_count_type` in the counts +#' slot +#' @param principal_components vector with numbered principal components to plot. Use 2 for a 2D pca with ggplot, or 3 +#' for a 3D pca with plotly. (Default: `c(1,2)`) +#' @param ... additional arguments forwarded to method (see Details below) +#' +#' @examples +#' # multiOmicDataSet +#' moo <- multiOmicDataSet( +#' sample_metadata = nidap_sample_metadata, +#' anno_dat = data.frame(), +#' counts_lst = list( +#' "raw" = nidap_raw_counts, +#' "clean" = nidap_clean_raw_counts +#' ) +#' ) +#' plot_pca(moo, count_type = "clean", principal_components = c(1, 2)) +#' +#' # 3D +#' plot_pca(moo, count_type = "clean", principal_components = c(1, 2, 3)) +#' +#' # dataframe +#' plot_pca(nidap_clean_raw_counts, +#' sample_metadata = nidap_sample_metadata, +#' principal_components = c(1, 2) +#' ) +#' +#' @details +#' +#' See the low-level function docs for additional arguments +#' depending on whether you're plotting 2 or 3 PCs: +#' +#' - [plot_pca_2d()] - used when there are **2** principal components +#' - [plot_pca_3d()] - used when there are **3** principal components +#' +#' @seealso +#' - [plot_pca.multiOmicDataSet()] +#' - [plot_pca.data.frame()] +#' +#' @export +#' @return PCA plot (2D or 3D depending on the number of `principal_components`) +#' +#' @family plotters +#' @family PCA functions +#' @keywords plotters +#' @family moo methods +plot_pca <- S7::new_generic( + "plot_pca", + "moo_counts", + function(moo_counts, principal_components = c(1, 2), ...) { + return(S7::S7_dispatch()) + } +) + +#' Plot 2D or 3D PCA for multiOmicDataset +#' +#' @rdname plot_pca.multiOmicDataSet +#' @aliases plot_pca.multiOmicDataSet +#' @usage NULL +#' +#' @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]])`. +#' +#' @returns PCA plot +#' +#' @seealso [plot_pca()] generic +#' @family plotters for multiOmicDataSets +S7::method(plot_pca, multiOmicDataSet) <- function( + moo_counts, + count_type, + sub_count_type = NULL, + principal_components = c(1, 2), + ... +) { + counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) + return( + plot_pca( + counts_dat, + sample_metadata = moo_counts@sample_meta, + principal_components = principal_components, + ... + ) + ) +} + +#' Plot 2D or 3D PCA for counts dataframe +#' +#' @rdname plot_pca.data.frame +#' @aliases plot_pca.data.frame +#' @usage NULL +#' +#' @param sample_metadata **Required** if `moo_counts` is a `data.frame`: sample metadata as a data frame or tibble. +#' +#' @seealso [plot_pca()] generic +#' @family plotters for counts dataframes +S7::method(plot_pca, S7::class_data.frame) <- function( + moo_counts, + sample_metadata, + principal_components = c(1, 2), + ... +) { + len_pcs <- length(principal_components) + if (len_pcs == 2) { + plot_fun <- plot_pca_2d + } else if (len_pcs == 3) { + plot_fun <- plot_pca_3d + } else { + stop(glue::glue( + "Principal components must have exactly 2 or 3 items. Length: {len_pcs}" + )) + } + return( + plot_fun( + moo_counts, + sample_metadata = sample_metadata, + principal_components = principal_components, + ... + ) + ) +} + +#' Perform and plot a 2D Principal Components Analysis +#' +#' @rdname plot_pca_2d +#' @aliases plot_pca_2d +#' @export +plot_pca_2d <- S7::new_generic( + "plot_pca_2d", + "moo_counts", + function( + moo_counts, + 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 = c( + "#5954d6", + "#e1562c", + "#b80058", + "#00c6f8", + "#d163e6", + "#00a76c", + "#ff9287", + "#008cf9", + "#006e00", + "#796880", + "#FFA500", + "#878500" + ), + principal_components = c(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 = options::opt("print_plots"), + save_plots = options::opt("save_plots") + ) { + return(S7::S7_dispatch()) + } +) + +#' @rdname plot_pca_2d +S7::method(plot_pca_2d, multiOmicDataSet) <- function( + moo_counts, + 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 = c( + "#5954d6", + "#e1562c", + "#b80058", + "#00c6f8", + "#d163e6", + "#00a76c", + "#ff9287", + "#008cf9", + "#006e00", + "#796880", + "#FFA500", + "#878500" + ), + principal_components = c(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 = options::opt("print_plots"), + save_plots = options::opt("save_plots") +) { + counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) + return(plot_pca_2d( + counts_dat, + sample_metadata = moo_counts@sample_meta, + sample_id_colname = sample_id_colname, + feature_id_colname = feature_id_colname, + group_colname = group_colname, + label_colname = label_colname, + samples_to_rename = samples_to_rename, + color_values = color_values, + principal_components = principal_components, + legend_position = legend_position, + point_size = point_size, + add_label = add_label, + label_font_size = label_font_size, + label_offset_x_ = label_offset_x_, + label_offset_y_ = label_offset_y_, + interactive_plots = interactive_plots, + plots_subdir = plots_subdir, + plot_filename = plot_filename, + print_plots = print_plots, + save_plots = save_plots + )) +} + +#' Perform and plot a 2D Principal Components Analysis +#' +#' @inheritParams create_multiOmicDataSet_from_dataframes +#' @inheritParams plot_histogram +#' @inheritParams plot_expr_heatmap +#' @inheritParams filter_counts +#' +#' @param sample_metadata sample metadata as a data frame or tibble. +#' @param 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: `NULL` - first +#' column in the sample metadata will be used.) +#' @param feature_id_colname The column from the counts dataa 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: `NULL` - first column in the counts matrix will be +#' used.) +#' @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 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 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 +#' +#' @return ggplot object +#' +#' @seealso [plot_pca()] generic +#' @family PCA functions +#' +#' @rdname plot_pca_2d +S7::method(plot_pca_2d, S7::class_data.frame) <- function( + moo_counts, + 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 = c( + "#5954d6", + "#e1562c", + "#b80058", + "#00c6f8", + "#d163e6", + "#00a76c", + "#ff9287", + "#008cf9", + "#006e00", + "#796880", + "#FFA500", + "#878500" + ), + principal_components = c(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 = options::opt("print_plots"), + save_plots = options::opt("save_plots") +) { + PC <- std.dev <- percent <- cumulative <- NULL + if (length(principal_components) != 2) { + stop( + glue::glue( + "principal_components must contain 2 values: {principal_components}" + ) + ) + } + + 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] + } + + # calculate PCA + pca_df <- calc_pca( + counts_dat = moo_counts, + sample_metadata = sample_metadata, + sample_id_colname = sample_id_colname, + feature_id_colname = feature_id_colname + ) |> + dplyr::filter(PC %in% principal_components) |> + # TODO consider redesigning to make rename_samples() unnecessary. Use Label column instead? + rename_samples(samples_to_rename_manually = samples_to_rename) + + pca_wide <- pca_df |> + dplyr::select(-c(std.dev, percent, cumulative)) |> + tidyr::pivot_wider( + names_from = "PC", + names_prefix = "PC", + values_from = "value" + ) + prin_comp_x <- principal_components[1] + prin_comp_y <- principal_components[2] + # plot PCA + pca_plot <- pca_wide |> + dplyr::mutate( + !!rlang::sym(group_colname) := as.character(!!rlang::sym(group_colname)) + ) |> + 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) + )) + + ggplot2::geom_point( + ggplot2::aes(color = !!rlang::sym(group_colname)), + size = point_size + ) + + ggplot2::theme_bw() + + ggplot2::theme( + legend.position = legend_position, + legend.title = ggplot2::element_blank(), + panel.grid.major = ggplot2::element_blank(), + panel.grid.minor = ggplot2::element_blank(), + panel.background = ggplot2::element_blank(), + axis.text = ggplot2::element_text(size = 18), + axis.title = ggplot2::element_text(size = 20), + panel.border = ggplot2::element_rect( + colour = "black", + fill = NA, + linewidth = 1 + ), + axis.ticks = ggplot2::element_line(linewidth = 1), + legend.text = ggplot2::element_text(size = 18) + ) + + 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) { + abort_packages_not_installed("ggrepel") + pca_plot <- pca_plot + + ggrepel::geom_text_repel( + ggplot2::aes( + label = !!rlang::sym(label_colname), + color = !!rlang::sym(group_colname) + ), + size = 7, + show.legend = FALSE, + direction = c("both"), + box.padding = 1.25 + ) + } + if (isTRUE(interactive_plots)) { + pca_plot <- (pca_plot) |> + plotly::ggplotly(tooltip = c(sample_id_colname, group_colname)) + } + + print_or_save_plot( + pca_plot, + filename = file.path(plots_subdir, plot_filename), + print_plots = print_plots, + save_plots = save_plots + ) + + return(pca_plot) +} + +#' Perform and plot a 3D Principal Components Analysis +#' +#' @rdname plot_pca_3d +#' @aliases plot_pca_3d +#' @export +plot_pca_3d <- S7::new_generic( + "plot_pca_3d", + "moo_counts", + function( + moo_counts, + 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 = 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" + ), + plot_title = "PCA 3D", + plot_filename = "pca_3D.html", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "pca" + ) { + return(S7::S7_dispatch()) + } +) + +#' @rdname plot_pca_3d +S7::method(plot_pca_3d, multiOmicDataSet) <- function( + moo_counts, + 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 = 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" + ), + plot_title = "PCA 3D", + plot_filename = "pca_3D.html", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "pca" +) { + counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) + return( + plot_pca_3d( + counts_dat, + sample_metadata = moo_counts@sample_meta, + count_type = count_type, + sub_count_type = sub_count_type, + feature_id_colname = feature_id_colname, + sample_id_colname = sample_id_colname, + samples_to_rename = samples_to_rename, + group_colname = group_colname, + label_colname = label_colname, + principal_components = principal_components, + point_size = point_size, + label_font_size = label_font_size, + color_values = color_values, + plot_title = plot_title, + plot_filename = plot_filename, + print_plots = print_plots, + save_plots = save_plots, + plots_subdir = plots_subdir + ) + ) +} + +#' 3D PCA for counts dataframe +#' +#' @param moo_counts counts dataframe +#' @param count_type the type of counts to use. Ignored when `moo_counts` is already a dataframe. +#' @param sub_count_type used if `count_type` is a list in the counts slot: specify the sub count type within the list. +#' @param sample_metadata sample metadata as a data frame or tibble. +#' @param feature_id_colname The column from the counts data containing feature IDs. If `NULL`, first column is used. +#' @param sample_id_colname The column from sample metadata containing sample names. If `NULL`, first column is used. +#' @param samples_to_rename optional named mapping in `old_name: new_name` format for display labels. +#' @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 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. +#' @param plots_subdir output subdirectory for saved plots. +#' +#' @param principal_components vector with numbered principal components to plot +#' @param point_size size for `ggplot2::geom_point()` +#' @param plot_title title for the plot +#' +#' @returns `plotly::plot_ly` figure +#' +#' @family PCA functions +#' +#' @rdname plot_pca_3d +S7::method(plot_pca_3d, S7::class_data.frame) <- function( + moo_counts, + 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 = 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" + ), + plot_title = "PCA 3D", + plot_filename = "pca_3D.html", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "pca" +) { + PC <- std.dev <- percent <- cumulative <- NULL + if (length(principal_components) != 3) { + stop( + glue::glue( + "principal_components must contain 3 values: {principal_components}" + ) + ) + } + + if (is.null(sample_metadata)) { + stop("sample_metadata cannot be NULL") + } + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } + + # if (is.null(color_values)) { + # color_values <- moo_nidap@analyses[['colors']][['Group']] + # } + + # calculate PCA + pca_df <- calc_pca( + counts_dat = moo_counts, + sample_metadata = sample_metadata, + sample_id_colname = sample_id_colname, + feature_id_colname = feature_id_colname + ) |> + dplyr::filter(PC %in% principal_components) + pca_wide <- pca_df |> + dplyr::select(-c(std.dev, percent, cumulative)) |> + tidyr::pivot_wider( + names_from = "PC", + names_prefix = "PC", + values_from = "value" + ) + prin_comp_x <- principal_components[1] + prin_comp_y <- principal_components[2] + prin_comp_z <- principal_components[3] + + fig <- plotly::plot_ly( + pca_wide, + x = stats::as.formula(paste0("~ PC", prin_comp_x)), + y = stats::as.formula(paste0("~ PC", prin_comp_y)), + z = stats::as.formula(paste0("~ PC", prin_comp_z)), + color = stats::as.formula(paste("~", group_colname)), + colors = color_values, + type = "scatter3d", + mode = "markers", + marker = list(size = point_size), + hoverinfo = "text", + text = stats::as.formula(paste("~", sample_id_colname)), + size = label_font_size + ) + + print_or_save_plot( + fig, + filename = file.path(plots_subdir, plot_filename), + print_plots = print_plots, + save_plots = save_plots + ) + + return(fig) +} + +#' Get label for Principal Component with percent of variation +#' +#' @param pca_df data frame from `calc_pca()` +#' @param pc which principal component to report (e.g. `1`) +#' +#' @returns glue string formatted with PC's percent of variation +#' @keywords internal +#' @examples +#' \dontrun{ +#' data.frame(PC = c(1, 2, 3), percent = c(40, 10, 0.5)) |> +#' get_pc_percent_lab(2) +#' } +get_pc_percent_lab <- function(pca_df, pc) { + PC <- percent <- NULL + perc <- pca_df |> + dplyr::filter(PC == pc) |> + dplyr::pull(percent) |> + unique() |> + round(digits = 1) + return(glue::glue("PC{pc} {perc}%")) +} + +#' Perform principal components analysis +#' +#' @param counts_dat data frame of feature counts (e.g. from the counts slot of a `multiOmicDataSet`). +#' @param sample_metadata sample metadata as a data frame or tibble. +#' @param 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: `NULL` - first +#' column in the sample metadata will be used.) +#' @param feature_id_colname The column from the counts dataa 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: `NULL` - first column in the counts matrix will be +#' used.) +#' +#' @returns data frame with statistics for each principal component +#' @export +#' +#' @examples +#' calc_pca(nidap_raw_counts, nidap_sample_metadata) |> head() +#' @family PCA functions +calc_pca <- function( + counts_dat, + sample_metadata, + sample_id_colname = NULL, + feature_id_colname = NULL +) { + var <- row <- percent <- NULL + if (is.null(sample_id_colname)) { + sample_id_colname <- colnames(sample_metadata)[1] + } + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(counts_dat)[1] + } + counts_dat <- counts_dat |> + as.data.frame() |> + tibble::remove_rownames() |> + tibble::column_to_rownames(feature_id_colname) + # sample-wise PCA + tedf <- t(counts_dat) + # remove samples with all NAs + tedf_filt <- tedf[, colSums(is.na(tedf)) != nrow(tedf)] + # remove samples with zero variance + tedf_var <- tedf_filt[, apply(tedf_filt, 2, var) != 0] + # calculate PCA + pca_fit <- stats::prcomp(tedf_var, scale = TRUE) + pca_df <- pca_fit |> + broom::tidy() |> + dplyr::rename(!!rlang::sym(sample_id_colname) := row) |> + dplyr::left_join( + pca_fit |> + broom::tidy(matrix = "eigenvalues") |> + dplyr::mutate(percent = percent * 100), + by = "PC" + ) |> + dplyr::left_join(sample_metadata, by = sample_id_colname) + return(pca_df) +} diff --git a/code/MOSuite/R/plot_read_depth.R b/code/MOSuite/R/plot_read_depth.R new file mode 100644 index 0000000..f78d073 --- /dev/null +++ b/code/MOSuite/R/plot_read_depth.R @@ -0,0 +1,138 @@ +#' Plot read depth as a bar plot +#' +#' The first argument can be a `multiOmicDataset` object (`moo`) or a `data.frame` containing counts. +#' For a `moo`, choose which counts slot to use with `count_type` & (optionally) `sub_count_type`. +#' +#' @param moo_counts counts dataframe or `multiOmicDataSet` containing `count_type` & `sub_count_type` in the counts +#' slot +#' @param ... arguments forwarded to method +#' +#' @return ggplot barplot +#' +#' @export +#' @examples +#' # multiOmicDataSet +#' moo <- multiOmicDataSet( +#' sample_metadata = nidap_sample_metadata, +#' anno_dat = data.frame(), +#' counts_lst = list( +#' "raw" = nidap_raw_counts, +#' "clean" = nidap_clean_raw_counts +#' ) +#' ) +#' +#' plot_read_depth(moo, count_type = "clean") +#' +#' # dataframe +#' plot_read_depth(nidap_clean_raw_counts) +#' +#' @details +#' +#' # Methods +#' +#' | link to docs | class | +#' |---|---| +#' | [plot_read_depth()] | `multiOmicDataSet` | +#' | [plot_read_depth()] | `data.frame` | +#' +#' @seealso +#' - [plot_read_depth.multiOmicDataSet()] +#' - [plot_read_depth.data.frame()] +#' +#' @family plotters +#' @keywords plotters +#' @family moo methods +plot_read_depth <- S7::new_generic( + "plot_read_depth", + dispatch_args = "moo_counts" +) + +#' Plot read depth for multiOmicDataSet +#' +#' @rdname plot_read_depth.multiOmicDataSet +#' @aliases plot_read_depth.multiOmicDataSet +#' @usage NULL +#' +#' @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]])`. +#' +#' @return ggplot barplot +#' +#' @examples +#' # multiOmicDataSet +#' moo <- multiOmicDataSet( +#' sample_metadata = nidap_sample_metadata, +#' anno_dat = data.frame(), +#' counts_lst = list( +#' "raw" = nidap_raw_counts, +#' "clean" = nidap_clean_raw_counts +#' ) +#' ) +#' +#' plot_read_depth(moo, count_type = "clean") +#' +#' @seealso [plot_read_depth()] generic +#' @family plotters for multiOmicDataSets +S7::method(plot_read_depth, multiOmicDataSet) <- function( + moo_counts, + count_type, + sub_count_type = NULL, + ... +) { + counts_dat <- extract_counts(moo_counts, count_type, sub_count_type) + return(plot_read_depth(counts_dat, ...)) +} + +#' Plot read depth for `data.frame` +#' +#' @rdname plot_read_depth.data.frame +#' @aliases plot_read_depth.data.frame +#' @usage NULL +#' +#' @param ... additional arguments (ignored; accepted for compatibility with the moo dispatch) +#' +#' @return ggplot barplot +#' +#' @examples +#' # dataframe +#' plot_read_depth(nidap_clean_raw_counts) +#' +#' @seealso [plot_read_depth()] generic +#' @family plotters for counts dataframes +S7::method(plot_read_depth, S7::class_data.frame) <- function(moo_counts, ...) { + sample_names <- column_sums <- NULL + counts_dat <- moo_counts + sum_df <- counts_dat |> + dplyr::summarize(dplyr::across(tidyselect::where(is.numeric), sum)) |> + tidyr::pivot_longer( + dplyr::everything(), + names_to = "sample_names", + values_to = "column_sums" + ) + + # Plotting + read_plot <- ggplot2::ggplot( + sum_df, + ggplot2::aes(x = sample_names, y = column_sums) + ) + + ggplot2::geom_bar(stat = "identity", fill = "blue") + + ggplot2::labs( + title = "Total Reads per Sample", + x = "Samples", + y = "Read Count" + ) + + ggplot2::scale_y_continuous(labels = scales::label_comma()) + + ggplot2::theme_minimal() + + ggplot2::theme( + axis.text.x = ggplot2::element_text( + angle = 45, + hjust = 1, + size = 14 + ), + axis.text.y = ggplot2::element_text(size = 14), + axis.title = ggplot2::element_text(size = 16), + plot.title = ggplot2::element_text(size = 20) + ) + return(read_plot) +} diff --git a/code/MOSuite/R/plot_venn_diagram.R b/code/MOSuite/R/plot_venn_diagram.R new file mode 100644 index 0000000..3a176fe --- /dev/null +++ b/code/MOSuite/R/plot_venn_diagram.R @@ -0,0 +1,572 @@ +#' Plot a venn diagram, UpSet plot, or table of intersections +#' +#' Generates Venn diagram of intersections across a series of sets (e.g., intersections of significant genes across +#' tested contrasts). This 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. +#' An S7 generic with methods for `multiOmicDataSet` and `data.frame`. +#' +#' @param moo_diff_summary_dat multiOmicDataSet or summarized differential expression analysis data frame. +#' +#' @export +plot_venn_diagram <- S7::new_generic( + "plot_venn_diagram", + "moo_diff_summary_dat", + function( + moo_diff_summary_dat, + feature_id_colname = NULL, + contrasts_colname = "Contrast", + select_contrasts = c(), + plot_type = "Venn diagram", + intersection_ids = c(), + venn_force_unique = TRUE, + venn_numbers_format = "raw", + venn_significant_digits = 2, + venn_fill_colors = c( + "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 = c(), + venn_category_names_position = c(), + 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 = grDevices::png, + dpi = 300, + image_width = 4000, + image_height = 3000, + plot_filename = "venn_diagram.png", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" + ) { + return(S7::S7_dispatch()) + } +) + +#' @rdname plot_venn_diagram +S7::method(plot_venn_diagram, multiOmicDataSet) <- function( + moo_diff_summary_dat, + feature_id_colname = NULL, + contrasts_colname = "Contrast", + select_contrasts = c(), + plot_type = "Venn diagram", + intersection_ids = c(), + venn_force_unique = TRUE, + venn_numbers_format = "raw", + venn_significant_digits = 2, + venn_fill_colors = c( + "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 = c(), + venn_category_names_position = c(), + 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 = grDevices::png, + dpi = 300, + image_width = 4000, + image_height = 3000, + plot_filename = "venn_diagram.png", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" +) { + return( + moo_diff_summary_dat@analyses$diff |> + join_dfs_wide() |> + plot_volcano_summary(print_plots = FALSE, save_plots = FALSE) |> + plot_venn_diagram( + feature_id_colname, + contrasts_colname, + select_contrasts, + plot_type, + intersection_ids, + venn_force_unique, + venn_numbers_format, + venn_significant_digits, + venn_fill_colors, + venn_fill_transparency, + venn_border_colors, + venn_font_size_for_category_names, + venn_category_names_distance, + venn_category_names_position, + venn_font_size_for_counts, + venn_outer_margin, + intersections_order, + display_empty_intersections, + intersection_bar_color, + intersection_point_size, + intersection_line_width, + table_font_size, + table_content, + graphics_device, + dpi, + image_width, + image_height, + plot_filename, + print_plots, + save_plots, + plots_subdir, + ) + ) +} + +#' @inheritParams option_params +#' @inheritParams filter_counts +#' @inheritParams plot_volcano_enhanced +#' @inheritParams plot_volcano_summary +#' +#' @param moo_diff_summary_dat Summarized differential expression analysis +#' @param contrasts_colname Name of the column in `moo_diff_summary_dat` that contains the contrast names (default: +#' "Contrast") +#' @param select_contrasts A vector of contrast names to select for the plot. If empty, all contrasts are used. +#' @param plot_type Type of plot to generate: "Venn diagram" or "Intersection plot". Default: "Venn diagram" +#' @param intersection_ids A vector of intersection IDs to select for the plot. If empty, all intersections are used. +#' @param venn_force_unique If TRUE, forces unique elements in the Venn diagram. Default: TRUE +#' @param venn_numbers_format Format for the numbers in the Venn diagram. Options: "raw", "percent", "raw-percent", +#' "percent-raw". Default: "raw" +#' @param venn_significant_digits Number of significant digits for the Venn diagram numbers. Default: 2 +#' @param venn_fill_colors A vector of colors to fill the Venn diagram categories. Default: c("darkgoldenrod2", +#' "darkolivegreen2", "mediumpurple3", "darkorange2", "lightgreen") +#' @param venn_fill_transparency Transparency level for the Venn diagram fill colors. Default: 0.2 +#' @param venn_border_colors Colors for the borders of the Venn diagram categories. Default: "fill colors" (uses the +#' same colors as `venn_fill_colors`) +#' @param venn_font_size_for_category_names Font size for the category names in the Venn diagram. Default: 3 +#' @param venn_category_names_distance Distance of the category names from the Venn diagram circles. Default: c() +#' @param venn_category_names_position Position of the category names in the Venn diagram. Default: c() +#' @param venn_font_size_for_counts Font size for the counts in the Venn diagram. Default: 6 +#' @param venn_outer_margin Outer margin for the Venn diagram. Default: 0 +#' @param intersections_order Order of the intersections in the plot. Default: "by size" +#' @param display_empty_intersections If TRUE, displays empty intersections in the plot. Default: FALSE +#' @param intersection_bar_color Color for the intersection bars in the plot. Default: "lightgray" +#' @param intersection_point_size Size of the points in the intersection plot. Default: 2 +#' @param intersection_line_width Width of the lines in the intersection plot. Default: 0.5 +#' @param table_font_size Font size for the table in the plot. Default: 3 +#' @param table_content Content of the table in the plot. Default: NULL +#' +#' @keywords plotters +#' +#' @examples +#' plot_venn_diagram(nidap_volcano_summary_dat, print_plots = TRUE) +#' +#' @rdname plot_venn_diagram +S7::method(plot_venn_diagram, S7::class_data.frame) <- function( + moo_diff_summary_dat, + feature_id_colname = NULL, + contrasts_colname = "Contrast", + select_contrasts = c(), + plot_type = "Venn diagram", + intersection_ids = c(), + venn_force_unique = TRUE, + venn_numbers_format = "raw", + venn_significant_digits = 2, + venn_fill_colors = c( + "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 = c(), + venn_category_names_position = c(), + 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 = grDevices::png, + dpi = 300, + image_width = 4000, + image_height = 3000, + plot_filename = "venn_diagram.png", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" +) { + Freq <- Gene <- Id <- Size <- Var1 <- NULL + abort_packages_not_installed(c( + "VennDiagram", + "gridExtra", + "patchwork", + "UpSetR" + )) + + if (nrow(moo_diff_summary_dat) == 0) { + stop("Dataframe is empty") + } + + ### PH: + # Input - DEG table from Volcano Summary, I think we need to make this function more generic. + # The input should be the Limma DEG table and maybe be used with the DEG Gene List Template + # Output - Venn Diagram Figure + Venn table + # Purpose - compare DEGS from different Comparisons + + input_dataset <- as.data.frame(moo_diff_summary_dat) + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(moo_diff_summary_dat)[1] + } + + ### PH: Create venn Table from DEG table + + # SET INPUT ==== + + # select required columns + set_elements <- input_dataset[, feature_id_colname] + set_names <- input_dataset[, contrasts_colname] + + # prepare format - R list + vlist <- split(set_elements, set_names) + if (!is.null(select_contrasts)) { + vlist <- vlist[select_contrasts] + } + num_categories <- length(vlist) + if (num_categories == 0) { + stop("Zero categories found") + } + + # generate upset object + + # modify UpSetR function (keep gene names as rownames of intersection matrix) + fromList <- function(input) { + # Same as original fromList()... + elements <- unique(unlist(input)) + data <- unlist(lapply(input, function(x) { + return(as.vector(match(elements, x))) + })) + data[is.na(data)] <- as.integer(0) + data[data != 0] <- as.integer(1) + data <- data.frame(matrix(data, ncol = length(input), byrow = FALSE)) + data <- data[which(rowSums(data) != 0), ] + names(data) <- names(input) + # ... Except now it conserves your original value names! + row.names(data) <- elements + return(data) + } + + if (num_categories > 1) { + sets <- fromList(vlist) + + if (!is.null(select_contrasts)) { + Intersection <- sets[, match(select_contrasts, colnames(sets))] + } else { + Intersection <- sets + } + + # generate intersection frequency table and gene list (all intersections for the output dataset/table not the plot) + intersection_matrix <- Intersection + Intersection <- sapply(colnames(intersection_matrix), function(x) { + return(ifelse(intersection_matrix[, x] == 1, x, "{}")) + }) + rownames(Intersection) <- rownames(sets) + Intersection <- apply(Intersection, 1, function(x) { + return(sprintf("(%s)", paste(x, collapse = " "))) + }) + tab <- table(Intersection) + tab <- tab[order(tab)] + nn <- stringr::str_count(names(tab), pattern = "\\{\\}") + tab <- tab[order(nn, decreasing = FALSE)] + names(tab) <- gsub("\\{\\} | \\{\\}|\\{\\} |\\{\\} \\{\\}", "", names(tab)) + names(tab) <- sub("\\( ", "(", names(tab)) + names(tab) <- gsub(" ", " \u2229 ", names(tab)) + 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) + Intersection <- gsub( + "\\{\\} | \\{\\}|\\{\\} |\\{\\} \\{\\}", + "", + Intersection + ) + Intersection <- sub("\\( ", "(", Intersection) + Intersection <- gsub(" ", " \u2229 ", Intersection) + 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) + } else if (num_categories == 1) { + Intersection <- data.frame( + Gene = vlist[[1]], + Intersection = sprintf("(%s)", names(vlist)), + Id = 1, + Size = length(vlist[[1]]) + ) + tab <- table(Intersection$Intersection) + tab <- data.frame(Id = 1, tab) |> + dplyr::rename(Intersection = Var1, Size = Freq) |> + dplyr::select(Intersection, Id, Size) + } + + # returned intersections + + if (!is.null(intersection_ids)) { + intersection_ids <- sort(as.numeric(intersection_ids)) + tabsel <- tab[tab$Id %in% intersection_ids, ] + Intersectionsel <- Intersection[Intersection$Id %in% intersection_ids, ] + } else { + tabsel <- tab + Intersectionsel <- Intersection + } + tab$"Return" <- ifelse( + tab$Intersection %in% tabsel$Intersection, + "Yes", + "\u2014" + ) + + if (intersections_order == "freq") { + tab <- tab |> dplyr::arrange(-Size) + tabsel <- tabsel |> dplyr::arrange(-Size) + } + + message(glue::glue("All intersections: {paste(tab, collapse=',')}")) + message(glue::glue("\nIntersections returned: {paste(tabsel, collapse=',')}")) + + ### PH: End Create venn Table from DEG table + + ### PH: START This section sets immage output parameters and includes error check + + # Logic Error Check ==== + if (num_categories == 1) { + if (plot_type == "Intersection plot") { + plot_type <- "Venn diagram" + cat( + "\nIntersection plot not available for a single contrast, the Venn diagram generated instead" + ) + } + } else if (num_categories > 5) { + plot_type <- "Intersection plot" + cat( + "\nVenn diagram available for up to 5 contrasts, the Intersection plot generated instead" + ) + } + + ### PH: End This section sets immage output parameters and includes error check + + # DO PLOT ==== + + ### PH: START Create Intersection plot + + # Intersection Plot + + if (plot_type == "Intersection plot") { + # do plot + empty <- display_empty_intersections + if (empty) { + keepEmpty <- "on" + } else { + keepEmpty <- NULL + } + + barcol <- intersection_bar_color + + pSet <- UpSetR::upset( + sets, + nsets = num_categories, + sets = select_contrasts, + order.by = intersections_order, + nintersects = NA, + text.scale = 2, + empty.intersections = keepEmpty, + matrix.color = barcol, + main.bar.color = barcol, + sets.bar.color = barcol, + point.size = intersection_point_size, + line.size = intersection_line_width + ) + + output_plot <- pSet + ### PH: End Create Intersection plot + + ### PH: START Create Venn Diagram + } else if (plot_type == "Venn diagram") { + # Venn diagram + + ## If venn fill color param empty upon template upgrade, + ## then fill it with the default colors. + if (length(venn_fill_colors) == 0) { + venn_fill_colors <- c( + "darkgoldenrod2", + "darkolivegreen2", + "mediumpurple3", + "darkorange2", + "lightgreen" + ) + } + + color_border <- venn_border_colors + if (color_border != "black") { + color_border <- venn_fill_colors[1:num_categories] + } + + print_mode <- venn_numbers_format + if (print_mode == "raw-percent") { + print_mode <- c("raw", "percent") + } else if (print_mode == "percent-raw") { + print_mode <- c("percent", "raw") + } + + distance <- venn_category_names_distance + position <- venn_category_names_position + + if (is.null(distance) && is.null(position)) { + vobj <- VennDiagram::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 + ) + } else if (!is.null(distance) && is.null(position)) { + distance <- as.numeric(distance) + + vobj <- VennDiagram::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 + ) + } else if (is.null(distance) && !is.null(position)) { + position <- as.numeric(position) + + vobj <- VennDiagram::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 + ) + } else { + distance <- as.numeric(distance) + position <- as.numeric(position) + + vobj <- VennDiagram::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 + ) + } + + pVenn <- patchwork::wrap_elements(grid::gTree(children = vobj)) + output_plot <- pVenn + + ### PH: END Create Venn Diagram + + ### PH: START Create figure from Intersect table + ## this might be a NIDAP specific function. as long as we have access to the table in the MOobject + } else { + font_size_table <- table_font_size + table_content <- table_content + if (table_content == "all intersections") { + pTab <- patchwork::wrap_elements(gridExtra::tableGrob( + tab, + rows = NULL, + theme = gridExtra::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)) + ) + )) + } else { + pTab <- patchwork::wrap_elements(gridExtra::tableGrob( + tabsel, + rows = NULL, + theme = gridExtra::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)) + ) + )) + } + output_plot <- pTab + } + + print_or_save_plot( + output_plot, + filename = file.path(plots_subdir, plot_filename), + device = graphics_device, + dpi = dpi, + width = image_width, + height = image_height, + units = "px", + print_plots = print_plots, + save_plots = save_plots + ) + ### PH: END Create figure from Intersect table + + # SAVE DATASET ==== + return(Intersectionsel) +} diff --git a/code/MOSuite/R/plot_volcano_enhanced.R b/code/MOSuite/R/plot_volcano_enhanced.R new file mode 100644 index 0000000..30e2fe8 --- /dev/null +++ b/code/MOSuite/R/plot_volcano_enhanced.R @@ -0,0 +1,469 @@ +#' Enhanced Volcano Plot +#' +#' Uses [Bioconductor's Enhanced Volcano +#' Plot](https://bioconductor.org/packages/release/bioc/html/EnhancedVolcano.html). +#' An S7 generic with methods for `multiOmicDataSet` and `data.frame`. +#' +#' @param moo_diff multiOmicDataSet or differential expression analysis result data frame. +#' +#' @export +plot_volcano_enhanced <- S7::new_generic( + "plot_volcano_enhanced", + "moo_diff", + function( + moo_diff, + feature_id_colname = NULL, + signif_colname = c("B-A_adjpval", "B-C_adjpval"), + 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, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff", + plot_filename = "volcano_enhanced.png" + ) { + return(S7::S7_dispatch()) + } +) + +#' @rdname plot_volcano_enhanced +S7::method(plot_volcano_enhanced, multiOmicDataSet) <- function( + moo_diff, + feature_id_colname = NULL, + signif_colname = c("B-A_adjpval", "B-C_adjpval"), + 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, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff", + plot_filename = "volcano_enhanced.png" +) { + return( + join_dfs_wide(moo_diff@analyses$diff) |> + plot_volcano_enhanced( + feature_id_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 + ) + ) +} + +#' @inheritParams option_params +#' @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_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 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 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 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 axis_lab_size Size of the axis labels. +#' @param point_size Size of the points in the plot. +#' @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 +#' +#' @keywords plotters volcano +#' +#' @examples +#' plot_volcano_enhanced(nidap_deg_analysis, print_plots = TRUE) +#' +#' @rdname plot_volcano_enhanced +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"), + 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, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff", + plot_filename = "volcano_enhanced.png" +) { + abort_packages_not_installed("EnhancedVolcano") + ### PH + # Input - DEG table from Limma DEG template + # Output - Volcano plot + interactive Volcano Plot + # Purpose Create detailed Volcano for each contrast individually + + diff_dat <- as.data.frame(moo_diff) + + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(diff_dat)[1] + } + label_col <- feature_id_colname + + rank <- list() + plots_list <- list() + + # user can select multiple comparisons to create volcano plots + for (i in seq_along(change_colname)) { + ### PH: START Build table for Volcano plot + + lfccol <- change_colname[i] + sigcol <- signif_colname[i] + columns_of_interest <- c(label_col, change_colname[i], signif_colname[i]) + df <- diff_dat |> + dplyr::select(tidyselect::one_of(columns_of_interest)) |> + dplyr::mutate( + !!rlang::sym(lfccol) := tidyr::replace_na(!!rlang::sym(lfccol), 0) + ) |> + dplyr::mutate( + !!rlang::sym(sigcol) := tidyr::replace_na(!!rlang::sym(sigcol), 1) + ) + # 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] + } + if (nchar(change_sig_name) == 0) { + sig_name <- signif_colname[i] + } + colnames(df) <- c(label_col, change_lfc_name, sig_name) + } else { + lfc_name <- change_colname[i] + sig_name <- signif_colname[i] + } + + ### PH: START Creating rank based on pvalue and fold change + # This is unique to this template and could be useful as a generic tool to create rankes for GSEA. Recommend + # extracting this function + group <- gsub("_pval|p_val_", "", sig_name) + rank[[i]] <- -log10(df[[sig_name]]) * sign(df[[lfc_name]]) + names(rank)[i] <- paste0("C_", group, "_rank") + ### PH: End Creating rank based on pvalue and fold change + + message(paste0("Genes in initial dataset: ", nrow(df), "\n")) + + # Select top genes by logFC or Significance + 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]]) + } + + if (is_red) { + df_sub <- df[ + df[[sigcol]] <= signif_threshold & + abs(df[[lfccol]]) >= 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 != ""] + + filter <- additional_labels %in% df[, label_col] + missing_labels <- additional_labels[!filter] + additional_labels <- additional_labels[filter] + + if (length(missing_labels) > 0) { + message(glue::glue( + ("Could not find missing labels:\t{paste(missing_labels, collapse = ', ')}") + )) + } + + if (use_only_addition_labels) { + genes_to_label <- additional_labels + } else { + genes_to_label <- unique(append(genes_to_label, additional_labels)) + } + + significant <- vector(length = nrow(df)) + significant[] <- "Not significant" + significant[which(abs(df[, 2]) > change_threshold)] <- "Fold change only" + significant[which(df[, 3] < signif_threshold)] <- "Significant only" + significant[which( + abs(df[, 2]) > change_threshold & df[, 3] < signif_threshold + )] <- "Significant and fold change" + + ### PH: END Build table for Volcano plot + + ### PH: START Create Volcano plot + + ### PH: Set Axis limits - Unique feature to this plot that should be included with any Volcano plot function + ############################## + + ## Y-axis range change: + # fix pvalue == 0 + shapeCustom <- rep(19, nrow(df)) + maxy <- max(-log10(df[[sig_name]]), na.rm = TRUE) + if (ylim > 0) { + maxy <- ylim + } + + message(paste0("Max y: ", maxy, "\n")) + if (maxy == Inf) { + # Sometimes, pvalues == 0 + keep <- df[[sig_name]] > 0 + df[[sig_name]][!keep] <- min(df[[sig_name]][keep]) + shapeCustom[!keep] <- 17 + + maxy <- -log10(min(df[[sig_name]][keep])) + message("Some p-values equal zero. Adjusting y-limits.\n") + message(paste0("Max y adjusted: ", maxy, "\n")) + } + + # By default, nothing will be greater than maxy. User can set this value lower + keep <- -log10(df[[sig_name]]) <= maxy + df[[sig_name]][!keep] <- maxy + shapeCustom[!keep] <- 17 + + names(shapeCustom) <- rep("Exact", length(shapeCustom)) + names(shapeCustom)[shapeCustom == 17] <- "Adjusted" + + # Remove if nothin' doin' + if (all(shapeCustom == 19)) { + shapeCustom <- NULL + } + maxy <- ceiling(maxy) + + ## X-axis custom range change: + if (custom_xlim == "") { + xlim <- c( + floor(min(df[, lfc_name])) - xlim_additional, + ceiling(max(df[, lfc_name])) + xlim_additional + ) + } else if (grepl(",", custom_xlim) == FALSE) { + xlim <- c( + -1 * as.numeric(trimws(custom_xlim)), + as.numeric(trimws(custom_xlim)) + ) + } 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) + } + + ### Create axis labels + ############################## + + if (grepl("log", change_colname[i])) { + xlab <- bquote(~ Log[2] ~ "fold change") + } else { + xlab <- "Fold change" + } + if (grepl("adj", signif_colname[i])) { + ylab <- bquote(~ -Log[10] ~ "FDR") + } else { + ylab <- bquote(~ -Log[10] ~ "p-value") + } + if (use_custom_lab) { + if (lfc_name != change_colname[i]) { + xlab <- gsub("_", " ", lfc_name) + } + if (sig_name != signif_colname[i]) { + ylab <- gsub("_", " ", sig_name) + } + } + + 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, + xlab = xlab, + ylab = ylab, + xlim = xlim, + ylim = c(0, maxy + ylim_additional), + pCutoff = signif_threshold, + FCcutoff = change_threshold, + axisLabSize = axis_lab_size, + labSize = lab_size, + pointSize = point_size, + shapeCustom = shapeCustom + ) + + ## Creating plot that can be converted to plotly interactive plot (no labels): + ## PH: make this feature an option not default + if (isTRUE(interactive_plots)) { + p_empty <- EnhancedVolcano::EnhancedVolcano( + df, + x = lfc_name, + y = sig_name, + lab = rep("", nrow(df)), + # Setting labels to empty strings + selectLab = NULL, + title = title, + # CHANGE NW: See line 78 + subtitle = group, + xlab = xlab, + ylab = ylab, + xlim = xlim, + ylim = c(0, maxy + ylim_additional), + pCutoff = signif_threshold, + FCcutoff = change_threshold, + axisLabSize = axis_lab_size, + labSize = lab_size, + pointSize = point_size, + shapeCustom = shapeCustom + ) + + # Extract the data used for plotting + plot_data <- ggplot2::ggplot_build(p_empty)$data[[1]] + + pxx <- p_empty + + ggplot2::xlab("Fold Change") + # Simplify x-axis label + ggplot2::ylab("Significance") + # Simplify y-axis label + ggplot2::theme_minimal() + + ggplot2::geom_point( + ggplot2::aes( + text = paste( + "Gene:", + df[[label_col]], + "
change_threshold:", + df[[lfc_name]], + "
P-value:", + df[[sig_name]] + ), + colour = as.character(plot_data$colour), + fill = as.character(plot_data$colour) # Set fill to the same as colour + ), + shape = 21, + # Shape that supports both colour and fill + size = 2, + # Size of the points + stroke = 0.1 # Stroke width + ) + + ggplot2::scale_fill_identity() + + # Add interactive hover labels for the gene names + volcano_plot <- plotly::ggplotly(pxx, tooltip = c("text")) + } + 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 + ) + + df_final <- cbind(diff_dat, do.call(cbind, rank)) + return(df_final) +} diff --git a/code/MOSuite/R/plot_volcano_summary.R b/code/MOSuite/R/plot_volcano_summary.R new file mode 100644 index 0000000..92a50f3 --- /dev/null +++ b/code/MOSuite/R/plot_volcano_summary.R @@ -0,0 +1,539 @@ +#' Volcano Plot - Summary +#' +#' Produces one volcano plot for each tested contrast in the input DEG table. +#' It 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. +#' An S7 generic with methods for `multiOmicDataSet` and `data.frame`. +#' +#' @param moo_diff multiOmicDataSet or differential expression analysis result data frame. +#' +#' @export +plot_volcano_summary <- S7::new_generic( + "plot_volcano_summary", + "moo_diff", + function( + moo_diff, + 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 = c("FC", "logFC", "tstat", "pval", "adjpval"), + graphics_device = grDevices::png, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" + ) { + return(S7::S7_dispatch()) + } +) + +#' @rdname plot_volcano_summary +S7::method(plot_volcano_summary, multiOmicDataSet) <- function( + moo_diff, + 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 = c("FC", "logFC", "tstat", "pval", "adjpval"), + graphics_device = grDevices::png, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" +) { + return( + moo_diff@analyses$diff |> + join_dfs_wide() |> + plot_volcano_summary( + feature_id_colname, + signif_colname, + signif_threshold, + change_threshold, + value_to_sort_the_output_dataset, + num_features_to_label, + add_features, + label_features, + custom_gene_list, + 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, + color_of_signif_threshold_line, + 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, + flip_vplot, + use_default_x_axis_limit, + x_axis_limit, + use_default_y_axis_limit, + y_axis_limit, + point_size, + add_deg_columns, + graphics_device, + image_width, + image_height, + dpi, + use_default_grid_layout, + number_of_rows_in_grid_layout, + aspect_ratio, + plot_filename, + print_plots, + save_plots, + plots_subdir + ) + ) +} + +#' @inheritParams option_params +#' @inheritParams plot_volcano_enhanced +#' @inheritParams filter_counts +#' +#' @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. +#' @param label_features Select TRUE when you want to label ONLY a specific list of features(features) given in the +#' "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 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 color_of_features_meeting_only_signif_threshold Color of the features that meet only the significance +#' threshold. Default: "lightgoldenrod2" +#' @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" +#' @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 +#' @param x_axis_limit Custom x-axis limit. Default: c(-5, 5) +#' @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 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" +#' +#' @keywords plotters volcano +#' +#' @examples +#' plot_volcano_summary(nidap_deg_analysis, print_plots = TRUE) +#' +#' @rdname plot_volcano_summary +#' +S7::method(plot_volcano_summary, S7::class_data.frame) <- function( + moo_diff, + 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 = c("FC", "logFC", "tstat", "pval", "adjpval"), + graphics_device = grDevices::png, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" +) { + abort_packages_not_installed("patchwork", "ggrepel") + diff_dat <- as.data.frame(moo_diff) + + ## -------------------------------- ## + ## User-Defined Template Parameters ## + ## -------------------------------- ## + ### PH + # Input - DEG table from Limma DEG template + # Output - Venn Diagrams for selected Comparisons + + # Simplified DEG table for selected Comparisons (Only used for Venn Diagram) + # Purpose - Create Multiple Venn Diagrams + # Can we use Visualizations from Advanced Volcano function used in the stand alone Volcano plot? + + # Basic Parameters: + if (is.null(feature_id_colname)) { + feature_id_colname <- colnames(diff_dat)[1] + } + + # Identify all contrasts in DEG output table + volcols <- colnames(diff_dat) + statcols <- volcols[grepl("logFC", volcols)] + contrasts <- unique(gsub("_logFC", "", statcols)) + + Plots <- list() + df_outs <- list() + + # Create Volcano for each DEG comparison + for (contrast in contrasts) { + ### PH: START Build table for Volcano plot + message(paste0("Preparing table for contrast: ", contrast)) + lfccol <- paste0(contrast, "_logFC") + pvalcol <- paste0(contrast, "_", signif_colname) + tstatcol <- paste0(contrast, "_", "tstat") + + message(paste0("Fold change column: ", lfccol)) + message(paste0(signif_colname, " column: ", pvalcol)) + + if (value_to_sort_the_output_dataset == "fold-change") { + diff_dat <- diff_dat |> + dplyr::arrange(dplyr::desc(abs(diff_dat[, lfccol]))) + } else if (value_to_sort_the_output_dataset == "p-value") { + diff_dat <- diff_dat |> dplyr::arrange(diff_dat[, pvalcol]) + } else if (value_to_sort_the_output_dataset == "t-statistic") { + 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 + } + } + + ## optional Parameter: IF DEG was set up A-B User can Flip FC values so that Volcano plot looks like comparison was + ## B-A + ## flip contrast section + indc <- which(colnames(diff_dat) == lfccol) # get the indice of the column that contains the contrast_logFC data + + if (length(indc) == 0) { + message( + "Please rename the logFC column to include the contrast evaluated." + ) + } else { + old_contrast <- colnames(diff_dat)[indc] + } + # actually flip contrast + if (flip_vplot == TRUE) { + # get the indice of the contrast to flip + indcc <- match(old_contrast, colnames(diff_dat)) + # create flipped contrast label + splt1 <- strsplit(old_contrast, "_") # split by underline symbol to isolate the contrast name + splt2 <- strsplit(splt1[[1]][1], "-") # split the contrast name in the respective components + flipped_contrast <- paste(splt2[[1]][2], splt2[[1]][1], sep = "-") # flip contrast name + new_contrast_label <- paste(flipped_contrast, c("logFC"), sep = "_") + # rename contrast column to the flipped contrast + colnames(diff_dat)[indcc] <- new_contrast_label + # flip the contrast data around y-axis + diff_dat[, indcc] <- -diff_dat[indcc] + } else { + new_contrast_label <- old_contrast + } + + filtered_features <- diff_dat$Gene[ + diff_dat[, pvalcol] < signif_threshold & + abs(diff_dat[, new_contrast_label]) > change_threshold + ] + repeated_column <- rep(contrast, length(filtered_features)) + + ## If param empty or FALSE, fill it with default value. + if ( + is.null(add_deg_columns) || + length(add_deg_columns) == 0 || + isFALSE(add_deg_columns) + ) { + add_deg_columns <- c("FC", "logFC", "tstat", "pval", "adjpval") + } + + if (all(add_deg_columns == "none")) { + new_df <- data.frame(filtered_features, repeated_column) + names(new_df) <- c(feature_id_colname, "Contrast") + } else { + add_deg_columns <- setdiff(add_deg_columns, "none") + out_columns <- paste(contrast, add_deg_columns, sep = "_") + deg <- diff_dat[, c(feature_id_colname, out_columns)] + names(deg)[1] <- feature_id_colname + new_df <- data.frame(filtered_features, repeated_column) |> + dplyr::left_join(deg, by = c("filtered_features" = feature_id_colname)) + names(new_df) <- c(feature_id_colname, "Contrast", add_deg_columns) + } + + 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 + + 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 + } + + # 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) + } else { + xmax <- x_axis_limit + } + + 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 + } + 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)) + + return(df_out) +} diff --git a/code/MOSuite/R/plots.R b/code/MOSuite/R/plots.R new file mode 100644 index 0000000..c814b78 --- /dev/null +++ b/code/MOSuite/R/plots.R @@ -0,0 +1,52 @@ +#' Print and/or save a ggplot +#' +#' If `save_plots` is `TRUE`, the plot will be saved as an image to the path at +#' `file.path(plots_dir, filename)`. +#' If `plot_obj` is a ggplot, `ggplot2::ggsave()` is used to save the image. +#' Otherwise, `graphics_device` is used (`grDevice::png()` by default). +#' +#' @inheritParams option_params +#' @param plot_obj plot object (e.g. ggplot, ComplexHeatmap...) +#' @param filename name of the output file. will be joined with the `plots_dir` option. +#' @param graphics_device Default: `grDevice::png()`. Only used if the plot is not a ggplot. +#' @param ... arguments forwarded to `ggplot2::ggsave()` +#' +#' @return invisibly returns the path where the plot image was saved to the disk +#' @export +#' @family plotters +#' @keywords plotters +print_or_save_plot <- function( + plot_obj, + filename, + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_dir = options::opt("plots_dir"), + graphics_device = grDevices::png, + ... +) { + if (isTRUE(print_plots)) { + print(plot_obj) + } + if (isTRUE(save_plots)) { + # create output directory if it doesn't exist + if (!is.null(plots_dir) && nchar(plots_dir) > 0) { + filename <- file.path(plots_dir, filename) + } + outdir <- dirname(filename) + if (!dir.exists(outdir)) { + dir.create(outdir, recursive = TRUE) + } + + # select saving methods depending on plot object class + if (inherits(plot_obj, "ggplot")) { + ggplot2::ggsave(filename = filename, plot = plot_obj, ...) + } else if (inherits(plot_obj, "htmlwidget")) { + htmlwidgets::saveWidget(plot_obj, filename, ...) + } else { + graphics_device(file = filename) + plot(plot_obj) + grDevices::dev.off() + } + } + return(invisible(filename)) +} diff --git a/code/MOSuite/R/reexports.R b/code/MOSuite/R/reexports.R new file mode 100644 index 0000000..c7c32ad --- /dev/null +++ b/code/MOSuite/R/reexports.R @@ -0,0 +1,20 @@ +#' walrus operator +#' @importFrom rlang := +#' @export +rlang::`:=` + +#' bang-bang +#' @importFrom rlang !! +#' @export +rlang::`!!` + +#' rlang data pronoun +#' @importFrom rlang .data +#' @export +rlang::.data + +# Suppress R CMD check note 'All declared Imports should be used'. +# These are used in S7 methods. +#' @importFrom dendextend rotate +#' @importFrom matrixStats rowVars +NULL diff --git a/code/MOSuite/R/rename.R b/code/MOSuite/R/rename.R new file mode 100644 index 0000000..065af00 --- /dev/null +++ b/code/MOSuite/R/rename.R @@ -0,0 +1,31 @@ +#' Rename samples +#' +#' TODO this should happen right at the beginning of the template? +#' +#' TODO accept new names for samples in sample metadata spreadsheet +#' +#' +#' @param dat data frame +#' @param samples_to_rename_manually TODO use sample metadata spreadsheet custom column. Need to document the format of +#' this object. +#' +#' @return data frame with samples renamed +#' @keywords internal +#' +rename_samples <- function(dat, samples_to_rename_manually) { + replacements <- samples_to_rename_manually + + if ( + !is.null(replacements) && + (length(replacements) > 0) && + (nchar(replacements) > 0) + ) { + # TODO: refactor with dplyr::rename for simplicity + for (x in replacements) { + old <- strsplit(x, ": ?")[[1]][1] + new <- strsplit(x, ": ?")[[1]][2] + colnames(dat)[colnames(dat) %in% old] <- new + } + } + return(dat) +} diff --git a/code/MOSuite/R/utils.R b/code/MOSuite/R/utils.R new file mode 100644 index 0000000..8d7106c --- /dev/null +++ b/code/MOSuite/R/utils.R @@ -0,0 +1,332 @@ +#' Glue gene_id and GeneName columns into one column +#' +#' @param counts_dat data frame containing gene_id and GeneName columns +#' +#' @returns counts_dat with gene_id and GeneName joined with `|` as the new gene_id column +#' @keywords internal +#' @examples +#' \dontrun{ +#' gene_counts |> +#' glue_gene_symbols() |> +#' head() +#' } +glue_gene_symbols <- function(counts_dat) { + if ( + "gene_id" %in% colnames(counts_dat) && "GeneName" %in% colnames(counts_dat) + ) { + counts_dat <- counts_dat |> + dplyr::mutate( + gene_id = glue::glue("{gene_id}|{GeneName}"), + .keep = "unused" + ) + } + return(counts_dat) +} + +#' Check whether package(s) are installed +#' +#' @param ... names of packages to check +#' @return named vector with status of each packages; installed (`TRUE`) or not (`FALSE`) +#' @keywords internal +#' +#' @examples +#' \dontrun{ +#' check_packages_installed("base") +#' check_packages_installed("not-a-package-name") +#' all(check_packages_installed("parallel", "doFuture")) +#' } +check_packages_installed <- function(...) { + return(sapply(c(...), requireNamespace, quietly = TRUE)) +} + +#' Throw error if required packages are not installed. +#' +#' Reports which packages need to be installed and the parent function name. +#' See +#' https://stackoverflow.com/questions/15595478/how-to-get-the-name-of-the-calling-function-inside-the-called-routine +#' +#' @inheritParams check_packages_installed +#' @keywords internal +#' +#' @examples +#' \dontrun{ +#' abort_packages_not_installed("base") +#' abort_packages_not_installed("not-a-package-name", "caret", "dplyr", "non_package") +#' } +abort_packages_not_installed <- function(...) { + package_status <- check_packages_installed(...) + packages_not_installed <- Filter(isFALSE, package_status) + if (length(packages_not_installed) > 0) { + msg <- paste0( + "The following package(s) are required but are not installed: \n ", + paste0(names(packages_not_installed), collapse = ", ") + ) + stop(msg) + } +} + +#' Function for testing CLI argument parsing +#' +#' @param add whether to add left and right +#' @param subtract whether to subtract left and right +#' @param left number on the left side of the operand +#' @param right number on the right side of the operand +#' +#' @returns result of adding or subtracting left and right +#' +#' @export +#' @keywords internal +do_math <- function(add = TRUE, subtract = FALSE, left = 1, right = 2) { + result <- NULL + if (isTRUE(add)) { + result <- left + right + } else if (isTRUE(subtract)) { + result <- left - right + } + return(result) +} + +#' Join dataframes in named list to wide dataframe +#' +#' The first column is assumed to be shared by all dataframes +#' +#' @param df_list named list of dataframes +#' @param join_fn join function to use (Default: `dplyr::left_join`) +#' +#' @returns wide dataframe +#' @export +#' @keywords utilities +#' +#' @examples +#' +#' dfs <- list( +#' "a_vs_b" = data.frame(id = c("a1", "b2", "c3"), score = runif(3)), +#' "b_vs_c" = data.frame(id = c("a1", "b2", "c3"), score = rnorm(3)) +#' ) +#' dfs |> join_dfs_wide() +#' +join_dfs_wide <- function(df_list, join_fn = dplyr::left_join) { + if (!inherits(df_list, "list")) { + stop(glue::glue("df_list must be a named list. class: {class(df_list)}")) + } + if (is.null(names(df_list))) { + stop(glue::glue("df_list does not have names")) + } + # use first column as start + common_col <- df_list[[1]] |> + dplyr::select(1) |> + colnames() + dat_joined <- purrr::map(names(df_list), \(df_name) { + result <- df_list[[df_name]] |> + dplyr::rename_with( + .cols = !tidyselect::any_of(common_col), + .fn = \(x) { + return(glue::glue("{df_name}_{x}")) + } + ) + return(result) + }) |> + purrr::reduce(join_fn) + return(dat_joined) +} + +#' Bind dataframes in named list to long dataframe +#' +#' The dataframes must have all of the same columns +#' +#' @param df_list named list of dataframes +#' @param outcolname column name in output dataframe for the names from the named list +#' +#' @returns long dataframe with new column `outcolname` from named list +#' @export +#' @keywords utilities +#' +#' @examples +#' +#' dfs <- list( +#' "a_vs_b" = data.frame(id = c("a1", "b2", "c3"), score = runif(3)), +#' "b_vs_c" = data.frame(id = c("a1", "b2", "c3"), score = rnorm(3)) +#' ) +#' dfs |> bind_dfs_long() +#' +bind_dfs_long <- function(df_list, outcolname = contrast) { + contrast <- NULL # data variable + if (!inherits(df_list, "list")) { + stop(glue::glue("df_list must be a named list. class: {class(df_list)}")) + } + if (is.null(names(df_list))) { + stop(glue::glue("df_list does not have names")) + } + # use first column as start + common_col <- df_list[[1]] |> + dplyr::select(1) |> + colnames() + dat_joined <- purrr::map(names(df_list), \(df_name) { + result <- df_list[[df_name]] |> + dplyr::mutate({{ outcolname }} := df_name, .after = common_col) + return(result) + }) |> + dplyr::bind_rows() + return(dat_joined) +} + +#' Set up capsule environment and directories +#' +#' Initializes the results directory structure and logs installed R package versions. +#' This is a common setup task used across all Code Ocean capsules. +#' +#' @param base_results_dir base path to results directory (default: `../results`) +#' +#' @returns invisibly returns a list with `results_dir` and `plots_dir` paths +#' @keywords internal +#' +#' @examples +#' \dontrun{ +#' setup_capsule_environment() +#' } +#' +#' @export +setup_capsule_environment <- function( + base_results_dir = file.path("..", "results") +) { + results_dir <- base_results_dir + plots_dir <- file.path(results_dir, "figures") + + # Set options for plots directory + options(moo_plots_dir = plots_dir, moo_save_plots = TRUE) + + # Log installed packages & versions + pkg_versions <- tibble::as_tibble(utils::installed.packages()) + readr::write_csv(pkg_versions, file.path(results_dir, "r-packages.csv")) + + return(invisible(list(results_dir = results_dir, plots_dir = plots_dir))) +} + +#' Load multiOmicDataSet from data directory +#' +#' Searches the ../data directory for .rds files and loads the first matching +#' multiOmicDataSet object. Validates that the loaded object is of the correct class. +#' +#' @param data_dir path to data directory containing .rds file (default: `../data`) +#' +#' @returns loaded multiOmicDataSet object +#' @keywords internal +#' +#' @examples +#' \dontrun{ +#' moo <- load_moo_from_data_dir() +#' } +#' +#' @export +load_moo_from_data_dir <- function(data_dir = file.path("..", "data")) { + regex_moo <- ".*\\.rds$" + data_files <- list.files(data_dir, recursive = TRUE, full.names = TRUE) + moo_files <- Filter( + \(x) stringr::str_detect(x, stringr::regex(regex_moo, ignore_case = TRUE)), + data_files + ) + + if (length(moo_files) == 0) { + stop(glue::glue("No files matching regex: {regex_moo}")) + } + + moo_filename <- moo_files[1] + moo <- readr::read_rds(moo_filename) + + message(glue::glue("Reading multiOmicDataSet from {moo_filename}")) + + if (!inherits(moo, "MOSuite::multiOmicDataSet")) { + stop(glue::glue("The input is not a multiOmicDataSet. class: {class(moo)}")) + } + + return(moo) +} + +#' Parse comma-separated string into a vector +#' +#' Splits a comma-separated string into a trimmed character vector. +#' Returns NULL if input is empty, NULL, or has zero length. +#' +#' @param x character string with comma-separated values +#' +#' @returns character vector or NULL if input is empty +#' @keywords internal +#' +#' @examples +#' \dontrun{ +#' parse_optional_vector("a, b, c") +#' parse_optional_vector("") +#' } +#' +#' @export +parse_optional_vector <- function(x) { + if (is.null(x) || identical(x, "") || length(x) == 0) { + return(NULL) + } + return(trimws(unlist(strsplit(x, ",")))) +} + +#' Parse comma-separated string with default fallback +#' +#' Splits a comma-separated string into a trimmed character vector. +#' Returns a default value if input is empty, NULL, or has zero length. +#' +#' @param x character string with comma-separated values +#' @param default default value to return if x is empty +#' +#' @returns character vector or default value +#' @keywords internal +#' +#' @examples +#' \dontrun{ +#' parse_vector_with_default("a, b, c", "default") +#' parse_vector_with_default("", "default") +#' } +#' +#' @export +parse_vector_with_default <- function(x, default) { + parsed <- parse_optional_vector(x) + if (is.null(parsed)) { + return(default) + } + return(parsed) +} + +#' Parse sample rename pairs from string +#' +#' Parses a string containing sample rename pairs in format "old:new,old2:new2" +#' and returns a named list where names are old sample names and values are new names. +#' +#' @param x character string with rename pairs in format "old:new,old2:new2" +#' +#' @returns named list with old names as keys and new names as values, or NULL if empty +#' @keywords internal +#' +#' @examples +#' \dontrun{ +#' parse_samples_to_rename("sample1:S1,sample2:S2") +#' parse_samples_to_rename("") +#' } +#' +#' @export +parse_samples_to_rename <- function(x) { + if (is.null(x) || identical(x, "") || length(x) == 0) { + return(NULL) + } + + pairs <- trimws(unlist(strsplit(x, ","))) + result <- list() + + for (pair in pairs) { + parts <- trimws(unlist(strsplit(pair, ":"))) + if (length(parts) == 2) { + result[[parts[1]]] <- parts[2] + } + } + + if (length(result) == 0) { + return(NULL) + } + + return(result) +} diff --git a/code/MOSuite/R/zzz.R b/code/MOSuite/R/zzz.R new file mode 100644 index 0000000..31a395d --- /dev/null +++ b/code/MOSuite/R/zzz.R @@ -0,0 +1,28 @@ +# source: https://rconsortium.github.io/S7/articles/packages.html#method-registration +.onLoad <- function(...) { + S7::methods_register() + + # necessary because moo_save_plots defaults to TRUE, causing figures to be + # written during R CMD check + is_r_cmd_check <- nzchar(Sys.getenv("_R_CHECK_PACKAGE_NAME_")) || + identical(tolower(Sys.getenv("R_CMD_CHECK")), "true") || + identical(tolower(Sys.getenv("R CMD check")), "true") + if ( + is_r_cmd_check && + is.null(getOption("moo_save_plots")) && + !nzchar(Sys.getenv("MOO_SAVE_PLOTS")) + ) { + options(moo_save_plots = FALSE) + } +} + +# enable usage of @name in package code +# source: https://rconsortium.github.io/S7/articles/packages.html#backward-compatibility +#' @rawNamespace if (getRversion() < "4.3.0") importFrom("S7", "@") +NULL + + +# Suppress R CMD check note 'All declared Imports should be used'. +# These packages are used within S7 methods. +#' @importFrom DESeq2 DESeq +NULL diff --git a/code/MOSuite/README.Rmd b/code/MOSuite/README.Rmd new file mode 100644 index 0000000..60c65b6 --- /dev/null +++ b/code/MOSuite/README.Rmd @@ -0,0 +1,78 @@ +--- +output: github_document +--- + + + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + fig.path = "man/figures/README-", + out.width = "100%" +) +``` + +# MOSuite MOSuite website + +R package for differential multi-omics analysis + + +[![R-CMD-check](https://github.com/CCBR/MOSuite/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/CCBR/MOSuite/actions/workflows/R-CMD-check.yaml) +[![codecov](https://codecov.io/gh/CCBR/MOSuite/graph/badge.svg?token=730OAPA4NU)](https://codecov.io/gh/CCBR/MOSuite) +[![CodeQL](https://github.com/CCBR/MOSuite/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/CCBR/MOSuite/actions/workflows/github-code-scanning/codeql) +[![version](https://img.shields.io/github/v/release/ccbr/mosuite)](https://github.com/CCBR/MOSuite/releases/latest) +[![docker](https://img.shields.io/docker/v/nciccbr/mosuite?logo=docker&label=docker&color=blue)](https://hub.docker.com/r/nciccbr/mosuite) +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.16371580.svg)](https://doi.org/10.5281/zenodo.16371580) + + +Multi-Omics Suite provides a suite of functions to clean, filter, batch-correct, +normalize, visualize, and perform differential expression analysis. While the +package is designed for differential [RNA-seq](https://github.com/CCBR/RENEE) +analysis and multi-omics datasets, it can be used for any data represented in a +counts table. See the website for more information, documentation, and examples: + + +## Installation + +You can install the development version of MOSuite from [GitHub](https://github.com/CCBR/MOSuite) with: + +```r +# install.packages("remotes") +remotes::install_github("CCBR/MOSuite", dependencies = TRUE) +``` + +Or install a specific version: + +```r +remotes::install_github("CCBR/MOSuite", dependencies = TRUE, ref = "v0.3.0") +``` + +There is also a Docker container available at + +```sh +singularity exec docker://nciccbr/mosuite:v0.3.0 R -s -e \ + 'cat("MOSuite version:", installed.packages()["MOSuite",][["Version"]])' +``` + +## Usage + +Please see the [introductory vignette](https://ccbr.github.io/MOSuite/articles/intro.html) +for a quick start tutorial. +Take a look at the [reference documentation](https://ccbr.github.io/MOSuite/reference/index.html) +for detailed information on each function in the package. + +## Help & Contributing + +Come across a **bug**? Open an [issue](https://github.com/CCBR/MOSuite/issues) and include a minimal reproducible example. + +Have a **question**? Ask it in [discussions](https://github.com/CCBR/MOSuite/discussions). + +Want to **contribute** to this project? Check out the [contributing guidelines](.github/CONTRIBUTING.md). + +## Development Roadmap + +![](./man/figures/development-plan.png) + +- [dev spreadsheet](https://nih-my.sharepoint.com/:x:/g/personal/homanpj_nih_gov/ETvHXgnwxExEpcP57Jj9_EwBHBvZBqNuZ_c3eu51w-SlnA?e=PcXKU8) +- [project board](https://github.com/orgs/CCBR/projects/32) diff --git a/code/MOSuite/README.md b/code/MOSuite/README.md new file mode 100644 index 0000000..e34f8ad --- /dev/null +++ b/code/MOSuite/README.md @@ -0,0 +1,76 @@ + + + +# MOSuite MOSuite website + +R package for differential multi-omics analysis + + + +[![R-CMD-check](https://github.com/CCBR/MOSuite/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/CCBR/MOSuite/actions/workflows/R-CMD-check.yaml) +[![codecov](https://codecov.io/gh/CCBR/MOSuite/graph/badge.svg?token=730OAPA4NU)](https://codecov.io/gh/CCBR/MOSuite) +[![CodeQL](https://github.com/CCBR/MOSuite/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/CCBR/MOSuite/actions/workflows/github-code-scanning/codeql) +[![version](https://img.shields.io/github/v/release/ccbr/mosuite)](https://github.com/CCBR/MOSuite/releases/latest) +[![docker](https://img.shields.io/docker/v/nciccbr/mosuite?logo=docker&label=docker&color=blue)](https://hub.docker.com/r/nciccbr/mosuite) +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.16371580.svg)](https://doi.org/10.5281/zenodo.16371580) + + +Multi-Omics Suite provides a suite of functions to clean, filter, +batch-correct, normalize, visualize, and perform differential expression +analysis. While the package is designed for differential +[RNA-seq](https://github.com/CCBR/RENEE) analysis and multi-omics +datasets, it can be used for any data represented in a counts table. See +the website for more information, documentation, and examples: + + +## Installation + +You can install the development version of MOSuite from +[GitHub](https://github.com/CCBR/MOSuite) with: + +``` r +# install.packages("remotes") +remotes::install_github("CCBR/MOSuite", dependencies = TRUE) +``` + +Or install a specific version: + +``` r +remotes::install_github("CCBR/MOSuite", dependencies = TRUE, ref = "v0.3.0") +``` + +There is also a Docker container available at + + +``` sh +singularity exec docker://nciccbr/mosuite:v0.3.0 R -s -e \ + 'cat("MOSuite version:", installed.packages()["MOSuite",][["Version"]])' +``` + +## Usage + +Please see the [introductory +vignette](https://ccbr.github.io/MOSuite/articles/intro.html) for a +quick start tutorial. Take a look at the [reference +documentation](https://ccbr.github.io/MOSuite/reference/index.html) for +detailed information on each function in the package. + +## Help & Contributing + +Come across a **bug**? Open an +[issue](https://github.com/CCBR/MOSuite/issues) and include a minimal +reproducible example. + +Have a **question**? Ask it in +[discussions](https://github.com/CCBR/MOSuite/discussions). + +Want to **contribute** to this project? Check out the [contributing +guidelines](.github/CONTRIBUTING.md). + +## Development Roadmap + +![](./man/figures/development-plan.png) + +- [dev + spreadsheet](https://nih-my.sharepoint.com/:x:/g/personal/homanpj_nih_gov/ETvHXgnwxExEpcP57Jj9_EwBHBvZBqNuZ_c3eu51w-SlnA?e=PcXKU8) +- [project board](https://github.com/orgs/CCBR/projects/32) diff --git a/code/MOSuite/_pkgdown.yml b/code/MOSuite/_pkgdown.yml new file mode 100644 index 0000000..504949b --- /dev/null +++ b/code/MOSuite/_pkgdown.yml @@ -0,0 +1,74 @@ +url: https://ccbr.github.io/MOSuite/ +template: + bootstrap: 5 + bslib: + bootswatch: yeti + primary: "#296b7f" + secondary: "#7cc349" + base_font: {google: "Roboto"} + heading_font: {google: "Roboto"} + code_font: {google: "Roboto Mono"} + border-radius: 0 + btn-border-radius: 3px + grid-gutter-width: 3rem + pkgdown-nav-height: 78px +footer: + structure: + left: [developed_by] + +development: + mode: auto +authors: + Kelly Sovacool: + href: "https://github.com/kelly-sovacool" + Philip Homan: + href: "https://github.com/phoman14" + Vishal Koparde: + href: "https://github.com/kopardev" + CCR Collaborative Bioinformatics Resource: + href: "https://github.com/CCBR" + footer: + roles: [cph, fnd] + text: "Created by the" + +articles: +- title: Articles + navbar: ~ + contents: + - intro + - renee + - visualization + - cli + - memory + +reference: +- title: multiOmicDataSet + contents: contains("multiOmicDataSet") +- title: Main functions + desc: See `vignette('intro')` for recommended usage + contents: + - ends_with("_counts") + - -has_keyword("data") + - filter_diff +- title: Visualization + contents: + - has_keyword("plotters") +- subtitle: Color selectors + contents: + - contains("color") +- title: Misc. helpers & utilities + contents: + - starts_with('calc_') + - has_keyword('utilities') +- title: Datasets + contents: + - has_keyword('data') +- title: Options + contents: + - options +- subtitle: Low-level plot helpers + desc: | + These functions are called by the main visualization functions. + contents: + - starts_with("plot_") + - -has_keyword("plotters") diff --git a/code/MOSuite/air.toml b/code/MOSuite/air.toml new file mode 100644 index 0000000..5ad7d17 --- /dev/null +++ b/code/MOSuite/air.toml @@ -0,0 +1,11 @@ +[format] +line-width = 80 +indent-width = 2 +indent-style = "space" +line-ending = "auto" +persistent-line-breaks = true +exclude = [] +default-exclude = true +skip = [] +table = [] +default-table = true diff --git a/code/MOSuite/codemeta.json b/code/MOSuite/codemeta.json new file mode 100644 index 0000000..cb4a191 --- /dev/null +++ b/code/MOSuite/codemeta.json @@ -0,0 +1,36 @@ +{ + "@context": "https://doi.org/10.5063/schema/codemeta-2.0", + "@type": "SoftwareSourceCode", + "author": [ + { + "@id": "https://orcid.org/0000-0003-3283-829X", + "@type": "Person", + "familyName": "Sovacool", + "givenName": "Kelly" + }, + { + "@type": "Person", + "familyName": "Homan", + "givenName": "Philip" + }, + { + "@id": "https://orcid.org/0000-0001-8978-8495", + "@type": "Person", + "familyName": "Koparde", + "givenName": "Vishal" + }, + { + "@id": "https://orcid.org/0000-0002-8734-9875", + "@type": "Person", + "familyName": "Chill", + "givenName": "Samantha" + } + ], + "codeRepository": "https://github.com/CCBR/MOSuite", + "description": "Multi-Omics Suite provides a suite of functions to clean, filter, batch-correct, normalize, visualize, and perform differential analysis. While the package is designed for differential RNA-seq analysis and multi-omics datasets, it can be used for any data represented in a counts table. See the website for more information, documentation, and examples at .", + "identifier": "https://doi.org/10.5281/zenodo.16371580", + "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" +} diff --git a/code/MOSuite/data-raw/gene_counts.R b/code/MOSuite/data-raw/gene_counts.R new file mode 100644 index 0000000..4cad503 --- /dev/null +++ b/code/MOSuite/data-raw/gene_counts.R @@ -0,0 +1,11 @@ +# WT_S1.RSEM.genes.results was generated from running RENEE v2.5.3 on the test dataset +# https://github.com/CCBR/RENEE/tree/e08f7db6c6e638cfd330caa182f64665d2ef37fa/.tests +gene_counts <- readr::read_tsv( + system.file( + "inst", + "extdata", + "RSEM.genes.expected_count.all_samples.txt.gz", + package = "MOSuite" + ) +) +usethis::use_data(gene_counts, overwrite = TRUE, compress = "xz") diff --git a/code/MOSuite/data-raw/nidap.R b/code/MOSuite/data-raw/nidap.R new file mode 100644 index 0000000..b5a96a7 --- /dev/null +++ b/code/MOSuite/data-raw/nidap.R @@ -0,0 +1,138 @@ +# training data set from the NIDAP Bulk RNA-seq workflow +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", + covariates_colname = "Group", + batch_colname = "Batch", + label_colname = "Label" + ) |> + diff_counts( + count_type = "filt", + sub_count_type = NULL, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + voom_normalization_method = "quantile", + ) |> + filter_diff( + significance_column = "adjpval", + significance_cutoff = 0.05, + change_column = "logFC", + change_cutoff = 1, + filtering_mode = "any", + include_estimates = c("FC", "logFC", "tstat", "pval", "adjpval"), + round_estimates = TRUE, + rounding_decimal_for_percent_cells = 0, + contrast_filter = "none", + contrasts = c(), + groups = c(), + groups_filter = "none", + plot_type = "bar", + save_plots = FALSE, + print_plots = FALSE + ) + + +nidap_sample_metadata <- readr::read_csv( + system.file( + "extdata", + "nidap", + "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", + package = "MOSuite" + ) +) +usethis::use_data(nidap_sample_metadata, overwrite = TRUE) + +nidap_raw_counts <- readr::read_csv(system.file( + "extdata", + "nidap", + "Raw_Counts.csv.gz", + package = "MOSuite" +)) +usethis::use_data(nidap_raw_counts, overwrite = TRUE) + +nidap_clean_raw_counts <- readr::read_csv(system.file( + "extdata", + "nidap", + "Clean_Raw_Counts.csv.gz", + package = "MOSuite" +)) +usethis::use_data(nidap_clean_raw_counts, overwrite = TRUE) + +nidap_filtered_counts <- readr::read_csv(system.file( + "extdata", + "nidap", + "Filtered_Counts.csv.gz", + package = "MOSuite" +)) +usethis::use_data(nidap_filtered_counts, overwrite = TRUE) + +nidap_norm_counts <- readr::read_csv(system.file( + "extdata", + "nidap", + "Normalized_Counts.csv.gz", + package = "MOSuite" +)) +usethis::use_data(nidap_norm_counts, overwrite = TRUE) + +nidap_batch_corrected_counts <- readr::read_csv( + system.file( + "extdata", + "nidap", + "Batch_Corrected_Counts.csv.gz", + package = "MOSuite" + ) +) +usethis::use_data(nidap_batch_corrected_counts, overwrite = TRUE) + +nidap_batch_corrected_counts_2 <- moo@counts[["batch"]] +usethis::use_data(nidap_batch_corrected_counts_2, overwrite = TRUE) + +nidap_deg_analysis <- readr::read_csv(system.file( + "extdata", + "nidap", + "DEG_Analysis.csv.gz", + package = "MOSuite" +)) +usethis::use_data(nidap_deg_analysis, overwrite = TRUE) + + +nidap_deg_analysis_2 <- moo@analyses$diff +usethis::use_data(nidap_deg_analysis_2, overwrite = TRUE) + +# nidap_deg_gene_list <- readr::read_csv(system.file("extdata", "nidap", "DEG_Gene_List.csv.gz", package = "MOSuite")) +# usethis::use_data(nidap_deg_gene_list, overwrite = TRUE) + +nidap_deg_gene_list <- moo@analyses$diff_filt +usethis::use_data(nidap_deg_gene_list, overwrite = TRUE) + +nidap_volcano_summary_dat <- readr::read_csv(system.file( + "extdata", + "nidap", + "Volcano_Summary.csv.gz", + package = "MOSuite" +)) +usethis::use_data(nidap_volcano_summary_dat, overwrite = TRUE) + +nidap_venn_diagram_dat <- readr::read_csv(system.file( + "extdata", + "nidap", + "Venn_Diagram.csv.gz", + package = "MOSuite" +)) +usethis::use_data(nidap_venn_diagram_dat, overwrite = TRUE) + +## re-compress Rda files +# tools::resaveRdaFiles('data') diff --git a/code/MOSuite/data/gene_counts.rda b/code/MOSuite/data/gene_counts.rda new file mode 100644 index 0000000..59b5b9c Binary files /dev/null and b/code/MOSuite/data/gene_counts.rda differ diff --git a/code/MOSuite/data/nidap_batch_corrected_counts.rda b/code/MOSuite/data/nidap_batch_corrected_counts.rda new file mode 100644 index 0000000..0fcab5e Binary files /dev/null and b/code/MOSuite/data/nidap_batch_corrected_counts.rda differ diff --git a/code/MOSuite/data/nidap_batch_corrected_counts_2.rda b/code/MOSuite/data/nidap_batch_corrected_counts_2.rda new file mode 100644 index 0000000..ab45f73 Binary files /dev/null and b/code/MOSuite/data/nidap_batch_corrected_counts_2.rda differ diff --git a/code/MOSuite/data/nidap_clean_raw_counts.rda b/code/MOSuite/data/nidap_clean_raw_counts.rda new file mode 100644 index 0000000..c32d94f Binary files /dev/null and b/code/MOSuite/data/nidap_clean_raw_counts.rda differ diff --git a/code/MOSuite/data/nidap_deg_analysis.rda b/code/MOSuite/data/nidap_deg_analysis.rda new file mode 100644 index 0000000..9d3fb28 Binary files /dev/null and b/code/MOSuite/data/nidap_deg_analysis.rda differ diff --git a/code/MOSuite/data/nidap_deg_analysis_2.rda b/code/MOSuite/data/nidap_deg_analysis_2.rda new file mode 100644 index 0000000..37fbd18 Binary files /dev/null and b/code/MOSuite/data/nidap_deg_analysis_2.rda differ diff --git a/code/MOSuite/data/nidap_deg_gene_list.rda b/code/MOSuite/data/nidap_deg_gene_list.rda new file mode 100644 index 0000000..e5fdc18 Binary files /dev/null and b/code/MOSuite/data/nidap_deg_gene_list.rda differ diff --git a/code/MOSuite/data/nidap_filtered_counts.rda b/code/MOSuite/data/nidap_filtered_counts.rda new file mode 100644 index 0000000..1361edd Binary files /dev/null and b/code/MOSuite/data/nidap_filtered_counts.rda differ diff --git a/code/MOSuite/data/nidap_norm_counts.rda b/code/MOSuite/data/nidap_norm_counts.rda new file mode 100644 index 0000000..3bc43f7 Binary files /dev/null and b/code/MOSuite/data/nidap_norm_counts.rda differ diff --git a/code/MOSuite/data/nidap_raw_counts.rda b/code/MOSuite/data/nidap_raw_counts.rda new file mode 100644 index 0000000..22e92d3 Binary files /dev/null and b/code/MOSuite/data/nidap_raw_counts.rda differ diff --git a/code/MOSuite/data/nidap_sample_metadata.rda b/code/MOSuite/data/nidap_sample_metadata.rda new file mode 100644 index 0000000..d7fe5a2 Binary files /dev/null and b/code/MOSuite/data/nidap_sample_metadata.rda differ diff --git a/code/MOSuite/data/nidap_venn_diagram_dat.rda b/code/MOSuite/data/nidap_venn_diagram_dat.rda new file mode 100644 index 0000000..9c01b50 Binary files /dev/null and b/code/MOSuite/data/nidap_venn_diagram_dat.rda differ diff --git a/code/MOSuite/data/nidap_volcano_summary_dat.rda b/code/MOSuite/data/nidap_volcano_summary_dat.rda new file mode 100644 index 0000000..4c3cd28 Binary files /dev/null and b/code/MOSuite/data/nidap_volcano_summary_dat.rda differ diff --git a/code/MOSuite/docker/Dockerfile b/code/MOSuite/docker/Dockerfile new file mode 100644 index 0000000..a97d70b --- /dev/null +++ b/code/MOSuite/docker/Dockerfile @@ -0,0 +1,76 @@ +FROM nciccbr/ccbr_ubuntu_24.04:v1 + +# build time variables +ARG BUILD_DATE="000000" +ENV BUILD_DATE=${BUILD_DATE} +ARG BUILD_TAG="000000" +ENV BUILD_TAG=${BUILD_TAG} +ARG REPONAME="000000" +ENV REPONAME=${REPONAME} + +ARG R_VERSION=4.4 +ENV R_VERSION=${R_VERSION} + +# install conda packages +RUN mamba install -y -c conda-forge \ + r-base=${R_VERSION} \ + r-argparse \ + r-amap \ + r-broom \ + r-cffr \ + r-colorspace \ + r-dendextend \ + r-devtools \ + r-dplyr \ + "r-ggplot2 <4.0.0" \ + r-ggrepel \ + r-gridExtra \ + r-here \ + r-matrix \ + r-mgcv \ + r-pak \ + r-patchwork \ + r-plotly \ + r-rcolorbrewer \ + r-readr \ + r-remotes \ + r-rmarkdown \ + r-survival \ + r-upsetr \ + r-viridis \ + bioconductor-annotationdbi \ + bioconductor-annotate \ + bioconductor-complexheatmap \ + bioconductor-delayedarray \ + bioconductor-deseq2 \ + bioconductor-edger \ + bioconductor-genomicranges \ + bioconductor-keggrest \ + bioconductor-limma \ + bioconductor-s4arrays \ + bioconductor-summarizedexperiment \ + bioconductor-sva \ + && conda clean -afy + +# install R package +COPY . /opt2/MOSuite +RUN R -e "devtools::install_local('/opt2/MOSuite', dependencies = TRUE, repos='http://cran.rstudio.com', upgrade='never')" && \ + R -e "library(MOSuite); devtools::test('/opt2/MOSuite')" && \ + R -s -e "readr::write_csv(tibble::as_tibble(installed.packages()), '/data2/r-packages_mosuite.csv')" + +# add mosuite exec to the path +RUN chmod -R +x /opt2/conda/lib/R/library/MOSuite/exec +ENV PATH="$PATH:/opt2/conda/lib/R/library/MOSuite/exec" +RUN mosuite --help + +# copy .Rprofile to R_HOME +ADD .github/.Rprofile /opt2/conda/lib/R/ + +# copy example script & json to data +COPY ./inst/extdata/example_script.sh /data2/ +COPY ./inst/extdata/json_args/ /data2/json_args/ + +# cleanup +WORKDIR /data2 +RUN apt-get clean && apt-get purge \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/code/MOSuite/docker/Dockerfile_minimal b/code/MOSuite/docker/Dockerfile_minimal new file mode 100644 index 0000000..eb91b2c --- /dev/null +++ b/code/MOSuite/docker/Dockerfile_minimal @@ -0,0 +1,66 @@ +FROM nciccbr/ccbr_ubuntu_24.04:v1 + +# build time variables +ARG BUILD_DATE="000000" +ENV BUILD_DATE=${BUILD_DATE} +ARG BUILD_TAG="000000" +ENV BUILD_TAG=${BUILD_TAG} +ARG REPONAME="000000" +ENV REPONAME=${REPONAME} + +ARG R_VERSION=4.4 +ENV R_VERSION=${R_VERSION} + +# install conda packages +RUN mamba install -y -c conda-forge \ + r-base=${R_VERSION} \ + r-argparse \ + r-amap \ + r-broom \ + r-cffr \ + r-colorspace \ + r-dendextend \ + r-devtools \ + r-dplyr \ + "r-ggplot2 <4.0.0" \ + r-ggrepel \ + r-gridExtra \ + r-here \ + r-matrix \ + r-mgcv \ + r-pak \ + r-patchwork \ + r-plotly \ + r-rcolorbrewer \ + r-readr \ + r-rmarkdown \ + r-survival \ + r-upsetr \ + r-viridis \ + bioconductor-annotationdbi \ + bioconductor-annotate \ + bioconductor-complexheatmap \ + bioconductor-delayedarray \ + bioconductor-deseq2 \ + bioconductor-edger \ + bioconductor-genomicranges \ + bioconductor-keggrest \ + bioconductor-limma \ + bioconductor-s4arrays \ + bioconductor-summarizedexperiment \ + bioconductor-sva \ + && conda clean -afy + +# install dependencies, but not the R package itself +# using --mount avoids copying the context into the image +RUN --mount=type=bind,source=.,target=/opt2/MOSuite \ + R -e "pak::local_install_dev_deps('/opt2/MOSuite', upgrade=FALSE)" && \ + R -s -e "readr::write_csv(tibble::as_tibble(installed.packages()), '/data2/r-packages_mosuite-minimal.csv')" + +# copy .Rprofile to R_HOME +ADD .github/.Rprofile /opt2/conda/lib/R/ + +# cleanup +WORKDIR /data2 +RUN apt-get clean && apt-get purge \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/code/MOSuite/exec/mosuite b/code/MOSuite/exec/mosuite new file mode 100755 index 0000000..87e6961 --- /dev/null +++ b/code/MOSuite/exec/mosuite @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +# inspired by https://github.com/rstudio/renv/blob/d0eb86349d35679eb6920ca59072bd7369fe620f/inst/bin/renv + +R --no-save --no-restore -s -e "getExportedValue('MOSuite','cli_exec')()" --args "$@" diff --git a/code/MOSuite/inst/CITATION b/code/MOSuite/inst/CITATION new file mode 100644 index 0000000..8e7b615 --- /dev/null +++ b/code/MOSuite/inst/CITATION @@ -0,0 +1,23 @@ +bibentry(bibtype = "Manual", + key = "sovacool_mosuite_2025", + title = "{MOSuite}: R package for differential multi-omics analysis", + author = c(person(given = "Kelly", + family = "Sovacool", + email = "kelly.sovacool@nih.gov", + comment = c(ORCID = "0000-0003-3283-829X")), + person(given = "Philip", + family = "Homan", + email = "philip.homan@nih.gov"), + person(given = "Vishal", + family = "Koparde", + email = "vishal.koparde@nih.gov", + comment = c(ORCID = "0000-0001-8978-8495")), + person(given = "Samantha", + family = "Chill", + email = "samantha.chill@nih.gov", + comment = c(ORCID = "0000-0002-8734-9875"))), + year = "2025", + doi = "10.5281/zenodo.16371580", + url = "https://ccbr.github.io/MOSuite/", + header = "To cite MOSuite in publications, please use:" +) diff --git a/code/MOSuite/inst/extdata/.gitignore b/code/MOSuite/inst/extdata/.gitignore new file mode 100644 index 0000000..508df73 --- /dev/null +++ b/code/MOSuite/inst/extdata/.gitignore @@ -0,0 +1 @@ +/moo.rds diff --git a/code/MOSuite/inst/extdata/LIHC_HTseqCounts.txt.gz b/code/MOSuite/inst/extdata/LIHC_HTseqCounts.txt.gz new file mode 100644 index 0000000..eab3352 Binary files /dev/null and b/code/MOSuite/inst/extdata/LIHC_HTseqCounts.txt.gz differ diff --git a/code/MOSuite/inst/extdata/LIHC_PatientData.txt.gz b/code/MOSuite/inst/extdata/LIHC_PatientData.txt.gz new file mode 100644 index 0000000..97492b4 Binary files /dev/null and b/code/MOSuite/inst/extdata/LIHC_PatientData.txt.gz differ diff --git a/code/MOSuite/inst/extdata/RSEM.genes.expected_count.all_samples.txt.gz b/code/MOSuite/inst/extdata/RSEM.genes.expected_count.all_samples.txt.gz new file mode 100644 index 0000000..aad3ce7 Binary files /dev/null and b/code/MOSuite/inst/extdata/RSEM.genes.expected_count.all_samples.txt.gz differ diff --git a/code/MOSuite/inst/extdata/example.json b/code/MOSuite/inst/extdata/example.json new file mode 100644 index 0000000..5c97bb1 --- /dev/null +++ b/code/MOSuite/inst/extdata/example.json @@ -0,0 +1,5 @@ +{ + "feature_counts_filepath": "inst/extdata/RSEM.genes.expected_count.all_samples.txt.gz", + "sample_meta_filepath": "inst/extdata/sample_metadata.tsv.gz", + "moo_output_rds": "inst/extdata/moo.rds" +} diff --git a/code/MOSuite/inst/extdata/example_script.sh b/code/MOSuite/inst/extdata/example_script.sh new file mode 100644 index 0000000..93b5ab1 --- /dev/null +++ b/code/MOSuite/inst/extdata/example_script.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -euo pipefail + +# set MOSuite options for plots +export MOO_SAVE_PLOTS=TRUE +export MOO_PLOTS_DIR=./figures +mkdir -p $MOO_PLOTS_DIR + +# add mosuite executable to the path +mosuite=$(R -s -e "cat(system.file('exec','mosuite', package='MOSuite'))") +export PATH="$PATH:$(dirname $mosuite)" + +mosuite create_multiOmicDataSet_from_files --json=json_args/common/create_multiOmicDataSet_from_files.json +mosuite clean_raw_counts --json=json_args/common/clean_raw_counts.json +mosuite filter_counts --json=json_args/common/filter_counts.json +mosuite normalize_counts --json=json_args/common/normalize_counts.json +mosuite batch_correct_counts --json=json_args/common/batch_correct_counts.json +mosuite diff_counts --json=json_args/common/diff_counts.json +mosuite filter_diff --json=json_args/common/filter_diff.json diff --git a/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Batch_Correction_CCBR_.code-template.json b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Batch_Correction_CCBR_.code-template.json new file mode 100644 index 0000000..6d2b2d5 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Batch_Correction_CCBR_.code-template.json @@ -0,0 +1,381 @@ +{ + "codeTemplate": "Batch_Corrected_Counts <- function({{{counts_matrix}}}, {{{sample_metadata}}}) {\n \n ## --------- ##\n ## Libraries ##\n ## --------- ##\n \n library(tidyverse)\n library(sva)\n library(magrittr)\n library(reshape2)\n library(RColorBrewer)\n library(colorspace)\n library(ggplot2)\n library(dplyr)\n library(plotly)\n library(gridExtra)\n library(amap)\n library(dendsort)\n library(gplots)\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_names_column <- \"{{{Feature_ID_Column}}}\" \n columns_to_include <- {{{Columns_to_Include}}}\n sample_names_column <- \"{{{Sample_Names_Column}}}\"\n \n groups_column <- \"{{{Groups_Column}}}\"\n covariates <- {{{Covariates}}}\n batch_column <- \"{{{Batch_Column}}}\"\n skip_batch_correction <- \"{{{Skip_Batch_Correction}}}\"\n\n #PCA Parameters:\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 colors_for_plots <- {{{Colors_for_plots}}}\n point_size_for_pca <- {{{Point_Size_for_PCA}}}\n add_labels_to_pca <- {{{Add_Labels_to_PCA}}}\n labels_column <- \"{{{Labels_Column}}}\"\n label_offset_y_for_pca <- {{{Label_Offset_y_for_PCA}}}\n label_offset_x_for_pca <- {{{Label_Offset_x_for_PCA}}}\n label_font_size_for_pca <- {{{Label_Font_Size_for_PCA}}}\n legend_position_for_pca <- \"{{{Legend_Position_for_PCA}}}\"\n samples_to_rename_manually_on_pca <- {{{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_Max_Min_for_X_axis_for_Histogram}}}\n minimum_for_x_axis_for_histogram <- {{{Minimum_X_axis_in_Histogram}}}\n maximum_for_x_axis_for_histogram <- {{{Maximum_X_axis_in_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 #Visualization Parameters:\n make_plots_interactive <- {{{Make_Plots_Interactive}}}\n number_of_image_rows <- {{{Number_of_Image_Rows}}}\n\n #TCGA Parameters:\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 ## --------------- ##\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 new file mode 100644 index 0000000..cdfc6d3 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Clean_Raw_Counts_CCBR_.code-template.json @@ -0,0 +1,119 @@ +{ + "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 new file mode 100644 index 0000000..cbc29a8 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/DEG_Analysis_CCBR_.code-template.json @@ -0,0 +1,153 @@ +{ + "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 new file mode 100644 index 0000000..ab1578a --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/DEG_Gene_List_CCBR_.code-template.json @@ -0,0 +1,316 @@ +{ + "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 new file mode 100644 index 0000000..4f27bd6 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Expression_Heatmap_CCBR_.code-template.json @@ -0,0 +1,571 @@ +{ + "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 new file mode 100644 index 0000000..66fa2bf --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Filter_Low_Counts_CCBR_.code-template.json @@ -0,0 +1,419 @@ +{ + "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 new file mode 100644 index 0000000..2158ed3 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/NIDAPBulkTemplate_parameterTo_MOSuiteMapping.json @@ -0,0 +1,350 @@ +{ + "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 new file mode 100644 index 0000000..5f74711 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Normalization_CCBR_.code-template.json @@ -0,0 +1,378 @@ +{ + "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 new file mode 100644 index 0000000..16d088d --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/PCA_3D_CCBR_.code-template.json @@ -0,0 +1,229 @@ +{ + "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 new file mode 100644 index 0000000..e58edd6 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Venn_Diagram_CCBR_.code-template.json @@ -0,0 +1,1087 @@ +{ + "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 new file mode 100644 index 0000000..e5f62eb --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Volcano_Plot_Enhanced_CCBR_.code-template.json @@ -0,0 +1,310 @@ +{ + "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 new file mode 100644 index 0000000..a4c5a7d --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/Volcano_Plot_Summary_CCBR_.code-template.json @@ -0,0 +1,5126 @@ +{ + "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 new file mode 100644 index 0000000..a8a9172 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/0_nidap-1.0/missing_parameters.csv @@ -0,0 +1,12 @@ +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 new file mode 100644 index 0000000..77344a5 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/batch_correct_counts.json @@ -0,0 +1,167 @@ +{ + "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 new file mode 100644 index 0000000..cbadece --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/clean_raw_counts.json @@ -0,0 +1,159 @@ +{ + "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 new file mode 100644 index 0000000..54d8019 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/create_multiOmicDataSet_from_files.json @@ -0,0 +1,89 @@ +{ + "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 new file mode 100644 index 0000000..87394f2 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/diff_counts.json @@ -0,0 +1,189 @@ +{ + "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 new file mode 100644 index 0000000..f2eca99 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/filter_counts.json @@ -0,0 +1,433 @@ +{ + "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 new file mode 100644 index 0000000..21bc470 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/filter_diff.json @@ -0,0 +1,357 @@ +{ + "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 new file mode 100644 index 0000000..cc899c7 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/initialize-templates.py @@ -0,0 +1,57 @@ +#!/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 new file mode 100644 index 0000000..d6073e8 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/normalize_counts.json @@ -0,0 +1,414 @@ +{ + "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 new file mode 100644 index 0000000..550d562 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_expr_heatmap.json @@ -0,0 +1,567 @@ +{ + "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 new file mode 100644 index 0000000..8565011 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_pca_2d.json @@ -0,0 +1,296 @@ +{ + "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 new file mode 100644 index 0000000..39b95b4 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_pca_3d.json @@ -0,0 +1,217 @@ +{ + "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 new file mode 100644 index 0000000..c163c04 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_venn_diagram.json @@ -0,0 +1,1106 @@ +{ + "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 new file mode 100644 index 0000000..0ce898a --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_volcano_enhanced.json @@ -0,0 +1,331 @@ +{ + "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 new file mode 100644 index 0000000..2d411a5 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/plot_volcano_summary.json @@ -0,0 +1,5125 @@ +{ + "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 new file mode 100644 index 0000000..d18be56 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/1_mosuite-templates/write_multiOmicDataSet_properties.json @@ -0,0 +1,53 @@ +{ + "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 new file mode 100644 index 0000000..006f336 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/batch_correct_counts.json @@ -0,0 +1,161 @@ +{ + "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 new file mode 100644 index 0000000..7f5c144 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/clean_raw_counts.json @@ -0,0 +1,156 @@ +{ + "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 new file mode 100644 index 0000000..c20d116 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/create_multiOmicDataSet_from_files.json @@ -0,0 +1,83 @@ +{ + "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 new file mode 100644 index 0000000..dfbc40e --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/diff_counts.json @@ -0,0 +1,181 @@ +{ + "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 new file mode 100644 index 0000000..58d5f49 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/filter_counts.json @@ -0,0 +1,427 @@ +{ + "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 new file mode 100644 index 0000000..d1756e0 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/filter_diff.json @@ -0,0 +1,345 @@ +{ + "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 new file mode 100644 index 0000000..118f7fe --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/normalize_counts.json @@ -0,0 +1,408 @@ +{ + "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 new file mode 100644 index 0000000..5d77de0 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_expr_heatmap.json @@ -0,0 +1,558 @@ +{ + "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 new file mode 100644 index 0000000..1655813 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_pca_2d.json @@ -0,0 +1,275 @@ +{ + "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 new file mode 100644 index 0000000..54b06e8 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_pca_3d.json @@ -0,0 +1,212 @@ +{ + "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 new file mode 100644 index 0000000..9bda288 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_venn_diagram.json @@ -0,0 +1,1100 @@ +{ + "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 new file mode 100644 index 0000000..b9acb91 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_volcano_enhanced.json @@ -0,0 +1,329 @@ +{ + "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 new file mode 100644 index 0000000..9e3cf80 --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/plot_volcano_summary.json @@ -0,0 +1,5129 @@ +{ + "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 new file mode 100644 index 0000000..3dd9a5f --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/2_blueprints/write_multiOmicDataSet_properties.json @@ -0,0 +1,52 @@ +{ + "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 new file mode 100644 index 0000000..3d92b9f --- /dev/null +++ b/code/MOSuite/inst/extdata/galaxy/galaxy.R @@ -0,0 +1,263 @@ +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 new file mode 100644 index 0000000..c128597 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/batch_correct_counts.json @@ -0,0 +1,16 @@ +{ + "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 new file mode 100644 index 0000000..e11a4fb --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/clean_raw_counts.json @@ -0,0 +1,14 @@ +{ + "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 new file mode 100644 index 0000000..7fc474a --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/create_multiOmicDataSet_from_files.json @@ -0,0 +1,5 @@ +{ + "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 new file mode 100644 index 0000000..700bf35 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/diff_counts.json @@ -0,0 +1,25 @@ +{ + "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 new file mode 100644 index 0000000..0e71be4 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/filter_counts.json @@ -0,0 +1,48 @@ +{ + "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 new file mode 100644 index 0000000..bc41bd7 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/filter_diff.json @@ -0,0 +1,38 @@ +{ + "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 new file mode 100644 index 0000000..a5acdb5 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/normalize_counts.json @@ -0,0 +1,33 @@ +{ + "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 new file mode 100644 index 0000000..b1dc1f3 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/plot_expr_heatmap.json @@ -0,0 +1,80 @@ +{ + "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 new file mode 100644 index 0000000..ab25827 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/plot_pca_2d.json @@ -0,0 +1,36 @@ +{ + "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 new file mode 100644 index 0000000..308d197 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/plot_pca_3d.json @@ -0,0 +1,31 @@ +{ + "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 new file mode 100644 index 0000000..2c3b334 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/plot_venn_diagram.json @@ -0,0 +1,40 @@ +{ + "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 new file mode 100644 index 0000000..960d6be --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/plot_volcano_enhanced.json @@ -0,0 +1,33 @@ +{ + "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 new file mode 100644 index 0000000..ee16ff7 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/plot_volcano_summary.json @@ -0,0 +1,52 @@ +{ + "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 new file mode 100644 index 0000000..61b1d34 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/common/write_multiOmicDataSet_properties.json @@ -0,0 +1,6 @@ +{ + "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 new file mode 100644 index 0000000..fe8d42e --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/batch_correct_counts.json @@ -0,0 +1,16 @@ +{ + "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 new file mode 100644 index 0000000..43c5568 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/clean_raw_counts.json @@ -0,0 +1,15 @@ +{ + "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 new file mode 100644 index 0000000..02c0e00 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/create_multiOmicDataSet_from_files.json @@ -0,0 +1,8 @@ +{ + "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 new file mode 100644 index 0000000..bc0c531 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/diff_counts.json @@ -0,0 +1,18 @@ +{ + "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 new file mode 100644 index 0000000..1e6feff --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/filter_counts.json @@ -0,0 +1,37 @@ +{ + "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 new file mode 100644 index 0000000..d255743 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/filter_diff.json @@ -0,0 +1,29 @@ +{ + "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 new file mode 100644 index 0000000..50c0e32 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/normalize_counts.json @@ -0,0 +1,35 @@ +{ + "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 new file mode 100644 index 0000000..c421963 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/plot_expr_heatmap.json @@ -0,0 +1,51 @@ +{ + "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 new file mode 100644 index 0000000..edada7f --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/plot_pca_2d.json @@ -0,0 +1,25 @@ +{ + "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 new file mode 100644 index 0000000..d8e342b --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/plot_pca_3d.json @@ -0,0 +1,21 @@ +{ + "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 new file mode 100644 index 0000000..10e4fb8 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/plot_venn_diagram.json @@ -0,0 +1,35 @@ +{ + "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 new file mode 100644 index 0000000..6185918 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/plot_volcano_enhanced.json @@ -0,0 +1,33 @@ +{ + "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 new file mode 100644 index 0000000..a7cf8ea --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/plot_volcano_summary.json @@ -0,0 +1,47 @@ +{ + "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 new file mode 100644 index 0000000..123f832 --- /dev/null +++ b/code/MOSuite/inst/extdata/json_args/defaults/write_multiOmicDataSet_properties.json @@ -0,0 +1,5 @@ +{ + "moo_input_rds": "moo.rds", + "moo_output_rds": "moo.rds", + "output_dir": "moo" +} diff --git a/code/MOSuite/inst/extdata/logo/create_logo.R b/code/MOSuite/inst/extdata/logo/create_logo.R new file mode 100644 index 0000000..ee0fc57 --- /dev/null +++ b/code/MOSuite/inst/extdata/logo/create_logo.R @@ -0,0 +1,213 @@ +#!/usr/bin/env Rscript +# Create hex logo for MOSuite package +# Design: Combine volcano plot + heatmap + +library(ggplot2) +library(hexSticker) +library(ggimage) +library(magick) +library(tidyverse) + +# Create directory if it doesn't exist + +set.seed(123) + +emoji_url <- "https://raw.githubusercontent.com/twitter/twemoji/master/assets/72x72/1f42e.png" +emoji_temp <- tempfile(fileext = ".png") +download.file(emoji_url, emoji_temp, quiet = TRUE, mode = "wb") + +# Convert to grayscale and apply transparency +emoji_gray <- magick::image_read(emoji_temp) |> + magick::image_quantize(colorspace = "gray") +emoji_gray_transparent <- magick::image_fx( + emoji_gray, + "0.3*u", + channel = "alpha" +) +magick::image_write(emoji_gray_transparent, emoji_temp) + +emoji_df <- data.frame( + x = 0.366, + y = 0.73, + image = emoji_temp +) + + +# ---- Volcano plot layer ---- + +load(here::here('data', 'nidap_deg_analysis.rda')) +volcano_data <- nidap_deg_analysis |> + rename(log2fc = `C-A_logFC`) |> + mutate(neg_log10_pval = -log10(`C-A_pval`)) + +fc_cut <- 1.0 +p_cut <- 2.5 + +volcano_data <- volcano_data |> + mutate( + regulation = case_when( + log2fc >= fc_cut & neg_log10_pval >= p_cut ~ "Upregulated", + log2fc <= -fc_cut & neg_log10_pval >= p_cut ~ "Downregulated", + neg_log10_pval >= p_cut ~ "Significant", + .default = "Not significant" + ), + x = scales::rescale(log2fc, to = c(0.12, 0.88)), + y = scales::rescale(neg_log10_pval, to = c(0.18, 0.94)), + color = case_when( + regulation == "Upregulated" ~ "#4e9db5", + regulation == "Downregulated" ~ "#ecba4c", + regulation == "Significant" ~ "#528230", + regulation == "Not significant" ~ "#999999", + .default = NA_character_ + ) + ) + +# ---- Heatmap layer ---- +rows <- paste0("G", sprintf("%02d", 1:12)) +cols <- paste0("S", sprintf("%02d", 1:10)) + +base_matrix <- matrix(rnorm(12 * 10, mean = 0, sd = 0.5), nrow = 12, ncol = 10) +base_matrix[1:4, 1:5] <- base_matrix[1:4, 1:5] + 2.0 # up cluster +base_matrix[9:12, 6:10] <- base_matrix[9:12, 6:10] - 2.0 # down cluster +base_matrix[5:8, 4:7] <- base_matrix[5:8, 4:7] + 1.0 # moderate cluster + +heatmap_df <- expand.grid(Row = rows, Col = cols) |> + mutate( + Value = as.vector(base_matrix), + Value = scales::rescale(Value, to = c(-2, 2)), + x = scales::rescale( + as.numeric(factor(Col, levels = cols)), + to = c(0.10, 0.90) + ), + y = scales::rescale( + as.numeric(factor(Row, levels = rows)), + to = c(0.16, 0.96) + ) + ) + +heat_colors <- c("#4e9db5", "#F7F7F7", "#ecba4c") +tile_width <- (0.90 - 0.10) / length(cols) +tile_height <- (0.96 - 0.16) / length(rows) + +# ---- Combined plot ---- +# Heatmap as background, volcano points as foreground +p <- ggplot() + + geom_tile( + data = heatmap_df, + aes(x = x, y = y, fill = Value), + width = tile_width, + height = tile_height, + color = "#D0D0D0", + linewidth = 0.2, + alpha = 0.5, + show.legend = FALSE + ) + + scale_fill_gradient2( + low = heat_colors[1], + mid = heat_colors[2], + high = heat_colors[3], + midpoint = 0, + guide = "none" + ) + + # Volcano points on top + geom_point( + data = volcano_data, + aes(x = x, y = y, color = color), + size = 2.0, + alpha = 0.5, + shape = 16, + show.legend = FALSE + ) + + annotate( + "text", + x = 0.5, + y = 0.725, + label = "MOSuite", + size = 16, + fontface = "bold", + family = "sans", + color = "#296b7f" + ) + + ggimage::geom_image( + # emoji + data = emoji_df, + aes(x = 0.33, y = 0.725, image = image), + size = 0.08, + inherit.aes = FALSE + ) + + scale_color_identity() + + coord_fixed(xlim = c(0, 1), ylim = c(0, 1), expand = FALSE) + + theme_void() + + theme( + plot.background = element_rect(fill = "#FFF", color = NA), + plot.margin = margin(0, 0, 0, 0) + ) +print(p) + +ggsave( + here::here('inst', 'extdata', 'logo', 'mosuite_logo_with_text.png'), + plot = p, + dpi = 300, + width = 3, + height = 3 +) + +# background only +p_background <- ggplot() + + geom_tile( + data = heatmap_df, + aes(x = x, y = y, fill = Value), + width = tile_width, + height = tile_height, + color = "#D0D0D0", + linewidth = 0.2, + alpha = 0.8, + show.legend = FALSE + ) + + scale_fill_gradient2( + low = heat_colors[1], + mid = heat_colors[2], + high = heat_colors[3], + midpoint = 0, + guide = "none" + ) + + # Volcano points on top + geom_point( + data = volcano_data, + aes(x = x, y = y, color = color), + size = 2.0, + alpha = 0.8, + shape = 16, + show.legend = FALSE + ) + + ggimage::geom_image( + # emoji + data = emoji_df, + aes(x = 0.33, y = 0.725, image = image), + size = 0.08, + inherit.aes = FALSE + ) + + scale_color_identity() + + coord_fixed(xlim = c(0, 1), ylim = c(0, 1), expand = FALSE) + + theme_void() + + theme( + plot.background = element_rect(fill = "#FFF", color = NA), + plot.margin = margin(0, 0, 0, 0) + ) +print(p_background) +ggsave( + here::here('inst', 'extdata', 'logo', 'mosuite_logo_background.png'), + plot = p_background, + dpi = 300, + width = 3, + height = 3 +) + +# need to run this line interactively for it to actually overwrite the logo file +usethis::use_logo(here::here( + 'inst', + 'extdata', + 'logo', + 'mosuite_logo_background.png' +)) +pkgdown::build_favicons(overwrite = TRUE) diff --git a/code/MOSuite/inst/extdata/logo/mosuite_logo_background.png b/code/MOSuite/inst/extdata/logo/mosuite_logo_background.png new file mode 100644 index 0000000..eb0645e Binary files /dev/null and b/code/MOSuite/inst/extdata/logo/mosuite_logo_background.png differ diff --git a/code/MOSuite/inst/extdata/logo/mosuite_logo_with_text.png b/code/MOSuite/inst/extdata/logo/mosuite_logo_with_text.png new file mode 100644 index 0000000..05bfa7f Binary files /dev/null and b/code/MOSuite/inst/extdata/logo/mosuite_logo_with_text.png differ diff --git a/code/MOSuite/inst/extdata/nidap/Batch_Corrected_Counts.csv.gz b/code/MOSuite/inst/extdata/nidap/Batch_Corrected_Counts.csv.gz new file mode 100644 index 0000000..43cdc75 Binary files /dev/null and b/code/MOSuite/inst/extdata/nidap/Batch_Corrected_Counts.csv.gz differ diff --git a/code/MOSuite/inst/extdata/nidap/Clean_Raw_Counts.csv.gz b/code/MOSuite/inst/extdata/nidap/Clean_Raw_Counts.csv.gz new file mode 100644 index 0000000..e47f767 Binary files /dev/null and b/code/MOSuite/inst/extdata/nidap/Clean_Raw_Counts.csv.gz differ diff --git a/code/MOSuite/inst/extdata/nidap/DEG_Analysis.csv.gz b/code/MOSuite/inst/extdata/nidap/DEG_Analysis.csv.gz new file mode 100644 index 0000000..21660b7 Binary files /dev/null and b/code/MOSuite/inst/extdata/nidap/DEG_Analysis.csv.gz differ diff --git a/code/MOSuite/inst/extdata/nidap/DEG_Gene_List.csv.gz b/code/MOSuite/inst/extdata/nidap/DEG_Gene_List.csv.gz new file mode 100644 index 0000000..cd78a54 Binary files /dev/null and b/code/MOSuite/inst/extdata/nidap/DEG_Gene_List.csv.gz differ diff --git a/code/MOSuite/inst/extdata/nidap/Filtered_Counts.csv.gz b/code/MOSuite/inst/extdata/nidap/Filtered_Counts.csv.gz new file mode 100644 index 0000000..54be377 Binary files /dev/null and b/code/MOSuite/inst/extdata/nidap/Filtered_Counts.csv.gz differ diff --git a/code/MOSuite/inst/extdata/nidap/Normalized_Counts.csv.gz b/code/MOSuite/inst/extdata/nidap/Normalized_Counts.csv.gz new file mode 100644 index 0000000..0a4a12d Binary files /dev/null and b/code/MOSuite/inst/extdata/nidap/Normalized_Counts.csv.gz differ diff --git a/code/MOSuite/inst/extdata/nidap/Raw_Counts.csv.gz b/code/MOSuite/inst/extdata/nidap/Raw_Counts.csv.gz new file mode 100644 index 0000000..6a89e8b Binary files /dev/null and b/code/MOSuite/inst/extdata/nidap/Raw_Counts.csv.gz differ diff --git a/code/MOSuite/inst/extdata/nidap/Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz b/code/MOSuite/inst/extdata/nidap/Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz new file mode 100644 index 0000000..51036aa Binary files /dev/null and b/code/MOSuite/inst/extdata/nidap/Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz differ diff --git a/code/MOSuite/inst/extdata/nidap/Venn_Diagram.csv.gz b/code/MOSuite/inst/extdata/nidap/Venn_Diagram.csv.gz new file mode 100644 index 0000000..c14dc31 Binary files /dev/null and b/code/MOSuite/inst/extdata/nidap/Venn_Diagram.csv.gz differ diff --git a/code/MOSuite/inst/extdata/nidap/Volcano_Summary.csv.gz b/code/MOSuite/inst/extdata/nidap/Volcano_Summary.csv.gz new file mode 100644 index 0000000..fb3ec17 Binary files /dev/null and b/code/MOSuite/inst/extdata/nidap/Volcano_Summary.csv.gz differ diff --git a/code/MOSuite/inst/extdata/sample_metadata.tsv.gz b/code/MOSuite/inst/extdata/sample_metadata.tsv.gz new file mode 100644 index 0000000..022e127 Binary files /dev/null and b/code/MOSuite/inst/extdata/sample_metadata.tsv.gz differ diff --git a/code/MOSuite/man/MOSuite-package.Rd b/code/MOSuite/man/MOSuite-package.Rd new file mode 100644 index 0000000..f9afbde --- /dev/null +++ b/code/MOSuite/man/MOSuite-package.Rd @@ -0,0 +1,43 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/MOSuite-package.R +\docType{package} +\name{MOSuite-package} +\alias{MOSuite} +\alias{MOSuite-package} +\title{MOSuite: R package for downstream multi-omics analysis} +\description{ +Designed for differential \href{https://github.com/CCBR/RENEE}{RNA-seq} analysis +or any data represented in a counts table. +} +\details{ +See the website for more information, documentation, and examples: +\url{https://ccbr.github.io/MOSuite} +} +\seealso{ +Useful links: +\itemize{ + \item \url{https://github.com/CCBR/MOSuite} + \item \url{https://ccbr.github.io/MOSuite/} + \item Report bugs at \url{https://github.com/CCBR/MOSuite/issues} +} + +} +\author{ +\strong{Maintainer}: Kelly Sovacool \email{kelly.sovacool@nih.gov} (\href{https://orcid.org/0000-0003-3283-829X}{ORCID}) + +Authors: +\itemize{ + \item Kelly Sovacool \email{kelly.sovacool@nih.gov} (\href{https://orcid.org/0000-0003-3283-829X}{ORCID}) + \item Philip Homan \email{philip.homan@nih.gov} + \item Vishal Koparde \email{vishal.koparde@nih.gov} (\href{https://orcid.org/0000-0001-8978-8495}{ORCID}) + \item Samantha Chill \email{samantha.chill@nih.gov} (\href{https://orcid.org/0000-0002-8734-9875}{ORCID}) +} + +Other contributors: +\itemize{ + \item T. Joshua Meyer \email{thomas.meyer@nih.gov} [contributor] + \item CCR Collaborative Bioinformatics Resource [copyright holder] +} + +} +\keyword{internal} diff --git a/code/MOSuite/man/abort_packages_not_installed.Rd b/code/MOSuite/man/abort_packages_not_installed.Rd new file mode 100644 index 0000000..929885a --- /dev/null +++ b/code/MOSuite/man/abort_packages_not_installed.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{abort_packages_not_installed} +\alias{abort_packages_not_installed} +\title{Throw error if required packages are not installed.} +\usage{ +abort_packages_not_installed(...) +} +\arguments{ +\item{...}{names of packages to check} +} +\description{ +Reports which packages need to be installed and the parent function name. +See +https://stackoverflow.com/questions/15595478/how-to-get-the-name-of-the-calling-function-inside-the-called-routine +} +\examples{ +\dontrun{ +abort_packages_not_installed("base") +abort_packages_not_installed("not-a-package-name", "caret", "dplyr", "non_package") +} +} +\keyword{internal} diff --git a/code/MOSuite/man/aggregate_duplicate_gene_names.Rd b/code/MOSuite/man/aggregate_duplicate_gene_names.Rd new file mode 100644 index 0000000..368d64b --- /dev/null +++ b/code/MOSuite/man/aggregate_duplicate_gene_names.Rd @@ -0,0 +1,46 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/clean.R +\name{aggregate_duplicate_gene_names} +\alias{aggregate_duplicate_gene_names} +\title{Aggregate duplicate gene names} +\usage{ +aggregate_duplicate_gene_names( + counts_dat, + gene_name_column_to_use_for_collapsing_duplicates, + aggregate_rows_with_duplicate_gene_names, + split_gene_name +) +} +\arguments{ +\item{counts_dat}{dataframe with raw counts data} + +\item{gene_name_column_to_use_for_collapsing_duplicates}{Select the column +with Feature IDs to use as grouping elements to collapse the counts matrix. +The log output will list the columns available to identify duplicate row +IDs in order to aggregate information. +If left blank your "Feature ID" Column will be used to Aggregate Rows. If +"Feature ID" column can be split into multiple IDs the non Ensembl ID name +will be used to aggregate duplicate IDs. If "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 an error will occur and you will have +to manually enter the Column ID for this field.} + +\item{aggregate_rows_with_duplicate_gene_names}{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. +Using the default behavior (\code{TRUE}), 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.} + +\item{split_gene_name}{If \code{TRUE}, split the gene name column by any of these special characters: \verb{,|_-:}} +} +\value{ +data frame with columns separated if possible +} +\description{ +Aggregate duplicate gene names +} +\keyword{internal} diff --git a/code/MOSuite/man/as_integer_df.Rd b/code/MOSuite/man/as_integer_df.Rd new file mode 100644 index 0000000..9bf4fce --- /dev/null +++ b/code/MOSuite/man/as_integer_df.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/counts.R +\name{as_integer_df} +\alias{as_integer_df} +\title{Convert all numeric columns in a dataframe to integers} +\usage{ +as_integer_df(counts_tbl) +} +\arguments{ +\item{counts_tbl}{data frame with numeric columns} +} +\value{ +data frame with any numeric columns as integers +} +\description{ +Round doubles to integers and convert to integer type +} +\examples{ +\dontrun{ +data.frame(a = c(0, 0.1, 2.3, 5L, 6.9)) |> as_integer_df() +} +} +\keyword{internal} diff --git a/code/MOSuite/man/batch_correct_counts.Rd b/code/MOSuite/man/batch_correct_counts.Rd new file mode 100644 index 0000000..9be8aa8 --- /dev/null +++ b/code/MOSuite/man/batch_correct_counts.Rd @@ -0,0 +1,116 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/batch-correction.R +\name{batch_correct_counts} +\alias{batch_correct_counts} +\title{Perform batch correction} +\usage{ +batch_correct_counts( + moo, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "batch" +) +} +\arguments{ +\item{moo}{multiOmicDataSet object (see \code{create_multiOmicDataSet_from_dataframes()})} + +\item{count_type}{the type of counts to use -- must be a name in the counts slot (\code{moo@counts})} + +\item{sub_count_type}{if \code{count_type} is a list, specify the sub count type within the list. (Default: \code{"voom"})} + +\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 +used.)} + +\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{covariates_colnames}{The column name(s) from the sample metadata +containing variable(s) 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. +Do not include the \code{batch_colname} here.} + +\item{batch_colname}{The column from the sample metadata 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 data sets have batches, in which case you do not need batch correction. +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.)} + +\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{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{plots_subdir}{subdirectory in \verb{figures/} where plots will be saved if \code{save_plots} is \code{TRUE}} +} +\value{ +\code{multiOmicDataSet} with batch-corrected counts +} +\description{ +Perform batch correction using sva::ComBat() +} +\examples{ +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", + covariates_colnames = "Group", + batch_colname = "Batch", + label_colname = "Label" + ) + +head(moo@counts[["batch"]]) + +} +\seealso{ +Other moo methods: +\code{\link[=clean_raw_counts]{clean_raw_counts()}}, +\code{\link[=diff_counts]{diff_counts()}}, +\code{\link[=filter_counts]{filter_counts()}}, +\code{\link[=filter_diff]{filter_diff()}}, +\code{\link[=normalize_counts]{normalize_counts()}}, +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=run_deseq2]{run_deseq2()}}, +\code{\link[=set_color_pal]{set_color_pal()}} +} +\concept{moo methods} diff --git a/code/MOSuite/man/bind_dfs_long.Rd b/code/MOSuite/man/bind_dfs_long.Rd new file mode 100644 index 0000000..661d9b1 --- /dev/null +++ b/code/MOSuite/man/bind_dfs_long.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{bind_dfs_long} +\alias{bind_dfs_long} +\title{Bind dataframes in named list to long dataframe} +\usage{ +bind_dfs_long(df_list, outcolname = contrast) +} +\arguments{ +\item{df_list}{named list of dataframes} + +\item{outcolname}{column name in output dataframe for the names from the named list} +} +\value{ +long dataframe with new column \code{outcolname} from named list +} +\description{ +The dataframes must have all of the same columns +} +\examples{ + +dfs <- list( + "a_vs_b" = data.frame(id = c("a1", "b2", "c3"), score = runif(3)), + "b_vs_c" = data.frame(id = c("a1", "b2", "c3"), score = rnorm(3)) +) +dfs |> bind_dfs_long() + +} +\keyword{utilities} diff --git a/code/MOSuite/man/calc_cpm.Rd b/code/MOSuite/man/calc_cpm.Rd new file mode 100644 index 0000000..0c589da --- /dev/null +++ b/code/MOSuite/man/calc_cpm.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/counts.R +\name{calc_cpm} +\alias{calc_cpm} +\title{Calculate counts-per-million (CPM) on raw counts in a multiOmicDataSet} +\usage{ +calc_cpm(moo, ...) +} +\arguments{ +\item{moo}{multiOmicDataSet object} + +\item{...}{additional arguments to pass to edgeR::cpm()} +} +\value{ +multiOmicDataSet with cpm-transformed counts +} +\description{ +Calculate counts-per-million (CPM) on raw counts in a multiOmicDataSet +} +\examples{ +sample_meta <- data.frame( + sample_id = c("KO_S3", "KO_S4", "WT_S1", "WT_S2"), + condition = factor( + c("knockout", "knockout", "wildtype", "wildtype"), + levels = c("wildtype", "knockout") + ) +) +moo <- create_multiOmicDataSet_from_dataframes(sample_meta, gene_counts) |> + calc_cpm() +head(moo@counts$cpm) +} diff --git a/code/MOSuite/man/calc_cpm_df.Rd b/code/MOSuite/man/calc_cpm_df.Rd new file mode 100644 index 0000000..440e0f7 --- /dev/null +++ b/code/MOSuite/man/calc_cpm_df.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/counts.R +\name{calc_cpm_df} +\alias{calc_cpm_df} +\title{Calculate CPM on a data frame} +\usage{ +calc_cpm_df(dat, feature_id_colname = "gene_id", ...) +} +\arguments{ +\item{dat}{data frame of counts with a gene column} + +\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{...}{additional arguments to pass to edger::cpm()} +} +\value{ +cpm-transformed counts as a data frame +} +\description{ +Calculate CPM on a data frame +} +\keyword{internal} diff --git a/code/MOSuite/man/calc_pca.Rd b/code/MOSuite/man/calc_pca.Rd new file mode 100644 index 0000000..c88960b --- /dev/null +++ b/code/MOSuite/man/calc_pca.Rd @@ -0,0 +1,43 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_pca.R +\name{calc_pca} +\alias{calc_pca} +\title{Perform principal components analysis} +\usage{ +calc_pca( + counts_dat, + sample_metadata, + sample_id_colname = NULL, + feature_id_colname = NULL +) +} +\arguments{ +\item{counts_dat}{data frame of feature counts (e.g. from the counts slot of a \code{multiOmicDataSet}).} + +\item{sample_metadata}{sample metadata as a data frame or tibble.} + +\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 dataa 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 +used.)} +} +\value{ +data frame with statistics for each principal component +} +\description{ +Perform principal components analysis +} +\examples{ +calc_pca(nidap_raw_counts, nidap_sample_metadata) |> head() +} +\seealso{ +Other PCA functions: +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_pca_2d]{plot_pca_2d()}}, +\code{\link[=plot_pca_3d]{plot_pca_3d()}} +} +\concept{PCA functions} diff --git a/code/MOSuite/man/check_packages_installed.Rd b/code/MOSuite/man/check_packages_installed.Rd new file mode 100644 index 0000000..96e5a77 --- /dev/null +++ b/code/MOSuite/man/check_packages_installed.Rd @@ -0,0 +1,25 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{check_packages_installed} +\alias{check_packages_installed} +\title{Check whether package(s) are installed} +\usage{ +check_packages_installed(...) +} +\arguments{ +\item{...}{names of packages to check} +} +\value{ +named vector with status of each packages; installed (\code{TRUE}) or not (\code{FALSE}) +} +\description{ +Check whether package(s) are installed +} +\examples{ +\dontrun{ +check_packages_installed("base") +check_packages_installed("not-a-package-name") +all(check_packages_installed("parallel", "doFuture")) +} +} +\keyword{internal} diff --git a/code/MOSuite/man/clean_raw_counts.Rd b/code/MOSuite/man/clean_raw_counts.Rd new file mode 100644 index 0000000..f4f580d --- /dev/null +++ b/code/MOSuite/man/clean_raw_counts.Rd @@ -0,0 +1,112 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/clean.R +\name{clean_raw_counts} +\alias{clean_raw_counts} +\title{Clean Raw Counts} +\usage{ +clean_raw_counts( + moo, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "clean" +) +} +\arguments{ +\item{moo}{multiOmicDataSet object (see \code{create_multiOmicDataSet_from_dataframes()})} + +\item{count_type}{the type of counts to use -- must be a name in the counts slot (\code{moo@counts})} + +\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 +used.)} + +\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{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 +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.} + +\item{split_gene_name}{If \code{TRUE}, split the gene name column by any of these special characters: \verb{,|_-:}} + +\item{aggregate_rows_with_duplicate_gene_names}{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. +Using the default behavior (\code{TRUE}), 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.} + +\item{gene_name_column_to_use_for_collapsing_duplicates}{Select the column +with Feature IDs to use as grouping elements to collapse the counts matrix. +The log output will list the columns available to identify duplicate row +IDs in order to aggregate information. +If left blank your "Feature ID" Column will be used to Aggregate Rows. If +"Feature ID" column can be split into multiple IDs the non Ensembl ID name +will be used to aggregate duplicate IDs. If "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 an error will occur and you will have +to manually enter the Column ID for this field.} + +\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{plots_subdir}{subdirectory in \verb{figures/} where plots will be saved if \code{save_plots} is \code{TRUE}} +} +\value{ +\code{multiOmicDataSet} with cleaned counts +} +\description{ +This function checks the input raw counts matrix for common formatting problems with feature identifiers and sample +names. If feature IDs contain multiple IDs separated by special characters (| - , or space) they will be split into +multiple columns. If duplicate feature IDs are detected the counts are summed across duplicate feature ID rows +within each sample. Invalid sample names will also be reported and can be automatically +corrected. If your sample names are corrected here, be sure to make equivalent changes to your metadata table. +} +\examples{ +moo <- create_multiOmicDataSet_from_dataframes( + as.data.frame(nidap_sample_metadata), + as.data.frame(nidap_raw_counts), + sample_id_colname = "Sample", +) |> + clean_raw_counts(sample_id_colname = "Sample", feature_id_colname = "GeneName") +head(moo@counts$clean) +} +\seealso{ +Other moo methods: +\code{\link[=batch_correct_counts]{batch_correct_counts()}}, +\code{\link[=diff_counts]{diff_counts()}}, +\code{\link[=filter_counts]{filter_counts()}}, +\code{\link[=filter_diff]{filter_diff()}}, +\code{\link[=normalize_counts]{normalize_counts()}}, +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=run_deseq2]{run_deseq2()}}, +\code{\link[=set_color_pal]{set_color_pal()}} +} +\concept{moo methods} diff --git a/code/MOSuite/man/cli_exec.Rd b/code/MOSuite/man/cli_exec.Rd new file mode 100644 index 0000000..5b4e011 --- /dev/null +++ b/code/MOSuite/man/cli_exec.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cli.R +\name{cli_exec} +\alias{cli_exec} +\title{Execute MOSuite from the CLI} +\usage{ +cli_exec(clargs = commandArgs(trailingOnly = TRUE)) +} +\description{ +Execute MOSuite from the CLI +} +\keyword{internal} diff --git a/code/MOSuite/man/cli_from_json.Rd b/code/MOSuite/man/cli_from_json.Rd new file mode 100644 index 0000000..c608dcb --- /dev/null +++ b/code/MOSuite/man/cli_from_json.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cli.R +\name{cli_from_json} +\alias{cli_from_json} +\title{Call an MOSuite function with arguments specified in a json file} +\usage{ +cli_from_json(method, json, debug = FALSE) +} +\arguments{ +\item{method}{function in MOSuite to call} + +\item{json}{path to a JSON file containing arguments for the function. +Additionally, the JSON can contain the following keys: +\itemize{ +\item \code{moo_input_rds} - filepath to an existing MultiOmicsDataset object in RDS format. +This is required if the MOSuite function contains \code{moo} as an argument. +\item \code{moo_output_rds} - filepath to write the result to. +}} + +\item{debug}{when TRUE, do not call the command, just return the expression.} +} +\value{ +invisible returns the function call +} +\description{ +Call an MOSuite function with arguments specified in a json file +} +\keyword{internal} diff --git a/code/MOSuite/man/counts_dat_to_matrix.Rd b/code/MOSuite/man/counts_dat_to_matrix.Rd new file mode 100644 index 0000000..7976d80 --- /dev/null +++ b/code/MOSuite/man/counts_dat_to_matrix.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/counts.R +\name{counts_dat_to_matrix} +\alias{counts_dat_to_matrix} +\title{Convert a data frame of gene counts to a matrix} +\usage{ +counts_dat_to_matrix(counts_tbl, feature_id_colname = NULL) +} +\arguments{ +\item{counts_tbl}{expected feature counts as a dataframe or tibble, with all columns except \code{feature_id_colname}} + +\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.)} +} +\value{ +matrix of gene counts with rows as gene IDs +} +\description{ +Convert a data frame of gene counts to a matrix +} +\examples{ +\dontrun{ +counts_dat_to_matrix(head(gene_counts)) +} +} +\keyword{internal} diff --git a/code/MOSuite/man/create_multiOmicDataSet_from_dataframes.Rd b/code/MOSuite/man/create_multiOmicDataSet_from_dataframes.Rd new file mode 100644 index 0000000..2b41357 --- /dev/null +++ b/code/MOSuite/man/create_multiOmicDataSet_from_dataframes.Rd @@ -0,0 +1,63 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/0_mo-class.R +\name{create_multiOmicDataSet_from_dataframes} +\alias{create_multiOmicDataSet_from_dataframes} +\title{Construct a multiOmicDataSet object from data frames} +\usage{ +create_multiOmicDataSet_from_dataframes( + sample_metadata, + counts_dat, + sample_id_colname = NULL, + feature_id_colname = NULL, + count_type = "raw" +) +} +\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{counts_dat}{data frame of feature counts (e.g. expected feature counts from RSEM).} + +\item{sample_id_colname}{name of the column in \code{sample_metadata} that contains the sample IDs. (Default: \code{NULL} - +first column in the sample metadata will be used.)} + +\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{count_type}{type to assign the values of \code{counts_dat} to in the \code{counts} slot} +} +\value{ +\link{multiOmicDataSet} object +} +\description{ +Construct a multiOmicDataSet object from data frames +} +\examples{ +sample_meta <- data.frame( + sample_id = c("KO_S3", "KO_S4", "WT_S1", "WT_S2"), + condition = factor( + c("knockout", "knockout", "wildtype", "wildtype"), + levels = c("wildtype", "knockout") + ) +) +moo <- create_multiOmicDataSet_from_dataframes(sample_meta, gene_counts) +head(moo@sample_meta) +head(moo@counts$raw) +head(moo@annotation) + +sample_meta_nidap <- readr::read_csv(system.file("extdata", "nidap", + "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", + package = "MOSuite" +)) +raw_counts_nidap <- readr::read_csv(system.file("extdata", "nidap", "Raw_Counts.csv.gz", + package = "MOSuite" +)) +moo_nidap <- create_multiOmicDataSet_from_dataframes(sample_meta_nidap, raw_counts_nidap) + +} +\seealso{ +Other moo constructors: +\code{\link[=create_multiOmicDataSet_from_files]{create_multiOmicDataSet_from_files()}}, +\code{\link[=multiOmicDataSet]{multiOmicDataSet()}} +} +\concept{moo constructors} diff --git a/code/MOSuite/man/create_multiOmicDataSet_from_files.Rd b/code/MOSuite/man/create_multiOmicDataSet_from_files.Rd new file mode 100644 index 0000000..b931f40 --- /dev/null +++ b/code/MOSuite/man/create_multiOmicDataSet_from_files.Rd @@ -0,0 +1,71 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/0_mo-class.R +\name{create_multiOmicDataSet_from_files} +\alias{create_multiOmicDataSet_from_files} +\title{Construct a multiOmicDataSet object from text files (e.g. TSV, CSV).} +\usage{ +create_multiOmicDataSet_from_files( + sample_meta_filepath, + feature_counts_filepath, + count_type = "raw", + sample_id_colname = NULL, + feature_id_colname = NULL, + delim = NULL, + ... +) +} +\arguments{ +\item{sample_meta_filepath}{path to text file with sample IDs and metadata for differential analysis.} + +\item{feature_counts_filepath}{path to text file of expected feature counts (e.g. gene counts from RSEM).} + +\item{count_type}{type to assign the values of \code{counts_dat} to in the \code{counts} slot} + +\item{sample_id_colname}{name of the column in \code{sample_metadata} that contains the sample IDs. (Default: \code{NULL} - +first column in the sample metadata will be used.)} + +\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{delim}{Delimiter used in the input files. Any delimiter accepted by \code{readr::read_delim()} can be used. +If the files are in CSV format, set \code{delim = ','}; for TSV format, set \code{delim = '\\t'}.} + +\item{...}{additional arguments forwarded to \code{readr::read_delim()}.} +} +\value{ +\link{multiOmicDataSet} object +} +\description{ +Construct a multiOmicDataSet object from text files (e.g. TSV, CSV). +} +\examples{ +moo <- create_multiOmicDataSet_from_files( + sample_meta_filepath = system.file("extdata", + "sample_metadata.tsv.gz", + package = "MOSuite" + ), + feature_counts_filepath = system.file("extdata", + "RSEM.genes.expected_count.all_samples.txt.gz", + package = "MOSuite" + ), + delim = "\t" +) +moo@counts$raw |> head() +moo@sample_meta + +moo_nidap <- create_multiOmicDataSet_from_files( + system.file("extdata", "nidap", + "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", + package = "MOSuite" + ), + system.file("extdata", "nidap", "Raw_Counts.csv.gz", package = "MOSuite"), + delim = "," +) + +} +\seealso{ +Other moo constructors: +\code{\link[=create_multiOmicDataSet_from_dataframes]{create_multiOmicDataSet_from_dataframes()}}, +\code{\link[=multiOmicDataSet]{multiOmicDataSet()}} +} +\concept{moo constructors} diff --git a/code/MOSuite/man/diff_counts.Rd b/code/MOSuite/man/diff_counts.Rd new file mode 100644 index 0000000..bf72697 --- /dev/null +++ b/code/MOSuite/man/diff_counts.Rd @@ -0,0 +1,110 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/differential.R +\name{diff_counts} +\alias{diff_counts} +\title{Differential expression analysis} +\usage{ +diff_counts( + moo, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" +) +} +\arguments{ +\item{moo}{multiOmicDataSet object (see \code{create_multiOmicDataSet_from_dataframes()})} + +\item{count_type}{the type of counts to use -- must be a name in the counts slot (\code{moo@counts})} + +\item{sub_count_type}{if \code{count_type} is a list, specify the sub count type within the list. (Default: \code{NULL})} + +\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 +used.)} + +\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{covariates_colnames}{The column name(s) from the sample metadata containing variable(s) 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.} + +\item{contrast_colname}{The column in the metadata that contains the group variables you wish to find differential +expression between. Up to 2 columns (2-factor analysis) can be used.} + +\item{contrasts}{Specify each contrast in the format group1-group2, e.g. treated-control} + +\item{input_in_log_counts}{set this to \code{TRUE} if counts are already log2-transformed} + +\item{return_mean_and_sd}{if TRUE, return Mean and Standard Deviation of groups in addition to DEG estimates for +contrast(s)} + +\item{voom_normalization_method}{Normalization method to be applied to the logCPM values when using \code{limma::voom}} + +\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{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}) +} +\description{ +Differential expression analysis +} +\examples{ +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) + ) +) |> + diff_counts( + count_type = "filt", + sub_count_type = NULL, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + voom_normalization_method = "quantile", + ) +head(moo@analyses$diff) +} +\seealso{ +Other moo methods: +\code{\link[=batch_correct_counts]{batch_correct_counts()}}, +\code{\link[=clean_raw_counts]{clean_raw_counts()}}, +\code{\link[=filter_counts]{filter_counts()}}, +\code{\link[=filter_diff]{filter_diff()}}, +\code{\link[=normalize_counts]{normalize_counts()}}, +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=run_deseq2]{run_deseq2()}}, +\code{\link[=set_color_pal]{set_color_pal()}} +} +\concept{moo methods} diff --git a/code/MOSuite/man/do_math.Rd b/code/MOSuite/man/do_math.Rd new file mode 100644 index 0000000..79a56cf --- /dev/null +++ b/code/MOSuite/man/do_math.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{do_math} +\alias{do_math} +\title{Function for testing CLI argument parsing} +\usage{ +do_math(add = TRUE, subtract = FALSE, left = 1, right = 2) +} +\arguments{ +\item{add}{whether to add left and right} + +\item{subtract}{whether to subtract left and right} + +\item{left}{number on the left side of the operand} + +\item{right}{number on the right side of the operand} +} +\value{ +result of adding or subtracting left and right +} +\description{ +Function for testing CLI argument parsing +} +\keyword{internal} diff --git a/code/MOSuite/man/extract_counts.Rd b/code/MOSuite/man/extract_counts.Rd new file mode 100644 index 0000000..960be31 --- /dev/null +++ b/code/MOSuite/man/extract_counts.Rd @@ -0,0 +1,46 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/0_mo-class.R +\name{extract_counts} +\alias{extract_counts} +\alias{extract_counts,MOSuite::multiOmicDataSet-method} +\title{Extract count data} +\usage{ +extract_counts(moo, count_type, sub_count_type = NULL) + +## S7 method for class +extract_counts(moo, count_type, sub_count_type = NULL) +} +\arguments{ +\item{moo}{multiOmicDataSet containing \code{count_type} & \code{sub_count_type} in the counts slot} + +\item{count_type}{the type of counts to use -- must be a name in the counts slot (\code{moo@counts[[count_type]]})} + +\item{sub_count_type}{if \code{count_type} is a list, specify the sub count type within the list +(\code{moo@counts[[count_type]][[sub_count_type]]}). (Default: \code{NULL})} +} +\description{ +Extract count data +} +\examples{ +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) + ) + ) +) + +moo |> + extract_counts("filt") |> + head() + +moo |> + extract_counts("norm", "voom") |> + head() + +} diff --git a/code/MOSuite/man/figures/development-plan.png b/code/MOSuite/man/figures/development-plan.png new file mode 100644 index 0000000..8cd9f45 Binary files /dev/null and b/code/MOSuite/man/figures/development-plan.png differ diff --git a/code/MOSuite/man/figures/logo.png b/code/MOSuite/man/figures/logo.png new file mode 100644 index 0000000..24983da Binary files /dev/null and b/code/MOSuite/man/figures/logo.png differ diff --git a/code/MOSuite/man/filter_counts.Rd b/code/MOSuite/man/filter_counts.Rd new file mode 100644 index 0000000..984545b --- /dev/null +++ b/code/MOSuite/man/filter_counts.Rd @@ -0,0 +1,195 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/filter.R +\name{filter_counts} +\alias{filter_counts} +\title{Filter low counts} +\usage{ +filter_counts( + moo, + 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 = c(""), + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + interactive_plots = FALSE, + plots_subdir = "filt" +) +} +\arguments{ +\item{moo}{multiOmicDataSet object (see \code{create_multiOmicDataSet_from_dataframes()})} + +\item{count_type}{the type of counts to use -- must be a name in the counts slot (\code{moo@counts})} + +\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 +used.)} + +\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{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{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{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_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_a_group}{Only keeps genes that have at least this number of +samples with nonzero CPM counts 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 +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.} + +\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} + +\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{point_size_for_pca}{geom point size for the PCA plot} + +\item{add_label_to_pca}{label points on the PCA plot} + +\item{label_font_size}{label font size for the PCA plot} + +\item{label_offset_y_}{label offset y for the PCA plot} + +\item{label_offset_x_}{label offset x for the PCA plot} + +\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_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.} + +\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_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{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{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{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{ +\code{multiOmicDataSet} with filtered counts +} +\description{ +This is often the first step in the QC portion of an analysis to filter out +features that have very low raw counts across most or all of your samples. +} +\details{ +This function takes a multiOmicDataSet containing clean raw counts and a sample +metadata table, and returns the multiOmicDataSet object with filtered counts. +It also produces an image consisting of three QC plots. + +You can tune the threshold for tuning how low counts for a given gene are +before they are deemed "too low" and filtered out of downstream analysis. By +default, this parameter is set to 1, meaning any raw count value less than 1 +will count as "too low". + +The 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. +} +\examples{ +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( + count_type = "raw" + ) +head(moo@counts$filt) + +} +\seealso{ +Other moo methods: +\code{\link[=batch_correct_counts]{batch_correct_counts()}}, +\code{\link[=clean_raw_counts]{clean_raw_counts()}}, +\code{\link[=diff_counts]{diff_counts()}}, +\code{\link[=filter_diff]{filter_diff()}}, +\code{\link[=normalize_counts]{normalize_counts()}}, +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=run_deseq2]{run_deseq2()}}, +\code{\link[=set_color_pal]{set_color_pal()}} +} +\concept{moo methods} diff --git a/code/MOSuite/man/filter_diff.Rd b/code/MOSuite/man/filter_diff.Rd new file mode 100644 index 0000000..2a82849 --- /dev/null +++ b/code/MOSuite/man/filter_diff.Rd @@ -0,0 +1,144 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/differential.R +\name{filter_diff} +\alias{filter_diff} +\title{Filter features from differential analysis based on statistical significance} +\usage{ +filter_diff( + moo, + feature_id_colname = NULL, + significance_column = "adjpval", + significance_cutoff = 0.05, + change_column = "logFC", + change_cutoff = 1, + filtering_mode = "any", + include_estimates = c("FC", "logFC", "tstat", "pval", "adjpval"), + round_estimates = TRUE, + rounding_decimal_for_percent_cells = 0, + contrast_filter = "none", + contrasts = c(), + groups = c(), + groups_filter = "none", + label_font_size = 6, + label_distance = 1, + y_axis_expansion = 0.08, + fill_colors = c("steelblue1", "whitesmoke"), + pie_chart_in_3d = TRUE, + bar_width = 0.4, + draw_bar_border = TRUE, + plot_type = "bar", + plot_titles_fontsize = 12, + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = file.path("diff", "filt") +) +} +\arguments{ +\item{moo}{multiOmicDataSet object (see \code{create_multiOmicDataSet_from_dataframes()})} + +\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 +used.)} + +\item{significance_column}{Column name for significance, e.g. \code{"pval"} or \code{"pvaladj"} (default)} + +\item{significance_cutoff}{Features will only be kept if their \code{significance_column} is less then this cutoff +threshold} + +\item{change_column}{Column name for change, e.g. \code{"logFC"} (default)} + +\item{change_cutoff}{Features will only be kept if the absolute value of their \code{change_column} is greater than or +equal to this cutoff threshold} + +\item{filtering_mode}{Accepted values: \code{"any"} or \code{"all"} to include features that meet the criteria in \emph{any} +contrast or in \emph{all} contrasts} + +\item{include_estimates}{Column names of estimates to include. Default: \code{c("FC", "logFC", "tstat", "pval", "adjpval")}} + +\item{round_estimates}{Whether to round estimates. Default: \code{TRUE}} + +\item{rounding_decimal_for_percent_cells}{Decimal place to use when rounding Percent cells} + +\item{contrast_filter}{Whether to filter \code{contrasts} in or our of analysis. If \code{"keep"}, only the contrast names +listed in \code{contrasts} will be included. If \verb{"remove}, the contrast names listed by \code{contrasts} will be removed. If +\code{"none"}, all contrasts in the dataset are used. Options: \code{"keep"}, \code{"remove"}, or \code{"none"}} + +\item{contrasts}{Contrast names to filter by \code{contrast_filter}. If \code{contrast_filter} is \code{"none"}, this parameter has +no effect.} + +\item{groups}{Group names to filter by \code{groups_filter}. If \code{groups_filter} is \code{"none"}, this parameter has no effect. +Options: \code{"keep"}, \code{"remove"}, or \code{"none"}} + +\item{groups_filter}{Whether to filter \code{groups} in or out of analysis. If \code{"keep"}, only the group names listed in +\code{groups} will be included. If \code{"remove"}, the group names listed by \code{groups} will be removed. If \code{"none"}, all +groups in the dataset are used.} + +\item{label_font_size}{Font size for labels in the plot (default: 6)} + +\item{label_distance}{Distance of labels from the bars (default: 1)} + +\item{y_axis_expansion}{Expansion of the y-axis (default: 0.08)} + +\item{fill_colors}{Fill colors for the bars (default: c("steelblue1", "whitesmoke"))} + +\item{pie_chart_in_3d}{Whether to draw pie charts in 3D (default: TRUE)} + +\item{bar_width}{Width of the bars (default: 0.4)} + +\item{draw_bar_border}{Whether to draw borders around bars (default: TRUE)} + +\item{plot_type}{"bar" or "pie"} + +\item{plot_titles_fontsize}{Font size for plot titles (default: 12)} + +\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{plots_subdir}{subdirectory in where plots will be saved if \code{save_plots} is \code{TRUE}} +} +\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. +} +\examples{ +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) + ) +) |> + diff_counts( + count_type = "filt", + sub_count_type = NULL, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + voom_normalization_method = "quantile", + ) |> + filter_diff() +head(moo@analyses$diff_filt) +} +\seealso{ +Other moo methods: +\code{\link[=batch_correct_counts]{batch_correct_counts()}}, +\code{\link[=clean_raw_counts]{clean_raw_counts()}}, +\code{\link[=diff_counts]{diff_counts()}}, +\code{\link[=filter_counts]{filter_counts()}}, +\code{\link[=normalize_counts]{normalize_counts()}}, +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=run_deseq2]{run_deseq2()}}, +\code{\link[=set_color_pal]{set_color_pal()}} +} +\concept{moo methods} diff --git a/code/MOSuite/man/gene_counts.Rd b/code/MOSuite/man/gene_counts.Rd new file mode 100644 index 0000000..9fc18b9 --- /dev/null +++ b/code/MOSuite/man/gene_counts.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{gene_counts} +\alias{gene_counts} +\title{RSEM expected gene counts} +\format{ +\subsection{\code{gene_counts}}{ + +A data frame with columns 'gene_id', 'GeneName', and a column for each sample's expected count. +} +} +\source{ +Generated by running RENEE v2.5.8 on the +\href{https://github.com/CCBR/RENEE/tree/e08f7db6c6e638cfd330caa182f64665d2ef37fa/.tests}{test dataset} +} +\usage{ +gene_counts +} +\description{ +RSEM expected gene counts +} +\keyword{data} diff --git a/code/MOSuite/man/get_colors_lst.Rd b/code/MOSuite/man/get_colors_lst.Rd new file mode 100644 index 0000000..fbe22fa --- /dev/null +++ b/code/MOSuite/man/get_colors_lst.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/colors.R +\name{get_colors_lst} +\alias{get_colors_lst} +\title{Create named list of default colors for plotting} +\usage{ +get_colors_lst(sample_metadata, palette_fun = grDevices::palette.colors, ...) +} +\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}} +} +\value{ +named list, with each column in \code{sample_metadata} containing 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") +} +} diff --git a/code/MOSuite/man/get_colors_vctr.Rd b/code/MOSuite/man/get_colors_vctr.Rd new file mode 100644 index 0000000..adef32e --- /dev/null +++ b/code/MOSuite/man/get_colors_vctr.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/colors.R +\name{get_colors_vctr} +\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, ...) +} +\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{...}{additional arguments forwarded to \code{palette_fun}} +} +\value{ +named vector of colors for each unique observation in \code{dat$colname} +} +\description{ +Get vector of colors for observations in one column of a data frame +} diff --git a/code/MOSuite/man/get_pc_percent_lab.Rd b/code/MOSuite/man/get_pc_percent_lab.Rd new file mode 100644 index 0000000..a317d66 --- /dev/null +++ b/code/MOSuite/man/get_pc_percent_lab.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_pca.R +\name{get_pc_percent_lab} +\alias{get_pc_percent_lab} +\title{Get label for Principal Component with percent of variation} +\usage{ +get_pc_percent_lab(pca_df, pc) +} +\arguments{ +\item{pca_df}{data frame from \code{calc_pca()}} + +\item{pc}{which principal component to report (e.g. \code{1})} +} +\value{ +glue string formatted with PC's percent of variation +} +\description{ +Get label for Principal Component with percent of variation +} +\examples{ +\dontrun{ +data.frame(PC = c(1, 2, 3), percent = c(40, 10, 0.5)) |> + get_pc_percent_lab(2) +} +} +\keyword{internal} diff --git a/code/MOSuite/man/get_random_colors.Rd b/code/MOSuite/man/get_random_colors.Rd new file mode 100644 index 0000000..3b6fd5a --- /dev/null +++ b/code/MOSuite/man/get_random_colors.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/colors.R +\name{get_random_colors} +\alias{get_random_colors} +\title{Get random colors.} +\usage{ +get_random_colors(num_colors, n = 2000) +} +\arguments{ +\item{num_colors}{number of colors to select.} + +\item{n}{number of random RGB values to generate in the color space.} +} +\value{ +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)}. +} +\examples{ +\dontrun{ +set.seed(10) +get_random_colors(5) +} +} +\keyword{internal} diff --git a/code/MOSuite/man/glue_gene_symbols.Rd b/code/MOSuite/man/glue_gene_symbols.Rd new file mode 100644 index 0000000..0eece4a --- /dev/null +++ b/code/MOSuite/man/glue_gene_symbols.Rd @@ -0,0 +1,25 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{glue_gene_symbols} +\alias{glue_gene_symbols} +\title{Glue gene_id and GeneName columns into one column} +\usage{ +glue_gene_symbols(counts_dat) +} +\arguments{ +\item{counts_dat}{data frame containing gene_id and GeneName columns} +} +\value{ +counts_dat with gene_id and GeneName joined with \code{|} as the new gene_id column +} +\description{ +Glue gene_id and GeneName columns into one column +} +\examples{ +\dontrun{ +gene_counts |> + glue_gene_symbols() |> + head() +} +} +\keyword{internal} diff --git a/code/MOSuite/man/join_dfs_wide.Rd b/code/MOSuite/man/join_dfs_wide.Rd new file mode 100644 index 0000000..19590f4 --- /dev/null +++ b/code/MOSuite/man/join_dfs_wide.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{join_dfs_wide} +\alias{join_dfs_wide} +\title{Join dataframes in named list to wide dataframe} +\usage{ +join_dfs_wide(df_list, join_fn = dplyr::left_join) +} +\arguments{ +\item{df_list}{named list of dataframes} + +\item{join_fn}{join function to use (Default: \code{dplyr::left_join})} +} +\value{ +wide dataframe +} +\description{ +The first column is assumed to be shared by all dataframes +} +\examples{ + +dfs <- list( + "a_vs_b" = data.frame(id = c("a1", "b2", "c3"), score = runif(3)), + "b_vs_c" = data.frame(id = c("a1", "b2", "c3"), score = rnorm(3)) +) +dfs |> join_dfs_wide() + +} +\keyword{utilities} diff --git a/code/MOSuite/man/load_moo_from_data_dir.Rd b/code/MOSuite/man/load_moo_from_data_dir.Rd new file mode 100644 index 0000000..210aa48 --- /dev/null +++ b/code/MOSuite/man/load_moo_from_data_dir.Rd @@ -0,0 +1,25 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{load_moo_from_data_dir} +\alias{load_moo_from_data_dir} +\title{Load multiOmicDataSet from data directory} +\usage{ +load_moo_from_data_dir(data_dir = file.path("..", "data")) +} +\arguments{ +\item{data_dir}{path to data directory containing .rds file (default: \code{../data})} +} +\value{ +loaded multiOmicDataSet object +} +\description{ +Searches the ../data directory for .rds files and loads the first matching +multiOmicDataSet object. Validates that the loaded object is of the correct class. +} +\examples{ +\dontrun{ +moo <- load_moo_from_data_dir() +} + +} +\keyword{internal} diff --git a/code/MOSuite/man/meta_tbl_to_dat.Rd b/code/MOSuite/man/meta_tbl_to_dat.Rd new file mode 100644 index 0000000..23becd1 --- /dev/null +++ b/code/MOSuite/man/meta_tbl_to_dat.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/metadata.R +\name{meta_tbl_to_dat} +\alias{meta_tbl_to_dat} +\title{Convert sample metadata from a tibble to a dataframe with sample IDs as row names} +\usage{ +meta_tbl_to_dat(meta_tbl, sample_id_colname = sample_id) +} +\arguments{ +\item{meta_tbl}{tibble with \code{sample_id} column} + +\item{sample_id_colname}{name of the column in \code{sample_metadata} that contains the sample IDs. (Default: \code{NULL} - +first column in the sample metadata will be used.)} +} +\value{ +dataframe where row names are the sample IDs +} +\description{ +Convert sample metadata from a tibble to a dataframe with sample IDs as row names +} +\examples{ +\dontrun{ +sample_meta_tbl <- readr::read_tsv(system.file("extdata", + "sample_metadata.tsv.gz", + package = "MOSuite" +)) +head(sample_meta_tbl) +meta_tbl_to_dat(sample_meta_tbl) +} +} +\keyword{internal} diff --git a/code/MOSuite/man/multiOmicDataSet.Rd b/code/MOSuite/man/multiOmicDataSet.Rd new file mode 100644 index 0000000..07efd66 --- /dev/null +++ b/code/MOSuite/man/multiOmicDataSet.Rd @@ -0,0 +1,48 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/0_mo-class.R +\name{multiOmicDataSet} +\alias{multiOmicDataSet} +\title{multiOmicDataSet class} +\usage{ +multiOmicDataSet(sample_metadata, anno_dat, counts_lst, analyses_lst = list()) +} +\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{anno_dat}{data frame of feature annotations, such as gene symbols or any other information about the features +in \code{counts_lst}.} + +\item{counts_lst}{named list of data frames containing counts, e.g. expected feature counts from RSEM. Each data +frame is expected to contain a \code{feature_id} column as the first column, and all remaining columns are sample IDs in +the \code{sample_meta}.} + +\item{analyses_lst}{named list of analysis results, e.g. DESeq results object} +} +\value{ +A \code{multiOmicDataSet} S7 object. +} +\description{ +multiOmicDataSet class +} +\seealso{ +Other moo constructors: +\code{\link[=create_multiOmicDataSet_from_dataframes]{create_multiOmicDataSet_from_dataframes()}}, +\code{\link[=create_multiOmicDataSet_from_files]{create_multiOmicDataSet_from_files()}} +} +\concept{moo constructors} +\section{Additional properties}{ + +\describe{ +\item{\code{@sample_meta}}{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{\code{@annotation}}{data frame of feature annotations, such as gene symbols or any other information about the +features in the counts list.} + +\item{\code{@counts}}{named list of counts data frames (e.g. \code{raw}, \code{clean}, \code{cpm}, \code{filt}, \code{norm}, \code{batch}). Each data +frame is expected to contain a feature ID column as the first column, and all remaining columns are sample IDs.} + +\item{\code{@analyses}}{named list of analysis results (e.g. DESeq2 results, colors).} +}} + diff --git a/code/MOSuite/man/nidap_batch_corrected_counts.Rd b/code/MOSuite/man/nidap_batch_corrected_counts.Rd new file mode 100644 index 0000000..ca00e82 --- /dev/null +++ b/code/MOSuite/man/nidap_batch_corrected_counts.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nidap_batch_corrected_counts} +\alias{nidap_batch_corrected_counts} +\title{Batch-corrected counts for the NIDAP test dataset.} +\format{ +An object of class \code{spec_tbl_df} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 7943 rows and 10 columns. +} +\usage{ +nidap_batch_corrected_counts +} +\description{ +Batch-corrected counts for the NIDAP test dataset. +} +\keyword{data} diff --git a/code/MOSuite/man/nidap_batch_corrected_counts_2.Rd b/code/MOSuite/man/nidap_batch_corrected_counts_2.Rd new file mode 100644 index 0000000..386d71c --- /dev/null +++ b/code/MOSuite/man/nidap_batch_corrected_counts_2.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nidap_batch_corrected_counts_2} +\alias{nidap_batch_corrected_counts_2} +\title{Batch-corrected counts for the NIDAP test dataset. +The result of running \code{batch_correct_counts()} on \code{nidap_norm_counts}.} +\format{ +An object of class \code{data.frame} with 7943 rows and 10 columns. +} +\usage{ +nidap_batch_corrected_counts_2 +} +\description{ +Batch-corrected counts for the NIDAP test dataset. +The result of running \code{batch_correct_counts()} on \code{nidap_norm_counts}. +} +\keyword{data} diff --git a/code/MOSuite/man/nidap_clean_raw_counts.Rd b/code/MOSuite/man/nidap_clean_raw_counts.Rd new file mode 100644 index 0000000..7a9b2fe --- /dev/null +++ b/code/MOSuite/man/nidap_clean_raw_counts.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nidap_clean_raw_counts} +\alias{nidap_clean_raw_counts} +\title{Clean raw counts for the NIDAP test dataset. +The result of running \code{clean_raw_counts()} on \code{nidap_raw_counts}.} +\format{ +An object of class \code{spec_tbl_df} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 43280 rows and 10 columns. +} +\usage{ +nidap_clean_raw_counts +} +\description{ +Clean raw counts for the NIDAP test dataset. +The result of running \code{clean_raw_counts()} on \code{nidap_raw_counts}. +} +\keyword{data} diff --git a/code/MOSuite/man/nidap_deg_analysis.Rd b/code/MOSuite/man/nidap_deg_analysis.Rd new file mode 100644 index 0000000..daec3f9 --- /dev/null +++ b/code/MOSuite/man/nidap_deg_analysis.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nidap_deg_analysis} +\alias{nidap_deg_analysis} +\title{Differential gene expression analysis for the NIDAP test dataset.} +\format{ +An object of class \code{spec_tbl_df} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 7943 rows and 25 columns. +} +\usage{ +nidap_deg_analysis +} +\description{ +Differential gene expression analysis for the NIDAP test dataset. +} +\keyword{data} diff --git a/code/MOSuite/man/nidap_deg_analysis_2.Rd b/code/MOSuite/man/nidap_deg_analysis_2.Rd new file mode 100644 index 0000000..0bf6ab7 --- /dev/null +++ b/code/MOSuite/man/nidap_deg_analysis_2.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nidap_deg_analysis_2} +\alias{nidap_deg_analysis_2} +\title{Differential gene expression analysis for the NIDAP test dataset. +The result of running \code{diff_counts()} on \code{nidap_filtered_counts}.} +\format{ +An object of class \code{list} of length 3. +} +\usage{ +nidap_deg_analysis_2 +} +\description{ +Differential gene expression analysis for the NIDAP test dataset. +The result of running \code{diff_counts()} on \code{nidap_filtered_counts}. +} +\keyword{data} diff --git a/code/MOSuite/man/nidap_deg_gene_list.Rd b/code/MOSuite/man/nidap_deg_gene_list.Rd new file mode 100644 index 0000000..12bbc31 --- /dev/null +++ b/code/MOSuite/man/nidap_deg_gene_list.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nidap_deg_gene_list} +\alias{nidap_deg_gene_list} +\title{List of differentially expressed genes from the NIDAP test dataset using +default parameters with \code{filter_diff()}.} +\format{ +An object of class \code{data.frame} with 641 rows and 16 columns. +} +\usage{ +nidap_deg_gene_list +} +\description{ +List of differentially expressed genes from the NIDAP test dataset using +default parameters with \code{filter_diff()}. +} +\keyword{data} diff --git a/code/MOSuite/man/nidap_filtered_counts.Rd b/code/MOSuite/man/nidap_filtered_counts.Rd new file mode 100644 index 0000000..5886eab --- /dev/null +++ b/code/MOSuite/man/nidap_filtered_counts.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nidap_filtered_counts} +\alias{nidap_filtered_counts} +\title{Filtered counts for the NIDAP test dataset. +The result of running \code{filter_counts()} on \code{nidap_clean_raw_counts}.} +\format{ +An object of class \code{spec_tbl_df} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 7943 rows and 10 columns. +} +\usage{ +nidap_filtered_counts +} +\description{ +Filtered counts for the NIDAP test dataset. +The result of running \code{filter_counts()} on \code{nidap_clean_raw_counts}. +} +\keyword{data} diff --git a/code/MOSuite/man/nidap_norm_counts.Rd b/code/MOSuite/man/nidap_norm_counts.Rd new file mode 100644 index 0000000..bc659b7 --- /dev/null +++ b/code/MOSuite/man/nidap_norm_counts.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nidap_norm_counts} +\alias{nidap_norm_counts} +\title{Normalized counts for the NIDAP test dataset. +The result of running \code{normalize_counts()} on \code{nidap_filtered_counts}.} +\format{ +An object of class \code{spec_tbl_df} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 7943 rows and 10 columns. +} +\usage{ +nidap_norm_counts +} +\description{ +Normalized counts for the NIDAP test dataset. +The result of running \code{normalize_counts()} on \code{nidap_filtered_counts}. +} +\keyword{data} diff --git a/code/MOSuite/man/nidap_raw_counts.Rd b/code/MOSuite/man/nidap_raw_counts.Rd new file mode 100644 index 0000000..77bc2b8 --- /dev/null +++ b/code/MOSuite/man/nidap_raw_counts.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nidap_raw_counts} +\alias{nidap_raw_counts} +\title{Raw counts for the NIDAP test dataset +Pairs with \code{nidap_sample_metadata}.} +\format{ +An object of class \code{spec_tbl_df} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 43280 rows and 10 columns. +} +\usage{ +nidap_raw_counts +} +\description{ +Raw counts for the NIDAP test dataset +Pairs with \code{nidap_sample_metadata}. +} +\keyword{data} diff --git a/code/MOSuite/man/nidap_sample_metadata.Rd b/code/MOSuite/man/nidap_sample_metadata.Rd new file mode 100644 index 0000000..31ed521 --- /dev/null +++ b/code/MOSuite/man/nidap_sample_metadata.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nidap_sample_metadata} +\alias{nidap_sample_metadata} +\title{Sample metadata for the NIDAP test dataset} +\format{ +An object of class \code{spec_tbl_df} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 9 rows and 5 columns. +} +\usage{ +nidap_sample_metadata +} +\description{ +Sample metadata for the NIDAP test dataset +} +\keyword{data} diff --git a/code/MOSuite/man/nidap_venn_diagram_dat.Rd b/code/MOSuite/man/nidap_venn_diagram_dat.Rd new file mode 100644 index 0000000..6ab32bb --- /dev/null +++ b/code/MOSuite/man/nidap_venn_diagram_dat.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nidap_venn_diagram_dat} +\alias{nidap_venn_diagram_dat} +\title{Output data from venn diagram. +The result of running \code{plot_venn_diagram()} on \code{nidap_volcano_summary_dat}} +\format{ +An object of class \code{spec_tbl_df} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 3068 rows and 4 columns. +} +\usage{ +nidap_venn_diagram_dat +} +\description{ +Output data from venn diagram. +The result of running \code{plot_venn_diagram()} on \code{nidap_volcano_summary_dat} +} +\keyword{data} diff --git a/code/MOSuite/man/nidap_volcano_summary_dat.Rd b/code/MOSuite/man/nidap_volcano_summary_dat.Rd new file mode 100644 index 0000000..43bdf38 --- /dev/null +++ b/code/MOSuite/man/nidap_volcano_summary_dat.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nidap_volcano_summary_dat} +\alias{nidap_volcano_summary_dat} +\title{Summarized differential expression analysis for input to venn diagram} +\format{ +An object of class \code{spec_tbl_df} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 4929 rows and 7 columns. +} +\usage{ +nidap_volcano_summary_dat +} +\description{ +Summarized differential expression analysis for input to venn diagram +} +\keyword{data} diff --git a/code/MOSuite/man/normalize_counts.Rd b/code/MOSuite/man/normalize_counts.Rd new file mode 100644 index 0000000..0bfd0ea --- /dev/null +++ b/code/MOSuite/man/normalize_counts.Rd @@ -0,0 +1,169 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/normalize.R +\name{normalize_counts} +\alias{normalize_counts} +\title{Normalize counts} +\usage{ +normalize_counts( + moo, + 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 = 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 = 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + interactive_plots = FALSE, + plots_subdir = "norm" +) +} +\arguments{ +\item{moo}{multiOmicDataSet object (see \code{create_multiOmicDataSet_from_dataframes()})} + +\item{count_type}{the type of counts to use -- must be a name in the counts slot (\code{moo@counts})} + +\item{norm_type}{normalization type. Default: "voom" which uses \code{limma::voom}.} + +\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 +used.)} + +\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{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{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{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{input_in_log_counts}{set this to \code{TRUE} if counts are already log2-transformed} + +\item{voom_normalization_method}{Normalization method to be applied to the logCPM values when using \code{limma::voom}} + +\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}{label points on the PCA plot} + +\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 FALSE.} + +\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} + +\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}{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{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{ +\code{multiOmicDataSet} with normalized counts +} +\description{ +Normalize counts +} +\examples{ +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( + group_colname = "Group", + label_colname = "Label" + ) +head(moo@counts[["norm"]][["voom"]]) +} +\seealso{ +Other moo methods: +\code{\link[=batch_correct_counts]{batch_correct_counts()}}, +\code{\link[=clean_raw_counts]{clean_raw_counts()}}, +\code{\link[=diff_counts]{diff_counts()}}, +\code{\link[=filter_counts]{filter_counts()}}, +\code{\link[=filter_diff]{filter_diff()}}, +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=run_deseq2]{run_deseq2()}}, +\code{\link[=set_color_pal]{set_color_pal()}} +} +\concept{moo methods} diff --git a/code/MOSuite/man/option_params.Rd b/code/MOSuite/man/option_params.Rd new file mode 100644 index 0000000..4ea8a38 --- /dev/null +++ b/code/MOSuite/man/option_params.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/options.R +\name{option_params} +\alias{option_params} +\title{Option parameters} +\arguments{ +\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{plots_dir}{Path where plots are saved when \code{moo_save_plots} is \code{TRUE} (Defaults to \code{"figures/"}, overwritable using option 'moo_plots_dir' or environment variable 'MOO_PLOTS_DIR')} + +\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')} +} +\description{ +Option parameters +} +\keyword{internal} diff --git a/code/MOSuite/man/options.Rd b/code/MOSuite/man/options.Rd new file mode 100644 index 0000000..10d4fcd --- /dev/null +++ b/code/MOSuite/man/options.Rd @@ -0,0 +1,46 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/options.R +\name{options} +\alias{options} +\title{MOSuite Options} +\description{ +Internally used, package-specific options. All options will prioritize R options() values, and fall back to environment variables if undefined. If neither the option nor the environment variable is set, a default value is used. +} +\section{Checking Option Values}{ + +Option values specific to \code{MOSuite} can be +accessed by passing the package name to \code{env}. + +\if{html}{\out{
}}\preformatted{options::opts(env = "MOSuite") + +options::opt(x, default, env = "MOSuite") +}\if{html}{\out{
}} +} + +\section{Options}{ + +\describe{ +\item{print_plots}{\describe{ +Whether to print plots during analysis\item{default: }{\preformatted{FALSE}} +\item{option: }{moo_print_plots} +\item{envvar: }{MOO_PRINT_PLOTS (evaluated if possible, raw string otherwise)} +}} + +\item{save_plots}{\describe{ +Whether to save plots to files during analysis\item{default: }{\preformatted{TRUE}} +\item{option: }{moo_save_plots} +\item{envvar: }{MOO_SAVE_PLOTS (evaluated if possible, raw string otherwise)} +}} + +\item{plots_dir}{\describe{ +Path where plots are saved when \code{moo_save_plots} is \code{TRUE}\item{default: }{\preformatted{"figures/"}} +\item{option: }{moo_plots_dir} +\item{envvar: }{MOO_PLOTS_DIR (evaluated if possible, raw string otherwise)} +}} + +} +} + +\seealso{ +options getOption Sys.setenv Sys.getenv +} diff --git a/code/MOSuite/man/parse_optional_vector.Rd b/code/MOSuite/man/parse_optional_vector.Rd new file mode 100644 index 0000000..291bee1 --- /dev/null +++ b/code/MOSuite/man/parse_optional_vector.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{parse_optional_vector} +\alias{parse_optional_vector} +\title{Parse comma-separated string into a vector} +\usage{ +parse_optional_vector(x) +} +\arguments{ +\item{x}{character string with comma-separated values} +} +\value{ +character vector or NULL if input is empty +} +\description{ +Splits a comma-separated string into a trimmed character vector. +Returns NULL if input is empty, NULL, or has zero length. +} +\examples{ +\dontrun{ +parse_optional_vector("a, b, c") +parse_optional_vector("") +} + +} +\keyword{internal} diff --git a/code/MOSuite/man/parse_samples_to_rename.Rd b/code/MOSuite/man/parse_samples_to_rename.Rd new file mode 100644 index 0000000..6a9e7e9 --- /dev/null +++ b/code/MOSuite/man/parse_samples_to_rename.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{parse_samples_to_rename} +\alias{parse_samples_to_rename} +\title{Parse sample rename pairs from string} +\usage{ +parse_samples_to_rename(x) +} +\arguments{ +\item{x}{character string with rename pairs in format "old:new,old2:new2"} +} +\value{ +named list with old names as keys and new names as values, or NULL if empty +} +\description{ +Parses a string containing sample rename pairs in format "old:new,old2:new2" +and returns a named list where names are old sample names and values are new names. +} +\examples{ +\dontrun{ +parse_samples_to_rename("sample1:S1,sample2:S2") +parse_samples_to_rename("") +} + +} +\keyword{internal} diff --git a/code/MOSuite/man/parse_vector_with_default.Rd b/code/MOSuite/man/parse_vector_with_default.Rd new file mode 100644 index 0000000..d4a5f01 --- /dev/null +++ b/code/MOSuite/man/parse_vector_with_default.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{parse_vector_with_default} +\alias{parse_vector_with_default} +\title{Parse comma-separated string with default fallback} +\usage{ +parse_vector_with_default(x, default) +} +\arguments{ +\item{x}{character string with comma-separated values} + +\item{default}{default value to return if x is empty} +} +\value{ +character vector or default value +} +\description{ +Splits a comma-separated string into a trimmed character vector. +Returns a default value if input is empty, NULL, or has zero length. +} +\examples{ +\dontrun{ +parse_vector_with_default("a, b, c", "default") +parse_vector_with_default("", "default") +} + +} +\keyword{internal} diff --git a/code/MOSuite/man/plot_corr_heatmap-data.frame.Rd b/code/MOSuite/man/plot_corr_heatmap-data.frame.Rd new file mode 100644 index 0000000..0eec133 --- /dev/null +++ b/code/MOSuite/man/plot_corr_heatmap-data.frame.Rd @@ -0,0 +1,44 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_heatmap.R +\name{plot_corr_heatmap,data.frame-method} +\alias{plot_corr_heatmap,data.frame-method} +\alias{plot_corr_heatmap.data.frame} +\title{Plot correlation heatmap for counts dataframe} +\arguments{ +\item{moo_counts}{a \code{data.frame} of counts} + +\item{sample_metadata}{sample metadata as a data frame or tibble (\strong{Required})} + +\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 +used.)} + +\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{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{color_values}{vector of colors as hex values or names recognized by R} +} +\description{ +Plot correlation heatmap for counts dataframe +} +\seealso{ +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}} generic + +Other plotters for counts dataframes: +\code{\link{plot_histogram,data.frame-method}}, +\code{\link{plot_pca,data.frame-method}}, +\code{\link{plot_read_depth,data.frame-method}} +} +\concept{plotters for counts dataframes} diff --git a/code/MOSuite/man/plot_corr_heatmap-multiOmicDataSet.Rd b/code/MOSuite/man/plot_corr_heatmap-multiOmicDataSet.Rd new file mode 100644 index 0000000..0f09035 --- /dev/null +++ b/code/MOSuite/man/plot_corr_heatmap-multiOmicDataSet.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_heatmap.R +\name{plot_corr_heatmap,MOSuite::multiOmicDataSet-method} +\alias{plot_corr_heatmap,MOSuite::multiOmicDataSet-method} +\alias{plot_corr_heatmap.multiOmicDataSet} +\title{Plot correlation heatmap for multiOmicDataSet} +\arguments{ +\item{moo_counts}{a \code{multiOmicDataSet} object} + +\item{count_type}{the type of counts to use. Must be a name in the counts slot (\code{names(moo@counts)}).} + +\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{...}{additional arguments forwarded to \code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}} for \code{data.frame}} +} +\description{ +Plot correlation heatmap for multiOmicDataSet +} +\seealso{ +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}} generic + +Other plotters for multiOmicDataSets: +\code{\link{plot_histogram,MOSuite::multiOmicDataSet-method}}, +\code{\link{plot_pca,MOSuite::multiOmicDataSet-method}}, +\code{\link{plot_read_depth,MOSuite::multiOmicDataSet-method}} +} +\concept{plotters for multiOmicDataSets} diff --git a/code/MOSuite/man/plot_corr_heatmap.Rd b/code/MOSuite/man/plot_corr_heatmap.Rd new file mode 100644 index 0000000..f09d191 --- /dev/null +++ b/code/MOSuite/man/plot_corr_heatmap.Rd @@ -0,0 +1,96 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_heatmap.R +\name{plot_corr_heatmap} +\alias{plot_corr_heatmap} +\title{Plot correlation heatmap} +\usage{ +plot_corr_heatmap(moo_counts, ...) +} +\arguments{ +\item{moo_counts}{counts dataframe or \code{multiOmicDataSet} containing \code{count_type} & \code{sub_count_type} in the counts +slot} + +\item{...}{arguments forwarded to method} +} +\value{ +heatmap from \code{ComplexHeatmap::Heatmap()} +} +\description{ +Plot correlation heatmap +} +\details{ +\subsection{Method Usage}{ + +\if{html}{\out{
}}\preformatted{# multiOmicDataSet +plot_corr_heatmap(moo_counts, + count_type, + sub_count_type = NULL, + ...) + +# dataframe +plot_corr_heatmap(moo_counts, + sample_metadata, + sample_id_colname = NULL, + 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" + )) +}\if{html}{\out{
}} +} +} +\examples{ +# plot correlation heatmap for a counts slot in a multiOmicDataset Object +moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list("raw" = as.data.frame(nidap_raw_counts)) +) +p <- plot_corr_heatmap(moo, count_type = "raw") + +# plot correlation heatmap for a counts dataframe +plot_corr_heatmap( + moo@counts$raw, + sample_metadata = moo@sample_meta, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + label_colname = "Label" +) +} +\seealso{ +\itemize{ +\item \code{\link[=plot_corr_heatmap.multiOmicDataSet]{plot_corr_heatmap.multiOmicDataSet()}} +\item \code{\link[=plot_corr_heatmap.data.frame]{plot_corr_heatmap.data.frame()}} +} + +Other plotters: +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=print_or_save_plot]{print_or_save_plot()}} + +Other heatmaps: +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}} + +Other moo methods: +\code{\link[=batch_correct_counts]{batch_correct_counts()}}, +\code{\link[=clean_raw_counts]{clean_raw_counts()}}, +\code{\link[=diff_counts]{diff_counts()}}, +\code{\link[=filter_counts]{filter_counts()}}, +\code{\link[=filter_diff]{filter_diff()}}, +\code{\link[=normalize_counts]{normalize_counts()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=run_deseq2]{run_deseq2()}}, +\code{\link[=set_color_pal]{set_color_pal()}} +} +\concept{heatmaps} +\concept{moo methods} +\concept{plotters} +\keyword{plotters} diff --git a/code/MOSuite/man/plot_expr_heatmap.Rd b/code/MOSuite/man/plot_expr_heatmap.Rd new file mode 100644 index 0000000..8f8b890 --- /dev/null +++ b/code/MOSuite/man/plot_expr_heatmap.Rd @@ -0,0 +1,376 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_heatmap.R +\name{plot_expr_heatmap} +\alias{plot_expr_heatmap} +\alias{plot_expr_heatmap,MOSuite::multiOmicDataSet-method} +\alias{plot_expr_heatmap,data.frame-method} +\title{Plot expression heatmap} +\usage{ +plot_expr_heatmap( + moo_counts, + count_type, + 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 = c("#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 = c(), + display_sample_names = TRUE, + 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, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "heatmap" +) + +## S7 method for class +plot_expr_heatmap( + moo_counts, + count_type, + 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 = c("#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 = c(), + display_sample_names = TRUE, + 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, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "heatmap" +) + +## S7 method for class +plot_expr_heatmap( + moo_counts, + count_type, + 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 = c("#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 = c(), + display_sample_names = TRUE, + 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, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "heatmap" +) +} +\arguments{ +\item{moo_counts}{counts dataframe or \code{multiOmicDataSet} containing \code{count_type} & \code{sub_count_type} in the counts +slot} + +\item{count_type}{the type of counts to use. Must be a name in the counts slot (\code{names(moo@counts)}).} + +\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_metadata}{sample metadata as a data frame or tibble (only required if \code{moo_counts} is a dataframe)} + +\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 dataa 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 +used.)} + +\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{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{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{color_values}{vector of colors as hex values or names recognized by R} + +\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.} + +\item{filter_top_genes_by_variance}{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.} + +\item{top_genes_by_variance_to_include}{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.} + +\item{specific_genes_to_include_in_heatmap}{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.} + +\item{cluster_genes}{Choose whether to cluster the rows (genes). If TRUE, rows will have clustering applied. If +FALSE, clustering will not be applied to rows.} + +\item{gene_distance_metric}{Distance metric to be used in clustering genes. (TODO document options)} + +\item{gene_clustering_method}{Clustering method metric to be used in clustering samples. (TODO document options)} + +\item{display_gene_dendrograms}{Set to TRUE to show gene dendrograms. Set to FALSE to hide dendrograms.} + +\item{display_gene_names}{Set to TRUE to display gene names on the right side of the heatmap. Set to FALSE to hide +gene names.} + +\item{center_and_rescale_expression}{Center and rescale expression for each gene across all included samples.} + +\item{cluster_samples}{Choose whether to cluster the columns (samples). If TRUE, columns will have clustering +applied. If FALSE, clustering will not be applied to columns.} + +\item{arrange_sample_columns}{If TRUE, arranges columns by annotation groups. If FALSE, and "Cluster Samples" is +FALSE, samples will appear in the order of input (samples to include)} + +\item{order_by_gene_expression}{If TRUE, set gene name below and direction for ordering} + +\item{gene_to_order_columns}{Gene to order columns by expression levels} + +\item{gene_expression_order}{Choose direction for gene order} + +\item{smpl_distance_metric}{Distance metric to be used in clustering samples. (TODO document options)} + +\item{smpl_clustering_method}{Clustering method to be used in clustering samples. (TODO document options)} + +\item{display_smpl_dendrograms}{Set to TRUE to show sample dendrograms. Set to FALSE to hide dendrogram.} + +\item{reorder_dendrogram}{If TRUE, set the order of the dendrogram (below)} + +\item{reorder_dendrogram_order}{Reorder the samples (columns) of the dendrogram by name, e.g. +“sample2”,“sample3",“sample1".} + +\item{display_sample_names}{Set to TRUE if you want sample names to be displayed on the plot. Set to FALSE to hide +sample names.} + +\item{group_columns}{Columns containing the sample groups for annotation tracks} + +\item{assign_group_colors}{If TRUE, set the groups assigned colors (below)} + +\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 +color parameters. If FALSE, set the heatmap colors between "Set max heatmap color" and "Set min heatmap color" +(below).} + +\item{set_min_heatmap_color}{If Autoscale heatmap color is set to FALSE, set the minimum heatmap z-score value} + +\item{set_max_heatmap_color}{If Autoscale heatmap color is set to FALSE, set the maximum heatmap z-score value.} + +\item{aspect_ratio}{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} + +\item{legend_font_size}{Set Font size for figure legend. Default is 10.} + +\item{gene_name_font_size}{Font size for gene names. If you don't want gene labels to show, toggle "Display Gene +Names" below to FALSE} + +\item{sample_name_font_size}{Font size for sample names. If you don't want to display samples names, toggle "Display +sample names" (below) to FALSE} + +\item{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.} + +\item{plot_filename}{plot output filename - only used if save_plots is TRUE} + +\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{plots_subdir}{subdirectory in \verb{figures/} where plots will be saved if \code{save_plots} is \code{TRUE}} +} +\value{ +heatmap from \code{ComplexHeatmap::Heatmap()} +} +\description{ +The samples (i.e. the columns) are clustered 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. +} +\details{ +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. +} +\examples{ +# plot expression heatmap for a counts slot in a multiOmicDataset Object +moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = nidap_raw_counts, + "norm" = list( + "voom" = as.data.frame(nidap_norm_counts) + ) + ) +) +p <- plot_expr_heatmap(moo, count_type = "norm", sub_count_type = "voom") + +# customize the plot +plot_expr_heatmap(moo, + count_type = "norm", sub_count_type = "voom", + top_genes_by_variance_to_include = 100 +) + +# plot expression heatmap for a counts dataframe +counts_dat <- moo@counts$norm$voom +plot_expr_heatmap( + counts_dat, + sample_metadata = nidap_sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + label_colname = "Label", + top_genes_by_variance_to_include = 100 +) + +} +\seealso{ +Other plotters: +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=print_or_save_plot]{print_or_save_plot()}} + +Other heatmaps: +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}} + +Other moo methods: +\code{\link[=batch_correct_counts]{batch_correct_counts()}}, +\code{\link[=clean_raw_counts]{clean_raw_counts()}}, +\code{\link[=diff_counts]{diff_counts()}}, +\code{\link[=filter_counts]{filter_counts()}}, +\code{\link[=filter_diff]{filter_diff()}}, +\code{\link[=normalize_counts]{normalize_counts()}}, +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=run_deseq2]{run_deseq2()}}, +\code{\link[=set_color_pal]{set_color_pal()}} +} +\concept{heatmaps} +\concept{moo methods} +\concept{plotters} +\keyword{plotters} diff --git a/code/MOSuite/man/plot_histogram.Rd b/code/MOSuite/man/plot_histogram.Rd new file mode 100644 index 0000000..4f6a920 --- /dev/null +++ b/code/MOSuite/man/plot_histogram.Rd @@ -0,0 +1,76 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_histogram.R +\name{plot_histogram} +\alias{plot_histogram} +\title{Plot histogram} +\usage{ +plot_histogram(moo_counts, ...) +} +\arguments{ +\item{moo_counts}{counts dataframe or \code{multiOmicDataSet} containing \code{count_type} & \code{sub_count_type} in the counts +slot} + +\item{...}{arguments forwarded to method} +} +\value{ +ggplot object +} +\description{ +Plot histogram +} +\examples{ +# plot histogram for a counts slot in a multiOmicDataset Object +moo <- multiOmicDataSet( + sample_metadata = nidap_sample_metadata, + anno_dat = data.frame(), + counts_lst = list("raw" = nidap_raw_counts) +) +p <- plot_histogram(moo, count_type = "raw") + +# customize the plot +plot_histogram(moo, + count_type = "raw", + group_colname = "Group", color_by_group = TRUE +) + +# plot histogram for a counts dataframe directly +counts_dat <- moo@counts$raw +plot_histogram( + counts_dat, + sample_metadata = nidap_sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "GeneName", + label_colname = "Label" +) + +} +\seealso{ +\itemize{ +\item \code{\link[=plot_histogram.multiOmicDataSet]{plot_histogram.multiOmicDataSet()}} +\item \code{\link[=plot_histogram.data.frame]{plot_histogram.data.frame()}} +} + +Other plotters: +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=print_or_save_plot]{print_or_save_plot()}} + +Other moo methods: +\code{\link[=batch_correct_counts]{batch_correct_counts()}}, +\code{\link[=clean_raw_counts]{clean_raw_counts()}}, +\code{\link[=diff_counts]{diff_counts()}}, +\code{\link[=filter_counts]{filter_counts()}}, +\code{\link[=filter_diff]{filter_diff()}}, +\code{\link[=normalize_counts]{normalize_counts()}}, +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=run_deseq2]{run_deseq2()}}, +\code{\link[=set_color_pal]{set_color_pal()}} +} +\concept{moo methods} +\concept{plotters} +\keyword{plotters} diff --git a/code/MOSuite/man/plot_histogram.data.frame.Rd b/code/MOSuite/man/plot_histogram.data.frame.Rd new file mode 100644 index 0000000..ba46275 --- /dev/null +++ b/code/MOSuite/man/plot_histogram.data.frame.Rd @@ -0,0 +1,89 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_histogram.R +\name{plot_histogram,data.frame-method} +\alias{plot_histogram,data.frame-method} +\alias{plot_histogram.data.frame} +\title{Plot histogram for counts dataframe} +\arguments{ +\item{sample_metadata}{sample metadata as a data frame or tibble (\strong{required})} + +\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 dataa 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 +used.)} + +\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{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{color_values}{vector of colors as hex values or names recognized by R} + +\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.} + +\item{set_min_max_for_x_axis}{whether to override the default for \code{ggplot2::xlim()} (default: \code{FALSE})} + +\item{minimum_for_x_axis}{value to override default \code{min} for \code{ggplot2::xlim()}} + +\item{maximum_for_x_axis}{value to override default \code{max} for \code{ggplot2::xlim()}} + +\item{x_axis_label}{text label for the x axis \code{ggplot2::xlab()}} + +\item{y_axis_label}{text label for the y axis \code{ggplot2::ylab()}} + +\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{number_of_legend_columns}{passed to \code{ncol} in \code{ggplot2::guide_legend()}} + +\item{interactive_plots}{set to TRUE to make the plot 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 +TRUE. Default is FALSE.} + +\item{...}{additional arguments (ignored; accepted for compatibility with the moo dispatch)} +} +\description{ +Plot histogram for counts dataframe +} +\examples{ + +# plot histogram for a counts dataframe directly +plot_histogram( + nidap_clean_raw_counts, + sample_metadata = nidap_sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + label_colname = "Label" +) + +# customize the plot +plot_histogram( + nidap_clean_raw_counts, + sample_metadata = nidap_sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + color_by_group = TRUE +) + +} +\seealso{ +\code{\link[=plot_histogram]{plot_histogram()}} generic + +Other plotters for counts dataframes: +\code{\link{plot_corr_heatmap,data.frame-method}}, +\code{\link{plot_pca,data.frame-method}}, +\code{\link{plot_read_depth,data.frame-method}} +} +\concept{plotters for counts dataframes} diff --git a/code/MOSuite/man/plot_histogram.multiOmicDataSet.Rd b/code/MOSuite/man/plot_histogram.multiOmicDataSet.Rd new file mode 100644 index 0000000..75da66e --- /dev/null +++ b/code/MOSuite/man/plot_histogram.multiOmicDataSet.Rd @@ -0,0 +1,41 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_histogram.R +\name{plot_histogram,MOSuite::multiOmicDataSet-method} +\alias{plot_histogram,MOSuite::multiOmicDataSet-method} +\alias{plot_histogram.multiOmicDataSet} +\title{Plot histogram for multiOmicDataSet} +\arguments{ +\item{count_type}{Required if \code{moo_counts} is a \code{multiOmicDataSet}: the type of counts to use -- must be a name in +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} +} +\description{ +Plot histogram for multiOmicDataSet +} +\examples{ +# plot histogram for a counts slot in a multiOmicDataset Object +moo <- multiOmicDataSet( + sample_metadata = nidap_sample_metadata, + anno_dat = data.frame(), + counts_lst = list("raw" = nidap_raw_counts) +) +p <- plot_histogram(moo, count_type = "raw") + +# customize the plot +plot_histogram(moo, + count_type = "raw", + group_colname = "Group", color_by_group = TRUE +) + +} +\seealso{ +\code{\link[=plot_histogram]{plot_histogram()}} generic + +Other plotters for multiOmicDataSets: +\code{\link{plot_corr_heatmap,MOSuite::multiOmicDataSet-method}}, +\code{\link{plot_pca,MOSuite::multiOmicDataSet-method}}, +\code{\link{plot_read_depth,MOSuite::multiOmicDataSet-method}} +} +\concept{plotters for multiOmicDataSets} diff --git a/code/MOSuite/man/plot_pca.Rd b/code/MOSuite/man/plot_pca.Rd new file mode 100644 index 0000000..6dfa47e --- /dev/null +++ b/code/MOSuite/man/plot_pca.Rd @@ -0,0 +1,89 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_pca.R +\name{plot_pca} +\alias{plot_pca} +\title{Perform and plot a Principal Components Analysis} +\usage{ +plot_pca(moo_counts, principal_components = c(1, 2), ...) +} +\arguments{ +\item{moo_counts}{counts dataframe or \code{multiOmicDataSet} containing \code{count_type} & \code{sub_count_type} in the counts +slot} + +\item{principal_components}{vector with numbered principal components to plot. Use 2 for a 2D pca with ggplot, or 3 +for a 3D pca with plotly. (Default: \code{c(1,2)})} + +\item{...}{additional arguments forwarded to method (see Details below)} +} +\value{ +PCA plot (2D or 3D depending on the number of \code{principal_components}) +} +\description{ +Perform and plot a Principal Components Analysis +} +\details{ +See the low-level function docs for additional arguments +depending on whether you're plotting 2 or 3 PCs: +\itemize{ +\item \code{\link[=plot_pca_2d]{plot_pca_2d()}} - used when there are \strong{2} principal components +\item \code{\link[=plot_pca_3d]{plot_pca_3d()}} - used when there are \strong{3} principal components +} +} +\examples{ +# multiOmicDataSet +moo <- multiOmicDataSet( + sample_metadata = nidap_sample_metadata, + anno_dat = data.frame(), + counts_lst = list( + "raw" = nidap_raw_counts, + "clean" = nidap_clean_raw_counts + ) +) +plot_pca(moo, count_type = "clean", principal_components = c(1, 2)) + +# 3D +plot_pca(moo, count_type = "clean", principal_components = c(1, 2, 3)) + +# dataframe +plot_pca(nidap_clean_raw_counts, + sample_metadata = nidap_sample_metadata, + principal_components = c(1, 2) +) + +} +\seealso{ +\itemize{ +\item \code{\link[=plot_pca.multiOmicDataSet]{plot_pca.multiOmicDataSet()}} +\item \code{\link[=plot_pca.data.frame]{plot_pca.data.frame()}} +} + +Other plotters: +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=print_or_save_plot]{print_or_save_plot()}} + +Other PCA functions: +\code{\link[=calc_pca]{calc_pca()}}, +\code{\link[=plot_pca_2d]{plot_pca_2d()}}, +\code{\link[=plot_pca_3d]{plot_pca_3d()}} + +Other moo methods: +\code{\link[=batch_correct_counts]{batch_correct_counts()}}, +\code{\link[=clean_raw_counts]{clean_raw_counts()}}, +\code{\link[=diff_counts]{diff_counts()}}, +\code{\link[=filter_counts]{filter_counts()}}, +\code{\link[=filter_diff]{filter_diff()}}, +\code{\link[=normalize_counts]{normalize_counts()}}, +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=run_deseq2]{run_deseq2()}}, +\code{\link[=set_color_pal]{set_color_pal()}} +} +\concept{PCA functions} +\concept{moo methods} +\concept{plotters} +\keyword{plotters} diff --git a/code/MOSuite/man/plot_pca.data.frame.Rd b/code/MOSuite/man/plot_pca.data.frame.Rd new file mode 100644 index 0000000..7a02771 --- /dev/null +++ b/code/MOSuite/man/plot_pca.data.frame.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_pca.R +\name{plot_pca,data.frame-method} +\alias{plot_pca,data.frame-method} +\alias{plot_pca.data.frame} +\title{Plot 2D or 3D PCA for counts dataframe} +\arguments{ +\item{sample_metadata}{\strong{Required} if \code{moo_counts} is a \code{data.frame}: sample metadata as a data frame or tibble.} +} +\description{ +Plot 2D or 3D PCA for counts dataframe +} +\seealso{ +\code{\link[=plot_pca]{plot_pca()}} generic + +Other plotters for counts dataframes: +\code{\link{plot_corr_heatmap,data.frame-method}}, +\code{\link{plot_histogram,data.frame-method}}, +\code{\link{plot_read_depth,data.frame-method}} +} +\concept{plotters for counts dataframes} diff --git a/code/MOSuite/man/plot_pca.multiOmicDataSet.Rd b/code/MOSuite/man/plot_pca.multiOmicDataSet.Rd new file mode 100644 index 0000000..f8206d7 --- /dev/null +++ b/code/MOSuite/man/plot_pca.multiOmicDataSet.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_pca.R +\name{plot_pca,MOSuite::multiOmicDataSet-method} +\alias{plot_pca,MOSuite::multiOmicDataSet-method} +\alias{plot_pca.multiOmicDataSet} +\title{Plot 2D or 3D PCA for multiOmicDataset} +\arguments{ +\item{count_type}{the type of counts to use. Must be a name in the counts slot (\code{names(moo@counts)}).} + +\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]])}.} +} +\value{ +PCA plot +} +\description{ +Plot 2D or 3D PCA for multiOmicDataset +} +\seealso{ +\code{\link[=plot_pca]{plot_pca()}} generic + +Other plotters for multiOmicDataSets: +\code{\link{plot_corr_heatmap,MOSuite::multiOmicDataSet-method}}, +\code{\link{plot_histogram,MOSuite::multiOmicDataSet-method}}, +\code{\link{plot_read_depth,MOSuite::multiOmicDataSet-method}} +} +\concept{plotters for multiOmicDataSets} diff --git a/code/MOSuite/man/plot_pca_2d.Rd b/code/MOSuite/man/plot_pca_2d.Rd new file mode 100644 index 0000000..244d8b2 --- /dev/null +++ b/code/MOSuite/man/plot_pca_2d.Rd @@ -0,0 +1,168 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_pca.R +\name{plot_pca_2d} +\alias{plot_pca_2d} +\alias{plot_pca_2d,MOSuite::multiOmicDataSet-method} +\alias{plot_pca_2d,data.frame-method} +\title{Perform and plot a 2D Principal Components Analysis} +\usage{ +plot_pca_2d( + moo_counts, + 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 = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", + "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), + principal_components = c(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 = options::opt("print_plots"), + save_plots = options::opt("save_plots") +) + +## S7 method for class +plot_pca_2d( + moo_counts, + 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 = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", + "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), + principal_components = c(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 = options::opt("print_plots"), + save_plots = options::opt("save_plots") +) + +## S7 method for class +plot_pca_2d( + moo_counts, + 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 = c("#5954d6", "#e1562c", "#b80058", "#00c6f8", "#d163e6", "#00a76c", + "#ff9287", "#008cf9", "#006e00", "#796880", "#FFA500", "#878500"), + principal_components = c(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 = options::opt("print_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{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_metadata}{sample metadata as a data frame or tibble.} + +\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 dataa 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 +used.)} + +\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{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{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{principal_components}{vector with numbered principal components to plot} + +\item{legend_position}{passed to in \code{legend.position} \code{ggplot2::theme()}} + +\item{point_size}{size for \code{ggplot2::geom_point()}} + +\item{add_label}{whether to add text labels for the points} + +\item{label_font_size}{label font size 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{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}} + +\item{plot_filename}{plot output filename - only used if save_plots is TRUE} + +\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')} +} +\value{ +ggplot object +} +\description{ +Perform and plot a 2D Principal Components Analysis + +Perform and plot a 2D Principal Components Analysis +} +\seealso{ +\code{\link[=plot_pca]{plot_pca()}} generic + +Other PCA functions: +\code{\link[=calc_pca]{calc_pca()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_pca_3d]{plot_pca_3d()}} +} +\concept{PCA functions} diff --git a/code/MOSuite/man/plot_pca_3d.Rd b/code/MOSuite/man/plot_pca_3d.Rd new file mode 100644 index 0000000..acf569d --- /dev/null +++ b/code/MOSuite/man/plot_pca_3d.Rd @@ -0,0 +1,128 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_pca.R +\name{plot_pca_3d} +\alias{plot_pca_3d} +\alias{plot_pca_3d,MOSuite::multiOmicDataSet-method} +\alias{plot_pca_3d,data.frame-method} +\title{Perform and plot a 3D Principal Components Analysis} +\usage{ +plot_pca_3d( + moo_counts, + 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 = 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"), + plot_title = "PCA 3D", + plot_filename = "pca_3D.html", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "pca" +) + +## S7 method for class +plot_pca_3d( + moo_counts, + 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 = 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"), + plot_title = "PCA 3D", + plot_filename = "pca_3D.html", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "pca" +) + +## S7 method for class +plot_pca_3d( + moo_counts, + 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 = 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"), + plot_title = "PCA 3D", + plot_filename = "pca_3D.html", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "pca" +) +} +\arguments{ +\item{moo_counts}{counts dataframe} + +\item{count_type}{the type of counts to use. Ignored when \code{moo_counts} is already a dataframe.} + +\item{sub_count_type}{used if \code{count_type} is a list in the counts slot: specify the sub count type within the list.} + +\item{sample_metadata}{sample metadata as a data frame or tibble.} + +\item{feature_id_colname}{The column from the counts data containing feature IDs. If \code{NULL}, first column is used.} + +\item{sample_id_colname}{The column from sample metadata containing sample names. If \code{NULL}, first column is used.} + +\item{samples_to_rename}{optional named mapping in \code{old_name: new_name} format for display labels.} + +\item{group_colname}{The column from sample metadata containing sample group information.} + +\item{label_colname}{The column from sample metadata containing sample labels.} + +\item{principal_components}{vector with numbered principal components to plot} + +\item{point_size}{size for \code{ggplot2::geom_point()}} + +\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{plot_title}{title for the plot} + +\item{plot_filename}{output filename when saving plots.} + +\item{print_plots}{whether to print plot to the active graphics device.} + +\item{save_plots}{whether to save plot to disk.} + +\item{plots_subdir}{output subdirectory for saved plots.} +} +\value{ +\code{plotly::plot_ly} figure +} +\description{ +Perform and plot a 3D Principal Components Analysis + +3D PCA for counts dataframe +} +\seealso{ +Other PCA functions: +\code{\link[=calc_pca]{calc_pca()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_pca_2d]{plot_pca_2d()}} +} +\concept{PCA functions} diff --git a/code/MOSuite/man/plot_read_depth.Rd b/code/MOSuite/man/plot_read_depth.Rd new file mode 100644 index 0000000..c6d5c1d --- /dev/null +++ b/code/MOSuite/man/plot_read_depth.Rd @@ -0,0 +1,76 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_read_depth.R +\name{plot_read_depth} +\alias{plot_read_depth} +\title{Plot read depth as a bar plot} +\usage{ +plot_read_depth(moo_counts, ...) +} +\arguments{ +\item{moo_counts}{counts dataframe or \code{multiOmicDataSet} containing \code{count_type} & \code{sub_count_type} in the counts +slot} + +\item{...}{arguments forwarded to method} +} +\value{ +ggplot barplot +} +\description{ +The first argument can be a \code{multiOmicDataset} object (\code{moo}) or a \code{data.frame} containing counts. +For a \code{moo}, choose which counts slot to use with \code{count_type} & (optionally) \code{sub_count_type}. +} +\section{Methods}{ +\tabular{ll}{ + link to docs \tab class \cr + \code{\link[=plot_read_depth]{plot_read_depth()}} \tab \code{multiOmicDataSet} \cr + \code{\link[=plot_read_depth]{plot_read_depth()}} \tab \code{data.frame} \cr +} +} + +\examples{ +# multiOmicDataSet +moo <- multiOmicDataSet( + sample_metadata = nidap_sample_metadata, + anno_dat = data.frame(), + counts_lst = list( + "raw" = nidap_raw_counts, + "clean" = nidap_clean_raw_counts + ) +) + +plot_read_depth(moo, count_type = "clean") + +# dataframe +plot_read_depth(nidap_clean_raw_counts) + +} +\seealso{ +\itemize{ +\item \code{\link[=plot_read_depth.multiOmicDataSet]{plot_read_depth.multiOmicDataSet()}} +\item \code{\link[=plot_read_depth.data.frame]{plot_read_depth.data.frame()}} +} + +Other plotters: +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=print_or_save_plot]{print_or_save_plot()}} + +Other moo methods: +\code{\link[=batch_correct_counts]{batch_correct_counts()}}, +\code{\link[=clean_raw_counts]{clean_raw_counts()}}, +\code{\link[=diff_counts]{diff_counts()}}, +\code{\link[=filter_counts]{filter_counts()}}, +\code{\link[=filter_diff]{filter_diff()}}, +\code{\link[=normalize_counts]{normalize_counts()}}, +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=run_deseq2]{run_deseq2()}}, +\code{\link[=set_color_pal]{set_color_pal()}} +} +\concept{moo methods} +\concept{plotters} +\keyword{plotters} diff --git a/code/MOSuite/man/plot_read_depth.data.frame.Rd b/code/MOSuite/man/plot_read_depth.data.frame.Rd new file mode 100644 index 0000000..35c2689 --- /dev/null +++ b/code/MOSuite/man/plot_read_depth.data.frame.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_read_depth.R +\name{plot_read_depth,data.frame-method} +\alias{plot_read_depth,data.frame-method} +\alias{plot_read_depth.data.frame} +\title{Plot read depth for \code{data.frame}} +\arguments{ +\item{...}{additional arguments (ignored; accepted for compatibility with the moo dispatch)} +} +\value{ +ggplot barplot +} +\description{ +Plot read depth for \code{data.frame} +} +\examples{ +# dataframe +plot_read_depth(nidap_clean_raw_counts) + +} +\seealso{ +\code{\link[=plot_read_depth]{plot_read_depth()}} generic + +Other plotters for counts dataframes: +\code{\link{plot_corr_heatmap,data.frame-method}}, +\code{\link{plot_histogram,data.frame-method}}, +\code{\link{plot_pca,data.frame-method}} +} +\concept{plotters for counts dataframes} diff --git a/code/MOSuite/man/plot_read_depth.multiOmicDataSet.Rd b/code/MOSuite/man/plot_read_depth.multiOmicDataSet.Rd new file mode 100644 index 0000000..50647ec --- /dev/null +++ b/code/MOSuite/man/plot_read_depth.multiOmicDataSet.Rd @@ -0,0 +1,41 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_read_depth.R +\name{plot_read_depth,MOSuite::multiOmicDataSet-method} +\alias{plot_read_depth,MOSuite::multiOmicDataSet-method} +\alias{plot_read_depth.multiOmicDataSet} +\title{Plot read depth for multiOmicDataSet} +\arguments{ +\item{count_type}{the type of counts to use. Must be a name in the counts slot (\code{names(moo@counts)}).} + +\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]])}.} +} +\value{ +ggplot barplot +} +\description{ +Plot read depth for multiOmicDataSet +} +\examples{ +# multiOmicDataSet +moo <- multiOmicDataSet( + sample_metadata = nidap_sample_metadata, + anno_dat = data.frame(), + counts_lst = list( + "raw" = nidap_raw_counts, + "clean" = nidap_clean_raw_counts + ) +) + +plot_read_depth(moo, count_type = "clean") + +} +\seealso{ +\code{\link[=plot_read_depth]{plot_read_depth()}} generic + +Other plotters for multiOmicDataSets: +\code{\link{plot_corr_heatmap,MOSuite::multiOmicDataSet-method}}, +\code{\link{plot_histogram,MOSuite::multiOmicDataSet-method}}, +\code{\link{plot_pca,MOSuite::multiOmicDataSet-method}} +} +\concept{plotters for multiOmicDataSets} diff --git a/code/MOSuite/man/plot_venn_diagram.Rd b/code/MOSuite/man/plot_venn_diagram.Rd new file mode 100644 index 0000000..658e8c1 --- /dev/null +++ b/code/MOSuite/man/plot_venn_diagram.Rd @@ -0,0 +1,202 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_venn_diagram.R +\name{plot_venn_diagram} +\alias{plot_venn_diagram} +\alias{plot_venn_diagram,MOSuite::multiOmicDataSet-method} +\alias{plot_venn_diagram,data.frame-method} +\title{Plot a venn diagram, UpSet plot, or table of intersections} +\usage{ +plot_venn_diagram( + moo_diff_summary_dat, + feature_id_colname = NULL, + contrasts_colname = "Contrast", + select_contrasts = c(), + plot_type = "Venn diagram", + intersection_ids = c(), + venn_force_unique = TRUE, + venn_numbers_format = "raw", + venn_significant_digits = 2, + venn_fill_colors = c("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 = c(), + venn_category_names_position = c(), + 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 = grDevices::png, + dpi = 300, + image_width = 4000, + image_height = 3000, + plot_filename = "venn_diagram.png", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" +) + +## S7 method for class +plot_venn_diagram( + moo_diff_summary_dat, + feature_id_colname = NULL, + contrasts_colname = "Contrast", + select_contrasts = c(), + plot_type = "Venn diagram", + intersection_ids = c(), + venn_force_unique = TRUE, + venn_numbers_format = "raw", + venn_significant_digits = 2, + venn_fill_colors = c("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 = c(), + venn_category_names_position = c(), + 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 = grDevices::png, + dpi = 300, + image_width = 4000, + image_height = 3000, + plot_filename = "venn_diagram.png", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" +) + +## S7 method for class +plot_venn_diagram( + moo_diff_summary_dat, + feature_id_colname = NULL, + contrasts_colname = "Contrast", + select_contrasts = c(), + plot_type = "Venn diagram", + intersection_ids = c(), + venn_force_unique = TRUE, + venn_numbers_format = "raw", + venn_significant_digits = 2, + venn_fill_colors = c("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 = c(), + venn_category_names_position = c(), + 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 = grDevices::png, + dpi = 300, + image_width = 4000, + image_height = 3000, + plot_filename = "venn_diagram.png", + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" +) +} +\arguments{ +\item{moo_diff_summary_dat}{Summarized differential expression analysis} + +\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 +used.)} + +\item{contrasts_colname}{Name of the column in \code{moo_diff_summary_dat} that contains the contrast names (default: +"Contrast")} + +\item{select_contrasts}{A vector of contrast names to select for the plot. If empty, all contrasts are used.} + +\item{plot_type}{Type of plot to generate: "Venn diagram" or "Intersection plot". Default: "Venn diagram"} + +\item{intersection_ids}{A vector of intersection IDs to select for the plot. If empty, all intersections are used.} + +\item{venn_force_unique}{If TRUE, forces unique elements in the Venn diagram. Default: TRUE} + +\item{venn_numbers_format}{Format for the numbers in the Venn diagram. Options: "raw", "percent", "raw-percent", +"percent-raw". Default: "raw"} + +\item{venn_significant_digits}{Number of significant digits for the Venn diagram numbers. Default: 2} + +\item{venn_fill_colors}{A vector of colors to fill the Venn diagram categories. Default: c("darkgoldenrod2", +"darkolivegreen2", "mediumpurple3", "darkorange2", "lightgreen")} + +\item{venn_fill_transparency}{Transparency level for the Venn diagram fill colors. Default: 0.2} + +\item{venn_border_colors}{Colors for the borders of the Venn diagram categories. Default: "fill colors" (uses the +same colors as \code{venn_fill_colors})} + +\item{venn_font_size_for_category_names}{Font size for the category names in the Venn diagram. Default: 3} + +\item{venn_category_names_distance}{Distance of the category names from the Venn diagram circles. Default: c()} + +\item{venn_category_names_position}{Position of the category names in the Venn diagram. Default: c()} + +\item{venn_font_size_for_counts}{Font size for the counts in the Venn diagram. Default: 6} + +\item{venn_outer_margin}{Outer margin for the Venn diagram. Default: 0} + +\item{intersections_order}{Order of the intersections in the plot. Default: "by size"} + +\item{display_empty_intersections}{If TRUE, displays empty intersections in the plot. Default: FALSE} + +\item{intersection_bar_color}{Color for the intersection bars in the plot. Default: "lightgray"} + +\item{intersection_point_size}{Size of the points in the intersection plot. Default: 2} + +\item{intersection_line_width}{Width of the lines in the intersection plot. Default: 0.5} + +\item{table_font_size}{Font size for the table in the plot. Default: 3} + +\item{table_content}{Content of the table in the plot. Default: NULL} + +\item{graphics_device}{passed to \code{ggsave(device)}. Default: \code{grDevices::png}} + +\item{dpi}{dots-per-inch of the output image (see \code{ggsave()}) - only used if save_plots is TRUE} + +\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{plot_filename}{plot output filename - only used if save_plots is TRUE} + +\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{plots_subdir}{subdirectory in \verb{figures/} where plots will be saved if \code{save_plots} is \code{TRUE}} +} +\description{ +Generates Venn diagram of intersections across a series of sets (e.g., intersections of significant genes across +tested contrasts). This 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. +An S7 generic with methods for \code{multiOmicDataSet} and \code{data.frame}. +} +\examples{ +plot_venn_diagram(nidap_volcano_summary_dat, print_plots = TRUE) + +} +\keyword{plotters} diff --git a/code/MOSuite/man/plot_volcano_enhanced.Rd b/code/MOSuite/man/plot_volcano_enhanced.Rd new file mode 100644 index 0000000..9b7f238 --- /dev/null +++ b/code/MOSuite/man/plot_volcano_enhanced.Rd @@ -0,0 +1,189 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_volcano_enhanced.R +\name{plot_volcano_enhanced} +\alias{plot_volcano_enhanced} +\alias{plot_volcano_enhanced,MOSuite::multiOmicDataSet-method} +\alias{plot_volcano_enhanced,data.frame-method} +\title{Enhanced Volcano Plot} +\usage{ +plot_volcano_enhanced( + moo_diff, + feature_id_colname = NULL, + signif_colname = c("B-A_adjpval", "B-C_adjpval"), + 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, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff", + plot_filename = "volcano_enhanced.png" +) + +## S7 method for class +plot_volcano_enhanced( + moo_diff, + feature_id_colname = NULL, + signif_colname = c("B-A_adjpval", "B-C_adjpval"), + 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, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff", + plot_filename = "volcano_enhanced.png" +) + +## S7 method for class +plot_volcano_enhanced( + moo_diff, + feature_id_colname = NULL, + signif_colname = c("B-A_adjpval", "B-C_adjpval"), + 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, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff", + plot_filename = "volcano_enhanced.png" +) +} +\arguments{ +\item{moo_diff}{Differential expression analysis result from one or more contrasts. This must be a dataframe.} + +\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 +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{signif_threshold}{Numeric value specifying the significance cutoff for p-values (i.e. filters on +\code{signif_colname})} + +\item{change_colname}{column name of fold change values.} + +\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{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{additional_labels}{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{lab_size}{Size of the labels in the volcano plot.} + +\item{change_sig_name}{Name for the significance column in the plot. Default is "p-value".} + +\item{change_lfc_name}{Name for the fold change column in the plot. Default is "log2FC".} + +\item{title}{Title of the plot. Default is "Volcano Plots".} + +\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{custom_xlim}{Custom X-axis limits for the plot.} + +\item{xlim_additional}{Additional space to add to the X-axis limits.} + +\item{ylim_additional}{Additional space to add to the Y-axis limits.} + +\item{axis_lab_size}{Size of the axis labels.} + +\item{point_size}{Size of the points in the plot.} + +\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{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{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{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} +} +\description{ +Uses \href{https://bioconductor.org/packages/release/bioc/html/EnhancedVolcano.html}{Bioconductor's Enhanced Volcano Plot}. +An S7 generic with methods for \code{multiOmicDataSet} and \code{data.frame}. +} +\examples{ +plot_volcano_enhanced(nidap_deg_analysis, print_plots = TRUE) + +} +\keyword{plotters} +\keyword{volcano} diff --git a/code/MOSuite/man/plot_volcano_summary.Rd b/code/MOSuite/man/plot_volcano_summary.Rd new file mode 100644 index 0000000..b6d410c --- /dev/null +++ b/code/MOSuite/man/plot_volcano_summary.Rd @@ -0,0 +1,271 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot_volcano_summary.R +\name{plot_volcano_summary} +\alias{plot_volcano_summary} +\alias{plot_volcano_summary,MOSuite::multiOmicDataSet-method} +\alias{plot_volcano_summary,data.frame-method} +\title{Volcano Plot - Summary} +\usage{ +plot_volcano_summary( + moo_diff, + 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 = c("FC", "logFC", "tstat", "pval", "adjpval"), + graphics_device = grDevices::png, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" +) + +## S7 method for class +plot_volcano_summary( + moo_diff, + 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 = c("FC", "logFC", "tstat", "pval", "adjpval"), + graphics_device = grDevices::png, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" +) + +## S7 method for class +plot_volcano_summary( + moo_diff, + 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 = c("FC", "logFC", "tstat", "pval", "adjpval"), + graphics_device = grDevices::png, + 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 = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_subdir = "diff" +) +} +\arguments{ +\item{moo_diff}{multiOmicDataSet or differential expression analysis result data frame.} + +\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 +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{signif_threshold}{Numeric value specifying the significance cutoff for p-values (i.e. filters on +\code{signif_colname})} + +\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{num_features_to_label}{Number of top features/genes to label in the volcano plot. Default is 30.} + +\item{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.} + +\item{label_features}{Select TRUE when you want to label ONLY a specific list of features(features) given in the +"custom_gene_list" 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{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: 4} + +\item{label_font_type}{Set the font type of the labels. Default: 1} + +\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{custom_gene_list_special_label_displacement}{Provide a list of features (comma separated) for which you want +special displacement of the feature label.} + +\item{special_label_displacement_x_axis}{Displacement of the feature label on the x-axis. Default: 2} + +\item{special_label_displacement_y_axis}{Displacement of the feature label on the y-axis. Default: 2} + +\item{color_of_signif_threshold_line}{Color of the significance threshold line. Default: "blue"} + +\item{color_of_non_significant_features}{Color of the non-significant features. Default: "black"} + +\item{color_of_logfold_change_threshold_line}{Color of the log fold change threshold line. Default: "red"} + +\item{color_of_features_meeting_only_signif_threshold}{Color of the features that meet only the significance +threshold. Default: "lightgoldenrod2"} + +\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"} + +\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} + +\item{use_default_x_axis_limit}{Set to TRUE to use the default x-axis limit. Default: TRUE} + +\item{x_axis_limit}{Custom x-axis limit. Default: c(-5, 5)} + +\item{use_default_y_axis_limit}{Set to TRUE to use the default y-axis limit. Default: TRUE} + +\item{y_axis_limit}{Custom y-axis limit. Default: c(0, 10)} + +\item{point_size}{Size of the points in the plot. Default: 1} + +\item{add_deg_columns}{Add additional columns from the DEG analysis to the +output dataset. Default: \verb{"FC", "logFC", "tstat", "pval", "adjpval"}} + +\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}{Set to TRUE to use the default grid layout. Default: TRUE} + +\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')} + +\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}} +} +\description{ +Produces one volcano plot for each tested contrast in the input DEG table. +It 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. +An S7 generic with methods for \code{multiOmicDataSet} and \code{data.frame}. +} +\examples{ +plot_volcano_summary(nidap_deg_analysis, print_plots = TRUE) + +} +\keyword{plotters} +\keyword{volcano} diff --git a/code/MOSuite/man/print_or_save_plot.Rd b/code/MOSuite/man/print_or_save_plot.Rd new file mode 100644 index 0000000..4d22ef1 --- /dev/null +++ b/code/MOSuite/man/print_or_save_plot.Rd @@ -0,0 +1,50 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plots.R +\name{print_or_save_plot} +\alias{print_or_save_plot} +\title{Print and/or save a ggplot} +\usage{ +print_or_save_plot( + plot_obj, + filename, + print_plots = options::opt("print_plots"), + save_plots = options::opt("save_plots"), + plots_dir = options::opt("plots_dir"), + graphics_device = grDevices::png, + ... +) +} +\arguments{ +\item{plot_obj}{plot object (e.g. ggplot, ComplexHeatmap...)} + +\item{filename}{name of the output file. will be joined with the \code{plots_dir} option.} + +\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{plots_dir}{Path where plots are saved when \code{moo_save_plots} is \code{TRUE} (Defaults to \code{"figures/"}, overwritable using option 'moo_plots_dir' or environment variable 'MOO_PLOTS_DIR')} + +\item{graphics_device}{Default: \code{grDevice::png()}. Only used if the plot is not a ggplot.} + +\item{...}{arguments forwarded to \code{ggplot2::ggsave()}} +} +\value{ +invisibly returns the path where the plot image was saved to the disk +} +\description{ +If \code{save_plots} is \code{TRUE}, the plot will be saved as an image to the path at +\code{file.path(plots_dir, filename)}. +If \code{plot_obj} is a ggplot, \code{ggplot2::ggsave()} is used to save the image. +Otherwise, \code{graphics_device} is used (\code{grDevice::png()} by default). +} +\seealso{ +Other plotters: +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}} +} +\concept{plotters} +\keyword{plotters} diff --git a/code/MOSuite/man/read_multiOmicDataSet.Rd b/code/MOSuite/man/read_multiOmicDataSet.Rd new file mode 100644 index 0000000..fdd0ef4 --- /dev/null +++ b/code/MOSuite/man/read_multiOmicDataSet.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/0_mo-class.R +\name{read_multiOmicDataSet} +\alias{read_multiOmicDataSet} +\title{Read a multiOmicDataSet from disk} +\usage{ +read_multiOmicDataSet(filepath) +} +\arguments{ +\item{filepath}{Path to an RDS file produced by \code{\link[=write_multiOmicDataSet]{write_multiOmicDataSet()}}} +} +\value{ +\link{multiOmicDataSet} +} +\description{ +Read a multiOmicDataSet from disk +} diff --git a/code/MOSuite/man/reexports.Rd b/code/MOSuite/man/reexports.Rd new file mode 100644 index 0000000..41acbe5 --- /dev/null +++ b/code/MOSuite/man/reexports.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/reexports.R +\docType{import} +\name{reexports} +\alias{reexports} +\alias{:=} +\alias{!!} +\alias{.data} +\title{walrus operator} +\keyword{internal} +\description{ +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}}} +}} + diff --git a/code/MOSuite/man/remove_low_count_genes.Rd b/code/MOSuite/man/remove_low_count_genes.Rd new file mode 100644 index 0000000..6564ecd --- /dev/null +++ b/code/MOSuite/man/remove_low_count_genes.Rd @@ -0,0 +1,52 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/filter.R +\name{remove_low_count_genes} +\alias{remove_low_count_genes} +\title{Remove low-count genes} +\usage{ +remove_low_count_genes( + counts_dat, + sample_metadata, + feature_id_colname, + group_colname, + use_cpm_counts_to_filter = TRUE, + use_group_based_filtering = FALSE, + 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 +) +} +\arguments{ +\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 +used.)} + +\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{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 +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.} + +\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} + +\item{minimum_count_value_to_be_considered_nonzero}{Minimum count value to be considered non-zero for a sample} + +\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_a_group}{Only keeps genes that have at least this number of +samples with nonzero CPM counts in at least one group} +} +\value{ +counts matrix with low-count genes removed +} +\description{ +TODO this function also transforms raw counts to CPM, but that should be a separate function before this step, before +filter_counts function() +} +\keyword{internal} diff --git a/code/MOSuite/man/rename_samples.Rd b/code/MOSuite/man/rename_samples.Rd new file mode 100644 index 0000000..0eaeb46 --- /dev/null +++ b/code/MOSuite/man/rename_samples.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/rename.R +\name{rename_samples} +\alias{rename_samples} +\title{Rename samples} +\usage{ +rename_samples(dat, samples_to_rename_manually) +} +\arguments{ +\item{dat}{data frame} + +\item{samples_to_rename_manually}{TODO use sample metadata spreadsheet custom column. Need to document the format of +this object.} +} +\value{ +data frame with samples renamed +} +\description{ +TODO this should happen right at the beginning of the template? +} +\details{ +TODO accept new names for samples in sample metadata spreadsheet +} +\keyword{internal} diff --git a/code/MOSuite/man/run_deseq2.Rd b/code/MOSuite/man/run_deseq2.Rd new file mode 100644 index 0000000..db9ff05 --- /dev/null +++ b/code/MOSuite/man/run_deseq2.Rd @@ -0,0 +1,52 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/deseq2.R +\name{run_deseq2} +\alias{run_deseq2} +\title{Run DESeq2 on a multiOmicDataSet} +\usage{ +run_deseq2(moo, design, ...) +} +\arguments{ +\item{moo}{multiOmicDataSet object} + +\item{design}{model formula for experimental design. Columns must exist in \code{meta_dat}.} + +\item{...}{remaining variables are forwarded to \code{DESeq2::DESeq()}.} +} +\value{ +multiOmicDataSet object with DESeq2 slot filled +} +\description{ +Run DESeq2 on a multiOmicDataSet +} +\examples{ +\dontrun{ +moo <- create_multiOmicDataSet_from_files( + system.file("extdata", "sample_metadata.tsv.gz", + package = "MOSuite" + ), + system.file("extdata", + "RSEM.genes.expected_count.all_samples.txt.gz", + package = "MOSuite" + ) +) |> filter_counts() +moo <- run_deseq2(moo, ~condition) +} +} +\seealso{ +Other moo methods: +\code{\link[=batch_correct_counts]{batch_correct_counts()}}, +\code{\link[=clean_raw_counts]{clean_raw_counts()}}, +\code{\link[=diff_counts]{diff_counts()}}, +\code{\link[=filter_counts]{filter_counts()}}, +\code{\link[=filter_diff]{filter_diff()}}, +\code{\link[=normalize_counts]{normalize_counts()}}, +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=set_color_pal]{set_color_pal()}} +} +\concept{moo methods} +\keyword{internal} diff --git a/code/MOSuite/man/separate_gene_meta_columns.Rd b/code/MOSuite/man/separate_gene_meta_columns.Rd new file mode 100644 index 0000000..5734a85 --- /dev/null +++ b/code/MOSuite/man/separate_gene_meta_columns.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/clean.R +\name{separate_gene_meta_columns} +\alias{separate_gene_meta_columns} +\title{Separate gene metadata column} +\usage{ +separate_gene_meta_columns(counts_dat, split_gene_name = TRUE) +} +\arguments{ +\item{counts_dat}{dataframe with raw counts data} + +\item{split_gene_name}{If \code{TRUE}, split the gene name column by any of these special characters: \verb{,|_-:}} +} +\value{ +dataframe with metadata separated +} +\description{ +Separate gene metadata column +} +\keyword{internal} diff --git a/code/MOSuite/man/set_color_pal.Rd b/code/MOSuite/man/set_color_pal.Rd new file mode 100644 index 0000000..c603f0e --- /dev/null +++ b/code/MOSuite/man/set_color_pal.Rd @@ -0,0 +1,50 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/colors.R +\name{set_color_pal} +\alias{set_color_pal} +\title{Set color palette for a single group/column} +\usage{ +set_color_pal(moo, colname, palette_fun = grDevices::palette.colors, ...) +} +\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}} +} +\value{ +\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 +} +\examples{ +moo <- create_multiOmicDataSet_from_dataframes( + sample_metadata = as.data.frame(nidap_sample_metadata), + 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@analyses$colors$Group + +} +\seealso{ +Other moo methods: +\code{\link[=batch_correct_counts]{batch_correct_counts()}}, +\code{\link[=clean_raw_counts]{clean_raw_counts()}}, +\code{\link[=diff_counts]{diff_counts()}}, +\code{\link[=filter_counts]{filter_counts()}}, +\code{\link[=filter_diff]{filter_diff()}}, +\code{\link[=normalize_counts]{normalize_counts()}}, +\code{\link[=plot_corr_heatmap]{plot_corr_heatmap()}}, +\code{\link[=plot_expr_heatmap]{plot_expr_heatmap()}}, +\code{\link[=plot_histogram]{plot_histogram()}}, +\code{\link[=plot_pca]{plot_pca()}}, +\code{\link[=plot_read_depth]{plot_read_depth()}}, +\code{\link[=run_deseq2]{run_deseq2()}} +} +\concept{moo methods} diff --git a/code/MOSuite/man/setup_capsule_environment.Rd b/code/MOSuite/man/setup_capsule_environment.Rd new file mode 100644 index 0000000..96b4acb --- /dev/null +++ b/code/MOSuite/man/setup_capsule_environment.Rd @@ -0,0 +1,25 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{setup_capsule_environment} +\alias{setup_capsule_environment} +\title{Set up capsule environment and directories} +\usage{ +setup_capsule_environment(base_results_dir = file.path("..", "results")) +} +\arguments{ +\item{base_results_dir}{base path to results directory (default: \code{../results})} +} +\value{ +invisibly returns a list with \code{results_dir} and \code{plots_dir} paths +} +\description{ +Initializes the results directory structure and logs installed R package versions. +This is a common setup task used across all Code Ocean capsules. +} +\examples{ +\dontrun{ +setup_capsule_environment() +} + +} +\keyword{internal} diff --git a/code/MOSuite/man/strip_ensembl_version.Rd b/code/MOSuite/man/strip_ensembl_version.Rd new file mode 100644 index 0000000..4e5e568 --- /dev/null +++ b/code/MOSuite/man/strip_ensembl_version.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/clean.R +\name{strip_ensembl_version} +\alias{strip_ensembl_version} +\title{Remove version number from ENSEMBLE IDs} +\usage{ +strip_ensembl_version(x) +} +\arguments{ +\item{x}{vector of IDs} +} +\value{ +IDs without version numbers +} +\description{ +Remove version number from ENSEMBLE IDs +} +\keyword{internal} diff --git a/code/MOSuite/man/write_multiOmicDataSet.Rd b/code/MOSuite/man/write_multiOmicDataSet.Rd new file mode 100644 index 0000000..83fd0dc --- /dev/null +++ b/code/MOSuite/man/write_multiOmicDataSet.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/0_mo-class.R +\name{write_multiOmicDataSet} +\alias{write_multiOmicDataSet} +\title{Write a multiOmicDataSet to disk as an RDS file} +\usage{ +write_multiOmicDataSet(moo, filepath = "moo.rds") +} +\arguments{ +\item{moo}{\link{multiOmicDataSet} object to serialize} + +\item{filepath}{Path to the RDS file to write (default: "moo.rds")} +} +\value{ +Invisibly returns \code{filepath} +} +\description{ +Write a multiOmicDataSet to disk as an RDS file +} diff --git a/code/MOSuite/man/write_multiOmicDataSet_properties.Rd b/code/MOSuite/man/write_multiOmicDataSet_properties.Rd new file mode 100644 index 0000000..79a19e3 --- /dev/null +++ b/code/MOSuite/man/write_multiOmicDataSet_properties.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/0_mo-class.R +\name{write_multiOmicDataSet_properties} +\alias{write_multiOmicDataSet_properties} +\alias{write_multiOmicDataSet_properties,MOSuite::multiOmicDataSet-method} +\title{Write multiOmicDataSet properties to disk as CSV files} +\usage{ +write_multiOmicDataSet_properties(moo, output_dir = "moo") + +## S7 method for class +write_multiOmicDataSet_properties(moo, output_dir = "moo") +} +\arguments{ +\item{moo}{\code{multiOmicDataSet} object to write properties from} + +\item{output_dir}{Directory where the properties will be saved (default: "moo")} +} +\value{ +Invisibly returns the \code{output_dir} where the files were saved +} +\description{ +Writes the properties of a multiOmicDataSet object to disk as separate files in output_dir. +Properties that are data frames are saved as CSV files, while all other objects are saved as RDS files. +} diff --git a/code/MOSuite/tests/testthat.R b/code/MOSuite/tests/testthat.R new file mode 100644 index 0000000..254e711 --- /dev/null +++ b/code/MOSuite/tests/testthat.R @@ -0,0 +1,14 @@ +# This file is part of the standard setup for testthat. +# It is recommended that you do not modify it. +# +# Where should you do additional test configuration? +# Learn more about the roles of various files in: +# * https://r-pkgs.org/testing-design.html#sec-tests-files-overview +# * https://testthat.r-lib.org/articles/special-files.html + +library(testthat) +library(MOSuite) + +options(moo_save_plots = FALSE) + +test_check("MOSuite") diff --git a/code/MOSuite/tests/testthat/_snaps/E2E.md b/code/MOSuite/tests/testthat/_snaps/E2E.md new file mode 100644 index 0000000..b420659 --- /dev/null +++ b/code/MOSuite/tests/testthat/_snaps/E2E.md @@ -0,0 +1,106 @@ +# E2E workflow succeeds for RENEE data + + Code + moo <- filter_diff(diff_counts(normalize_counts(filter_counts(clean_raw_counts( + create_multiOmicDataSet_from_files(sample_meta_filepath = metadata_tsv, + feature_counts_filepath = gene_counts_tsv)), group_colname = "condition", + label_colname = "sample_id", minimum_count_value_to_be_considered_nonzero = 1, + minimum_number_of_samples_with_nonzero_counts_in_total = 1, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 1, ), group_colname = "condition", + label_colname = "sample_id"), covariates_colnames = "condition", + contrast_colname = "condition", contrasts = c("knockout-wildtype")), + significance_column = "adjpval", significance_cutoff = 0.05, change_column = "logFC", + change_cutoff = 1, filtering_mode = "any", include_estimates = c("FC", "logFC", + "tstat", "pval", "adjpval"), round_estimates = TRUE, + rounding_decimal_for_percent_cells = 0, contrast_filter = "none", contrasts = c(), + groups = c(), groups_filter = "none", label_font_size = 6, label_distance = 1, + y_axis_expansion = 0.08, fill_colors = c("steelblue1", "whitesmoke"), + pie_chart_in_3d = TRUE, bar_width = 0.4, draw_bar_border = TRUE, plot_type = "bar", + plot_titles_fontsize = 12) + Message + Rows: 58929 Columns: 6 + -- Column specification -------------------------------------------------------- + Delimiter: "\t" + chr (2): gene_id, GeneName + dbl (4): KO_S3, KO_S4, WT_S1, WT_S2 + + i Use `spec()` to retrieve the full column specification for this data. + i Specify the column types or set `show_col_types = FALSE` to quiet this message. + Rows: 4 Columns: 2 + -- Column specification -------------------------------------------------------- + Delimiter: "\t" + chr (2): sample_id, condition + + i Use `spec()` to retrieve the full column specification for this data. + i Specify the column types or set `show_col_types = FALSE` to quiet this message. + * cleaning raw counts + Not able to identify multiple id's in gene_id + Columns that can be used to aggregate gene information gene_id + Aggregating the counts for the same ID in different chromosome locations. + Column used to Aggregate duplicate IDs: gene_id + Number of rows before Collapse: 58929 + 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 + * differential counts + Setting first column of `counts` as gene annotation. + Total number of genes included: 291 + * filtering differential features + Total number of genes selected with adjpval < 0.05 and | logFC | ≥ 1 is sum(selgenes) + +# E2E workflow succeeds for NIDAP data + + Code + moo_nidap <- filter_diff(diff_counts(batch_correct_counts(normalize_counts( + filter_counts(clean_raw_counts(create_multiOmicDataSet_from_dataframes( + sample_metadata = as.data.frame(nidap_sample_metadata), counts_dat = as.data.frame( + nidap_raw_counts))), group_colname = "Group"), group_colname = "Group"), + covariates_colname = "Group", batch_colname = "Batch", label_colname = "Label"), + count_type = "filt", sub_count_type = NULL, sample_id_colname = "Sample", + feature_id_colname = "GeneName", covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), contrasts = c("B-A", "C-A", "B-C"), + input_in_log_counts = FALSE, return_mean_and_sd = TRUE, + voom_normalization_method = "quantile", ), significance_column = "adjpval", + significance_cutoff = 0.05, change_column = "logFC", change_cutoff = 1, + filtering_mode = "any", include_estimates = c("FC", "logFC", "tstat", "pval", + "adjpval"), round_estimates = TRUE, rounding_decimal_for_percent_cells = 0, + contrast_filter = "none", contrasts = c(), groups = c(), groups_filter = "none", + label_font_size = 6, label_distance = 1, y_axis_expansion = 0.08, fill_colors = c( + "steelblue1", "whitesmoke"), pie_chart_in_3d = TRUE, bar_width = 0.4, + draw_bar_border = TRUE, plot_type = "bar", plot_titles_fontsize = 12) + Message + * cleaning raw counts + Not able to identify multiple id's in GeneName + Columns that can be used to aggregate gene information GeneName + Aggregating the counts for the same ID in different chromosome locations. + Column used to Aggregate duplicate IDs: GeneName + Number of rows before Collapse: 43280 + 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 + * batch-correcting norm-voom counts + Found2batches + Adjusting for2covariate(s) or covariate level(s) + Standardizing Data across genes + Fitting L/S model and finding priors + Finding parametric adjustments + Adjusting the Data + + The total number of features in output: 7943 + Number of samples after batch correction: 10 + * differential counts + Setting first column of `counts` as gene annotation. + Total number of genes included: 7942 + Joining with `by = join_by(GeneName)` + Joining with `by = join_by(GeneName)` + * filtering differential features + Total number of genes selected with adjpval < 0.05 and | logFC | ≥ 1 is sum(selgenes) + diff --git a/code/MOSuite/tests/testthat/_snaps/cli.md b/code/MOSuite/tests/testthat/_snaps/cli.md new file mode 100644 index 0000000..cc98210 --- /dev/null +++ b/code/MOSuite/tests/testthat/_snaps/cli.md @@ -0,0 +1,20 @@ +# mosuite cli + + Code + system(command) + +# mosuite --help + + Code + cli_exec("--help") + +--- + + Code + system(paste(system.file("exec", "mosuite", package = "MOSuite"), "--help")) + +--- + + Code + cli_exec("help") + diff --git a/code/MOSuite/tests/testthat/_snaps/plot_venn_diagram.md b/code/MOSuite/tests/testthat/_snaps/plot_venn_diagram.md new file mode 100644 index 0000000..b6e1eb0 --- /dev/null +++ b/code/MOSuite/tests/testthat/_snaps/plot_venn_diagram.md @@ -0,0 +1,9 @@ +# plot_venn_diagram works with defaults + + Code + p <- plot_venn_diagram(nidap_volcano_summary_dat, print_plots = FALSE, + save_plots = TRUE) + Message + All intersections: 1:7,c(1, 2, 3, 4, 5, 6, 7),c(163, 237, 518, 780, 225, 379, 766),c("Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes") + Intersections returned: 1:7,c(1, 2, 3, 4, 5, 6, 7),c(163, 237, 518, 780, 225, 379, 766) + diff --git a/code/MOSuite/tests/testthat/_snaps/plot_volcano_enhanced.md b/code/MOSuite/tests/testthat/_snaps/plot_volcano_enhanced.md new file mode 100644 index 0000000..58c8804 --- /dev/null +++ b/code/MOSuite/tests/testthat/_snaps/plot_volcano_enhanced.md @@ -0,0 +1,15 @@ +# plot_volcano_enhanced works on nidap dataset + + Code + df_volc_enh <- plot_volcano_enhanced(nidap_deg_analysis, save_plots = FALSE, + print_plots = FALSE) + Message + Genes in initial dataset: 7943 + + Max y: 4.60041859457819 + + 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 new file mode 100644 index 0000000..7b248c1 --- /dev/null +++ b/code/MOSuite/tests/testthat/_snaps/plot_volcano_summary.md @@ -0,0 +1,19 @@ +# plot_volcano_summary works on nidap dataset + + Code + df_volc_sum <- plot_volcano_summary(nidap_deg_analysis, save_plots = FALSE, + print_plots = FALSE) + Message + Preparing table for contrast: B-A + Fold change column: B-A_logFC + pval column: B-A_pval + 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 + 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 + Total number of features included in volcano plot: 7943 + diff --git a/code/MOSuite/tests/testthat/data/moo.rds b/code/MOSuite/tests/testthat/data/moo.rds new file mode 100644 index 0000000..4545d90 Binary files /dev/null and b/code/MOSuite/tests/testthat/data/moo.rds differ diff --git a/code/MOSuite/tests/testthat/data/test_mosuite_cli.sh b/code/MOSuite/tests/testthat/data/test_mosuite_cli.sh new file mode 100644 index 0000000..d592d74 --- /dev/null +++ b/code/MOSuite/tests/testthat/data/test_mosuite_cli.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -euo pipefail + +# set MOSuite options for plots +export MOO_SAVE_PLOTS=TRUE +export MOO_PLOTS_DIR=tests/testthat/data/figures +mkdir -p $MOO_PLOTS_DIR + +# add mosuite executable to the path +mosuite=$(R -s -e "cat(system.file('exec','mosuite', package='MOSuite'))") +export PATH="$PATH:$(dirname $mosuite)" + +mosuite create_multiOmicDataSet_from_files --json=tests/testthat/data/create_multiOmicDataSet_from_files.json +mosuite clean_raw_counts --json=tests/testthat/data/clean_raw_counts.json +mosuite filter_counts --json=tests/testthat/data/filter_counts.json +mosuite normalize_counts --json=tests/testthat/data/normalize_counts.json +mosuite batch_correct_counts --json=tests/testthat/data/batch_correct_counts.json +mosuite diff_counts --json=tests/testthat/data/diff_counts.json +mosuite filter_diff --json=tests/testthat/data/filter_diff.json diff --git a/code/MOSuite/tests/testthat/helper-functions.R b/code/MOSuite/tests/testthat/helper-functions.R new file mode 100644 index 0000000..cb655a1 --- /dev/null +++ b/code/MOSuite/tests/testthat/helper-functions.R @@ -0,0 +1,59 @@ +equal_dfs <- function(x, y) { + return(all( + class(x) == class(y), + names(x) == names(y), + rownames(x) == rownames(y), + all.equal(x, y), + all.equal(lapply(x, class), lapply(y, class)) + )) +} + +# source https://stackoverflow.com/a/75232781/5787827 +compare_proxy.plotly <- function(x, path = "x") { + names(x$x$visdat) <- "proxy" + e <- environment(x$x$visdat$proxy) + + # Maybe we should follow the recursion, but not now. + e$p <- NULL + + e$id <- "proxy" + + x$x$cur_data <- "proxy" + names(x$x$attrs) <- "proxy" + + return(list(object = x, path = paste0("compare_proxy(", path, ")"))) +} + +run_function_cli <- function(func_name) { + json_path <- paste0( + func_name, + ".json" + ) + + return(cli_exec(c( + func_name, + paste0('--json="', json_path, '"') + ))) +} + +# source: https://github.com/r-lib/testthat/issues/664#issuecomment-340809997 +create_empty_dir <- function(x) { + unlink(x, recursive = TRUE, force = TRUE) + return(dir.create(x)) +} + +# source: https://github.com/r-lib/testthat/issues/664#issuecomment-340809997 +test_with_dir <- function(desc, ...) { + new <- tempfile() + create_empty_dir(new) + withr::with_dir( + # or local_dir() + new = new, + code = { + capture.output( + testthat::test_that(desc = desc, ...) # nolint: object_usage_linter + ) + } + ) + return(invisible()) +} diff --git a/code/MOSuite/tests/testthat/test-0_mo-class.R b/code/MOSuite/tests/testthat/test-0_mo-class.R new file mode 100644 index 0000000..2bd946d --- /dev/null +++ b/code/MOSuite/tests/testthat/test-0_mo-class.R @@ -0,0 +1,451 @@ +test_that("constructing MOO works for RENEE data", { + moo <- create_multiOmicDataSet_from_files( + system.file("extdata", "sample_metadata.tsv.gz", package = "MOSuite"), + system.file( + "extdata", + "RSEM.genes.expected_count.all_samples.txt.gz", + package = "MOSuite" + ), + sample_id_colname = "sample_id", + feature_id_colname = "gene_id" + ) + expect_equal( + moo@sample_meta, + structure( + list( + sample_id = c("KO_S3", "KO_S4", "WT_S1", "WT_S2"), + condition = c("knockout", "knockout", "wildtype", "wildtype") + ), + row.names = c(NA, -4L), + class = c("tbl_df", "tbl", "data.frame") + ) + ) + expect_equal( + moo@annotation |> head(), + structure( + list( + gene_id = c( + "ENSG00000121410.11", + "ENSG00000268895.5", + "ENSG00000148584.15", + "ENSG00000175899.14", + "ENSG00000245105.3", + "ENSG00000166535.20" + ), + GeneName = c("A1BG", "A1BG-AS1", "A1CF", "A2M", "A2M-AS1", "A2ML1") + ), + row.names = c(NA, -6L), + class = c("tbl_df", "tbl", "data.frame") + ) + ) + expect_equal( + moo@counts$raw |> head(), + structure( + list( + gene_id = c( + "ENSG00000121410.11", + "ENSG00000268895.5", + "ENSG00000148584.15", + "ENSG00000175899.14", + "ENSG00000245105.3", + "ENSG00000166535.20" + ), + KO_S3 = c(0, 0, 0, 0, 0, 0), + KO_S4 = c(0, 0, 0, 0, 0, 0), + WT_S1 = c(0, 0, 0, 0, 0, 0), + WT_S2 = c(0, 0, 0, 0, 0, 0) + ), + row.names = c(NA, -6L), + class = c("tbl_df", "tbl", "data.frame") + ) + ) +}) + +test_that("constructing MOO works from CSV files", { + moo <- create_multiOmicDataSet_from_files( + system.file( + "extdata", + "nidap", + "Sample_Metadata_Bulk_RNA-seq_Training_Dataset_CCBR.csv.gz", + package = "MOSuite" + ), + system.file("extdata", "nidap", "Raw_Counts.csv.gz", package = "MOSuite"), + delim = "," + ) + expect_equal( + moo@sample_meta, + structure( + list( + Sample = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"), + Group = c("A", "A", "A", "B", "B", "B", "C", "C", "C"), + Replicate = c(1, 2, 3, 1, 2, 3, 1, 2, 3), + Batch = c(1, 2, 2, 1, 1, 2, 1, 2, 2), + Label = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3") + ), + row.names = c(NA, -9L), + class = c("tbl_df", "tbl", "data.frame") + ) + ) + expect_equal( + moo@annotation |> head(), + structure( + list( + GeneName = c( + "RP23-271O17.1", + "Gm26206", + "Xkr4", + "RP23-317L18.1", + "RP23-317L18.4", + "RP23-317L18.3" + ) + ), + row.names = c(NA, -6L), + class = c("tbl_df", "tbl", "data.frame") + ) + ) + expect_equal( + moo@counts$raw |> head(), + structure( + list( + GeneName = c( + "RP23-271O17.1", + "Gm26206", + "Xkr4", + "RP23-317L18.1", + "RP23-317L18.4", + "RP23-317L18.3" + ), + A1 = c(0, 0, 0, 0, 0, 0), + A2 = c(0, 0, 0, 0, 0, 0), + A3 = c(0, 0, 0, 0, 0, 0), + B1 = c(0, 0, 0, 0, 0, 0), + B2 = c(0, 0, 0, 0, 0, 0), + B3 = c(0, 0, 0, 0, 0, 0), + C1 = c(0, 0, 0, 0, 0, 0), + C2 = c(0, 0, 0, 0, 0, 0), + C3 = c(0, 0, 0, 0, 0, 0) + ), + row.names = c(NA, -6L), + class = c("tbl_df", "tbl", "data.frame") + ) + ) +}) + +test_that("annotation minimally contains feature id column", { + moo <- create_multiOmicDataSet_from_dataframes( + readr::read_tsv( + system.file("extdata", "sample_metadata.tsv.gz", package = "MOSuite") + ), + gene_counts |> glue_gene_symbols() + ) + expect_equal( + moo@annotation |> head(), + structure( + list( + gene_id = structure( + c( + "ENSG00000121410.11|A1BG", + "ENSG00000268895.5|A1BG-AS1", + "ENSG00000148584.15|A1CF", + "ENSG00000175899.14|A2M", + "ENSG00000245105.3|A2M-AS1", + "ENSG00000166535.20|A2ML1" + ), + class = c("glue", "character") + ) + ), + row.names = c(NA, -6L), + class = c("tbl_df", "tbl", "data.frame") + ) + ) +}) + +test_that("multiOmicDataSet from data frames detect problems", { + sample_meta <- data.frame( + sample_id = c("KO_S3", "KO_S4", "WT_S1", "WT_S2"), + condition = factor( + c("knockout", "knockout", "wildtype", "wildtype"), + levels = c("wildtype", "knockout") + ) + ) + expect_error( + create_multiOmicDataSet_from_dataframes(sample_meta, gene_counts[, 1:4]), + "Not all sample IDs in the sample metadata are in the count data" + ) +}) + +test_that("extract_counts works", { + 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)) + ) + ) + expect_equal(extract_counts(moo, "clean"), moo@counts$clean) + expect_equal(extract_counts(moo, "norm", "voom"), moo@counts$norm$voom) + expect_error(extract_counts(moo, "notacounttype"), "not in moo") + expect_error( + extract_counts(moo, "raw", "notasubtype"), + "does not contain subtypes" + ) + expect_error(extract_counts(moo, "norm"), "contains subtypes") +}) + + +test_that("write_multiOmicDataSet_properties works", { + moo_nidap <- 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)) + ) + ) |> + diff_counts( + count_type = "filt", + sub_count_type = NULL, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + voom_normalization_method = "quantile", + ) |> + filter_diff( + significance_column = "adjpval", + significance_cutoff = 0.05, + change_column = "logFC", + change_cutoff = 1, + filtering_mode = "any", + include_estimates = c("FC", "logFC", "tstat", "pval", "adjpval"), + round_estimates = TRUE, + rounding_decimal_for_percent_cells = 0, + contrast_filter = "none", + contrasts = c(), + groups = c(), + groups_filter = "none", + label_font_size = 6, + label_distance = 1, + y_axis_expansion = 0.08, + fill_colors = c("steelblue1", "whitesmoke"), + pie_chart_in_3d = TRUE, + bar_width = 0.4, + draw_bar_border = TRUE, + plot_type = "bar", + plot_titles_fontsize = 12 + ) + moo_nidap@analyses$foo <- "bar" + + temp_dir <- tempfile(pattern = "moo-write-") + on.exit(unlink(temp_dir, recursive = TRUE), add = TRUE) + + expect_equal(write_multiOmicDataSet_properties(moo_nidap, temp_dir), temp_dir) + + expect_true(file.exists(file.path(temp_dir, "sample_metadata.csv"))) + expect_true(file.exists(file.path(temp_dir, "feature_annotation.csv"))) + + expect_true(file.exists(file.path(temp_dir, "counts", "raw_counts.csv"))) + expect_true(file.exists(file.path(temp_dir, "counts", "clean_counts.csv"))) + expect_true(file.exists(file.path(temp_dir, "counts", "filt_counts.csv"))) + expect_true( + file.exists(file.path(temp_dir, "counts", "norm", "voom_counts.csv")) + ) + + expect_true(file.exists(file.path(temp_dir, "analyses", "foo.rds"))) + expect_true(file.exists(file.path( + temp_dir, + "analyses", + "diff", + "diff_B-A.csv" + ))) + expect_true(file.exists(file.path( + temp_dir, + "analyses", + "diff", + "diff_C-A.csv" + ))) + expect_true(file.exists(file.path( + temp_dir, + "analyses", + "diff", + "diff_B-C.csv" + ))) + expect_true(file.exists(file.path(temp_dir, "analyses", "diff_filt.csv"))) + expect_true(dir.exists(file.path(temp_dir, "analyses", "colors"))) + expect_true(file.exists(file.path( + temp_dir, + "analyses", + "colors", + "colors_Sample.rds" + ))) + expect_true(file.exists(file.path( + temp_dir, + "analyses", + "colors", + "colors_Batch.rds" + ))) + expect_true(file.exists(file.path( + temp_dir, + "analyses", + "colors", + "colors_Group.rds" + ))) + expect_true(file.exists(file.path( + temp_dir, + "analyses", + "colors", + "colors_Label.rds" + ))) + expect_true(file.exists(file.path( + temp_dir, + "analyses", + "colors", + "colors_Replicate.rds" + ))) +}) + +test_that("write_multiOmicDataSet and read_multiOmicDataSet work", { + # Create a simple moo object + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(GeneName = unique(nidap_raw_counts$GeneName)), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "clean" = as.data.frame(nidap_clean_raw_counts) + ) + ) + + # Write to temp file + temp_file <- tempfile(pattern = "moo-", fileext = ".rds") + on.exit(unlink(temp_file), add = TRUE) + + # Test write returns filepath invisibly + expect_equal(write_multiOmicDataSet(moo, temp_file), temp_file) + expect_true(file.exists(temp_file)) + + # Test read + moo_read <- read_multiOmicDataSet(temp_file) + expect_true(S7::S7_inherits(moo_read, multiOmicDataSet)) + + # Verify all properties match + expect_equal(moo_read@sample_meta, moo@sample_meta) + expect_equal(moo_read@annotation, moo@annotation) + expect_equal(moo_read@counts, moo@counts) + expect_equal(names(moo_read@analyses), names(moo@analyses)) +}) + +test_that("write_multiOmicDataSet validates input", { + expect_error( + write_multiOmicDataSet("not a moo"), + "moo must be a multiOmicDataSet" + ) + expect_error( + write_multiOmicDataSet(list(sample_meta = data.frame())), + "moo must be a multiOmicDataSet" + ) +}) + +test_that("read_multiOmicDataSet validates input", { + temp_file <- tempfile(fileext = ".rds") + on.exit(unlink(temp_file), add = TRUE) + + # Write a non-moo object + readr::write_rds(list(a = 1, b = 2), temp_file) + + expect_error( + read_multiOmicDataSet(temp_file), + "RDS does not contain a multiOmicDataSet" + ) +}) + +test_that("write and read preserves complex moo with analyses", { + moo_complex <- 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)) + ) + ) + + temp_file <- tempfile(pattern = "moo-complex-", fileext = ".rds") + on.exit(unlink(temp_file), add = TRUE) + + write_multiOmicDataSet(moo_complex, temp_file) + moo_restored <- read_multiOmicDataSet(temp_file) + + expect_equal(moo_restored@sample_meta, moo_complex@sample_meta) + expect_equal(moo_restored@annotation, moo_complex@annotation) + expect_equal(moo_restored@counts$raw, moo_complex@counts$raw) + expect_equal(moo_restored@counts$clean, moo_complex@counts$clean) + expect_equal(moo_restored@counts$filt, moo_complex@counts$filt) + expect_equal(moo_restored@counts$norm$voom, moo_complex@counts$norm$voom) + expect_equal( + names(moo_restored@analyses$colors), + names(moo_complex@analyses$colors) + ) +}) + +test_that("validator returns character vector for invalid objects", { + # Test validator with invalid count type + expect_error( + multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "invalid_type" = as.data.frame(nidap_clean_raw_counts) + ) + ), + "@counts can only contain these names" + ) + + # Test validator with missing raw counts + expect_error( + multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "clean" = as.data.frame(nidap_clean_raw_counts) + ) + ), + "@counts must contain at least 'raw' counts" + ) + + # Test validator with mismatched sample IDs + mismatched_counts <- as.data.frame(nidap_raw_counts) + colnames(mismatched_counts)[2] <- "WRONG_SAMPLE_ID" + expect_error( + multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = mismatched_counts + ) + ), + "@sample_meta" + ) +}) + +test_that("validator returns NULL for valid objects", { + # Create a valid moo object + 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) + ) + ) + # If the validator returned errors, the object wouldn't have been created + # So we just check that the object exists and is the correct type + expect_true(S7::S7_inherits(moo, multiOmicDataSet)) +}) diff --git a/code/MOSuite/tests/testthat/test-E2E.R b/code/MOSuite/tests/testthat/test-E2E.R new file mode 100644 index 0000000..d3080e5 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-E2E.R @@ -0,0 +1,113 @@ +test_that("E2E workflow succeeds for RENEE data", { + options(moo_print_plots = FALSE, moo_save_plots = FALSE) + gene_counts_tsv <- system.file( + "extdata", + "RSEM.genes.expected_count.all_samples.txt.gz", + package = "MOSuite" + ) + metadata_tsv <- system.file( + "extdata", + "sample_metadata.tsv.gz", + package = "MOSuite" + ) + + expect_snapshot( + moo <- create_multiOmicDataSet_from_files( + sample_meta_filepath = metadata_tsv, + feature_counts_filepath = gene_counts_tsv + ) |> + clean_raw_counts() |> + filter_counts( + group_colname = "condition", + label_colname = "sample_id", + minimum_count_value_to_be_considered_nonzero = 1, + minimum_number_of_samples_with_nonzero_counts_in_total = 1, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 1, + ) |> + normalize_counts( + group_colname = "condition", + label_colname = "sample_id" + ) |> + diff_counts( + covariates_colnames = "condition", + contrast_colname = "condition", + contrasts = c("knockout-wildtype") + ) |> + filter_diff( + significance_column = "adjpval", + significance_cutoff = 0.05, + change_column = "logFC", + change_cutoff = 1, + filtering_mode = "any", + include_estimates = c("FC", "logFC", "tstat", "pval", "adjpval"), + round_estimates = TRUE, + rounding_decimal_for_percent_cells = 0, + contrast_filter = "none", + contrasts = c(), + groups = c(), + groups_filter = "none", + label_font_size = 6, + label_distance = 1, + y_axis_expansion = 0.08, + fill_colors = c("steelblue1", "whitesmoke"), + pie_chart_in_3d = TRUE, + bar_width = 0.4, + draw_bar_border = TRUE, + plot_type = "bar", + plot_titles_fontsize = 12 + ) + ) +}) + +test_that("E2E workflow succeeds for NIDAP data", { + options(moo_print_plots = FALSE, moo_save_plots = FALSE) + expect_snapshot( + moo_nidap <- create_multiOmicDataSet_from_dataframes( + sample_metadata = as.data.frame(nidap_sample_metadata), + counts_dat = as.data.frame(nidap_raw_counts) + ) |> + clean_raw_counts() |> + filter_counts(group_colname = "Group") |> + normalize_counts(group_colname = "Group") |> + batch_correct_counts( + covariates_colname = "Group", + batch_colname = "Batch", + label_colname = "Label" + ) |> + diff_counts( + count_type = "filt", + sub_count_type = NULL, + sample_id_colname = "Sample", + feature_id_colname = "GeneName", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + input_in_log_counts = FALSE, + return_mean_and_sd = TRUE, + voom_normalization_method = "quantile", + ) |> + filter_diff( + significance_column = "adjpval", + significance_cutoff = 0.05, + change_column = "logFC", + change_cutoff = 1, + filtering_mode = "any", + include_estimates = c("FC", "logFC", "tstat", "pval", "adjpval"), + round_estimates = TRUE, + rounding_decimal_for_percent_cells = 0, + contrast_filter = "none", + contrasts = c(), + groups = c(), + groups_filter = "none", + label_font_size = 6, + label_distance = 1, + y_axis_expansion = 0.08, + fill_colors = c("steelblue1", "whitesmoke"), + pie_chart_in_3d = TRUE, + bar_width = 0.4, + draw_bar_border = TRUE, + plot_type = "bar", + plot_titles_fontsize = 12 + ) + ) +}) diff --git a/code/MOSuite/tests/testthat/test-batch-correction.R b/code/MOSuite/tests/testthat/test-batch-correction.R new file mode 100644 index 0000000..850b004 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-batch-correction.R @@ -0,0 +1,64 @@ +test_that("batch_correction works for NIDAP", { + 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", + covariates_colnames = "Group", + batch_colname = "Batch", + label_colname = "Label", + print_plots = TRUE + ) + # TODO: getting different results than nidap_batch_corrected_counts + expect_true(all.equal( + moo@counts[["batch"]] |> + dplyr::arrange(desc(Gene)), + as.data.frame(nidap_batch_corrected_counts_2) |> + dplyr::arrange(desc(Gene)) + )) +}) + +test_that("batch_correction warnings & errors", { + moo <- create_multiOmicDataSet_from_dataframes( + readr::read_tsv( + system.file("extdata", "sample_metadata.tsv.gz", package = "MOSuite") + ) |> + dplyr::mutate(batch = 1), + gene_counts + ) |> + clean_raw_counts() |> + filter_counts( + group_colname = "condition", + label_colname = "sample_id", + minimum_count_value_to_be_considered_nonzero = 1, + minimum_number_of_samples_with_nonzero_counts_in_total = 1, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 1, + print_plots = FALSE + ) |> + normalize_counts(group_colname = "condition", label_colname = "sample_id") + + expect_warning( + moo |> + batch_correct_counts( + covariates_colnames = "condition", + batch_colname = "batch" + ), + "Batch column 'batch' contains only 1 unique value" + ) + expect_error( + moo |> + batch_correct_counts( + covariates_colnames = "batch", + batch_colname = "batch" + ), + "Batch column 'batch' cannot be included in covariates." + ) +}) diff --git a/code/MOSuite/tests/testthat/test-clean.R b/code/MOSuite/tests/testthat/test-clean.R new file mode 100644 index 0000000..475c239 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-clean.R @@ -0,0 +1,106 @@ +test_that("clean_raw_counts works for NIDAP data", { + moo_nidap <- create_multiOmicDataSet_from_dataframes( + sample_metadata = as.data.frame(nidap_sample_metadata), + counts_dat = as.data.frame(nidap_raw_counts) + ) |> + clean_raw_counts(print_plots = TRUE) + + actual <- moo_nidap@counts[["clean"]] |> + dplyr::rename(Gene = GeneName) |> + as.data.frame() + + expected <- as.data.frame(nidap_clean_raw_counts) + + cmp <- all.equal(actual, expected, check.attributes = FALSE) + expect_true(isTRUE(cmp), info = paste(cmp, collapse = "\n")) +}) + +test_that("clean_raw_counts works for RENEE data", { + moo <- create_multiOmicDataSet_from_dataframes( + readr::read_tsv( + system.file("extdata", "sample_metadata.tsv.gz", package = "MOSuite") + ), + gene_counts + ) |> + clean_raw_counts() + expect_equal( + head(moo@counts$clean), + structure( + list( + gene_id = c( + "ENSG00000121410.11", + "ENSG00000268895.5", + "ENSG00000148584.15", + "ENSG00000175899.14", + "ENSG00000245105.3", + "ENSG00000166535.20" + ), + KO_S3 = c(0, 0, 0, 0, 0, 0), + KO_S4 = c(0, 0, 0, 0, 0, 0), + WT_S1 = c(0, 0, 0, 0, 0, 0), + WT_S2 = c(0, 0, 0, 0, 0, 0) + ), + row.names = c(NA, 6L), + class = "data.frame" + ) + ) + expect_equal( + tail(moo@counts$clean), + structure( + list( + gene_id = c( + "ENSG00000232242.2", + "ENSG00000162378.13", + "ENSG00000159840.16", + "ENSG00000274572.1", + "ENSG00000074755.15", + "ENSG00000272920.1" + ), + KO_S3 = c(0, 0, 0, 0, 0, 0), + KO_S4 = c(0, 0, 0, 0, 0, 0), + WT_S1 = c(0, 0, 0, 0, 0, 0), + WT_S2 = c(0, 0, 0, 0, 0, 0) + ), + row.names = 58924:58929, + class = "data.frame" + ) + ) +}) + +test_that("aggregate_duplicate_gene_names returns collapsed dfout", { + counts_dat <- data.frame( + gene_id = c("A", "A", "B"), + sample1 = c(1, 2, 3), + sample2 = c(4, 5, 6), + stringsAsFactors = FALSE, + check.names = FALSE + ) + + # Case 1: aggregation enabled + out <- MOSuite:::aggregate_duplicate_gene_names( + counts_dat = counts_dat, + gene_name_column_to_use_for_collapsing_duplicates = "gene_id", + aggregate_rows_with_duplicate_gene_names = TRUE, + split_gene_name = FALSE + ) + + expect_equal(nrow(out), 2) + expect_equal(sum(duplicated(out$gene_id)), 0) + + a_row <- out[out$gene_id == "A", , drop = FALSE] + expect_equal(a_row$sample1, 3) + expect_equal(a_row$sample2, 9) + + # Case 2: aggregation disabled + out_noagg <- MOSuite:::aggregate_duplicate_gene_names( + counts_dat = counts_dat, + gene_name_column_to_use_for_collapsing_duplicates = "gene_id", + aggregate_rows_with_duplicate_gene_names = FALSE, + split_gene_name = FALSE + ) + + expect_equal(nrow(out_noagg), 3) + expect_equal(sum(duplicated(out_noagg$gene_id)), 1) + expect_equal(out_noagg$sample1, counts_dat$sample1) + expect_equal(out_noagg$sample2, counts_dat$sample2) +}) diff --git a/code/MOSuite/tests/testthat/test-cli.R b/code/MOSuite/tests/testthat/test-cli.R new file mode 100644 index 0000000..8d580fb --- /dev/null +++ b/code/MOSuite/tests/testthat/test-cli.R @@ -0,0 +1,152 @@ +write_example_json <- function() { + 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" + ) + return(jsonlite::write_json(j, "inst/extdata/example.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") + ) + expect_snapshot(system(command)) +}) + +test_that("cli_exec parses args correctly", { + expect_equal(cli_exec("do_math"), 3) + expect_equal(cli_exec(c("do_math", "--subtract", "--no-add")), -1) + expect_equal(cli_exec(c("do_math", "left=2", "right=3")), 5) +}) + +test_that("cli_exec --json --debug", { + expect_equal( + deparse(cli_exec( + c( + "create_multiOmicDataSet_from_files", + paste0( + '--json="', + system.file("extdata", "example.json", package = "MOSuite"), + '"' + ), + "--debug" + ) + )), + c( + paste0( + "MOSuite::create_multiOmicDataSet_from_files(", + "feature_counts_filepath = \"inst/extdata/RSEM.genes.expected_count.all_samples.txt.gz\", " + ), + " sample_meta_filepath = \"inst/extdata/sample_metadata.tsv.gz\")" + ) + ) + expect_error( + cli_exec(c( + "filter_counts", + paste0( + '--json="', + system.file("extdata", "example.json", package = "MOSuite"), + '"' + ), + "--debug" + )), + "moo_input_rds must be included" + ) +}) + +test_that("mosuite --help", { + expect_snapshot(cli_exec("--help")) + expect_snapshot(system(paste( + system.file("exec", "mosuite", package = "MOSuite"), + "--help" + ))) + expect_snapshot(cli_exec("help")) + expect_true(inherits( + cli_exec(c( + "filter_counts", + "--help" + )), + "help_files_with_topic" + )) + expect_error(cli_exec("not_a_function"), "not a known function") +}) + +test_that("cli_unknown suggests closest matching function", { + # Test with a typo that has a close match + result <- cli_unknown("filter_count", getNamespaceExports("MOSuite")) + expect_match(result, "filter_count is not a known function") + expect_match(result, "Did you mean 'filter_counts'") + + # Test with another typo + result <- cli_unknown("batch_correct_count", getNamespaceExports("MOSuite")) + expect_match(result, "batch_correct_count is not a known function") + expect_match(result, "Did you mean 'batch_correct_counts'") + + # Test with completely unrelated name (no suggestions) + result <- cli_unknown("xyz123", getNamespaceExports("MOSuite")) + 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 new file mode 100644 index 0000000..3aea8b4 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-colors.R @@ -0,0 +1,173 @@ +test_that("get_random_colors works", { + set.seed(10) + expect_equal( + get_random_colors(5), + c("#B85CD0", "#B4E16D", "#DC967D", "#A6DCC5", "#B5AAD3") + ) + expect_equal(get_random_colors(3), c("#B3C4C7", "#B7D579", "#C56BC8")) + expect_error(get_random_colors(0), "num_colors must be at least 1") +}) + +test_that("get_colors_lst works on nidap_sample_metadata", { + expect_equal( + 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" + ), + Group = c( + A = "#000000", + B = "#E69F00", + C = "#56B4E9" + ), + Replicate = c( + `1` = "#000000", + `2` = "#E69F00", + `3` = "#56B4E9" + ), + Batch = c(`1` = "#000000", `2` = "#E69F00"), + Label = c( + A1 = "#000000", + A2 = "#E69F00", + A3 = "#56B4E9", + B1 = "#009E73", + B2 = "#F0E442", + B3 = "#0072B2", + C1 = "#D55E00", + C2 = "#CC79A7", + C3 = "#999999" + ) + ) + ) +}) +test_that("get_colors_lst handles alternative palette functions", { + 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 " + ) +}) +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 + # should fall back to get_random_colors() and emit a message. + dat_many_cats <- data.frame( + group = paste0("cat", seq_len(12)) + ) + expect_no_warning( + expect_message( + result <- get_colors_vctr(dat_many_cats, "group"), + "exceeds the palette maximum" + ) + ) + expect_length(result, 12) + expect_named(result, paste0("cat", seq_len(12))) +}) + +test_that("set_color_pal overrides the color palette", { + moo <- create_multiOmicDataSet_from_dataframes( + sample_metadata = as.data.frame(nidap_sample_metadata), + counts_dat = as.data.frame(nidap_raw_counts) + ) + expect_equal( + moo@analyses$colors, + list( + Sample = c( + A1 = "#000000", + A2 = "#E69F00", + A3 = "#56B4E9", + B1 = "#009E73", + B2 = "#F0E442", + B3 = "#0072B2", + C1 = "#D55E00", + C2 = "#CC79A7", + C3 = "#999999" + ), + Group = c( + A = "#000000", + B = "#E69F00", + C = "#56B4E9" + ), + Replicate = c( + `1` = "#000000", + `2` = "#E69F00", + `3` = "#56B4E9" + ), + Batch = c(`1` = "#000000", `2` = "#E69F00"), + Label = c( + A1 = "#000000", + A2 = "#E69F00", + A3 = "#56B4E9", + B1 = "#009E73", + B2 = "#F0E442", + B3 = "#0072B2", + C1 = "#D55E00", + C2 = "#CC79A7", + C3 = "#999999" + ) + ) + ) + moo2 <- moo |> + set_color_pal( + colname = "Group", + palette_fun = RColorBrewer::brewer.pal, + name = "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" + ), + Group = c( + A = "#66C2A5", + B = "#FC8D62", + C = "#8DA0CB" + ), + Replicate = c( + `1` = "#000000", + `2` = "#E69F00", + `3` = "#56B4E9" + ), + Batch = c(`1` = "#000000", `2` = "#E69F00"), + Label = c( + A1 = "#000000", + A2 = "#E69F00", + A3 = "#56B4E9", + B1 = "#009E73", + B2 = "#F0E442", + B3 = "#0072B2", + C1 = "#D55E00", + C2 = "#CC79A7", + C3 = "#999999" + ) + ) + ) +}) diff --git a/code/MOSuite/tests/testthat/test-counts.R b/code/MOSuite/tests/testthat/test-counts.R new file mode 100644 index 0000000..8633706 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-counts.R @@ -0,0 +1,106 @@ +test_that("counts_dat_to_matrix works", { + expect_equal( + gene_counts |> + dplyr::select(-GeneName) |> + head() |> + counts_dat_to_matrix(), + structure( + c( + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L, + 0L + ), + dim = c(6L, 4L), + dimnames = list( + c( + "ENSG00000121410.11", + "ENSG00000268895.5", + "ENSG00000148584.15", + "ENSG00000175899.14", + "ENSG00000245105.3", + "ENSG00000166535.20" + ), + c("KO_S3", "KO_S4", "WT_S1", "WT_S2") + ) + ) + ) +}) + +test_that("calc_cpm works on RENEE data", { + sample_meta <- data.frame( + sample_id = c("KO_S3", "KO_S4", "WT_S1", "WT_S2"), + condition = factor( + c("knockout", "knockout", "wildtype", "wildtype"), + levels = c("wildtype", "knockout") + ) + ) + moo <- create_multiOmicDataSet_from_dataframes( + sample_meta, + gene_counts |> dplyr::select(-GeneName) + ) + moo <- moo |> calc_cpm() + cpm_edger <- gene_counts |> + dplyr::select(-GeneName) |> + counts_dat_to_matrix() |> + edgeR::cpm() |> + as.data.frame() |> + tibble::rownames_to_column("gene_id") + expect_equal(moo@counts$cpm, cpm_edger) +}) + +test_that("calc_cpm_df works on NIDAP data", { + df <- nidap_clean_raw_counts |> as.data.frame() + trans.df <- df + trans.df[, -1] <- edgeR::cpm(as.matrix(df[, -1])) + + expect_equal( + calc_cpm_df(df, feature_id_colname = "Gene"), + trans.df, + ignore_attr = TRUE + ) +}) +test_that("calc_cpm_df preserves rownames", { + df <- nidap_clean_raw_counts |> + as.data.frame() |> + tail() + trans.df <- df + trans.df[, -1] <- edgeR::cpm(as.matrix(df[, -1])) + + expect_equal( + calc_cpm_df(df, feature_id_colname = "Gene"), + trans.df, + ignore_attr = TRUE + ) +}) + +test_that("calc_cpm_df preserves non-integer character rownames", { + df <- nidap_clean_raw_counts |> as.data.frame() + rownames(df) <- paste0("row_", seq_len(nrow(df))) + trans.df <- df + trans.df[, -1] <- edgeR::cpm(as.matrix(df[, -1])) + + result <- calc_cpm_df(df, feature_id_colname = "Gene") + expect_equal(rownames(result), rownames(trans.df)) + expect_equal(result, trans.df, ignore_attr = TRUE) +}) diff --git a/code/MOSuite/tests/testthat/test-deseq2.R b/code/MOSuite/tests/testthat/test-deseq2.R new file mode 100644 index 0000000..5d62d7f --- /dev/null +++ b/code/MOSuite/tests/testthat/test-deseq2.R @@ -0,0 +1,104 @@ +set.seed(20231228) +moo <- create_multiOmicDataSet_from_files( + sample_meta_filepath = system.file( + "extdata", + "sample_metadata.tsv.gz", + package = "MOSuite" + ), + feature_counts_filepath = system.file( + "extdata", + "RSEM.genes.expected_count.all_samples.txt.gz", + package = "MOSuite" + ) +) |> + suppressMessages() +moo@sample_meta <- moo@sample_meta |> + dplyr::mutate( + condition = factor(condition, levels = c("wildtype", "knockout")) + ) + +test_that("run_deseq2 works", { + expect_error( + run_deseq2(moo, design = ~condition), + "moo must contain filtered counts" + ) + + min_count <- 10 + genes_above_threshold <- moo@counts$raw |> + tidyr::pivot_longer( + !tidyselect::any_of(c("gene_id", "GeneName")), + names_to = "sample_id", + values_to = "count" + ) |> + dplyr::group_by(gene_id) |> + dplyr::summarize(count_sum = sum(count)) |> + dplyr::filter(count_sum >= min_count) |> + dplyr::pull(gene_id) + moo@counts$filt <- moo@counts$raw |> + dplyr::filter(gene_id %in% (genes_above_threshold)) + moo <- moo |> + run_deseq2( + moo, + design = ~condition, + fitType = "local", + feature_id_colname = "gene_id" + ) |> + suppressMessages() + dds <- moo@analyses$deseq2_ds + + # check colData + expect_equal( + dds@colData |> as.data.frame(), + structure( + list( + sample_id = c("KO_S3", "KO_S4", "WT_S1", "WT_S2"), + condition = structure( + c(2L, 2L, 1L, 1L), + levels = c("wildtype", "knockout"), + class = "factor" + ), + sizeFactor = c( + 0.739974960000608, + 0.717118872451827, + 1.34164078649987, + 1.69303431346171 + ) + ), + class = "data.frame", + row.names = c("KO_S3", "KO_S4", "WT_S1", "WT_S2") + ) + ) + + # check some of the counts + expect_equal( + dds@assays@data@listData |> + as.data.frame() |> + dplyr::filter(counts.KO_S3 > 15), + structure( + list( + counts.KO_S3 = c(25L, 16L, 19L), + counts.KO_S4 = c(22L, 10L, 26L), + counts.WT_S1 = c(74L, 0L, 10L), + counts.WT_S2 = c(104L, 0L, 8L), + mu.1 = c(23.8682703018296, 13.1709993621292, 22.8847421174049), + mu.2 = c(23.131035523431, 12.7641781441173, 22.1778862132993), + mu.3 = c(78.660598086526, 0.163744933328453, 8.02129153499216), + mu.4 = c(99.2628526338571, 0.20663190443383, 10.1221742389411), + H.1 = c(0.507689382133648, 0.502052019764842, 0.503779946658291), + H.2 = c(0.492310572696009, 0.497947673454118, 0.496219957488281), + H.3 = c(0.446124908477968, 0.499997692127505, 0.459429993613616), + H.4 = c(0.553875066333655, 0.499997692127505, 0.540569676700414), + cooks.1 = c(0.0157542703049353, 0.0289351707384892, 0.0400561954057841), + cooks.2 = c(0.0151418002975461, 0.0286548510838955, 0.0393806789741918), + cooks.3 = c(0.0212216674791077, 0.130797161405866, 0.058560061396526), + cooks.4 = c(0.026938300726748, 0.156792088506772, 0.0711568961752663) + ), + class = "data.frame", + row.names = c( + "ENSG00000185658.13", + "ENSG00000233922.2", + "ENSG00000157601.14" + ) + ) + ) +}) diff --git a/code/MOSuite/tests/testthat/test-differential.R b/code/MOSuite/tests/testthat/test-differential.R new file mode 100644 index 0000000..c2aedf1 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-differential.R @@ -0,0 +1,496 @@ +moo_nidap <- 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)) + ) +) + +test_that("differential analysis works for NIDAP", { + options(moo_print_plots = FALSE) + deg_moo <- moo_nidap |> + diff_counts( + count_type = "filt", + sub_count_type = NULL, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + voom_normalization_method = "quantile", + ) + + deg_moo_wide <- deg_moo@analyses$diff |> + join_dfs_wide() |> + dplyr::arrange(Gene) + deg_moo_wide <- deg_moo_wide |> + dplyr::select(colnames(deg_moo_wide) |> sort()) + + nidap_wide <- nidap_deg_analysis_2 |> + join_dfs_wide() |> + dplyr::arrange(Gene) + nidap_wide <- nidap_wide |> + dplyr::select(colnames(nidap_wide) |> sort()) + + expect_equal( + deg_moo_wide, + nidap_wide, + tolerance = 0.01 + ) +}) + +test_that("diff_counts works for RENEE on macOS", { + skip_on_os("linux") # these expected values only work for macOS + options(moo_print_plots = FALSE) + moo_renee <- create_multiOmicDataSet_from_dataframes( + readr::read_tsv( + system.file("extdata", "sample_metadata.tsv.gz", package = "MOSuite") + ), + counts_dat = gene_counts + ) |> + clean_raw_counts() |> + filter_counts( + group_colname = "condition", + label_colname = "sample_id", + minimum_count_value_to_be_considered_nonzero = 1, + minimum_number_of_samples_with_nonzero_counts_in_total = 1, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 1 + ) |> + normalize_counts(group_colname = "condition", label_colname = "sample_id") + moo_renee <- moo_renee |> + diff_counts( + count_type = "norm", + sub_count_type = "voom", + sample_id_colname = NULL, + feature_id_colname = NULL, + covariates_colnames = c("condition"), + contrast_colname = c("condition"), + # , 'condition2'), # TODO does not currently work for more than one contrast column + contrasts = c("knockout-wildtype"), + voom_normalization_method = "TMM", + return_mean_and_sd = TRUE, + input_in_log_counts = TRUE + ) + actual <- moo_renee@analyses$diff[[1]] |> head() + expected <- structure( + list( + gene_id = c( + "ENSG00000160179.18", + "ENSG00000258017.1", + "ENSG00000282393.1", + "ENSG00000286104.1", + "ENSG00000274422.1", + "ENSG00000154734.15" + ), + knockout_mean = c( + 10.9805713961628, + 9.00423753343925, + 9.00423753343925, + 9.00423753343925, + 9.00423753343925, + 8.60833480887895 + ), + knockout_sd = c( + 2.1542262015539, + 0.640731950886978, + 0.479050054020298, + 0.640731950886978, + 0.479050054020298, + 0.0808409484333391 + ), + wildtype_mean = c( + 12.3499548758012, + 8.87501967069015, + 8.87501967069015, + 8.87501967069015, + 8.87501967069015, + 14.6328231986934 + ), + wildtype_sd = c( + 0.082485020673847, + 0.00393703924789543, + 0.00393703924789543, + 0.00393703924789543, + 0.00393703924789543, + 0.00393703924789669 + ), + FC = c( + -2.54684822818721, + 1.11617198002536, + 1.07719571726849, + 1.11617198002536, + 1.07719571726849, + -65.0581764060579 + ), + logFC = c( + -1.34871298907199, + 0.158559335064906, + 0.107280399074217, + 0.158559335064906, + 0.107280399074217, + -6.02365847879717 + ), + tstat = c( + -1.27583132251236, + 0.432232276101188, + 0.344942879338297, + 0.432232276101188, + 0.344942879338297, + -32.9652734167629 + ), + pval = c( + 0.273465120057361, + 0.688646721521334, + 0.748130864876644, + 0.688646721521334, + 0.748130864876644, + 7.17809796209428e-06 + ), + adjpval = c( + 0.506868470934344, + 0.79745817464873, + 0.79745817464873, + 0.79745817464873, + 0.79745817464873, + 0.00102459282397239 + ) + ), + row.names = c(NA, 6L), + class = "data.frame" + ) + expect_equal(actual, expected) +}) + +test_that("diff_counts behaves consistently across platforms", { + # these expectations do not test exact numerical values that may be inconsistent + # across BLAS/LAPACK implementations, but rather test structure and reasonable + # value ranges. + options(moo_print_plots = FALSE) + moo_renee <- create_multiOmicDataSet_from_dataframes( + readr::read_tsv( + system.file("extdata", "sample_metadata.tsv.gz", package = "MOSuite") + ), + counts_dat = gene_counts + ) |> + clean_raw_counts() |> + filter_counts( + group_colname = "condition", + label_colname = "sample_id", + minimum_count_value_to_be_considered_nonzero = 1, + minimum_number_of_samples_with_nonzero_counts_in_total = 1, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 1 + ) |> + normalize_counts(group_colname = "condition", label_colname = "sample_id") + moo_renee <- moo_renee |> + diff_counts( + count_type = "norm", + sub_count_type = "voom", + sample_id_colname = NULL, + feature_id_colname = NULL, + covariates_colnames = c("condition"), + contrast_colname = c("condition"), + # , 'condition2'), # TODO does not currently work for more than one contrast column + contrasts = c("knockout-wildtype"), + voom_normalization_method = "TMM", + return_mean_and_sd = TRUE, + input_in_log_counts = TRUE + ) + + # Test structure and behavior instead of exact numerical values + # (exact values vary across BLAS/LAPACK implementations) + result <- moo_renee@analyses$diff[[1]] + + # Check that result is a data frame + expect_s3_class(result, "data.frame") + + # Check expected columns are present + expected_cols <- c( + "gene_id", + "knockout_mean", + "knockout_sd", + "wildtype_mean", + "wildtype_sd", + "FC", + "logFC", + "tstat", + "pval", + "adjpval" + ) + expect_true(all(expected_cols %in% names(result))) + + # Check data types + expect_type(result$gene_id, "character") + expect_type(result$knockout_mean, "double") + expect_type(result$knockout_sd, "double") + expect_type(result$wildtype_mean, "double") + expect_type(result$wildtype_sd, "double") + expect_type(result$FC, "double") + expect_type(result$logFC, "double") + expect_type(result$tstat, "double") + expect_type(result$pval, "double") + expect_type(result$adjpval, "double") + + # Check reasonable value ranges + expect_true(all(result$pval >= 0 & result$pval <= 1)) + expect_true(all(result$adjpval >= 0 & result$adjpval <= 1)) + expect_true(all(result$knockout_sd >= 0)) + expect_true(all(result$wildtype_sd >= 0)) + expect_true(all(is.finite(result$knockout_mean))) + expect_true(all(is.finite(result$wildtype_mean))) + + # Check that specific genes are present in expected order + expect_equal( + head(result$gene_id, 6), + c( + "ENSG00000160179.18", + "ENSG00000258017.1", + "ENSG00000282393.1", + "ENSG00000286104.1", + "ENSG00000274422.1", + "ENSG00000154734.15" + ) + ) + + # Check that the most significant gene (row 6) has small p-value + expect_true(result$pval[6] < 0.001) + expect_true(result$adjpval[6] < 0.01) +}) + +test_that("diff_counts errors", { + expect_error( + moo_nidap |> diff_counts(count_type = "DoesNotExist"), + "count_type DoesNotExist not in" + ) + expect_error( + moo_nidap |> + diff_counts(count_type = "raw", sub_count_type = "DoesNotExist"), + "raw counts is not a named list" + ) + expect_error( + moo_nidap |> + diff_counts(count_type = "norm", sub_count_type = "DoesNotExist"), + "sub_count_type DoesNotExist is not in" + ) +}) + +test_that("filter_diff works for NIDAP on macOS", { + skip_on_os("linux") + options(moo_print_plots = FALSE) + moo <- moo_nidap |> + diff_counts( + count_type = "filt", + sub_count_type = NULL, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + voom_normalization_method = "quantile", + ) |> + filter_diff( + significance_column = "adjpval", + significance_cutoff = 0.05, + change_column = "logFC", + change_cutoff = 1, + filtering_mode = "any", + include_estimates = c("FC", "logFC", "tstat", "pval", "adjpval"), + round_estimates = TRUE, + rounding_decimal_for_percent_cells = 0, + contrast_filter = "none", + contrasts = c(), + groups = c(), + groups_filter = "none", + label_font_size = 6, + label_distance = 1, + y_axis_expansion = 0.08, + fill_colors = c("steelblue1", "whitesmoke"), + pie_chart_in_3d = TRUE, + bar_width = 0.4, + draw_bar_border = TRUE, + plot_type = "bar", + plot_titles_fontsize = 12 + ) + expect_equal(moo@analyses$diff_filt, nidap_deg_gene_list) +}) + +test_that("filter_diff works for NIDAP on linux", { + skip_on_os("mac") + options(moo_print_plots = FALSE) + moo <- moo_nidap |> + diff_counts( + count_type = "filt", + sub_count_type = NULL, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + voom_normalization_method = "quantile", + ) |> + filter_diff( + significance_column = "adjpval", + significance_cutoff = 0.05, + change_column = "logFC", + change_cutoff = 1, + filtering_mode = "any", + include_estimates = c("FC", "logFC", "tstat", "pval", "adjpval"), + round_estimates = TRUE, + rounding_decimal_for_percent_cells = 0, + contrast_filter = "none", + contrasts = c(), + groups = c(), + groups_filter = "none", + label_font_size = 6, + label_distance = 1, + y_axis_expansion = 0.08, + fill_colors = c("steelblue1", "whitesmoke"), + pie_chart_in_3d = TRUE, + bar_width = 0.4, + draw_bar_border = TRUE, + plot_type = "bar", + plot_titles_fontsize = 12 + ) + expected_head <- structure( + list( + Gene = c( + "1110034G24Rik", + "3110082I17Rik", + "4632428N05Rik", + "4833439L19Rik", + "4930523C07Rik", + "5430427O19Rik" + ), + `B-A_FC` = c(21.7, -1.73, 2.43, -1.38, -2.3, -2.22), + `B-A_logFC` = c(4.44, -0.789, 1.28, -0.46, -1.2, -1.15), + `B-A_tstat` = c(3.2, -1.35, 2.76, -1.18, -1.62, -2.46), + `B-A_pval` = c(0.00782, 0.203, 0.0177, 0.26, 0.133, 0.0307), + `B-A_adjpval` = c(0.21, 0.71, 0.303, 0.758, 0.617, 0.377), + `C-A_FC` = c(36.6, -21.9, 4.66, -3.59, 4.5, -4.49), + `C-A_logFC` = c(5.2, -4.46, 2.22, -1.84, 2.17, -2.17), + `C-A_tstat` = c(4.15, -3.8, 5.25, -3.76, 4.5, -3.68), + `C-A_pval` = c(0.00141, 0.00265, 0.000222, 0.00281, 0.000767, 0.00327), + `C-A_adjpval` = c(0.027, 0.0383, 0.00929, 0.0395, 0.0191, 0.0432), + `B-C_FC` = c(-1.69, 12.7, -1.92, 2.61, -10.3, 2.02), + `B-C_logFC` = c(-0.758, 3.67, -0.941, 1.38, -3.37, 1.01), + `B-C_tstat` = c(-0.838, 2.93, -3.15, 2.63, -5.04, 1.53), + `B-C_pval` = c(0.419, 0.0129, 0.00859, 0.0222, 0.000311, 0.153), + `B-C_adjpval` = c(0.707, 0.144, 0.124, 0.186, 0.0224, 0.442) + ), + row.names = c(NA, 6L), + class = "data.frame" + ) + expected_tail <- structure( + list( + Gene = c("Zfand6", "Zfp35", "Zfp422", "Zfp706", "Zfp945", "Zhx1"), + `B-A_FC` = c(1.22, 1.15, -1.43, -1.92, 10.5, -1.28), + `B-A_logFC` = c(0.282, 0.198, -0.515, -0.938, 3.39, -0.356), + `B-A_tstat` = c(0.808, 0.725, -1.92, -5.49, 2.94, -1.33), + `B-A_pval` = c(0.435, 0.483, 0.0802, 0.00015, 0.0126, 0.209), + `B-A_adjpval` = c(0.859, 0.871, 0.529, 0.0247, 0.258, 0.712), + `C-A_FC` = c(2.19, -2.35, -2.39, -2.89, 21.5, 1.6), + `C-A_logFC` = c(1.13, -1.23, -1.26, -1.53, 4.43, 0.68), + `C-A_tstat` = c(3.61, -4.08, -4.61, -8.9, 4.26, 2.9), + `C-A_pval` = c(0.00372, 0.00161, 0.000638, 1.47e-06, 0.00117, 0.0137), + `C-A_adjpval` = c(0.0462, 0.0295, 0.0176, 0.000377, 0.0241, 0.0971), + `B-C_FC` = c(-1.8, 2.69, 1.67, 1.51, -2.06, -2.05), + `B-C_logFC` = c(-0.845, 1.43, 0.744, 0.594, -1.04, -1.04), + `B-C_tstat` = c(-2.76, 4.59, 2.56, 3.16, -1.24, -4.23), + `B-C_pval` = c(0.0175, 0.000656, 0.0253, 0.00845, 0.239, 0.00123), + `B-C_adjpval` = c(0.165, 0.0329, 0.199, 0.123, 0.542, 0.0455) + ), + row.names = 630:635, + class = "data.frame" + ) + # Use tolerance for numerical precision across different systems/BLAS implementations + expect_equal(head(moo@analyses$diff_filt), expected_head, tolerance = 0.02) + expect_equal(tail(moo@analyses$diff_filt), expected_tail, tolerance = 0.02) +}) + +test_that("filter_diff rejects invalid filtering_mode", { + options(moo_print_plots = FALSE) + moo <- moo_nidap |> + diff_counts( + count_type = "filt", + sub_count_type = NULL, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + voom_normalization_method = "quantile" + ) + + expect_error( + moo |> filter_diff(filtering_mode = "invalid"), + "filtering_mode not recognized" + ) +}) + +test_that("filter_diff accepts valid filtering_mode values", { + options(moo_print_plots = FALSE) + moo <- moo_nidap |> + diff_counts( + count_type = "filt", + sub_count_type = NULL, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + voom_normalization_method = "quantile" + ) + + expect_no_error( + moo |> filter_diff(filtering_mode = "any") + ) + + expect_no_error( + moo |> filter_diff(filtering_mode = "all") + ) +}) + +test_that("filter_diff rejects invalid plot_type", { + options(moo_print_plots = FALSE) + moo <- moo_nidap |> + diff_counts( + count_type = "filt", + sub_count_type = NULL, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + voom_normalization_method = "quantile" + ) + + expect_error( + moo |> filter_diff(plot_type = "invalid"), + "plot_type not recognized" + ) +}) + +test_that("filter_diff accepts valid plot_type values", { + options(moo_print_plots = FALSE) + moo <- moo_nidap |> + diff_counts( + count_type = "filt", + sub_count_type = NULL, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + voom_normalization_method = "quantile" + ) + + expect_no_error( + moo |> filter_diff(plot_type = "bar") + ) + + expect_no_error( + moo |> filter_diff(plot_type = "pie") + ) +}) diff --git a/code/MOSuite/tests/testthat/test-filter.R b/code/MOSuite/tests/testthat/test-filter.R new file mode 100644 index 0000000..aabfc78 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-filter.R @@ -0,0 +1,253 @@ +test_that("filter_counts reproduces NIDAP results", { + set.seed(10) + 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( + sample_id_colname = "Sample", + feature_id_colname = "Gene", + count_type = "raw", + print_plots = TRUE + ) + rds_counts_filt <- moo@counts$filt |> + dplyr::arrange(desc(Gene)) + nidap_counts_filt <- as.data.frame(nidap_filtered_counts) |> + dplyr::arrange(desc(Gene)) + + expect_true(equal_dfs(rds_counts_filt, nidap_counts_filt)) +}) + +# TODO get filter_counts() to work on tibbles too, not only dataframes + +test_that("filter_counts works on RENEE dataset", { + moo <- create_multiOmicDataSet_from_dataframes( + readr::read_tsv( + system.file("extdata", "sample_metadata.tsv.gz", package = "MOSuite") + ), + gene_counts |> glue_gene_symbols() + ) + rds2 <- moo |> + filter_counts( + feature_id_colname = "gene_id", + sample_id_colname = "sample_id", + group_colname = "condition", + label_colname = "sample_id", + samples_to_include = c("KO_S3", "KO_S4", "WT_S1", "WT_S2"), + minimum_count_value_to_be_considered_nonzero = 1, + minimum_number_of_samples_with_nonzero_counts_in_total = 1, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 1, + print_plots = TRUE, + count_type = "raw" + ) + expect_equal(dim(rds2@counts$filt), c(291, 5)) + expect_equal( + rds2@counts$filt |> dplyr::arrange(gene_id) |> head(), + structure( + list( + gene_id = c( + "ENSG00000072803.17|FBXW11", + "ENSG00000083845.9|RPS5", + "ENSG00000107371.13|EXOSC3", + "ENSG00000111639.8|MRPL51", + "ENSG00000111640.15|GAPDH", + "ENSG00000111786.9|SRSF9" + ), + KO_S3 = c(2, 1, 1, 0, 0, 0), + KO_S4 = c(0, 0, 1, 1, 1, 1), + WT_S1 = c(0, 0, 0, 0, 0, 0), + WT_S2 = c(0, 0, 0, 0, 0, 0) + ), + row.names = c(NA, 6L), + class = "data.frame" + ) + ) + expect_equal( + rds2@counts$filt |> dplyr::arrange(gene_id) |> tail(), + structure( + list( + gene_id = c( + "ENSG00000281903.2|LINC02246", + "ENSG00000282393.1|AC016588.2", + "ENSG00000283886.2|BX664615.2", + "ENSG00000285413.1|AP001056.2", + "ENSG00000286018.1|AF129075.3", + "ENSG00000286104.1|AC016629.3" + ), + KO_S3 = c(0.85, 0, 1, 3, 2, 1), + KO_S4 = c(0, 1, 0, 1, 0, 0), + WT_S1 = c(0, 0, 0, 0, 0, 0), + WT_S2 = c(0.71, 0, 0, 0, 0, 0) + ), + row.names = 286:291, + class = "data.frame" + ) + ) +}) + +test_that("remove_low_count_genes works", { + df <- data.frame( + Gene = c( + "mt-Nd5_43275", + "mt-Nd6_43276", + "mt-Te_43277", + "mt-Cytb_43278", + "mt-Tt_43279", + "mt-Tp_43280" + ), + A1 = c(6155, 858, 0, 20542, 0, 12), + A2 = c(10823, 1420, 1, 29677, 9, 16), + A3 = c(9482, 1167, 2, 31730, 0, 13), + B1 = c(6162, 1181, 0, 28293, 0, 15), + B2 = c(8002, 845, 1, 25617, 7, 19), + B3 = c(7225, 1198, 3, 30370, 3, 26), + C1 = c(4141, 515, 0, 21310, 0, 32), + C2 = c(9058, 1147, 4, 30108, 0, 33), + C3 = c(8481, 1124, 2, 30893, 2, 50), + row.names = seq(5, 10) + ) + sample_meta <- structure( + list( + Sample = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"), + Group = c("A", "A", "A", "B", "B", "B", "C", "C", "C"), + Replicate = c(1, 2, 3, 1, 2, 3, 1, 2, 3), + Batch = c(1, 2, 2, 1, 1, 2, 1, 2, 2), + Label = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3") + ), + row.names = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"), + class = "data.frame" + ) + + # test default params + expect_equal( + remove_low_count_genes( + counts_dat = df, + sample_metadata = sample_meta, + feature_id_colname = "Gene", + group_colname = "Group", + use_cpm_counts_to_filter = TRUE, + use_group_based_filtering = FALSE, + 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 + ), + structure( + list( + Gene = c( + "mt-Nd5_43275", + "mt-Nd6_43276", + "mt-Cytb_43278", + "mt-Tp_43280" + ), + A1 = c( + 223274.204664998, + 31124.1702035042, + 745166.322051728, + 435.303079769289 + ), + A2 = c( + 258022.219043532, + 33853.0491584418, + 707504.88723597, + 381.442807419063 + ), + A3 = c( + 223663.725998962, + 27527.4803038166, + 748454.970042931, + 306.647167051941 + ), + B1 = c( + 172842.276513983, + 33126.7005133096, + 793610.277411573, + 420.74556113433 + ), + B2 = c( + 232002.551390218, + 24499.1447044156, + 742715.490997652, + 550.868342466151 + ), + B3 = c( + 186091.435930457, + 30856.406954282, + 782227.94591114, + 669.671603348358 + ), + C1 = c( + 159281.483191015, + 19809.2160935457, + 819678.436802831, + 1230.86391260866 + ), + C2 = c( + 224485.749690211, + 28426.2701363073, + 746171.003717472, + 817.843866171004 + ), + C3 = c( + 209138.883408956, + 27717.4985204182, + 761811.994476228, + 1232.98480962715 + ) + ), + row.names = 1:4, + class = "data.frame" + ) + ) +}) + +test_that("remove_low_count_genes works with group-based filtering (no grouped tibble crash)", { + df <- data.frame( + Gene = c( + "mt-Nd5_43275", + "mt-Nd6_43276", + "mt-Te_43277", + "mt-Cytb_43278", + "mt-Tt_43279", + "mt-Tp_43280" + ), + A1 = c(6155, 858, 0, 20542, 0, 12), + A2 = c(10823, 1420, 1, 29677, 9, 16), + A3 = c(9482, 1167, 2, 31730, 0, 13), + B1 = c(6162, 1181, 0, 28293, 0, 15), + B2 = c(8002, 845, 1, 25617, 7, 19), + B3 = c(7225, 1198, 3, 30370, 3, 26), + C1 = c(4141, 515, 0, 21310, 0, 32), + C2 = c(9058, 1147, 4, 30108, 0, 33), + C3 = c(8481, 1124, 2, 30893, 2, 50), + row.names = seq(5, 10) + ) + sample_meta <- structure( + list( + Sample = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"), + Group = c("A", "A", "A", "B", "B", "B", "C", "C", "C"), + Replicate = c(1, 2, 3, 1, 2, 3, 1, 2, 3), + Batch = c(1, 2, 2, 1, 1, 2, 1, 2, 2), + Label = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3") + ), + row.names = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"), + class = "data.frame" + ) + + result <- remove_low_count_genes( + counts_dat = df, + sample_metadata = sample_meta, + feature_id_colname = "Gene", + group_colname = "Group", + use_cpm_counts_to_filter = TRUE, + use_group_based_filtering = TRUE, + 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 + ) + expect_s3_class(result, "data.frame") + expect_true("Gene" %in% colnames(result)) + expect_true(nrow(result) > 0) +}) diff --git a/code/MOSuite/tests/testthat/test-normalize.R b/code/MOSuite/tests/testthat/test-normalize.R new file mode 100644 index 0000000..87318d4 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-normalize.R @@ -0,0 +1,139 @@ +test_that("normalize works for NIDAP", { + 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( + group_colname = "Group", + label_colname = "Label", + print_plots = TRUE + ) + expect_true(equal_dfs( + moo@counts[["norm"]][["voom"]] |> + dplyr::arrange(desc(Gene)), + as.data.frame(nidap_norm_counts) |> + dplyr::arrange(desc(Gene)) + )) +}) + +test_that("normalize works for RENEE", { + moo <- create_multiOmicDataSet_from_dataframes( + readr::read_tsv( + system.file("extdata", "sample_metadata.tsv.gz", package = "MOSuite") + ), + gene_counts + ) |> + clean_raw_counts() |> + filter_counts( + group_colname = "condition", + label_colname = "sample_id", + minimum_count_value_to_be_considered_nonzero = 1, + minimum_number_of_samples_with_nonzero_counts_in_total = 1, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 1, + print_plots = FALSE + ) |> + normalize_counts(group_colname = "condition", label_colname = "sample_id") + expect_equal( + head(moo@counts$norm$voom), + structure( + list( + gene_id = c( + "ENSG00000215458.8", + "ENSG00000160179.18", + "ENSG00000258017.1", + "ENSG00000282393.1", + "ENSG00000286104.1", + "ENSG00000274422.1" + ), + KO_S3 = c( + 11.0751960068561, + 9.6086338540783, + 9.6086338540783, + 8.81615260371772, + 9.6086338540783, + 8.81615260371772 + ), + KO_S4 = c( + 12.3480907442867, + 12.7703165561761, + 8.81615260371772, + 9.6086338540783, + 8.81615260371772, + 9.6086338540783 + ), + WT_S1 = c( + 8.81615260371772, + 12.3480907442867, + 8.81615260371772, + 8.81615260371772, + 8.81615260371772, + 8.81615260371772 + ), + WT_S2 = c( + 10.0048744792586, + 12.2369960496953, + 8.81615260371772, + 8.81615260371772, + 8.81615260371772, + 8.81615260371772 + ) + ), + row.names = c(NA, 6L), + class = "data.frame" + ) + ) + expect_equal( + tail(moo@counts$norm$voom), + structure( + list( + gene_id = c( + "ENSG00000157538.14", + "ENSG00000160193.11", + "ENSG00000182093.15", + "ENSG00000182362.14", + "ENSG00000173276.14", + "ENSG00000237232.7" + ), + KO_S3 = c( + 12.3480907442867, + 9.6086338540783, + 11.8597009422769, + 11.0751960068561, + 11.8597009422769, + 8.81615260371772 + ), + KO_S4 = c( + 12.7703165561761, + 9.6086338540783, + 9.6086338540783, + 8.81615260371772, + 12.7703165561761, + 9.6086338540783 + ), + WT_S1 = c( + 12.2426956580003, + 10.5853565029804, + 11.7865266999202, + 8.81615260371772, + 11.7865266999202, + 8.81615260371772 + ), + WT_S2 = c( + 12.4720029602325, + 10.9249210977479, + 11.4357186116131, + 8.81615260371772, + 12.2369960496953, + 8.81615260371772 + ) + ), + row.names = 286:291, + class = "data.frame" + ) + ) +}) diff --git a/code/MOSuite/tests/testthat/test-plot_heatmap.R b/code/MOSuite/tests/testthat/test-plot_heatmap.R new file mode 100644 index 0000000..ba9fb1a --- /dev/null +++ b/code/MOSuite/tests/testthat/test-plot_heatmap.R @@ -0,0 +1,263 @@ +colors_vec <- c( + "#5954d6", + "#e1562c", + "#b80058", + "#00c6f8", + "#d163e6", + "#00a76c", + "#ff9287", + "#008cf9", + "#006e00", + "#796880", + "#FFA500", + "#878500" +) +test_that("correlation heatmap works", { + p <- plot_corr_heatmap( + nidap_filtered_counts |> + dplyr::select(tidyselect::all_of( + c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3") + )) |> + as.data.frame(), + sample_metadata = as.data.frame(nidap_sample_metadata), + sample_id_colname = "Sample", + label_colname = "Label", + group_colname = "Group", + color_values = colors_vec + ) + expect_s4_class(p, "Heatmap") + expect_equal( + p@matrix, + structure( + c( + 0, + 0.0349436686640265, + 0.0346707459478316, + 0.136436292332774, + 0.145504435322238, + 0.165715414451367, + 0.266892740192968, + 0.310669867608233, + 0.281044606820525, + 0.0349436686640265, + 0, + 0.026894587617103, + 0.139740412452416, + 0.144024768162842, + 0.156995761981556, + 0.256516858290949, + 0.289312631501573, + 0.275306551391499, + 0.0346707459478316, + 0.026894587617103, + 0, + 0.113462670330904, + 0.132707949438905, + 0.146137196349944, + 0.2518982836951, + 0.307893394909586, + 0.277982555134354, + 0.136436292332774, + 0.139740412452416, + 0.113462670330904, + 0, + 0.0467104077868874, + 0.0778256905442303, + 0.18935488124329, + 0.238494284141649, + 0.209007629325352, + 0.145504435322238, + 0.144024768162842, + 0.132707949438905, + 0.0467104077868874, + 0, + 0.0532124359450156, + 0.140242067145314, + 0.179723372754429, + 0.15251602311055, + 0.165715414451367, + 0.156995761981556, + 0.146137196349944, + 0.0778256905442303, + 0.0532124359450156, + 0, + 0.141067943113981, + 0.160160263560895, + 0.14605974755951, + 0.266892740192968, + 0.256516858290949, + 0.2518982836951, + 0.18935488124329, + 0.140242067145314, + 0.141067943113981, + 0, + 0.104501003317621, + 0.0500950924722408, + 0.310669867608233, + 0.289312631501573, + 0.307893394909586, + 0.238494284141649, + 0.179723372754429, + 0.160160263560895, + 0.104501003317621, + 0, + 0.0899444885709063, + 0.281044606820525, + 0.275306551391499, + 0.277982555134354, + 0.209007629325352, + 0.15251602311055, + 0.14605974755951, + 0.0500950924722408, + 0.0899444885709063, + 0 + ), + dim = c(9L, 9L), + dimnames = list( + c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"), + c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3") + ) + ) + ) +}) + +test_that("plot_corr_heatmap method dispatch works", { + 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)) + ) + ) + expect_equal( + plot_corr_heatmap(moo, "filt")@matrix, + plot_corr_heatmap( + as.data.frame(nidap_filtered_counts), + sample_metadata = as.data.frame(nidap_sample_metadata), + feature_id_colname = "Gene" + )@matrix + ) +}) + +# TODO get heatmap working on tibbles also +# test_that("heatmap works", { +# corHM <- plot_corr_heatmap( +# counts_dat = nidap_filtered_counts |> +# dplyr::select(tidyselect::all_of(c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"))), +# sample_metadata = nidap_sample_metadata, +# sample_id_colname = "Sample", +# label_colname = "Label", +# group_column = "Group", +# color_values = colors_vec +# ) +# }) + +test_that("plot_expr_heatmap works", { + 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)) + ) + ) + expect_message( + { + set.seed(20250226) + p_moo <- plot_expr_heatmap( + moo, + count_type = "norm", + sub_count_type = "voom", + feature_id_colname = "Gene" + ) + }, + "total number of genes in heatmap", + fixed = FALSE + ) + expect_equal( + head(p_moo@matrix), + structure( + c( + -0.469646298150098, + -0.999122775178692, + -1.63914985230916, + -1.11065487632401, + 1.06508157716121, + 0.129357631742822, + -1.6308124461643, + -0.700059853143015, + -1.5189464375787, + -0.224167735591629, + 1.06508157716121, + -1.56168918461362, + -1.6308124461643, + -1.89235880186714, + -0.541702967261003, + -2.0463972593436, + 1.06508157716121, + -1.79694425364586, + 0.329750044812768, + 0.0301570520160167, + 0.167894484181845, + -0.0423239634814564, + -0.120254965774652, + 0.199342022111398, + 0.642860459417498, + 0.367952795408648, + 0.373030023826938, + 0.474515861027971, + -0.0390725679377215, + 0.117730807477454, + 0.728033358831939, + 0.385380968911897, + 0.599797184786654, + 0.453174107982841, + -0.104093868102577, + 0.461536877004385, + 0.623852071863989, + 0.835927627565177, + 0.888284230577201, + 0.725967683142828, + -1.99037275585028, + 0.831065997888202, + 0.825036578059704, + 1.0208559858833, + 0.853098375022516, + 0.922704248230578, + -0.758155232754779, + 0.657242141825761, + 0.581738677492799, + 0.951267000403811, + 0.817694958753715, + 0.847181934356472, + -0.183295341063619, + 0.962357960209459 + ), + dim = c(6L, 9L), + dimnames = list( + c("Il2rb", "Rora", "Tcrg-C1", "Pdcd1", "Dntt", "Eya2"), + c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3") + ) + ) + ) + + expect_message( + { + set.seed(20250226) + p_dat <- plot_expr_heatmap( + as.data.frame(nidap_norm_counts), + sample_metadata = as.data.frame(nidap_sample_metadata), + feature_id_colname = "Gene" + ) + }, + "total number of genes in heatmap", + fixed = FALSE + ) + + expect_equal(p_moo@matrix, p_dat@matrix) +}) diff --git a/code/MOSuite/tests/testthat/test-plot_histogram.R b/code/MOSuite/tests/testthat/test-plot_histogram.R new file mode 100644 index 0000000..598289d --- /dev/null +++ b/code/MOSuite/tests/testthat/test-plot_histogram.R @@ -0,0 +1,603 @@ +log_counts <- structure( + c( + 4.68203758078952, + 4.85622577980595, + 4.78525385564269, + 4.49631900610197, + 4.06045359796882, + 4.23984554358195, + 4.5945977606547, + 4.64452454872198, + 5.01435137189661, + 4.97202092328668, + 4.63530665635318, + 4.2685504137767, + 4.55963475259408, + 4.48551456875509, + 4.8871583679813, + 4.80572893488115, + 4.62485692334614, + 3.28500783834613, + 4.27910086185478, + 4.44991091582054, + 5.1543875974913, + 5.04097648388479, + 3.93341992672261, + 3.60201340344135, + 4.38819757498796, + 4.52837375303351, + 5.04374399504142, + 5.16774070067169, + 4.88762227733767, + 3.4002608223214, + 4.86037842060906, + 5.24497940734463, + 4.91946017962122, + 5.04632856830695, + 4.96825190546972, + 4.23362208987531, + 4.11790170891073, + 4.05303076635639, + 4.92868500786216, + 4.94726383191083, + 3.80832003906478, + 4.59490650795107, + 4.85738793032812, + 4.40655427188147, + 4.22382743940071, + 4.58770826515446, + 4.96057466313368, + 4.99824283163569, + 4.5437556841171, + 4.97124300205374, + 4.93192370480255, + 4.13835014251084, + 5.0939015418123, + 5.03285949305828 + ), + dim = c(6L, 9L), + dimnames = list( + c( + "Mrpl15_32", + "Lypla1_34", + "Tcea1_36", + "Atp6v1h_44", + "Rb1cc1_54", + "Pcmtd1_68" + ), + c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3") + ) +) +sample_meta <- structure( + list( + Sample = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"), + Group = c("A", "A", "A", "B", "B", "B", "C", "C", "C"), + Replicate = c(1, 2, 3, 1, 2, 3, 1, 2, 3), + Batch = c(1, 2, 2, 1, 1, 2, 1, 2, 2), + Label = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3") + ), + row.names = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"), + class = "data.frame" +) +test_that("plot_histogram works with rownames", { + p <- plot_histogram( + log_counts |> as.data.frame() |> tibble::rownames_to_column("Gene"), + sample_meta, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + label_colname = "Label", + color_values = c( + indigo = "#5954d6", + carrot = "#e1562c", + lipstick = "#b80058", + turquoise = "#00c6f8", + lavender = "#d163e6", + jade = "#00a76c", + coral = "#ff9287", + azure = "#008cf9", + green = "#006e00", + rum = "#796880", + orange = "#FFA500", + olive = "#878500" + ), + color_by_group = FALSE, + set_min_max_for_x_axis = FALSE, + minimum_for_x_axis = -1, + maximum_for_x_axis = 1, + legend_position = "top", + legend_font_size = 10, + number_of_legend_columns = 6 + ) + + expect_s3_class(p$layers[[1]], "ggproto") + expect_s3_class(p$layers[[1]]$geom, "GeomArea") + expect_equal( + p$data, + structure( + list( + Gene = c( + "Mrpl15_32", + "Mrpl15_32", + "Mrpl15_32", + "Mrpl15_32", + "Mrpl15_32", + "Mrpl15_32", + "Mrpl15_32", + "Mrpl15_32", + "Mrpl15_32", + "Lypla1_34", + "Lypla1_34", + "Lypla1_34", + "Lypla1_34", + "Lypla1_34", + "Lypla1_34", + "Lypla1_34", + "Lypla1_34", + "Lypla1_34", + "Tcea1_36", + "Tcea1_36", + "Tcea1_36", + "Tcea1_36", + "Tcea1_36", + "Tcea1_36", + "Tcea1_36", + "Tcea1_36", + "Tcea1_36", + "Atp6v1h_44", + "Atp6v1h_44", + "Atp6v1h_44", + "Atp6v1h_44", + "Atp6v1h_44", + "Atp6v1h_44", + "Atp6v1h_44", + "Atp6v1h_44", + "Atp6v1h_44", + "Rb1cc1_54", + "Rb1cc1_54", + "Rb1cc1_54", + "Rb1cc1_54", + "Rb1cc1_54", + "Rb1cc1_54", + "Rb1cc1_54", + "Rb1cc1_54", + "Rb1cc1_54", + "Pcmtd1_68", + "Pcmtd1_68", + "Pcmtd1_68", + "Pcmtd1_68", + "Pcmtd1_68", + "Pcmtd1_68", + "Pcmtd1_68", + "Pcmtd1_68", + "Pcmtd1_68" + ), + Sample = c( + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3", + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3", + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3", + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3", + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3", + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3" + ), + count = c( + 4.68203758078952, + 4.5945977606547, + 4.55963475259408, + 4.27910086185478, + 4.38819757498796, + 4.86037842060906, + 4.11790170891073, + 4.85738793032812, + 4.5437556841171, + 4.85622577980595, + 4.64452454872198, + 4.48551456875509, + 4.44991091582054, + 4.52837375303351, + 5.24497940734463, + 4.05303076635639, + 4.40655427188147, + 4.97124300205374, + 4.78525385564269, + 5.01435137189661, + 4.8871583679813, + 5.1543875974913, + 5.04374399504142, + 4.91946017962122, + 4.92868500786216, + 4.22382743940071, + 4.93192370480255, + 4.49631900610197, + 4.97202092328668, + 4.80572893488115, + 5.04097648388479, + 5.16774070067169, + 5.04632856830695, + 4.94726383191083, + 4.58770826515446, + 4.13835014251084, + 4.06045359796882, + 4.63530665635318, + 4.62485692334614, + 3.93341992672261, + 4.88762227733767, + 4.96825190546972, + 3.80832003906478, + 4.96057466313368, + 5.0939015418123, + 4.23984554358195, + 4.2685504137767, + 3.28500783834613, + 3.60201340344135, + 3.4002608223214, + 4.23362208987531, + 4.59490650795107, + 4.99824283163569, + 5.03285949305828 + ), + Group = c( + "A", + "A", + "A", + "B", + "B", + "B", + "C", + "C", + "C", + "A", + "A", + "A", + "B", + "B", + "B", + "C", + "C", + "C", + "A", + "A", + "A", + "B", + "B", + "B", + "C", + "C", + "C", + "A", + "A", + "A", + "B", + "B", + "B", + "C", + "C", + "C", + "A", + "A", + "A", + "B", + "B", + "B", + "C", + "C", + "C", + "A", + "A", + "A", + "B", + "B", + "B", + "C", + "C", + "C" + ), + Replicate = c( + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3 + ), + Batch = c( + 1, + 2, + 2, + 1, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 2, + 1, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 2, + 1, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 2, + 1, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 2, + 1, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 2, + 1, + 1, + 2, + 1, + 2, + 2 + ), + Label = c( + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3", + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3", + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3", + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3", + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3", + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3" + ) + ), + row.names = c(NA, -54L), + class = c("tbl_df", "tbl", "data.frame") + ) + ) +}) + +test_that("plot_histogram works with tibbles", { + p <- plot_histogram( + nidap_filtered_counts, + sample_metadata = nidap_sample_metadata, + sample_id_colname = "Sample", + feature_id_colname = "Gene", + group_colname = "Group", + label_colname = "Label", + color_values = c( + "#5954d6", + "#e1562c", + "#b80058", + "#00c6f8", + "#d163e6", + "#00a76c", + "#ff9287", + "#008cf9", + "#006e00", + "#796880", + "#FFA500", + "#878500" + ), + color_by_group = FALSE, + set_min_max_for_x_axis = FALSE, + minimum_for_x_axis = -1, + maximum_for_x_axis = 1, + legend_position = "top", + legend_font_size = 10, + number_of_legend_columns = 6 + ) + expect_s3_class(p$layers[[1]], "ggproto") + expect_s3_class(p$layers[[1]]$geom, "GeomArea") + expect_equal( + head(p$data), + structure( + list( + Gene = c( + "0610007P14Rik", + "0610007P14Rik", + "0610007P14Rik", + "0610007P14Rik", + "0610007P14Rik", + "0610007P14Rik" + ), + Sample = c("A1", "A2", "A3", "B1", "B2", "B3"), + count = c(1049, 950, 934, 1068, 1140, 947), + Group = c("A", "A", "A", "B", "B", "B"), + Replicate = c(1, 2, 3, 1, 2, 3), + Batch = c(1, 2, 2, 1, 1, 2), + Label = c("A1", "A2", "A3", "B1", "B2", "B3") + ), + row.names = c(NA, -6L), + class = c("tbl_df", "tbl", "data.frame") + ) + ) +}) + +test_that("plot_histogram result is the same for MOO or dataframe", { + moo <- multiOmicDataSet( + sample_metadata = nidap_sample_metadata, + anno_dat = data.frame(), + counts_lst = list("raw" = nidap_raw_counts) + ) + expect_equal( + plot_histogram(moo, count_type = "raw"), + plot_histogram(nidap_raw_counts, sample_meta = nidap_sample_metadata) + ) +}) + +test_that("plot_histogram accepts print_plots and save_plots via moo dispatch without error", { + moo <- multiOmicDataSet( + sample_metadata = nidap_sample_metadata, + anno_dat = data.frame(), + counts_lst = list("raw" = nidap_raw_counts) + ) + expect_no_error( + plot_histogram( + moo, + count_type = "raw", + group_colname = "Group", + color_by_group = TRUE, + print_plots = FALSE, + save_plots = FALSE + ) + ) +}) diff --git a/code/MOSuite/tests/testthat/test-plot_pca.R b/code/MOSuite/tests/testthat/test-plot_pca.R new file mode 100644 index 0000000..db003f3 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-plot_pca.R @@ -0,0 +1,347 @@ +test_that("calc_pca works", { + pca_dat <- calc_pca(nidap_clean_raw_counts, nidap_sample_metadata) |> + dplyr::filter(PC %in% c(1, 2)) + expect_equal( + pca_dat, + structure( + list( + Sample = c( + "A1", + "A1", + "A2", + "A2", + "A3", + "A3", + "B1", + "B1", + "B2", + "B2", + "B3", + "B3", + "C1", + "C1", + "C2", + "C2", + "C3", + "C3" + ), + PC = c(1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2), + value = c( + -40.6241668816455, + 25.2297268619146, + -56.2133160433603, + 6.13385771612248, + -69.1070711020441, + -21.8952345106934, + -36.1660251215743, + 7.80504297978752, + -25.865255255388, + -11.2138080494717, + -9.6232450176941, + 9.32724696042314, + 74.3345576680281, + -86.7286802229905, + 85.0442226808989, + 117.992340543509, + 78.2202990727852, + -46.6504922786012 + ), + std.dev = c( + 61.7780383925471, + 55.9548424792563, + 61.7780383925471, + 55.9548424792563, + 61.7780383925471, + 55.9548424792563, + 61.7780383925471, + 55.9548424792563, + 61.7780383925471, + 55.9548424792563, + 61.7780383925471, + 55.9548424792563, + 61.7780383925471, + 55.9548424792563, + 61.7780383925471, + 55.9548424792563, + 61.7780383925471, + 55.9548424792563 + ), + percent = c( + 21.219, + 17.408, + 21.219, + 17.408, + 21.219, + 17.408, + 21.219, + 17.408, + 21.219, + 17.408, + 21.219, + 17.408, + 21.219, + 17.408, + 21.219, + 17.408, + 21.219, + 17.408 + ), + cumulative = c( + 0.21219, + 0.38627, + 0.21219, + 0.38627, + 0.21219, + 0.38627, + 0.21219, + 0.38627, + 0.21219, + 0.38627, + 0.21219, + 0.38627, + 0.21219, + 0.38627, + 0.21219, + 0.38627, + 0.21219, + 0.38627 + ), + Group = c( + "A", + "A", + "A", + "A", + "A", + "A", + "B", + "B", + "B", + "B", + "B", + "B", + "C", + "C", + "C", + "C", + "C", + "C" + ), + Replicate = c(1, 1, 2, 2, 3, 3, 1, 1, 2, 2, 3, 3, 1, 1, 2, 2, 3, 3), + Batch = c(1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2), + Label = c( + "A1", + "A1", + "A2", + "A2", + "A3", + "A3", + "B1", + "B1", + "B2", + "B2", + "B3", + "B3", + "C1", + "C1", + "C2", + "C2", + "C3", + "C3" + ) + ), + class = c("tbl_df", "tbl", "data.frame"), + row.names = c(NA, -18L) + ) + ) +}) + +test_that("plot_pca layers are expected", { + p <- plot_pca( + moo_counts = nidap_filtered_counts, + sample_metadata = nidap_sample_metadata, + principal_components = c(1, 2), + samples_to_rename = NULL, + group_colname = "Group", + label_colname = "Label", + color_values = c( + "#5954d6", + "#e1562c", + "#b80058", + "#00c6f8", + "#d163e6", + "#00a76c", + "#ff9287", + "#008cf9", + "#006e00", + "#796880", + "#FFA500", + "#878500" + ), + legend_position = "top", + point_size = 1, + add_label = TRUE, + label_font_size = 3, + label_offset_y_ = 2, + label_offset_x_ = 2 + ) + + expect_s3_class(p$layers[[1]], "ggproto") + expect_s3_class(p$layers[[1]]$geom, "GeomPoint") +}) + + +test_that("2D & 3D PCA method dispatch works", { + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ) + ) + expect_equal( + plot_pca( + moo, + count_type = "filt", + principal_components = c(1, 2) + ), + plot_pca( + moo@counts$filt, + moo@sample_meta, + principal_components = c(1, 2) + ) + ) + + # 3D PCA + p1 <- plot_pca(moo, count_type = "filt", principal_components = c(1, 2, 3)) + p2 <- plot_pca( + moo@counts$filt, + moo@sample_meta, + principal_components = c(1, 2, 3) + ) + # see compare_proxy.plotly + # expect_equal(p1, p2) +}) + +test_that("plot_pca_3d returns plotly object and has correct structure", { + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ) + ) + + # Test with multiOmicDataSet + fig_moo <- plot_pca_3d( + moo, + count_type = "filt", + principal_components = c(1, 2, 3), + group_colname = "Group", + label_colname = "Label", + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(fig_moo, "plotly") + expect_type(fig_moo$x, "list") + + # Test with data.frame + fig_df <- plot_pca_3d( + moo@counts$filt, + sample_metadata = moo@sample_meta, + principal_components = c(1, 2, 3), + group_colname = "Group", + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(fig_df, "plotly") + expect_type(fig_df$x, "list") +}) + +test_that("plot_pca_3d validates principal_components length", { + expect_error( + plot_pca_3d( + nidap_filtered_counts, + sample_metadata = nidap_sample_metadata, + principal_components = c(1, 2), + save_plots = FALSE, + print_plots = FALSE + ), + "principal_components must contain 3 values" + ) + + expect_error( + plot_pca_3d( + nidap_filtered_counts, + sample_metadata = nidap_sample_metadata, + principal_components = c(1, 2, 3, 4), + save_plots = FALSE, + print_plots = FALSE + ), + "principal_components must contain 3 values" + ) +}) + +test_that("plot_pca_2d works on multiOmicDataSet object", { + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ) + ) + + # Test with multiOmicDataSet + p_moo <- plot_pca_2d( + moo, + count_type = "filt", + principal_components = c(1, 2), + group_colname = "Group", + label_colname = "Label", + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(p_moo, "ggplot") + # Should have geom_point and geom_text_repel layers + expect_gte(length(p_moo$layers), 2) + expect_s3_class(p_moo$layers[[1]]$geom, "GeomPoint") +}) + +test_that("plot_pca_2d works with and without labels", { + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ) + ) + + # With labels + p_with_labels <- plot_pca_2d( + moo, + count_type = "filt", + principal_components = c(1, 2), + add_label = TRUE, + save_plots = FALSE, + print_plots = FALSE + ) + + # Without labels + p_without_labels <- plot_pca_2d( + moo, + count_type = "filt", + principal_components = c(1, 2), + add_label = FALSE, + 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)) +}) diff --git a/code/MOSuite/tests/testthat/test-plot_read_depth.R b/code/MOSuite/tests/testthat/test-plot_read_depth.R new file mode 100644 index 0000000..df2f4e1 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-plot_read_depth.R @@ -0,0 +1,30 @@ +test_that("plot_read_depth works on moo & dataframes", { + moo <- multiOmicDataSet( + sample_metadata = nidap_sample_metadata, + anno_dat = data.frame(), + counts_lst = list("raw" = nidap_raw_counts) + ) + expect_equal( + plot_read_depth(moo, "raw"), + plot_read_depth(nidap_raw_counts) + ) +}) + +test_that("plot_read_depth accepts extra args via moo dispatch without error", { + moo <- multiOmicDataSet( + sample_metadata = nidap_sample_metadata, + anno_dat = data.frame(), + counts_lst = list( + "raw" = nidap_raw_counts, + "clean" = nidap_clean_raw_counts + ) + ) + expect_no_error( + plot_read_depth( + moo, + count_type = "clean", + sample_id_colname = "Sample", + feature_id_colname = "Gene" + ) + ) +}) diff --git a/code/MOSuite/tests/testthat/test-plot_venn_diagram.R b/code/MOSuite/tests/testthat/test-plot_venn_diagram.R new file mode 100644 index 0000000..9c63715 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-plot_venn_diagram.R @@ -0,0 +1,56 @@ +test_that("plot_venn_diagram works with defaults", { + expect_snapshot( + p <- plot_venn_diagram( + nidap_volcano_summary_dat, + print_plots = FALSE, + save_plots = TRUE + ) + ) + expect_equal( + plot_venn_diagram(nidap_volcano_summary_dat), + as.data.frame(nidap_venn_diagram_dat) + ) +}) +test_that("plot_venn_diagram raises condition for empty df", { + expect_error( + plot_venn_diagram(structure( + list( + GeneName = character(0), + Contrast = character(0), + FC = numeric(0), + logFC = numeric(0), + tstat = numeric(0), + pval = numeric(0), + adjpval = numeric(0) + ), + class = "data.frame", + row.names = integer(0) + )), + "Dataframe is empty" + ) +}) + +test_that("intersection matrix assignment avoids recursive evaluation error", { + # This test demonstrates the fix for the recursive default argument reference error + # The error occurred with this pattern: + # Intersection <- sapply(colnames(Intersection), function(x) Intersection[, x]) + # The fix uses a temporary variable: + # intersection_matrix <- Intersection; + # Intersection <- sapply(colnames(intersection_matrix), ...) + + # Call plot_venn_diagram directly to ensure the fix works in practice + expect_no_error({ + result <- plot_venn_diagram( + nidap_volcano_summary_dat, + print_plots = FALSE, + save_plots = FALSE + ) + }) + + # Verify the result has the expected structure + expect_s3_class(result, "data.frame") + expect_true("Gene" %in% colnames(result)) + expect_true("Intersection" %in% colnames(result)) + expect_true("Id" %in% colnames(result)) + expect_true("Size" %in% colnames(result)) +}) diff --git a/code/MOSuite/tests/testthat/test-plot_volcano.R b/code/MOSuite/tests/testthat/test-plot_volcano.R new file mode 100644 index 0000000..c44bf93 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-plot_volcano.R @@ -0,0 +1,16 @@ +# moo_nidap <- 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)) +# ) +# ) +# moo_nidap@analyses$diff <- nidap_deg_analysis_2 +# +# test_that("volcano plots work on MOO", { +# volc_sum <- plot_volcano_summary(moo_nidap) +# volc_enh <- plot_volcano_enhanced(moo_nidap) +# }) diff --git a/code/MOSuite/tests/testthat/test-plot_volcano_enhanced.R b/code/MOSuite/tests/testthat/test-plot_volcano_enhanced.R new file mode 100644 index 0000000..6f351ca --- /dev/null +++ b/code/MOSuite/tests/testthat/test-plot_volcano_enhanced.R @@ -0,0 +1,58 @@ +test_that("plot_volcano_enhanced works on nidap dataset", { + expect_snapshot( + df_volc_enh <- plot_volcano_enhanced( + nidap_deg_analysis, + save_plots = FALSE, + print_plots = FALSE + ) + ) +}) + +test_that("plot_volcano_enhanced returns a data frame", { + 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", { + 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 works with multiOmicDataSet", { + # Create a multiOmicDataSet with differential analysis results + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ), + analyses_lst = list( + diff = nidap_deg_analysis_2 + ) + ) + + # Test that it returns a data frame + result <- plot_volcano_enhanced( + moo, + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + expect_true(ncol(result) > 0) + expect_true(nrow(result) > 0) +}) diff --git a/code/MOSuite/tests/testthat/test-plot_volcano_summary.R b/code/MOSuite/tests/testthat/test-plot_volcano_summary.R new file mode 100644 index 0000000..bfaa429 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-plot_volcano_summary.R @@ -0,0 +1,146 @@ +test_that("plot_volcano_summary works on nidap dataset", { + expect_snapshot( + df_volc_sum <- plot_volcano_summary( + nidap_deg_analysis, + save_plots = FALSE, + print_plots = FALSE + ) + ) + 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" + ) + ) + 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 + ) + ), + row.names = c( + "B-C.957", + "B-C.958", + "B-C.959", + "B-C.960", + "B-C.961", + "B-C.962" + ), + class = "data.frame" + ) + ) +}) + +test_that("plot_volcano_summary works with multiOmicDataSet", { + # Create a multiOmicDataSet with differential analysis results + moo <- multiOmicDataSet( + sample_metadata = as.data.frame(nidap_sample_metadata), + anno_dat = data.frame(), + counts_lst = list( + "raw" = as.data.frame(nidap_raw_counts), + "filt" = as.data.frame(nidap_filtered_counts) + ), + analyses_lst = list( + diff = nidap_deg_analysis_2 + ) + ) + + # Test that it returns a data frame + result <- plot_volcano_summary( + moo, + save_plots = FALSE, + print_plots = FALSE + ) + + expect_s3_class(result, "data.frame") + expect_true(ncol(result) > 0) + expect_true(nrow(result) > 0) + expect_true("Gene" %in% colnames(result)) + expect_true("Contrast" %in% colnames(result)) +}) diff --git a/code/MOSuite/tests/testthat/test-plots.R b/code/MOSuite/tests/testthat/test-plots.R new file mode 100644 index 0000000..43ada4f --- /dev/null +++ b/code/MOSuite/tests/testthat/test-plots.R @@ -0,0 +1,51 @@ +set.seed(20250225) +test_that("save_or_print_plot works for ComplexHeatmap", { + p <- plot_corr_heatmap( + nidap_filtered_counts |> + as.data.frame(), + sample_metadata = as.data.frame(nidap_sample_metadata), + sample_id_colname = "Sample", + feature_id_colname = "Gene", + label_colname = "Label", + group_colname = "Group", + color_values = c( + "#5954d6", + "#e1562c", + "#b80058", + "#00c6f8", + "#d163e6", + "#00a76c", + "#ff9287", + "#008cf9", + "#006e00", + "#796880", + "#FFA500", + "#878500" + ) + ) + skip() + expect_snapshot_file( + print_or_save_plot( + p, + filename = "heatmap.png", + print_plots = FALSE, + save_plots = TRUE, + plots_dir = "." + ), + "heatmap.png" + ) +}) +test_that("save_or_print_plot works for ggplot", { + p <- plot_read_depth(nidap_clean_raw_counts) + skip() + expect_snapshot_file( + print_or_save_plot( + p, + filename = "read_depth.png", + print_plots = FALSE, + save_plots = TRUE, + plots_dir = "." + ), + "read_depth.png" + ) +}) diff --git a/code/MOSuite/tests/testthat/test-rename.R b/code/MOSuite/tests/testthat/test-rename.R new file mode 100644 index 0000000..977e9f8 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-rename.R @@ -0,0 +1,61 @@ +pca_df <- structure( + list( + PC1 = c( + -30.8218758482181, + -30.4702492624378, + -33.2153357604014, + -29.4300387598409, + -17.3928202952984, + -15.0796711447318, + 12.5428903958151, + 125.002561238028, + 18.8645394370853 + ), + PC2 = c( + 21.782786691387, + 26.7296573707873, + 22.1341837691228, + 16.1535492176278, + 0.595950972197422, + 2.94923156300579, + -62.2311789028092, + 38.2727901160822, + -66.3869707974014 + ), + group = c("A", "A", "A", "B", "B", "B", "C", "C", "C"), + sample = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"), + xdata = c( + -30.8218758482181, + -30.4702492624378, + -33.2153357604014, + -29.4300387598409, + -17.3928202952984, + -15.0796711447318, + 12.5428903958151, + 125.002561238028, + 18.8645394370853 + ), + ydata = c( + 21.782786691387, + 26.7296573707873, + 22.1341837691228, + 16.1535492176278, + 0.595950972197422, + 2.94923156300579, + -62.2311789028092, + 38.2727901160822, + -66.3869707974014 + ) + ), + row.names = c("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"), + class = "data.frame" +) + +test_that("rename_samples does nothing with empty vector", { + expect_equal(rename_samples(pca_df, c("")), pca_df) + expect_equal(rename_samples(pca_df, ""), pca_df) + expect_equal(rename_samples(pca_df, NULL), pca_df) + expect_equal(rename_samples(pca_df, numeric(0)), pca_df) +}) + +# TODO need to know expected format of samples_to_rename_manually diff --git a/code/MOSuite/tests/testthat/test-utils.R b/code/MOSuite/tests/testthat/test-utils.R new file mode 100644 index 0000000..7540a91 --- /dev/null +++ b/code/MOSuite/tests/testthat/test-utils.R @@ -0,0 +1,313 @@ +test_that("abort_packages_not_installed works", { + expect_no_error(abort_packages_not_installed("base")) + expect_error( + abort_packages_not_installed("not-a-package-name"), + "The following package\\(s\\) are required but are not installed" + ) +}) +test_that("check_packages_installed works", { + expect_equal( + check_packages_installed("base"), + c(base = TRUE) + ) + expect_equal( + check_packages_installed("not-a-package-name"), + c(`not-a-package-name` = FALSE) + ) +}) + +# Tests for parse_optional_vector +test_that("parse_optional_vector handles normal input", { + result <- parse_optional_vector("a, b, c") + expect_equal(result, c("a", "b", "c")) +}) + +test_that("parse_optional_vector trims whitespace", { + result <- parse_optional_vector(" a , b , c ") + expect_equal(result, c("a", "b", "c")) +}) + +test_that("parse_optional_vector returns NULL for empty string", { + result <- parse_optional_vector("") + expect_null(result) +}) + +test_that("parse_optional_vector returns NULL for NULL input", { + result <- parse_optional_vector(NULL) + expect_null(result) +}) + +test_that("parse_optional_vector returns NULL for zero-length vector", { + result <- parse_optional_vector(character(0)) + expect_null(result) +}) + +test_that("parse_optional_vector handles single value", { + result <- parse_optional_vector("single") + expect_equal(result, "single") +}) + +test_that("parse_optional_vector handles numeric-like strings", { + result <- parse_optional_vector("1, 2, 3") + expect_equal(result, c("1", "2", "3")) +}) + +# Tests for parse_vector_with_default +test_that("parse_vector_with_default parses normal input", { + result <- parse_vector_with_default("a, b, c", "default") + expect_equal(result, c("a", "b", "c")) +}) + +test_that("parse_vector_with_default returns default for empty string", { + result <- parse_vector_with_default("", "default") + expect_equal(result, "default") +}) + +test_that("parse_vector_with_default returns default for NULL", { + result <- parse_vector_with_default(NULL, "default") + expect_equal(result, "default") +}) + +test_that("parse_vector_with_default returns default for zero-length vector", { + result <- parse_vector_with_default(character(0), "default") + expect_equal(result, "default") +}) + +test_that("parse_vector_with_default handles vector defaults", { + default_vec <- c("x", "y", "z") + result <- parse_vector_with_default("", default_vec) + expect_equal(result, default_vec) +}) + +test_that("parse_vector_with_default handles numeric defaults", { + result <- parse_vector_with_default("", 42) + expect_equal(result, 42) +}) + +# Tests for parse_samples_to_rename +test_that("parse_samples_to_rename parses single pair", { + result <- parse_samples_to_rename("old:new") + expect_equal(result, list(old = "new")) +}) + +test_that("parse_samples_to_rename parses multiple pairs", { + result <- parse_samples_to_rename("sample1:S1,sample2:S2,sample3:S3") + expect_equal(result, list(sample1 = "S1", sample2 = "S2", sample3 = "S3")) +}) + +test_that("parse_samples_to_rename handles many sample pairs", { + result <- parse_samples_to_rename( + "ctrl_1:Control_Rep1,ctrl_2:Control_Rep2,treat_1:Treatment_Rep1,treat_2:Treatment_Rep2,treat_3:Treatment_Rep3" + ) + expected <- list( + ctrl_1 = "Control_Rep1", + ctrl_2 = "Control_Rep2", + treat_1 = "Treatment_Rep1", + treat_2 = "Treatment_Rep2", + treat_3 = "Treatment_Rep3" + ) + expect_equal(result, expected) +}) + +test_that("parse_samples_to_rename trims whitespace", { + result <- parse_samples_to_rename(" old : new , old2 : new2 ") + expect_equal(result, list(old = "new", old2 = "new2")) +}) + +test_that("parse_samples_to_rename returns NULL for empty string", { + result <- parse_samples_to_rename("") + expect_null(result) +}) + +test_that("parse_samples_to_rename returns NULL for NULL input", { + result <- parse_samples_to_rename(NULL) + expect_null(result) +}) + +test_that("parse_samples_to_rename returns NULL for zero-length vector", { + result <- parse_samples_to_rename(character(0)) + expect_null(result) +}) + +test_that("parse_samples_to_rename ignores malformed pairs", { + result <- parse_samples_to_rename("valid:pair,invalid_no_colon") + expect_equal(result, list(valid = "pair")) +}) + +test_that("parse_samples_to_rename returns NULL if all pairs malformed", { + result <- parse_samples_to_rename("malformed,also_malformed") + expect_null(result) +}) + +test_that("parse_samples_to_rename handles colons in values", { + result <- parse_samples_to_rename("old:http://new") + # Only uses pairs with exactly 2 parts (one colon), so this is ignored + expect_null(result) +}) + +test_that("parse_samples_to_rename silently ignores pairs with colons in names", { + # When a column name contains colon, pair is silently skipped + result <- parse_samples_to_rename("old:with:colons:new,sample1:S1") + # Only sample1:S1 is valid, the other is ignored + expect_equal(result, list(sample1 = "S1")) +}) + +# Tests for setup_capsule_environment +test_that("setup_capsule_environment creates correct directory paths", { + tmpdir <- tempdir() + + result <- setup_capsule_environment(base_results_dir = tmpdir) + + expect_equal(result$results_dir, tmpdir) + expect_equal(result$plots_dir, file.path(tmpdir, "figures")) +}) + +test_that("setup_capsule_environment sets options", { + tmpdir <- tempdir() + + setup_capsule_environment(base_results_dir = tmpdir) + + expect_equal(getOption("moo_plots_dir"), file.path(tmpdir, "figures")) + expect_equal(getOption("moo_save_plots"), TRUE) +}) + +test_that("setup_capsule_environment creates r-packages.csv", { + tmpdir <- tempfile() + dir.create(tmpdir) + on.exit(unlink(tmpdir, recursive = TRUE)) + + setup_capsule_environment(base_results_dir = tmpdir) + + csv_path <- file.path(tmpdir, "r-packages.csv") + expect_true(file.exists(csv_path)) + + # Check it's a valid CSV + csv_content <- readr::read_csv(csv_path, show_col_types = FALSE) + expect_gt(nrow(csv_content), 0) +}) + +test_that("setup_capsule_environment returns invisibly", { + tmpdir <- tempdir() + + result <- setup_capsule_environment(base_results_dir = tmpdir) + + expect_type(result, "list") + expect_named(result, c("results_dir", "plots_dir")) +}) + +# Tests for load_moo_from_data_dir +test_that("load_moo_from_data_dir stops when no .rds files found", { + tmpdir <- tempfile() + dir.create(tmpdir) + on.exit(unlink(tmpdir, recursive = TRUE)) + + expect_error( + load_moo_from_data_dir(data_dir = tmpdir), + "No files matching regex" + ) +}) + +test_that("load_moo_from_data_dir loads valid MOO object", { + tmpdir <- tempfile() + dir.create(tmpdir) + on.exit(unlink(tmpdir, recursive = TRUE)) + + # Create a mock multiOmicDataSet object + moo <- structure( + list(data = "test"), + class = c("multiOmicDataSet", "MOSuite::multiOmicDataSet") + ) + + rds_file <- file.path(tmpdir, "test.rds") + readr::write_rds(moo, rds_file) + + result <- load_moo_from_data_dir(data_dir = tmpdir) + + expect_s3_class(result, "multiOmicDataSet") + expect_equal(result$data, "test") +}) + +test_that("load_moo_from_data_dir stops for invalid class", { + tmpdir <- tempfile() + dir.create(tmpdir) + on.exit(unlink(tmpdir, recursive = TRUE)) + + # Create an invalid object (not a multiOmicDataSet) + invalid_obj <- list(data = "test") + + rds_file <- file.path(tmpdir, "test.rds") + readr::write_rds(invalid_obj, rds_file) + + expect_error( + load_moo_from_data_dir(data_dir = tmpdir), + "The input is not a multiOmicDataSet" + ) +}) + +test_that("load_moo_from_data_dir finds file recursively", { + tmpdir <- tempfile() + dir.create(tmpdir) + subdir <- file.path(tmpdir, "subdir") + dir.create(subdir) + on.exit(unlink(tmpdir, recursive = TRUE)) + + # Create a mock multiOmicDataSet in subdirectory + moo <- structure( + list(data = "test"), + class = c("multiOmicDataSet", "MOSuite::multiOmicDataSet") + ) + + rds_file <- file.path(subdir, "test.rds") + readr::write_rds(moo, rds_file) + + result <- load_moo_from_data_dir(data_dir = tmpdir) + + expect_s3_class(result, "multiOmicDataSet") +}) + +test_that("load_moo_from_data_dir uses first matching file", { + tmpdir <- tempfile() + dir.create(tmpdir) + on.exit(unlink(tmpdir, recursive = TRUE)) + + # Create two mock multiOmicDataSet objects + moo1 <- structure( + list(data = "first"), + class = c("multiOmicDataSet", "MOSuite::multiOmicDataSet") + ) + moo2 <- structure( + list(data = "second"), + class = c("multiOmicDataSet", "MOSuite::multiOmicDataSet") + ) + + rds_file1 <- file.path(tmpdir, "a_test.rds") + rds_file2 <- file.path(tmpdir, "z_test.rds") + readr::write_rds(moo1, rds_file1) + readr::write_rds(moo2, rds_file2) + + result <- load_moo_from_data_dir(data_dir = tmpdir) + + # Should load one of them (order may vary, so just check it's valid) + expect_s3_class(result, "multiOmicDataSet") + expect_true(result$data %in% c("first", "second")) +}) + +test_that("load_moo_from_data_dir prints message", { + tmpdir <- tempfile() + dir.create(tmpdir) + on.exit(unlink(tmpdir, recursive = TRUE)) + + # Create a mock multiOmicDataSet object + moo <- structure( + list(data = "test"), + class = c("multiOmicDataSet", "MOSuite::multiOmicDataSet") + ) + + rds_file <- file.path(tmpdir, "test.rds") + readr::write_rds(moo, rds_file) + + expect_message( + load_moo_from_data_dir(data_dir = tmpdir), + "Reading multiOmicDataSet from" + ) +}) diff --git a/code/MOSuite/vignettes/.gitignore b/code/MOSuite/vignettes/.gitignore new file mode 100644 index 0000000..02c2733 --- /dev/null +++ b/code/MOSuite/vignettes/.gitignore @@ -0,0 +1,5 @@ +*.html +*.R +*.json +moo.rds +/figures diff --git a/code/MOSuite/vignettes/cli.Rmd b/code/MOSuite/vignettes/cli.Rmd new file mode 100644 index 0000000..5de79f6 --- /dev/null +++ b/code/MOSuite/vignettes/cli.Rmd @@ -0,0 +1,218 @@ +--- +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/intro.Rmd b/code/MOSuite/vignettes/intro.Rmd new file mode 100644 index 0000000..88783c7 --- /dev/null +++ b/code/MOSuite/vignettes/intro.Rmd @@ -0,0 +1,60 @@ +--- +title: "Introduction to MultiOmicsSuite" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{intro} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +options(rmarkdown.html_vignette.check_title = FALSE) +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(MOSuite) +library(dplyr) +``` + +```{r nidap_data} +options(moo_print_plots = TRUE) + +moo_nidap <- create_multiOmicDataSet_from_dataframes( + sample_metadata = as.data.frame(nidap_sample_metadata), + counts_dat = as.data.frame(nidap_raw_counts) +) |> + clean_raw_counts() |> + filter_counts(group_colname = "Group") |> + normalize_counts(group_colname = "Group") |> + batch_correct_counts( + covariates_colname = "Group", + batch_colname = "Batch", + label_colname = "Label" + ) |> + diff_counts( + count_type = "filt", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + input_in_log_counts = FALSE, + return_mean_and_sd = FALSE, + voom_normalization_method = "quantile", + ) |> + filter_diff() + +moo_nidap@analyses$diff |> + join_dfs_wide() |> + head() + +moo_nidap@analyses$diff_filt |> head() +``` + +## The multiOmicDataSet object structure + +```{r str_moo} +str(moo_nidap) +``` diff --git a/code/MOSuite/vignettes/memory.Rmd b/code/MOSuite/vignettes/memory.Rmd new file mode 100644 index 0000000..6d69fd0 --- /dev/null +++ b/code/MOSuite/vignettes/memory.Rmd @@ -0,0 +1,143 @@ +--- +title: "Memory Usage" +output: rmarkdown::html_vignette +self_contained: true +vignette: > + %\VignetteIndexEntry{memory} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +options(rmarkdown.html_vignette.check_title = FALSE) +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + echo = FALSE, + # eval = FALSE, + message = FALSE, + warning = FALSE +) +options(rmarkdown.html_vignette.check_title = FALSE) +``` + +```{r setup} +library(dplyr) +library(ggplot2) +library(glue) +library(readr) +library(MOSuite) +``` + +Dataset from: + +```{r data} +counts <- read_tsv(system.file( + "extdata", "LIHC_HTseqCounts.txt.gz", + package = "MOSuite" +)) |> + rename(gene_id = Gene) +metadat <- read_tsv(system.file( + "extdata", "LIHC_PatientData.txt.gz", + package = "MOSuite" +)) |> + select(-sample_id) |> + rename(sample_id = barcode) + +run_mosuite <- function(metadat, counts) { + return( + create_multiOmicDataSet_from_dataframes(metadat, counts) |> + clean_raw_counts() |> + calc_cpm() |> + filter_counts( + group_colname = "treatments_radiation_treatment_type", + label_colname = "sample" + ) + ) +} +moo <- run_mosuite(metadat, counts) +``` + + +```{r subset} +subset_mem <- lapply(c(10, 50, 100, 200, nrow(moo@sample_meta)), function(nsamples) { + samples_subset <- moo@sample_meta |> slice_sample(n = nsamples) + counts_subset <- moo@counts$raw |> + dplyr::select(gene_id, tidyselect::all_of(samples_subset |> dplyr::pull(sample_id))) + + moo_subset <- run_mosuite(samples_subset, counts_subset) + return(tibble( + n_samples = nsamples, + object_size = lobstr::obj_size(moo_subset) + )) +}) |> + bind_rows() +``` + +```{r single_cell} +to_bytes <- function(x, unit, base = 1024) { + bytes_units <- list( + K = 1, + M = 2, + G = 3, + T = 4 + ) + return(x * (base^bytes_units[[unit]])) +} +sc_dat <- tibble::tribble( + ~"project", ~"n_cells", ~"n_samples", ~"n_genes", ~"object_size_GB", + "CCBR1329/CCBR1243", 64642, 10, 26359, 9.35, + "CCBR1297", 9991, 2, 20989, 1.78, + "CCBR1035", 170789, 19, 32100, 31.54, + "CCBR1203", 208169, 35, 30858, 37.38 +) |> + mutate( + object_size = to_bytes(object_size_GB, "G", base = 1000), + dataset_type = "single-cell (Seurat)" + ) +``` + + +```{r plot_memory} +# what is the resource spec of default NIDAP allocation? +palette_name <- "Set2" +subset_mem |> + ggplot(aes(n_samples, object_size, color = "")) + + geom_point() + + geom_line(linewidth = 0.3) + + scale_y_continuous(labels = scales::label_bytes(units = "GB", accuracy = 0.1)) + + scale_color_manual(values = RColorBrewer::brewer.pal(3, palette_name)[[1]]) + + labs( + title = "Memory usage of S7 object", + x = "Number of samples", + y = "Memory usage", + caption = glue( + "The object contains sample metadata and count data as raw, CPM-transformed, and filtered counts.\n", + "Each dataset has the same number of genes: ", + format(length(moo@counts$raw$gene_id), big.mark = ",") + ) + ) + + theme_bw() + + theme(legend.position = "none") +``` + +```{r plot_memory_comp} +dat_comp <- bind_rows( + subset_mem |> mutate(dataset_type = "bulk (S7)", object_size = as.double(object_size)), + sc_dat +) +dat_comp |> + ggplot(aes(n_samples, object_size, colour = dataset_type)) + + geom_point() + + geom_line(linewidth = 0.3) + + scale_y_continuous(labels = scales::label_bytes(units = "GB", accuracy = 0.1)) + + scale_color_brewer(palette = palette_name) + + guides(colour = guide_legend( + title = "", + position = "top", + reverse = TRUE, + theme = theme(legend.text.position = "top") + )) + + labs(title = "Memory usage of bulk & single-cell RNA-seq objects", x = "Number of samples", y = "Memory usage") + + theme_bw() +``` diff --git a/code/MOSuite/vignettes/renee.Rmd b/code/MOSuite/vignettes/renee.Rmd new file mode 100644 index 0000000..f7804f3 --- /dev/null +++ b/code/MOSuite/vignettes/renee.Rmd @@ -0,0 +1,79 @@ +--- +title: "RSEM counts from RENEE" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{renee} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +options(rmarkdown.html_vignette.check_title = FALSE) +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(MOSuite) +library(dplyr) +``` + +## RENEE dataset + +```{r data} +# replace these lines with the actual paths to your files +gene_counts_tsv <- system.file("extdata", + "RSEM.genes.expected_count.all_samples.txt.gz", + package = "MOSuite" +) +metadata_tsv <- system.file("extdata", "sample_metadata.tsv.gz", + package = "MOSuite" +) + +# create multi-omic object +moo <- create_multiOmicDataSet_from_files( + sample_meta_filepath = metadata_tsv, + feature_counts_filepath = gene_counts_tsv +) + +head(moo@counts$raw) +head(moo@sample_meta) +head(moo@annotation) +``` + +```{r analysis} +moo <- moo |> + clean_raw_counts() |> + filter_counts( + group_colname = "condition", + label_colname = "sample_id", + minimum_count_value_to_be_considered_nonzero = 1, + minimum_number_of_samples_with_nonzero_counts_in_total = 1, + minimum_number_of_samples_with_nonzero_counts_in_a_group = 1, + ) |> + normalize_counts( + group_colname = "condition", + label_colname = "sample_id" + ) |> + diff_counts( + covariates_colnames = "condition", + contrast_colname = "condition", + contrasts = c("knockout-wildtype") + ) |> + filter_diff( + significance_cutoff = 0.05, + significance_column = "adjpval", + change_column = "logFC", + change_cutoff = 1 + ) + +moo@counts$norm$voom |> head() +``` + +## The multiOmicDataSet object structure + +```{r str_moo} +str(moo) +``` diff --git a/code/MOSuite/vignettes/visualization.Rmd b/code/MOSuite/vignettes/visualization.Rmd new file mode 100644 index 0000000..c46d6a0 --- /dev/null +++ b/code/MOSuite/vignettes/visualization.Rmd @@ -0,0 +1,152 @@ +--- +title: "Visualization with built-in plots" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{visualization} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include = FALSE} +options(rmarkdown.html_vignette.check_title = FALSE) +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + fig.width = 5, + fig.height = 4 +) +``` + +```{r load} +library(MOSuite) +``` + +## Default plots from each step + +Default plots can be printed to the screen and/or saved to the disk. + +```{r options} +# set options to print & save the plots +options(moo_print_plots = TRUE) +options(moo_save_plots = TRUE) +# when moo_save_plots is TRUE, plots are saved to this directory: +options(moo_plots_dir = "./figures") +``` + +See `?MOSuite::options` for more information. + +### clean + +```{r nidap_data_clean} +moo <- create_multiOmicDataSet_from_dataframes( + sample_metadata = as.data.frame(nidap_sample_metadata), + counts_dat = as.data.frame(nidap_raw_counts) +) |> + clean_raw_counts() +``` + +### filter + +```{r nidap_filter} +moo <- moo |> + filter_counts(group_colname = "Group") +``` + +### normalize + +```{r nidap_norm} +moo <- moo |> + normalize_counts(group_colname = "Group") +``` + +### batch correct + +```{r nidap_batch} +moo <- moo |> + batch_correct_counts( + covariates_colname = "Group", + batch_colname = "Batch", + label_colname = "Label" + ) +``` + +### differential expression + +```{r diff_counts} +moo <- moo |> + diff_counts( + count_type = "filt", + covariates_colnames = c("Group", "Batch"), + contrast_colname = c("Group"), + contrasts = c("B-A", "C-A", "B-C"), + input_in_log_counts = FALSE, + return_mean_and_sd = FALSE, + voom_normalization_method = "quantile", + ) +``` + +### filter differential features + +```{r filter_diff} +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 + +### 3D PCA + +```{r pca_3D} +plot_pca( + moo@counts$batch, + moo@sample_meta, + principal_components = c(1, 2, 3), + group_colname = "Group", + label_colname = "Label", + color_values = moo@analyses[["colors"]][["Group"]] +) +``` + +### 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/main.R b/code/main.R index 9b69cdd..a3eee69 100644 --- a/code/main.R +++ b/code/main.R @@ -2,10 +2,10 @@ rlang::global_entrace() library(argparse) library(glue) -library(MOSuite) library(readr) library(stringr) library(dplyr) +devtools::load_all("/code/MOSuite") # set up capsule environment setup_capsule_environment() @@ -13,48 +13,253 @@ setup_capsule_environment() # parse CLI arguments parser <- ArgumentParser() -parser$add_argument("--count_type", type="character", default="filt") -parser$add_argument("--sub_count_type", type="character", default=NULL, help="Sub count type if count_type is a list") -parser$add_argument("--sample_id_colname", type="character", default=NULL, help="Column name for sample IDs") -parser$add_argument("--feature_id_colname", type="character", default=NULL, help="Column name for feature IDs") -parser$add_argument("--group_colname", type="character", default="Group", help="Column name for sample groups") -parser$add_argument("--label_colname", type="character", default=NULL, help="Column name for sample labels") -parser$add_argument("--samples_to_include", type="character", default="", help="Comma-separated list of samples to include") -parser$add_argument("--color_values", type="character", default="#5954d6,#e1562c,#b80058,#00c6f8,#d163e6,#00a76c,#ff9287,#008cf9,#006e00,#796880,#FFA500,#878500", help="Comma-separated color values") -parser$add_argument("--include_all_genes", type="logical", default=FALSE, help="Include all genes") -parser$add_argument("--filter_top_genes_by_variance", type="logical", default=TRUE, help="Filter top genes by variance") -parser$add_argument("--top_genes_by_variance_to_include", type="integer", default=500, help="Number of top genes by variance") -parser$add_argument("--specific_genes_to_include_in_heatmap", type="character", default="None", help="Comma-separated list of specific genes") -parser$add_argument("--cluster_genes", type="logical", default=TRUE, help="Cluster genes") -parser$add_argument("--gene_distance_metric", type="character", default="correlation", help="Gene distance metric") -parser$add_argument("--gene_clustering_method", type="character", default="average", help="Gene clustering method") -parser$add_argument("--display_gene_dendrograms", type="logical", default=TRUE, help="Display gene dendrograms") -parser$add_argument("--display_gene_names", type="logical", default=FALSE, help="Display gene names") -parser$add_argument("--center_and_rescale_expression", type="logical", default=TRUE, help="Center and rescale expression") -parser$add_argument("--cluster_samples", type="logical", default=FALSE, help="Cluster samples") -parser$add_argument("--arrange_sample_columns", type="logical", default=TRUE, help="Arrange sample columns") -parser$add_argument("--order_by_gene_expression", type="logical", default=FALSE, help="Order by gene expression") -parser$add_argument("--gene_to_order_columns", type="character", default=" ", help="Gene to order columns") -parser$add_argument("--gene_expression_order", type="character", default="low_to_high", help="Gene expression order") -parser$add_argument("--smpl_distance_metric", type="character", default="correlation", help="Sample distance metric") -parser$add_argument("--smpl_clustering_method", type="character", default="average", help="Sample clustering method") -parser$add_argument("--display_smpl_dendrograms", type="logical", default=TRUE, help="Display sample dendrograms") -parser$add_argument("--reorder_dendrogram", type="logical", default=FALSE, help="Reorder dendrogram") -parser$add_argument("--reorder_dendrogram_order", type="character", default="", help="Reorder dendrogram order") -parser$add_argument("--display_sample_names", type="logical", default=TRUE, help="Display sample names") -parser$add_argument("--group_columns", type="character", default="Group,Replicate,Batch", help="Columns for groups") -parser$add_argument("--assign_group_colors", type="logical", default=FALSE, help="Assign group colors") -parser$add_argument("--assign_color_to_sample_groups", type="character", default="", help="Assign color to sample groups") -parser$add_argument("--group_colors", type="character", default="#5954d6,#e1562c,#b80058,#00c6f8,#d163e6,#00a76c,#ff9287,#008cf9,#006e00,#796880,#FFA500,#878500", help="Group colors") -parser$add_argument("--heatmap_color_scheme", type="character", default="Default", help="Heatmap color scheme") -parser$add_argument("--autoscale_heatmap_color", type="logical", default=TRUE, help="Autoscale heatmap color") -parser$add_argument("--set_min_heatmap_color", type="double", default=-2, help="Minimum heatmap color value") -parser$add_argument("--set_max_heatmap_color", type="double", default=2, help="Maximum heatmap color value") -parser$add_argument("--aspect_ratio", type="character", default="Auto", help="Aspect ratio") -parser$add_argument("--legend_font_size", type="integer", default=10, help="Legend font size") -parser$add_argument("--gene_name_font_size", type="integer", default=4, help="Gene name font size") -parser$add_argument("--sample_name_font_size", type="integer", default=8, help="Sample name font size") -parser$add_argument("--display_numbers", type="logical", default=FALSE, help="Display numbers in heatmap") +parser$add_argument("--count_type", type = "character", default = "filt") +parser$add_argument( + "--sub_count_type", + type = "character", + default = NULL, + help = "Sub count type if count_type is a list" +) +parser$add_argument( + "--sample_id_colname", + type = "character", + default = NULL, + help = "Column name for sample IDs" +) +parser$add_argument( + "--feature_id_colname", + type = "character", + default = NULL, + help = "Column name for feature IDs" +) +parser$add_argument( + "--group_colname", + type = "character", + default = "Group", + help = "Column name for sample groups" +) +parser$add_argument( + "--label_colname", + type = "character", + default = NULL, + help = "Column name for sample labels" +) +parser$add_argument( + "--samples_to_include", + type = "character", + default = "", + help = "Comma-separated list of samples to include" +) +parser$add_argument( + "--color_values", + type = "character", + default = "#5954d6,#e1562c,#b80058,#00c6f8,#d163e6,#00a76c,#ff9287,#008cf9,#006e00,#796880,#FFA500,#878500", + help = "Comma-separated color values" +) +parser$add_argument( + "--include_all_genes", + type = "logical", + default = FALSE, + help = "Include all genes" +) +parser$add_argument( + "--filter_top_genes_by_variance", + type = "logical", + default = TRUE, + help = "Filter top genes by variance" +) +parser$add_argument( + "--top_genes_by_variance_to_include", + type = "integer", + default = 500, + help = "Number of top genes by variance" +) +parser$add_argument( + "--specific_genes_to_include_in_heatmap", + type = "character", + default = "None", + help = "Comma-separated list of specific genes" +) +parser$add_argument( + "--cluster_genes", + type = "logical", + default = TRUE, + help = "Cluster genes" +) +parser$add_argument( + "--gene_distance_metric", + type = "character", + default = "correlation", + help = "Gene distance metric" +) +parser$add_argument( + "--gene_clustering_method", + type = "character", + default = "average", + help = "Gene clustering method" +) +parser$add_argument( + "--display_gene_dendrograms", + type = "logical", + default = TRUE, + help = "Display gene dendrograms" +) +parser$add_argument( + "--display_gene_names", + type = "logical", + default = FALSE, + help = "Display gene names" +) +parser$add_argument( + "--center_and_rescale_expression", + type = "logical", + default = TRUE, + help = "Center and rescale expression" +) +parser$add_argument( + "--cluster_samples", + type = "logical", + default = FALSE, + help = "Cluster samples" +) +parser$add_argument( + "--arrange_sample_columns", + type = "logical", + default = TRUE, + help = "Arrange sample columns" +) +parser$add_argument( + "--order_by_gene_expression", + type = "logical", + default = FALSE, + help = "Order by gene expression" +) +parser$add_argument( + "--gene_to_order_columns", + type = "character", + default = " ", + help = "Gene to order columns" +) +parser$add_argument( + "--gene_expression_order", + type = "character", + default = "low_to_high", + help = "Gene expression order" +) +parser$add_argument( + "--smpl_distance_metric", + type = "character", + default = "correlation", + help = "Sample distance metric" +) +parser$add_argument( + "--smpl_clustering_method", + type = "character", + default = "average", + help = "Sample clustering method" +) +parser$add_argument( + "--display_smpl_dendrograms", + type = "logical", + default = TRUE, + help = "Display sample dendrograms" +) +parser$add_argument( + "--reorder_dendrogram", + type = "logical", + default = FALSE, + help = "Reorder dendrogram" +) +parser$add_argument( + "--reorder_dendrogram_order", + type = "character", + default = "", + help = "Reorder dendrogram order" +) +parser$add_argument( + "--display_sample_names", + type = "logical", + default = TRUE, + help = "Display sample names" +) +parser$add_argument( + "--group_columns", + type = "character", + default = "Group,Replicate,Batch", + help = "Columns for groups" +) +parser$add_argument( + "--assign_group_colors", + type = "logical", + default = FALSE, + help = "Assign group colors" +) +parser$add_argument( + "--assign_color_to_sample_groups", + type = "character", + default = "", + help = "Assign color to sample groups" +) +parser$add_argument( + "--group_colors", + type = "character", + default = "#5954d6,#e1562c,#b80058,#00c6f8,#d163e6,#00a76c,#ff9287,#008cf9,#006e00,#796880,#FFA500,#878500", + help = "Group colors" +) +parser$add_argument( + "--heatmap_color_scheme", + type = "character", + default = "Default", + help = "Heatmap color scheme" +) +parser$add_argument( + "--autoscale_heatmap_color", + type = "logical", + default = TRUE, + help = "Autoscale heatmap color" +) +parser$add_argument( + "--set_min_heatmap_color", + type = "double", + default = -2, + help = "Minimum heatmap color value" +) +parser$add_argument( + "--set_max_heatmap_color", + type = "double", + default = 2, + help = "Maximum heatmap color value" +) +parser$add_argument( + "--aspect_ratio", + type = "character", + default = "Auto", + help = "Aspect ratio" +) +parser$add_argument( + "--legend_font_size", + type = "integer", + default = 10, + help = "Legend font size" +) +parser$add_argument( + "--gene_name_font_size", + type = "integer", + default = 4, + help = "Gene name font size" +) +parser$add_argument( + "--sample_name_font_size", + type = "integer", + default = 8, + help = "Sample name font size" +) +parser$add_argument( + "--display_numbers", + type = "logical", + default = FALSE, + help = "Display numbers in heatmap" +) args <- parser$parse_args() @@ -63,38 +268,45 @@ moo <- load_moo_from_data_dir() # run MOSuite plot_expr_heatmap( - moo, - count_type = args$count_type, - sub_count_type = args$sub_count_type, - sample_id_colname = args$sample_id_colname, - feature_id_colname = args$feature_id_colname, - group_colname = args$group_colname, - label_colname = args$label_colname, - samples_to_include = parse_optional_vector(args$samples_to_include), - color_values = parse_optional_vector(args$color_values), - include_all_genes = args$include_all_genes, - filter_top_genes_by_variance = args$filter_top_genes_by_variance, - top_genes_by_variance_to_include = args$top_genes_by_variance_to_include, - specific_genes_to_include_in_heatmap = parse_vector_with_default(args$specific_genes_to_include_in_heatmap, "None"), - cluster_genes = args$cluster_genes, - gene_distance_metric = args$gene_distance_metric, - gene_clustering_method = args$gene_clustering_method, - display_gene_dendrograms = args$display_gene_dendrograms, - display_gene_names = args$display_gene_names, - center_and_rescale_expression = args$center_and_rescale_expression, - cluster_samples = args$cluster_samples, - arrange_sample_columns = args$arrange_sample_columns, - order_by_gene_expression = args$order_by_gene_expression, - gene_to_order_columns = args$gene_to_order_columns, - gene_expression_order = args$gene_expression_order, - smpl_distance_metric = args$smpl_distance_metric, - smpl_clustering_method = args$smpl_clustering_method, - display_smpl_dendrograms = args$display_smpl_dendrograms, - reorder_dendrogram = args$reorder_dendrogram, - reorder_dendrogram_order = parse_optional_vector(args$reorder_dendrogram_order), - display_sample_names = args$display_sample_names, - group_columns = parse_optional_vector(args$group_columns), - assign_group_colors = args$assign_group_colors, - assign_color_to_sample_groups = parse_optional_vector(args$assign_color_to_sample_groups), - group_colors = parse_optional_vector(args$group_colors) + moo, + count_type = args$count_type, + sub_count_type = args$sub_count_type, + sample_id_colname = args$sample_id_colname, + feature_id_colname = args$feature_id_colname, + group_colname = args$group_colname, + label_colname = args$label_colname, + samples_to_include = parse_optional_vector(args$samples_to_include), + color_values = parse_optional_vector(args$color_values), + include_all_genes = args$include_all_genes, + filter_top_genes_by_variance = args$filter_top_genes_by_variance, + top_genes_by_variance_to_include = args$top_genes_by_variance_to_include, + specific_genes_to_include_in_heatmap = parse_vector_with_default( + args$specific_genes_to_include_in_heatmap, + "None" + ), + cluster_genes = args$cluster_genes, + gene_distance_metric = args$gene_distance_metric, + gene_clustering_method = args$gene_clustering_method, + display_gene_dendrograms = args$display_gene_dendrograms, + display_gene_names = args$display_gene_names, + center_and_rescale_expression = args$center_and_rescale_expression, + cluster_samples = args$cluster_samples, + arrange_sample_columns = args$arrange_sample_columns, + order_by_gene_expression = args$order_by_gene_expression, + gene_to_order_columns = args$gene_to_order_columns, + gene_expression_order = args$gene_expression_order, + smpl_distance_metric = args$smpl_distance_metric, + smpl_clustering_method = args$smpl_clustering_method, + display_smpl_dendrograms = args$display_smpl_dendrograms, + reorder_dendrogram = args$reorder_dendrogram, + reorder_dendrogram_order = parse_optional_vector( + args$reorder_dendrogram_order + ), + display_sample_names = args$display_sample_names, + group_columns = parse_optional_vector(args$group_columns), + assign_group_colors = args$assign_group_colors, + assign_color_to_sample_groups = parse_optional_vector( + args$assign_color_to_sample_groups + ), + group_colors = parse_optional_vector(args$group_colors) ) diff --git a/environment/Dockerfile b/environment/Dockerfile index 273dcf1..2823f50 100644 --- a/environment/Dockerfile +++ b/environment/Dockerfile @@ -1,10 +1,10 @@ -# hash:sha256:16a54343c83446772895fc0c0b1e88a6dbd136fee70bcacffff7886f30541b82 +# hash:sha256:3ddd04105ec5ac0dc17d676e30ef154cb818689953c1d6cdcd656c82272f4902 ARG REGISTRY_HOST -FROM $REGISTRY_HOST/codeocean/mosuite:v0.3.0 +FROM $REGISTRY_HOST/codeocean/mosuite-minimal:v0.3.1 ARG DEBIAN_FRONTEND=noninteractive ARG GIT_ASKPASS -COPY git-askpass / +COPY git-ask-pass / COPY postInstall / RUN --mount=type=secret,id=secrets . /run/secrets/secrets \