Running and testing ClinicalVariantR

Purpose

This vignette explains how to:

  1. Launch the ClinicalVariantR Shiny app for interactive testing
  2. Choose sample / benchmark VCFs for each workflow (Groups A-C)
  3. Run automated logic checks and unit tests

It complements the Introduction to ClinicalVariantR vignette.

Prerequisites

Install CRAN dependencies used by the app:

install.packages(c(
    "shiny", "bslib", "DT", "data.table", "readr", "jsonlite",
    "knitr", "rmarkdown", "testthat", "BiocManager"
))
BiocManager::install(c("BiocStyle", "VariantAnnotation"))

Optional (large VCF speed-up on Linux/WSL): install bcftools and ensure it is on PATH.

Confirm the package (or source tree) is available:

pkg_ok <- requireNamespace("ClinicalVariantR", quietly = TRUE)
pkg_ok
#> [1] TRUE

If you are developing from the Git clone (not yet installed), set the working directory to the package root (the folder that contains DESCRIPTION, app.R, global.R, ui.R, and server.R).

normalizePath(getwd(), winslash = "/", mustWork = FALSE)
#> [1] "/tmp/RtmpksZBwL/Rbuild1774439e5f8b/ClinicalVariantR/vignettes"

Launch the Shiny app

Preferred Bioconductor API

Package functions return a Shiny app; you launch it yourself:

if (requireNamespace("ClinicalVariantR", quietly = TRUE)) {
    stopifnot(is.function(ClinicalVariantR::ClinicalVariantR))
}
# To launch interactively:
# shiny::runApp(ClinicalVariantR(), launch.browser = TRUE)

Source-tree launch (development)

From the package root, either:

# Option 1 - classic Shiny entry
shiny::runApp(".", launch.browser = TRUE)

# Option 2 - after sourcing the package constructor from R/
# (works once ClinicalVariantR is installed or attached)
app <- ClinicalVariantR::ClinicalVariantR()
shiny::runApp(app, launch.browser = TRUE)

On Ubuntu/WSL (recommended for large VCFs):

cd /path/to/ClinicalVariantR
R -e "shiny::runApp('.', host='0.0.0.0', port=3838)"

Then open http://127.0.0.1:3838 in a browser.

Session settings useful for testing

Setting Default Notes
Max upload 1 GiB Set in global.R via shiny.maxRequestSize
Idle timeout 1 hour Override with env CLINICALVARIANTR_IDLE_TIMEOUT_SEC
Auth Off in local scaffolds when AUTH_ENABLED <- FALSE Re-enable only for secured demos
Sys.setenv(CLINICALVARIANTR_IDLE_TIMEOUT_SEC = "3600")
Sys.getenv("CLINICALVARIANTR_IDLE_TIMEOUT_SEC")
#> [1] "3600"

Test data locations

Paths below assume the development repository layout. After full Bioconductor conversion they will move under inst/extdata/ and should be loaded with system.file().

.root_candidates <- c(
    getwd(),
    file.path(getwd(), "ClinicalVariantR"),
    system.file(package = "ClinicalVariantR")
)
.root <- .root_candidates[dir.exists(.root_candidates)][1]

sample_vcf <- file.path(.root, "data", "samples", "example_variants.vcf")
clinical_csv <- file.path(.root, "data", "samples", "example_clinical_logs.csv")
pedigree_csv <- file.path(.root, "data", "samples", "example_pedigree.csv")

bench_dir <- normalizePath(
    file.path(.root, "..", "testig", "clinicalvariantr_benchmark"),
    winslash = "/",
    mustWork = FALSE
)
group_b_vcf <- file.path(bench_dir, "clinicalvariantr_group_b_benchmark.vcf")
group_b_key <- file.path(bench_dir, "clinicalvariantr_group_b_benchmark.key.csv")

data.frame(
    resource = c(
        "example_variants.vcf",
        "example_clinical_logs.csv",
        "example_pedigree.csv",
        "group_b_benchmark.vcf",
        "group_b_benchmark.key.csv"
    ),
    path = c(sample_vcf, clinical_csv, pedigree_csv, group_b_vcf, group_b_key),
    exists = file.exists(c(
        sample_vcf, clinical_csv, pedigree_csv, group_b_vcf, group_b_key
    ))
)
#>                    resource
#> 1      example_variants.vcf
#> 2 example_clinical_logs.csv
#> 3      example_pedigree.csv
#> 4     group_b_benchmark.vcf
#> 5 group_b_benchmark.key.csv
#>                                                                                                                                            path
#> 1                                               /tmp/RtmpksZBwL/Rbuild1774439e5f8b/ClinicalVariantR/vignettes/data/samples/example_variants.vcf
#> 2                                          /tmp/RtmpksZBwL/Rbuild1774439e5f8b/ClinicalVariantR/vignettes/data/samples/example_clinical_logs.csv
#> 3                                               /tmp/RtmpksZBwL/Rbuild1774439e5f8b/ClinicalVariantR/vignettes/data/samples/example_pedigree.csv
#> 4     /tmp/RtmpksZBwL/Rbuild1774439e5f8b/ClinicalVariantR/vignettes/../testig/clinicalvariantr_benchmark/clinicalvariantr_group_b_benchmark.vcf
#> 5 /tmp/RtmpksZBwL/Rbuild1774439e5f8b/ClinicalVariantR/vignettes/../testig/clinicalvariantr_benchmark/clinicalvariantr_group_b_benchmark.key.csv
#>   exists
#> 1  FALSE
#> 2  FALSE
#> 3  FALSE
#> 4  FALSE
#> 5  FALSE
File Use for
data/samples/example_variants.vcf Quick smoke test (few variants)
data/samples/example_clinical_logs.csv + example_pedigree.csv Group A companion inputs
testig/clinicalvariantr_benchmark/clinicalvariantr_group_b_benchmark.vcf Group B accuracy / traps (20 variants)
Matching *.key.csv / *.acmg.tsv Expected labels for CLI scoring

Interactive testing checklist (UI)

Group B - Automated prediction (start here)

  1. Open Group B - Rapid / Automated.
  2. Upload clinicalvariantr_group_b_benchmark.vcf (preferred) or example_variants.vcf.
  3. Confirm readiness checks turn green (CSQ/ANN present).
  4. Preview rows appear; Run Analysis is enabled.
  5. Watch the progress bar / status under Run.
  6. Open Results: classifications, criteria, confidence.
  7. Download CSV (full report and/or expert worklist).

Pass criteria for the 20-variant Group B benchmark (see testig/clinicalvariantr_benchmark/GROUP_B_BENCHMARK.md):

  • Exact accuracy 20/20
  • All pathogenic anchors detected (TCF4, MECP2, EGR2)
  • No false Pathogenic on benign traps

Group C - Gene panel

  1. Open Group C.
  2. Upload the same VCF as Group B.
  3. Enter a gene list that intersects the call set, for example:
# Paste into the Group C gene box:
# TCF4, MECP2, EGR2, ATM, TSC1
  1. Run analysis - only nominated genes should appear in results.

Group A - Full clinical

  1. Open Group A.
  2. Upload VCF + example_clinical_logs.csv + example_pedigree.csv.
  3. Optionally enable curator toggles (PS2, PS3, PS4, PM6, PP1, PP4).
  4. Run and confirm criteria appear in evidence export.

Automated testing (command line)

Run these from the package root (DESCRIPTION present).

Unit tests (testthat)

# After install:
# BiocManager::install("safarafique/ClinicalVariantR")  # or local install
devtools::test()           # development
# or:
testthat::test_package("ClinicalVariantR")

Minimal checks included in tests/testthat/test-ClinicalVariantR.R verify that ClinicalVariantR() / ClinicalVariantRApp() exist and return a shiny.appobj when Shiny entry files are present.

Engine / pipeline scripts

# Rules combining + criterion logic audit
Rscript scripts/audit_acmg_rules.R

# Group B/C coverage and gene-filter parity
Rscript scripts/verify_group_b_c.R

# Group A 28-criterion catalog check
Rscript scripts/verify_group_a_28.R

# Score the Group B benchmark VCF vs expected labels
Rscript scripts/run_group_b_benchmark.R

# Smaller accuracy fixture
Rscript scripts/run_accuracy_benchmark.R

# Formal validation report (expert set)
Rscript scripts/generate_validation_report.R

