Skip to content

--ERCC-correlation and --SIRV-concentration raise false "no data" errors with standard gene-level SIRV/ERCC IDs #12

Description

@kayihui

Summary

Both ERCCcorrelation and SIRVsuiteConcentration call countReader.read_counting_file() without specifying counting_type, so it silently falls back to the "transcript" default. The transcript-mode regex patterns in countReader.py don't match standard gene-level spike-in IDs (e.g. ERCC-00002, SIRV1, SIRV4001), so every spike-in row gets skipped during parsing. This produces misleading downstream errors that look like a data problem when it's actually a parsing problem:

Exception: Error: sample 'L1' does not contain any ERCCs! Please check if you counts file has a corresponding entry for ERCCs greater than 0!
Exception: Error: input data for sampe group 'L1' is empty! Please make sure that input count files contain some values greater than 0 for SIRV transcripts!

Root cause

In SIRVsuite/Pipeline/countReader.py:

self.spike_in_name_pattern["SIRV"]["transcript"] = "^SIRV\\d{3}$"
self.spike_in_name_pattern["ERCC"]["transcript"] = "(DQ|EF)\\d{6}"

The ERCC transcript pattern expects GenBank accession-style IDs (DQ123456), not the standard ERCC-XXXXX gene ID format that most quantification tools (Salmon, RSEM, Cufflinks, etc.) actually output. The SIRV transcript pattern only matches exactly 3-digit IDs, missing both the 1-digit gene-level IDs (SIRV1SIRV7) and the variable-length isoform IDs (SIRV4001, SIRV10001, SIRV12001, etc.) that real SIRV reference sets contain.

Both ERCCcorrelation.__init__ (ERCC_correlation.py) and SIRVsuiteConcentration.__init__ (SIRV_concentration.py) call read_counting_file() without ever passing counting_type, so there's no way to reach the (correctly-matching) "gene" patterns through the existing CLI — the "transcript" default is hit unconditionally regardless of the actual ID format in the user's counts file.

Reproduction

import re
# ERCC: real counts file has "ERCC-00002", "ERCC-00012", etc.
re.match(r"(DQ|EF)\d{6}", "ERCC-00002")  # None — silently skipped

# SIRV: real counts file has "SIRV1"..."SIRV7" and "SIRV4001", "SIRV10001", etc.
re.match(r"^SIRV\d{3}$", "SIRV1")     # None
re.match(r"^SIRV\d{3}$", "SIRV4001")  # None

Confirmed end-to-end: a counts file with valid, non-zero ERCC/SIRV values (verified by manual inspection) reproducibly triggers both exceptions above, purely from the regex mismatch — not from any actual absence of spike-in data.

Suggested fix

self.spike_in_name_pattern["SIRV"]["transcript"] = "^SIRV\\d+$"
self.spike_in_name_pattern["ERCC"]["transcript"] = "^ERCC-\\d{5}$"

^SIRV\d+$ covers both the 1-digit gene IDs and the longer isoform IDs without needing a fixed digit count, and correctly excludes ERCC IDs and malformed strings. ^ERCC-\d{5}$ matches the standard ERCC gene ID format directly.

This is a one-line-per-pattern change and resolves both reported exceptions in local testing.


Diagnosed and verified with help from Claude (Anthropic).


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions