Add dotseq/dotseq#11742
Open
pinin4fjords wants to merge 9 commits into
Open
Conversation
DOTSeq is a Bioconductor package for detecting differential ORF usage (DOU) and ORF-level differential translation efficiency (DTE) from Ribo-seq with matched RNA-seq. Module wraps DOTSeqDataSetsFromFeatureCounts + DOTSeq() + getContrasts() and emits per-ORF TSVs for the DOU and DTE interaction contrasts plus the serialised DOTSeqDataSets object. Pre-requisites (in flight): - Bioconda recipe: bioconda/bioconda-recipes#65677 - Test data: nf-core/test-datasets#2072
Bioconda recipe (bioconda/bioconda-recipes#65677) merged; biocontainer image is not yet built so swap the placeholder quay.io/depot URLs for a Wave community container built from the now-merged bioconda package. Also widen the singularity guard to include 'apptainer' and add the versions topic block in meta.yml (via nf-core modules lint --fix).
2 tasks
- Restructure the R template around optparse + readr + dplyr + purrr + ggplot2; drop the homemade parse_args / read_delim_flexible helpers in favour of the standard package idioms and native pipe. - Output set is now what DOTSeq itself emits natively: per-ORF DTE contrasts (translation.dotseq.results.tsv), DOU contrasts (dou.dotseq.results.tsv), optional dou_strategy / dte_strategy per-condition Ribo-vs-RNA contrasts, plus the four plotDOT() PNGs (volcano / composite / venn / heatmap) and a DTE p-value distribution histogram drawn directly from DOTSeq's padj column. - Container picks up r-eulerr + r-ggsignif (required for plotDOT venn) and explicit r-ggplot2 so the histogram has a stable ggplot version. - plotDOT() default of force_new_device=TRUE was killing our png() device on each call; pass FALSE so the PNGs land where Nextflow expects them.
- Drop the homemade read_delim_flexible() and write_results_tsv() wrappers in favour of read_tsv() / read_csv() / write_tsv() directly. The earlier to_orf_tibble() conditional is also gone now that we know getContrasts() always returns a frame with orf_id as a column (per the DOTSeq source in posthoc.R + main.R). - plotDOT(heatmap) requires gene-paired mORF + sorf entries; try uORF first (the package default) and fall back to dORF when no significant gene has both. tryCatch in safe_plot_dot still makes either a no-op when neither succeeds.
…fallback robustness - Add stub: block to main.nf matching the proteus/readproteingroups precedent. - Read sample sheet with read_delim() picking comma/tab from the file extension so the meta.yml-advertised TSV variant actually works. - Refuse to clobber an existing canonical column (e.g. an existing 'condition' column when --contrast_variable=treatment is supplied). - Dedupe multi-lane sample sheets and validate that both Ribo and RNA strategies are present (DOTSeq's interaction design is unestimable otherwise). - Add an is_set() predicate that catches NULL / empty stringent + required options before the tri-state switch silently returns NULL. - safe_plot_dot now unlinks the partially-written PNG on plotDOT error and returns success so the heatmap fallback (uORF then dORF) keys off whether the first call actually drew, not file.exists() of a stale handle. - getContrasts(type='interaction') errors propagate (headline outputs); type='strategy' stays tryCatch'd because absence is legitimate. - Cache getDOU(d) / getDTE(d) once and share across contrasts + plotDOT. - Drop redundant file.exists() walk - Nextflow's path staging already guarantees the inputs exist. - Expand the test to assert volcano / composite / venn plot emission and add a -stub test.
Lets CI verify the module is actually green; revert this commit once nf-core/test-datasets#2072 merges and the canonical modules-branch URL resolves.
Aligns the module's input contract with deltate / anota2seq so that consumers can dispatch between the three ORF-DTE methods without maintaining a separate prep step for dotseq. The four featureCounts/GTF/BED inputs collapse to a per-ORF count matrix (orf_id + sample columns) plus a per-ORF annotation TSV (orf_id + gene_id + optional orf_type/coords). The R template now calls DOTSeqDataSetsFromSummarizeOverlaps() and builds the required GRanges in-process from the annotation TSV; the model fit, contrast tables, and plotDOT outputs are unchanged. Test fixtures updated alongside in nf-core/test-datasets#2072 (commit 8c9b27c). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
DOTSeq's parse_condition_table() requires a `replicate` column for stable ordering of samples within strategy+condition. Pipeline samplesheets often have a `pair` column (or none at all), so the R template now treats the column as optional: when present it is renamed to `replicate` as before; when absent the template assigns a per-(strategy, condition) row counter so the model fit is unaffected. This matches how anota2seq/deltate consume the same samplesheets. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pinin4fjords
added a commit
to pinin4fjords/riboseq
that referenced
this pull request
May 22, 2026
Adds DOTSeq as a third option for per-ORF translational efficiency analysis alongside deltate and anota2seq. DOTSeq is ORF-only and produces both DTE (DESeq2 + ashr interaction) and DOU (beta-binomial glmmTMB) results. Module installed pre-merge from nf-core/modules#11742; modules.json carries it under a second-repo entry pointing at the PR branch on the user's fork. Also drops an unused alias import (RIBOTISH_QUALITY as RIBOTISH_QUALITY_TISEQ) surfaced during the workflow refactor. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pinin4fjords
added a commit
to nf-core/riboseq
that referenced
this pull request
May 22, 2026
Wire DOTSEQ_DOTSEQ_ORF through DTE_COUNTS_PREP at ORF resolution. Drop the --run_dotseq placeholder; dotseq is now a third value for --translational_efficiency_method. Module installed from nf-core/modules#11742-pending (registered under https://github.com/pinin4fjords/nf-core-modules.git so nf-core lint doesn't hit an interactive prompt under CI's no-TTY shell). Adds withName blocks for the ORF-level DTE chain plus extra_orf_dte_args / extra_dotseq_args params, and brings tests/dotseq.nf.test + snapshot. [skip ci]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a
dotseq/dotseqmodule wrapping DOTSeq, a Bioconductor package for detecting differential ORF usage (DOU) and ORF-level differential translation efficiency (DTE) from Ribo-seq with matched RNA-seq.Status
bioconductor-dotseq=1.0.0live on linux-64 + osx-64.bioconductor-dotseq+ tidyverse + plotting deps.tests/nextflow.configpoints at the PR's fork branch until that merges.nf-core modules lint dotseq/dotseqclean.What it does
(variable, reference, target)+(samplesheet, count_matrix, annotation_tsv). The shape mirrorsanota2seq/anota2seqrunanddeltate(samplesheet + counts) with one extra per-ORF annotation TSV that supplies the parent-gene id the DOU beta-binomial fit needs.samplesheet: CSV/TSV withrun, strategy, replicate, conditioncolumns (overridable via task.ext.args).count_matrix: TSV withorf_idas the first column and per-sample count columns. Both Ribo-seq and RNA-seq samples share the matrix; the sample sheet'sstrategycolumn distinguishes them.annotation_tsv: per-ORF rows withorf_id+gene_id(required), and optionalorf_type(mORF/uORF/dORF) and coordinate columns. Genomic coordinates are stored on the resultingGRangesfor downstream inspection only; the fit itself only usesgene_id(to group child ORFs per parent gene) andorf_type(to bucket the heatmap).DOTSeqDataSetsFromSummarizeOverlaps()->DOTSeq()->getContrasts(). The R template usesoptparsefor--key valueoverrides viatask.ext.argsand tidyverse syntax throughout.translation.dotseq.results.tsv- DTE (DESeq2 + ashr) interaction resultsdou.dotseq.results.tsv- DOU (beta-binomial glmmTMB + ashr) interaction resultsdou_strategy/dte_strategyTSVs when present (per-condition Ribo-vs-RNA contrasts)volcano.png,composite.png,venn.png,heatmap.pngfromplotDOT()interaction_p_distribution.png- histogram of DTE padj (plain ggplot on the package's own statistic)DOTSeqDataSets.rds,R_sessionInfo.log,versions.ymlWhy this input shape
The DOTSeq vignette uses
DOTSeqDataSetsFromFeatureCounts()because the cell_cycle example was generated withfeatureCounts -f -Oagainst a flattened ORF GTF; the constructor parses that featureCounts-format table and pairs it with a flattened GTF + BED to build the internalGRanges. That is not intrinsic to the DOTSeq model. The package also exportsDOTSeqDataSetsFromSummarizeOverlaps(), which takes a plain per-ORF count matrix plus aGRangesannotation. The latter is a much cleaner contract for upstream consumers (nf-core/riboseq's ORF-level pipeline already produces a per-ORF P-site count matrix and a per-ORF annotation TSV directly, with no need to synthesize a featureCounts header + flattened GTF + flattened BED). The module wrapsFromSummarizeOverlapsand builds theGRangesin-process from the annotation TSV.Cross-tool naming
The DTE interaction table is written as
translation.dotseq.results.tsvto matchanota2seq/anota2seqrun'stranslation.anota2seq.results.tsv- same biological quantity (differential translation efficiency), measured per-ORF here vs per-gene there. This keeps downstream pipelines portable across the three differential translation methods (anota2seq, deltate, DOTSeq) while each module still emits only what its underlying package supports natively. DOTSeq's DOU output is unique to this tool and has no anota2seq/deltate counterpart.Test
nextflow_processtest using DOTSeq's owncell_cycle_subsetbundled data (~150KB total, MIT licence, derived frominst/extdata), restricted to the Mitotic_Cycling vs Interphase contrast on chx-treatment samples. Snapshots filenames + versions topic + versions.yml md5; DOTSeq's Bayesian + glmmTMB outputs are stochastic so file content is not snapshotted.PR checklist
TODOstatements.versions.ymlfile.