1. Lookup basics: querying the pdactrace atlas

Goal

pdactrace is a queryable PDAC multi-omics gene-level lookup atlas. This vignette walks through the 5 core lookup functions in the order most users will need them.

library(pdactrace)

1. Single-gene query — query_gene()

q <- query_gene("LTBP1")
print(q)
#> LTBP1: Early_Burst_Up (rho=1.00, padj=1.7e-02) | Tier1_gold | serum-detected (n=1 cohort, Class B). 
#> Evidence:  RNA trajectory + Tissue protein trajectory + Multi-cohort RNA consistency + scRNA cell origin + 7-step serum filter audit + Strict RNA-protein-serum bridge + Predeclared panel member
#> Technical: phase33, phase34, stouffer_consistency, phase2c, phase60, phase77, phase80
#> 
#> Layers loaded: rna, protein, scrna, serum, clinical, filter_status, annotation 
#> Use $rna / $protein / $scrna / $serum / $clinical /
#> $filter_status / $annotation for full evidence.

Each layer is accessible as a named slot:

q$rna
#>           pattern pattern_rho runner_up_rho   lrt_padj beta_N    beta_E
#>            <char>       <num>         <num>      <num>  <int>     <num>
#> 1: Early_Burst_Up   0.9989047     0.8104464 0.01662033      0 0.4769994
#>       beta_M    beta_L stouffer_z cohort_agreement excluded_mid_pattern
#>        <num>     <num>      <num>            <num>               <lgcl>
#> 1: 0.4861358 0.5045503  0.6577856              0.5                FALSE
q$serum
#>    detected n_cohorts_detected log2fc_PDAC_vs_HC log2fc_Pan_vs_HC
#>      <lgcl>              <int>             <num>            <num>
#> 1:     TRUE                  1        -0.3595071               NA
#>    translation_class phase77_strict
#>               <char>         <lgcl>
#> 1:                 B           TRUE
q$filter_status
#>    signal_peptide serum_measurable serum_significant pancreatitis_pdac
#>            <lgcl>           <lgcl>            <lgcl>            <lgcl>
#> 1:           TRUE            FALSE             FALSE             FALSE
#>    pancreatitis_hc direction_match final_pass
#>             <lgcl>          <lgcl>     <lgcl>
#> 1:           FALSE           FALSE      FALSE

2. Multi-gene comparison — query_panel()

qp <- query_panel(c("LTBP1", "SERPINA1", "CDH13", "SPARC", "CP", "FGB"))
qp[, .(gene_symbol, rna_pattern, translation_class,
        flt_signal_peptide, flt_final, panel_member)]
#>    gene_symbol    rna_pattern translation_class flt_signal_peptide flt_final
#>         <char>         <char>            <char>             <lgcl>    <lgcl>
#> 1:       LTBP1 Early_Burst_Up                 B               TRUE     FALSE
#> 2:    SERPINA1 Early_Burst_Up                 A               TRUE      TRUE
#> 3:       CDH13           <NA>                 B               TRUE     FALSE
#> 4:       SPARC Early_Burst_Up                 B               TRUE     FALSE
#> 5:          CP Early_Burst_Up                 A               TRUE      TRUE
#> 6:         FGB Early_Burst_Up                 A               TRUE      TRUE
#>    panel_member
#>          <lgcl>
#> 1:         TRUE
#> 2:         TRUE
#> 3:         TRUE
#> 4:        FALSE
#> 5:         TRUE
#> 6:         TRUE

Genes not in the LRT-significant atlas universe are reported and skipped:

qp_miss <- query_panel(c("LTBP1", "FOOBAR_NOT_A_GENE"))
#> Genes not in atlas (skipped): FOOBAR_NOT_A_GENE

3. Multi-parameter candidate listing — list_candidates()

The new v0.1.0 signature accepts biology-level filters. Pass NULL (default) for any parameter to leave it unconstrained.

# Class B (inverse stromal) candidates
list_candidates(translation_class = "inverse")[
  , .(gene_symbol, rna_pattern, translation_class, panel_member)]
#>     gene_symbol     rna_pattern translation_class panel_member
#>          <char>          <char>            <char>       <lgcl>
#>  1:        LCN2  Early_Burst_Up                 B        FALSE
#>  2:         GGH  Early_Burst_Up                 B        FALSE
#>  3:       SPARC  Early_Burst_Up                 B        FALSE
#>  4:       APOL1  Early_Burst_Up                 B        FALSE
#>  5:      IGFBP3  Early_Burst_Up                 B        FALSE
#>  6:       ANPEP Early_Loss_Down                 B        FALSE
#>  7:      TAGLN2  Early_Burst_Up                 B        FALSE
#>  8:       LTBP1  Early_Burst_Up                 B         TRUE
#>  9:      IGFBP2 Early_Loss_Down                 B        FALSE
#> 10:        ECM1  Early_Burst_Up                 B        FALSE
#> 11:        ACTB  Early_Burst_Up                 B        FALSE

