Walk through one representative gene per audit_class to show how the v0.3.0 audit framework handles different evidence patterns. None of these genes are presented as the paper’s flagship candidate; each is an illustrative case of how the framework’s three axes plus two gates resolve a specific evidence pattern into a transparent label.
| Gene | audit_class | Why it ends here |
|---|---|---|
| LGALS3BP | high_confidence |
Both gates clean; multi-layer + Early-onset evidence + serum bridge all strong; recovered as a secondary anchor |
| LTBP1 | supported_uncertain |
Multi-layer concordant tissue evidence, but cohort I² = 75% triggers
heterogeneity_gate < 1; Class B inverse-translation
exemplar |
| ALB | penalized |
Plasma high-abundance flag triggers leakage_gate = 0.5;
tissue Early signal is real but not specific enough on its own |
| GAPDH | excluded |
Housekeeping flag triggers leakage_gate = 0; hard-zeros
the score regardless of trajectory shape |
case_genes <- c("LGALS3BP", "LTBP1", "ALB", "GAPDH")
audit <- compute_audit_score(case_genes)
audit
#> gene_symbol evidence_strength biological_coherence translational_relevance
#> <char> <num> <num> <num>
#> 1: LGALS3BP 1.0 0.8602854 1.0
#> 2: LTBP1 1.0 0.5971764 0.7
#> 3: ALB 0.5 0.7335634 0.0
#> 4: GAPDH 0.5 0.0000000 0.4
#> leakage_gate heterogeneity_gate positive_score audit_score
#> <num> <num> <num> <num>
#> 1: 1.0 1.0 0.9510999 1.0000000
#> 2: 1.0 0.7 0.7840117 0.5770248
#> 3: 0.5 1.0 0.4567472 0.2401153
#> 4: 0.0 1.0 0.3000000 0.0000000
#> audit_class
#> <char>
#> 1: high_confidence
#> 2: supported_uncertain
#> 3: penalized
#> 4: excludedTwo key observations:
audit_class is determined by gates
first, then by score. GAPDH (housekeeping →
leakage_gate = 0) is excluded regardless of
how strong its trajectory is. ALB (plasma high-abundance →
leakage_gate = 0.5) is penalized even though
its tissue signal is real.high_confidence, because the heterogeneity gate
(audit_heterogeneity_gate = 0.7) marks cohort divergence;
we frame it as an exemplar of Class B inverse translation rather than a
flagship candidate.detailed <- query_panel(case_genes)
extra <- pdactrace_reference[
gene_symbol %in% case_genes,
.(gene_symbol, audit_class, audit_score, max_I2_meta)]
detailed <- merge(detailed, extra, by = "gene_symbol", sort = FALSE)
detailed[, .(gene_symbol, rna_pattern, prot_pattern, translation_class,
audit_class, audit_score, max_I2_meta,
cell_origin_top)]
#> gene_symbol rna_pattern prot_pattern translation_class
#> <char> <char> <char> <char>
#> 1: LGALS3BP Early_Burst_Up Early_Burst_Up A
#> 2: LTBP1 Early_Burst_Up Early_Burst_Up B
#> 3: ALB Early_Trough Early_Burst_Up <NA>
#> 4: GAPDH <NA> Early_Burst_Up B
#> audit_class audit_score max_I2_meta cell_origin_top
#> <char> <num> <num> <char>
#> 1: high_confidence 1.0000000 25.52226 Ductal
#> 2: supported_uncertain 0.5770248 75.16350 myCAF
#> 3: penalized 0.2401153 56.84316 <NA>
#> 4: excluded 0.0000000 51.79413 <NA>high_confidence anchor)LGALS3BP (Galectin-3 binding protein) sits at the top of the
audit_score ranking and is one of the secondary anchors
recovered by the framework. It illustrates the simplest case: every axis
fires positively and neither gate triggers.
lg <- query_gene_detailed("LGALS3BP")
lg$summary
#> [1] "LGALS3BP: Early_Burst_Up (rho=0.98, padj=3.7e-04) | Tier1_gold | serum-detected (n=1 cohort, Class A)."
lg$per_stage
#> stage log2FC lfcSE ci_lo ci_hi lrt_padj wald_padj
#> <fctr> <num> <num> <num> <num> <num> <num>
#> 1: Normal 0.0000000 0.0000000 0.0000000 0.0000000 NA NA
#> 2: Early 0.4818728 0.1581037 0.1719896 0.7917561 0.0003660696 1.029833e-02
#> 3: Mid 0.6011442 0.1284123 0.3494560 0.8528324 0.0003660696 1.565348e-05
#> 4: Late 0.5433948 0.1347248 0.2793342 0.8074553 0.0003660696 2.160136e-04
#> significant
#> <lgcl>
#> 1: FALSE
#> 2: TRUE
#> 3: TRUE
#> 4: TRUEsupported_uncertain, Class B inverse
exemplar)LTBP1 has tissue-level concordant evidence (RNA + protein both
Early_Burst_Up, ρ ≈ 1.0, myCAF cell origin) but
cohort-level heterogeneity is high: TCGA shows an increasing trajectory,
CPTAC a decreasing trajectory, and two cohorts are non-monotonic. The
random-effects meta-analysis records max_I2_meta = 75 % and
the heterogeneity gate downweights the score by 0.70.
ltbp1 <- query_gene_detailed("LTBP1")
ltbp1$per_cohort
#> cohort trend monotonic
#> <char> <char> <lgcl>
#> 1: TCGA Increasing TRUE
#> 2: CPTAC Decreasing TRUE
#> 3: GSE224564 Non-monotonic FALSE
#> 4: GSE79668 Non-monotonic FALSEThe framework correctly assigns LTBP1 to
supported_uncertain rather than
high_confidence, traceably attributing the uncertainty to
cohort divergence:
LTBP1 also has translation_class = "B" (inverse): tissue
Burst-Up evidence does not translate to a serum-up biomarker.
Its panel value emerges only when paired with a Class A
(concordant-translation) marker — see Class A × Class B panel
diversity in the BiB Discussion (LTBP1 + SERPINA1 LOOCV AUC 0.97 vs
LTBP1 alone 0.83 vs SERPINA1 alone 0.89).
penalized, plasma high-abundance
gate)Albumin (ALB) has a real Early-onset signal at the tissue level
(Early_Trough — falling at PDAC onset) but is also one of
the most abundant plasma proteins. The leakage gate downweights ALB’s
score by 0.50 to reflect that abundance-driven false positives are a
known failure mode in serum biomarker discovery.
alb <- compute_audit_score("ALB")
alb[, .(gene_symbol, evidence_strength, biological_coherence,
translational_relevance, leakage_gate,
heterogeneity_gate, audit_score, audit_class)]
#> Key: <gene_symbol>
#> gene_symbol evidence_strength biological_coherence translational_relevance
#> <char> <num> <num> <num>
#> 1: ALB 0.5 0.7335634 0
#> leakage_gate heterogeneity_gate audit_score audit_class
#> <num> <num> <num> <char>
#> 1: 0.5 1 0.2401153 penalizedALB is admitted to the ranking (its real Early signal counts) but with a transparent abundance-driven discount, rather than being silently dropped. This is the difference between a “leakage gate” (graded 0 / 0.5 / 1) and a hard exclusion list.
excluded, housekeeping gate)GAPDH is a canonical housekeeping gene. Its
audit_is_housekeeping flag triggers
leakage_gate = 0, which hard-zeros the audit score
regardless of how strong its per-stage trajectory looks. This is the
“non-nominatable” failure mode of the framework: even a perfect
trajectory shape cannot rescue a housekeeping artifact.
gapdh <- compute_audit_score("GAPDH")
hk <- pdactrace_reference[gene_symbol == "GAPDH",
.(gene_symbol, audit_is_housekeeping)]
gapdh <- merge(gapdh, hk, by = "gene_symbol", sort = FALSE)
gapdh[, .(gene_symbol, audit_is_housekeeping, leakage_gate,
audit_score, audit_class)]
#> gene_symbol audit_is_housekeeping leakage_gate audit_score audit_class
#> <char> <lgcl> <num> <num> <char>
#> 1: GAPDH TRUE 0 0 excludedGAPDH is also reclassified under v0.4.0’s 12-template catalog as
Monotonic_Up (linear pan-stage progression) rather than
Early_Burst_Up, which removes it from the Early × 4 atlas
surface entirely — the leakage gate and the 12-template catalog
discipline defend against housekeeping contamination through two
independent mechanisms.
The four cases illustrate the explicit decomposition
that the audit framework provides: each gene’s audit_class
is traceable to specific axes and gates, and the same framework
discipline applies uniformly across genes regardless of biological role.
When you query your own candidate, the same decomposition is available
via compute_audit_score(c("YOUR_GENE")) and
query_gene_detailed(...) — see vignette
user_cohort_extension for applying this discipline to your
own multi-omics cohort.
sessionInfo()
#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 26.04.1 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] data.table_1.18.6.1 pdactrace_0.99.25 rmarkdown_2.32
#>
#> loaded via a namespace (and not attached):
#> [1] sass_0.4.10 generics_0.1.4
#> [3] SparseArray_1.13.3 lattice_0.23-1
#> [5] digest_0.6.39 magrittr_2.0.5
#> [7] evaluate_1.0.5 grid_4.6.1
#> [9] RColorBrewer_1.1-3 fastmap_1.2.0
#> [11] jsonlite_2.0.0 Matrix_1.7-6
#> [13] scales_1.4.0 jquerylib_0.1.4
#> [15] abind_1.4-8 cli_3.6.6
#> [17] rlang_1.3.0 XVector_0.53.0
#> [19] Biobase_2.73.2 withr_3.0.3
#> [21] cachem_1.1.0 DelayedArray_0.39.7
#> [23] yaml_2.3.12 otel_0.2.0
#> [25] S4Arrays_1.13.1 tools_4.6.1
#> [27] dplyr_1.2.1 ggplot2_4.0.3
#> [29] SummarizedExperiment_1.43.0 BiocGenerics_0.59.12
#> [31] buildtools_1.0.0 vctrs_0.7.3
#> [33] R6_2.6.1 matrixStats_1.5.0
#> [35] stats4_4.6.1 lifecycle_1.0.5
#> [37] Seqinfo_1.3.2 S4Vectors_0.51.10
#> [39] IRanges_2.47.5 pkgconfig_2.0.3
#> [41] pillar_1.11.1 bslib_0.12.0
#> [43] gtable_0.3.6 glue_1.8.1
#> [45] tidyselect_1.2.1 tibble_3.3.1
#> [47] xfun_0.61 GenomicRanges_1.65.4
#> [49] sys_3.4.3 MatrixGenerics_1.25.0
#> [51] knitr_1.52 farver_2.1.2
#> [53] htmltools_0.5.9 labeling_0.4.3
#> [55] maketools_1.3.2 compiler_4.6.1
#> [57] S7_0.2.2