Skip to content

fix: predictCoding on empty ranges returns AAStringSet for REFAA/VARAA (#86)#92

Open
jmg421 wants to merge 4 commits into
Bioconductor:develfrom
jmg421:fix/issue-86-predictCoding-empty-AAStringSet
Open

fix: predictCoding on empty ranges returns AAStringSet for REFAA/VARAA (#86)#92
jmg421 wants to merge 4 commits into
Bioconductor:develfrom
jmg421:fix/issue-86-predictCoding-empty-AAStringSet

Conversation

@jmg421

@jmg421 jmg421 commented Jun 12, 2026

Copy link
Copy Markdown

Problem

When predictCoding() is called with a query that has no overlap with any CDS (e.g. a non-coding variant), .localCoordinates() returns a zero-length GRanges. The early-exit guard at that point returned txlocal directly — before REFAA/VARAA columns were ever added to mcols(). This caused downstream operations like reverse() or subseq() on those columns to throw errors.

Reproducer from #86:

library(VariantAnnotation)
library(BSgenome.Hsapiens.UCSC.hg19)
library(TxDb.Hsapiens.UCSC.hg19.knownGene)

fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation")
vcf <- readVcf(fl, "hg19")[123]  # non-coding variant
seqlevels(vcf) <- "chr22"
coding <- predictCoding(vcf, TxDb.Hsapiens.UCSC.hg19.knownGene, seqSource=Hsapiens)

coding$REFAA  # NULL — should be AAStringSet()
coding$VARAA  # NULL — should be AAStringSet()

Fix

Two changes in R/methods-predictCoding.R:

  1. Remove the early return on length(txlocal) == 0 — let execution fall through to the full mcols()-building block, which naturally produces zero-length AAStringSet columns via AAStringSet(rep("", length(txlocal))).

  2. Fix scalar GENEID — change GENEID=NA_character_ to GENEID=rep(NA_character_, length(txlocal)) so DataFrame() construction is valid at zero length.

Test

Extended test_predictCoding_empty in inst/unitTests/test_predictCoding-methods.R to assert:

  • mcols(result)$REFAA is an AAStringSet
  • mcols(result)$VARAA is an AAStringSet
  • Both have length == 0L

Fixes #86.

@vjcitn

vjcitn commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

I bumped the version, installed the branch corresponding to this PR, and found

> library(RUnit)

> source("test_predictCoding-methods.R")
Loading required package: BSgenome
Loading required package: BiocIO
Loading required package: rtracklayer
> ls()
[1] "cdsbytx"                         "fun"                            
[3] "quiet"                           "test_mapToTranscripts"          
[5] "test_predictCoding_empty"        "test_predictCoding_nonsense_DBS"
[7] "test_predictCoding_strand"       "test_predictCoding_varAllele"   
> test_predictCoding_empty()
Error in checkIdentical(dim(mcols(current)), c(0L, 8L)) : FALSE 
 
> test_predictCoding_varAllele()
[1] TRUE
> test_predictCoding_strand()
[1] TRUE
> test_mapToTranscripts()
[1] TRUE
> test_predictCoding_nonsense_DBS()
Error in checkTrue(as.character(mcols(current)$CONSEQUENCE) == "nonsense") : 
  Test not TRUE
> test_predictCoding_varAllele()
[1] TRUE
> system("git log | head -5", intern=TRUE)
[1] "commit 1b13f0f9d17feb320dba8a93cb36a0500b298e55"                                       
[2] "Author: John Muirhead-Gould <john@magna-services.com>"                                 
[3] "Date:   Fri Jun 12 10:40:39 2026 -0400"                                                
[4] ""                                                                                      
[5] "    fix: use grepl() for stop-codon detection in predictCoding nonsense classification"
> sessionInfo()
R version 4.6.0 beta (2026-04-16 r89894)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 22.04.5 LTS

Matrix products: default
BLAS:   /home/exouser/R46-dist/lib/R/lib/libRblas.so 
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0  LAPACK version 3.10.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] stats4    stats     graphics  grDevices utils     datasets  methods  
[8] base     

other attached packages:
 [1] BSgenome.Hsapiens.UCSC.hg19_1.4.3 BSgenome_1.79.1                  
 [3] rtracklayer_1.71.3                BiocIO_1.21.0                    
 [5] RUnit_0.4.33.1                    VariantAnnotation_1.59.1         
 [7] Rsamtools_2.27.1                  Biostrings_2.79.5                
 [9] XVector_0.51.0                    SummarizedExperiment_1.41.1      
[11] MatrixGenerics_1.23.0             matrixStats_1.5.0                
[13] GenomicFeatures_1.63.1            AnnotationDbi_1.73.0             
[15] Biobase_2.71.0                    GenomicRanges_1.63.1             
[17] Seqinfo_1.1.0                     IRanges_2.45.0                   
[19] S4Vectors_0.49.0                  BiocGenerics_0.57.0              
[21] generics_0.1.4                   

loaded via a namespace (and not attached):
 [1] SparseArray_1.11.11      bitops_1.0-9             RSQLite_2.4.6           
 [4] lattice_0.22-9           grid_4.6.0               fastmap_1.2.0           
 [7] blob_1.3.0               Matrix_1.7-5             cigarillo_1.1.0         
[10] restfulr_0.0.16          DBI_1.3.0                httr_1.4.8              
[13] XML_3.99-0.23            codetools_0.2-20         abind_1.4-8             
[16] cli_3.6.6                rlang_1.2.0              crayon_1.5.3            
[19] bit64_4.6.0-1            cachem_1.1.0             DelayedArray_0.37.0     
[22] yaml_2.3.12              otel_0.2.0               S4Arrays_1.11.1         
[25] tools_4.6.0              parallel_4.6.0           BiocParallel_1.45.0     
[28] memoise_2.0.1            curl_7.0.0               vctrs_0.7.2             
[31] R6_2.6.1                 png_0.1-9                KEGGREST_1.51.1         
[34] bit_4.6.0                GenomicAlignments_1.47.0 rjson_0.2.23            
[37] compiler_4.6.0           RCurl_1.98-1.18         

Are you running R CMD check on the package after your changes?

@vjcitn

vjcitn commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

If the PRs are somehow cumulative please close the ones that should not be verified independently.

vjcitn and others added 2 commits July 17, 2026 21:15
Convert \itemize blocks that used \item{label}{desc} syntax to \describe,
and replace empty \item{}{} labels in \describe blocks with the function
signature from the body, resolving all checkRd warnings in isSNV-methods,
PolyPhenDb-class, readVcf-methods, SIFTDb-class, summarizeVariants-methods,
VariantType-class, VCF-class, VcfFile-class, VCFHeader-class, VRanges-class,
and VRangesList-class Rd files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jmg421
jmg421 force-pushed the fix/issue-86-predictCoding-empty-AAStringSet branch 2 times, most recently from 09df700 to e9748a2 Compare July 18, 2026 03:17
Bioconductor#86)

When query has no overlap with the CDS, .localCoordinates() returns a
zero-length GRanges. Previously an early return on length(txlocal)==0
caused REFAA and VARAA to be absent from mcols(), returning NULL instead
of empty AAStringSet objects. This breaks downstream operations like
reverse() and subseq() on the result columns.

Fix:
- Remove early return so the full mcols-building code runs even when
  txlocal is empty, naturally producing zero-length AAStringSet columns
- Fix GENEID=NA_character_ -> rep(NA_character_, length(txlocal)) so
  DataFrame() construction works correctly at zero length

Test: extend test_predictCoding_empty to assert REFAA and VARAA are
AAStringSet with length 0.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes predictCoding() behavior when the query has no CDS overlap by ensuring REFAA/VARAA (and related metadata) are still present as empty AAStringSet columns, preventing downstream failures on empty results. The PR also includes broad Rd documentation \item{} formatting cleanups and bumps the package version.

Changes:

  • Remove the early return on length(txlocal) == 0 so empty outputs still get REFAA/VARAA initialized as empty AAStringSet.
  • Fix zero-length DataFrame() construction by making GENEID length-consistent with txlocal.
  • Extend unit tests to assert REFAA/VARAA are empty AAStringSet (plus assorted documentation formatting updates and a version bump).

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
R/methods-predictCoding.R Removes empty-result early return and fixes GENEID length so empty results still include REFAA/VARAA.
inst/unitTests/test_predictCoding-methods.R Adds assertions for empty AAStringSet REFAA/VARAA on empty results.
man/VRangesList-class.Rd Rd \describe/\item formatting cleanup.
man/VRanges-class.Rd Rd \describe/\item formatting cleanup (includes a touched line with a remaining typo).
man/VCFHeader-class.Rd Rd \describe/\item formatting cleanup.
man/VcfFile-class.Rd Rd \describe/\item formatting cleanup and restructuring of arguments list.
man/VCF-class.Rd Rd \describe/\item formatting cleanup and restructuring of accessor documentation.
man/VariantType-class.Rd Rd \describe/\item formatting cleanup.
man/summarizeVariants-methods.Rd Rd list structure updated (\itemize\describe).
man/SIFTDb-class.Rd Rd \describe/\item formatting cleanup.
man/readVcf-methods.Rd Rd list structure updated (\itemize\describe) for genome argument details.
man/PolyPhenDb-class.Rd Rd \describe/\item formatting cleanup.
man/isSNV-methods.Rd Rd list structure updated (\itemize\describe).
DESCRIPTION Version bump to 1.59.2.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread inst/unitTests/test_predictCoding-methods.R Outdated
Comment thread man/VRanges-class.Rd
When \code{from} is a \code{GRanges}, metadata columns of
\code{ref}, \code{alt}, \code{refDepth}, \code{altDepth},
\code{totalDepth} and \code{sampleNames} are transfered to
\code{totalDepth} and \code{sampleNames} are transfered to
This expectation likely became outdated after removing the early return in .predictCodingGRangesList(): on an empty result, .localCoordinates() contributes 8 metadata columns and .predictCodingGRangesList() appends 6 more (GENEID/CONSEQUENCE/REFCODON/VARCODON/REFAA/VARAA), so mcols(current) should have 14 columns rather than 8.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@lwaldron

lwaldron commented Jul 21, 2026

Copy link
Copy Markdown

I think this PR is ready to be merged - with this fix to the mcols number of columns test (85de342), the check error is resolved for me locally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

predictCoding on empty ranges drops REFAA/VARAA, should be empty AAStringSet instead?

4 participants