# Compound filter: signal-peptide-positive panel members
list_candidates(signal_peptide = TRUE, panel_member = TRUE)[
  , .(gene_symbol, rna_pattern, translation_class, panel_member)]
#>    gene_symbol    rna_pattern translation_class panel_member
#>         <char>         <char>            <char>       <lgcl>
#> 1:    SERPINA1 Early_Burst_Up                 A         TRUE
#> 2:       LTBP1 Early_Burst_Up                 B         TRUE
#> 3:          CP Early_Burst_Up                 A         TRUE
#> 4:         FGB Early_Burst_Up                 A         TRUE

# Direction-aware: tissue-Up + serum-detected
nrow(list_candidates(tissue_direction = "Up", serum_detected = TRUE))
#> [1] 17

4. Filter audit trail — trace_filters()

Shows which phase60 7-step filters each gene passed plus auxiliary route flags (phase77_strict, panel_member, resectable_marker). Most genes pass one of the two narrowing funnels but not both — this is the audit message of pdactrace.

trace_filters(c("SERPINA1", "LTBP1", "SPARC", "CDH13"))[
  , .(gene_symbol, n_phase60_pass, class_route)]
#>    gene_symbol n_phase60_pass    class_route
#>         <char>          <num>         <char>
#> 1:    SERPINA1              7  phase60_final
#> 2:       CDH13              1 phase77_classB
#> 3:       LTBP1              1 phase77_classB
#> 4:       SPARC              1 phase77_classB

SERPINA1 passes all 7 (phase60_final); LTBP1, SPARC, CDH13 each pass only SignalP but are surfaced via phase77_classB. Both routes are valid — the tool shows them honestly.

5. Plain-text summary — summarize_gene_evidence()

cat(summarize_gene_evidence("LTBP1"))
#> === LTBP1 ===
#> RNA: Early_Burst_Up (rho = 1, LRT padj = 0.0166, Stouffer Z = 0.66, 50% cohort agreement).
#> Tissue protein: Early_Burst_Up [Tier1_gold; concordant = TRUE].
#> Cell origin: myCAF (46%), iCAF (28%), Endothelial (11%).
#> Serum: detected (n=1 cohort), Class B (inverse stromal, manually curated), log2FC PDAC vs HC = -0.36, phase77 strict candidate.
#> Clinical: panel member (LTBP1+SERPINA1 / hybrid).
#> Filter trace (phase60 7-step): 1/7 passed [SignalP].
#> Evidence:  RNA trajectory + Tissue protein trajectory + Multi-cohort RNA consistency + scRNA cell origin + 7-step serum filter audit + Strict RNA-protein-serum bridge + Predeclared panel member
#> Technical: phase33, phase34, stouffer_consistency, phase2c, phase60, phase77, phase80

Atlas metadata

str(list_atlas_metadata(), max.level = 1)
#> List of 13
#>  $ version           : chr "0.4.0"
#>  $ audit_rule_version: chr "v0.3.0 (frozen scoring rule)"
#>  $ snapshot_date     : Date[1:1], format: "2026-05-07"
#>  $ scope             : chr "PDAC stage-aware tissue-to-serum biomarker atlas"
#>  $ classifier        : chr "12-template competitive trajectory matching (Early x 4 + Mid x 4 + Late x 2 + Monotonic x 2); atlas surface res"| __truncated__
#>  $ pattern_scope     : chr "Surfaced: Early x 4. Competing alternatives: Mid x 4 + Late x 2 + Monotonic x 2."
#>  $ rna_cohorts       :Classes 'data.table' and 'data.frame': 11 obs. of  3 variables:
#>   ..- attr(*, ".internal.selfref")=<pointer: (nil)> 
#>  $ protein_cohorts   :Classes 'data.table' and 'data.frame': 6 obs. of  3 variables:
#>   ..- attr(*, ".internal.selfref")=<pointer: (nil)> 
#>  $ scrna_cohorts     :Classes 'data.table' and 'data.frame': 1 obs. of  3 variables:
#>   ..- attr(*, ".internal.selfref")=<pointer: (nil)> 
#>  $ serum_cohorts     :Classes 'data.table' and 'data.frame': 6 obs. of  3 variables:
#>   ..- attr(*, ".internal.selfref")=<pointer: (nil)> 
#>  $ source_csvs       :Classes 'data.table' and 'data.frame': 8 obs. of  3 variables:
#>   ..- attr(*, ".internal.selfref")=<pointer: (nil)> 
#>  $ audit_classes     : chr [1:5] "high_confidence" "supported_uncertain" "penalized" "excluded" ...
#>  $ caveats           : chr [1:6] "v0.4.0 widens the catalog from 8 to 12 templates (adds Late x 2 + Monotonic x 2). The atlas surface restricts v"| __truncated__ "excluded_mid_pattern / excluded_late_pattern / excluded_monotonic_pattern flag genes whose 12-template best-mat"| __truncated__ "resectable_pattern_phase29 retains the original phase29 s_pat label (8-tpl discovery)." "translation_class B is rare and manually curated, not predicted." ...

Session

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