Quick existence check for key scripts (does not execute them in the vignette build):

scripts <- c(
    "audit_acmg_rules.R",
    "verify_group_b_c.R",
    "verify_group_a_28.R",
    "run_group_b_benchmark.R",
    "run_accuracy_benchmark.R",
    "generate_validation_report.R",
    "test_upload_flow.R"
)
script_paths <- file.path(.root, "scripts", scripts)
data.frame(script = scripts, exists = file.exists(script_paths))
#>                         script exists
#> 1           audit_acmg_rules.R  FALSE
#> 2           verify_group_b_c.R  FALSE
#> 3          verify_group_a_28.R  FALSE
#> 4      run_group_b_benchmark.R  FALSE
#> 5     run_accuracy_benchmark.R  FALSE
#> 6 generate_validation_report.R  FALSE
#> 7           test_upload_flow.R  FALSE

Optional upload-flow smoke script

Rscript scripts/test_upload_flow.R

Optional Bioconductor / style checks (before submission)

# From the parent of the package directory:
# R CMD build ClinicalVariantR
# R CMD check ClinicalVariantR_0.99.0.tar.gz
# BiocCheck::BiocCheck("ClinicalVariantR_0.99.0.tar.gz", `new-package` = TRUE)
# BiocCheck::BiocCheckGitClone("ClinicalVariantR")

Expected app object (non-interactive sanity check)

This chunk verifies that the constructor returns a Shiny app when package sources are on the search path or the working directory is the package root:

has_entry <- file.exists(file.path(.root, "global.R")) &&
    file.exists(file.path(.root, "ui.R")) &&
    file.exists(file.path(.root, "server.R"))

if (requireNamespace("ClinicalVariantR", quietly = TRUE) && has_entry) {
    old <- getwd()
    on.exit(setwd(old), add = TRUE)
    setwd(.root)
    app <- ClinicalVariantR::ClinicalVariantR()
    inherits(app, "shiny.appobj")
} else if (has_entry) {
    "# Install/attach ClinicalVariantR or run shiny::runApp('.') from package root"
} else {
    "# Shiny entry files not found - setwd() to package root first"
}
#> [1] "# Shiny entry files not found - setwd() to package root first"

Troubleshooting while testing

Symptom What to check
Upload stuck / empty validation Restart app; confirm VCF has CSQ or ANN; wait for readiness UI
Run does nothing Use Group B static Run button; look for status / progress under button; check R console for [Group B] Run clicked
Auth modal blocks use Set AUTH_ENABLED <- FALSE in R/auth_storage.R for local testing
AES-GCM encrypt error Use 12-byte IV build; set CLINICALVARIANTR_ENCRYPTION_KEY (32 chars) if encryption on
High VUS rate on WGS Expected without gene filter - try Group C
Package not found setwd() to package root or devtools::load_all() / install

Session info

sessionInfo()
#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 26.04 LTS
#> 
#> Matrix products: default
#> BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so;  LAPACK version 3.12.0
#> 
#> locale:
#>  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
#>  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
#>  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
#>  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
#>  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
#> 
#> time zone: Etc/UTC
#> tzcode source: system (glibc)
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] BiocStyle_2.41.0
#> 
#> loaded via a namespace (and not attached):
#>  [1] cli_3.6.6               knitr_1.51              rlang_1.3.0            
#>  [4] xfun_0.60               otel_0.2.0              promises_1.5.0         
#>  [7] shiny_1.14.0            xtable_1.8-8            jsonlite_2.0.0         
#> [10] buildtools_1.0.0        htmltools_0.5.9         maketools_1.3.2        
#> [13] httpuv_1.6.17           sys_3.4.3               sass_0.4.10            
#> [16] rmarkdown_2.31          evaluate_1.0.5          jquerylib_0.1.4        
#> [19] fastmap_1.2.0           yaml_2.3.12             lifecycle_1.0.5        
#> [22] ClinicalVariantR_0.99.0 BiocManager_1.30.27     compiler_4.6.1         
#> [25] Rcpp_1.1.2              later_1.4.8             digest_0.6.39          
#> [28] R6_2.6.1                magrittr_2.0.5          bslib_0.11.0           
#> [31] tools_4.6.1             mime_0.13               cachem_1.1.0