diff --git a/CHANGELOG.md b/CHANGELOG.md index a6e62e3..ed21ddf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### `Fixed` + +- [#181](https://github.com/IntGenomicsLab/lrsomatic/pull/181) - NanoPlot pre- and post-alignment statistics now reach MultiQC. `ch_nanoplot_pre_txt` and `ch_nanoplot_post_txt` were declared empty and mixed into the MultiQC inputs, but never assigned from `NANOPLOT_PRE.out.txt` / `NANOPLOT_POST.out.txt`, so the NanoStat section was silently missing from every report (@ljwharbers). +- [#181](https://github.com/IntGenomicsLab/lrsomatic/pull/181) - `NANOPLOT_PRE` now includes the replicate in its output prefix, so samples with more than one replicate no longer collapse into a single MultiQC sample (@ljwharbers). + ## v1.1.0 - [2026-04-28] ### `Added` diff --git a/CITATIONS.md b/CITATIONS.md index e13600d..951e0a6 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -66,6 +66,10 @@ > Ewels P, Magnusson M, Lundin S, Käller M. MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics. 2016 Oct 1;32(19):3047-8. doi: 10.1093/bioinformatics/btw354. Epub 2016 Jun 16. PubMed PMID: 27312411; PubMed Central PMCID: PMC5039924. +- [NanoPlot](https://pubmed.ncbi.nlm.nih.gov/37171891/) + + > De Coster W, Rademakers R. NanoPack2: population-scale evaluation of long-read sequencing data. Bioinformatics. 2023 May 4;39(5):btad311. doi: 10.1093/bioinformatics/btad311. PubMed PMID: 37171891; PubMed Central PMCID: PMC10196664. + - [SAMtools](https://pubmed.ncbi.nlm.nih.gov/19505943/) > Li H, Handsaker B, Wysoker A, Fennell T, Ruan J, Homer N, Marth G, Abecasis G, Durbin R; 1000 Genome Project Data Processing Subgroup. The Sequence Alignment/Map format and SAMtools. Bioinformatics. 2009 Aug 15;25(16):2078-9. doi: 10.1093/bioinformatics/btp352. Epub 2009 Jun 8. PubMed PMID: 19505943; PubMed Central PMCID: PMC2723002. diff --git a/conf/modules.config b/conf/modules.config index 9f7d3c3..f6d7090 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -61,7 +61,10 @@ process { } withName: '.*:NANOPLOT_PRE' { - ext.prefix = { "${meta.id}_${meta.type}_ubam" } + // NANOPLOT_PRE runs once per replicate, so the replicate has to be part of the + // prefix -- otherwise every replicate produces an identically named NanoStats.txt + // and MultiQC keeps only one of them. + ext.prefix = { "${meta.id}_${meta.type}_rep${meta.replicate}_ubam" } publishDir = [ path: { "${params.outdir}/${meta.id}/qc/${meta.type}/nanoplot_ubam_rep${meta.replicate}" }, mode: params.publish_dir_mode, diff --git a/docs/output.md b/docs/output.md index 61d82b2..bd81091 100644 --- a/docs/output.md +++ b/docs/output.md @@ -182,8 +182,8 @@ QC outputs are placed under `tumor/` for all samples, and additionally under `no │ │ │ ├── sample_tumor_aln_NanoStats.txt │ │ │ ├── sample_tumor_aln_NanoPlot-report.html │ │ ├── nanoplot_ubam_rep1 -│ │ │ ├── sample_tumor_ubam_NanoStats.txt -│ │ │ ├── sample_tumor_ubam_NanoPlot-report.html +│ │ │ ├── sample_tumor_rep1_ubam_NanoStats.txt +│ │ │ ├── sample_tumor_rep1_ubam_NanoPlot-report.html │ │ ├── samtools │ │ │ ├── sample.flagstat │ │ │ ├── sample.idxstats @@ -195,22 +195,22 @@ QC outputs are placed under `tumor/` for all samples, and additionally under `no │ │ ├── sample.blocklist.tsv ``` -| File | Description | -| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | -| `cramino_aln/sample_{type}_cramino.txt` | cramino QC summary statistics for the aligned bam file | -| `cramino_ubam_rep1/sample_{type}_cramino.txt` | cramino QC summary statistics for the unaligned bam files | -| `fibertoolsrs/sample_qc.txt` | fibertools QC summary for the bam file | -| `mosdepth/sample.mosdepth.global.dist.txt` | a cumulative distribution indicating the proportion of total bases that were covered for at least a given coverage value | -| `mosdepth/sample.mosdepth.summary.txt` | overall summary file from mosdepth tool | -| `nanoplot_aln/sample_{type}_aln_NanoStats.txt` | NanoPlot summary statistics for the aligned BAM file | -| `nanoplot_aln/sample_{type}_aln_NanoPlot-report.html` | NanoPlot interactive HTML report for the aligned BAM file | -| `nanoplot_ubam_rep1/sample_{type}_ubam_NanoStats.txt` | NanoPlot summary statistics for the unaligned BAM file | -| `nanoplot_ubam_rep1/sample_{type}_ubam_NanoPlot-report.html` | NanoPlot interactive HTML report for the unaligned BAM file | -| `samtools/sample.flagstat` | a summary of the counts of different samtools flags | -| `samtools/sample.idxstats` | a summary of the number of mapped and unmapped reads | -| `samtools/sample.stats` | summary statistics from the bamfile | -| `whatshap_stats/sample.stats.tsv` | WhatsHap phasing statistics per chromosome including phase block N50 and switch error rates | -| `whatshap_stats/sample.blocklist.tsv` | list of all phase blocks with their genomic coordinates | +| File | Description | +| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | +| `cramino_aln/sample_{type}_cramino.txt` | cramino QC summary statistics for the aligned bam file | +| `cramino_ubam_rep1/sample_{type}_cramino.txt` | cramino QC summary statistics for the unaligned bam files | +| `fibertoolsrs/sample_qc.txt` | fibertools QC summary for the bam file | +| `mosdepth/sample.mosdepth.global.dist.txt` | a cumulative distribution indicating the proportion of total bases that were covered for at least a given coverage value | +| `mosdepth/sample.mosdepth.summary.txt` | overall summary file from mosdepth tool | +| `nanoplot_aln/sample_{type}_aln_NanoStats.txt` | NanoPlot summary statistics for the aligned BAM file | +| `nanoplot_aln/sample_{type}_aln_NanoPlot-report.html` | NanoPlot interactive HTML report for the aligned BAM file | +| `nanoplot_ubam_rep1/sample_{type}_rep1_ubam_NanoStats.txt` | NanoPlot summary statistics for the unaligned BAM file | +| `nanoplot_ubam_rep1/sample_{type}_rep1_ubam_NanoPlot-report.html` | NanoPlot interactive HTML report for the unaligned BAM file | +| `samtools/sample.flagstat` | a summary of the counts of different samtools flags | +| `samtools/sample.idxstats` | a summary of the number of mapped and unmapped reads | +| `samtools/sample.stats` | summary statistics from the bamfile | +| `whatshap_stats/sample.stats.tsv` | WhatsHap phasing statistics per chromosome including phase block N50 and switch error rates | +| `whatshap_stats/sample.blocklist.tsv` | list of all phase blocks with their genomic coordinates | @@ -536,8 +536,10 @@ Phased variant calls produced by Longphase. Present in all samples. │ │ ├── multiqc_data.json │ │ ├── multiqc_general_stats.txt │ │ ├── multiqc_software_versions.txt +│ │ ├── multiqc_nanostat.txt │ │ ├── multiqc_sources.txt │ │ ├── multiqc.log +│ │ ├── nanostat_fasta_stats_table.txt │ ├── multiqc_plots │ │ ├── pdf │ │ │ ├── mosdepth-coverage-per-contig-multi-cnt.pdf diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index c3ba2e3..b5795d3 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -122,6 +122,7 @@ "multiqc/multiqc_data/multiqc_citations.txt", "multiqc/multiqc_data/multiqc_data.json", "multiqc/multiqc_data/multiqc_general_stats.txt", + "multiqc/multiqc_data/multiqc_nanostat.txt", "multiqc/multiqc_data/multiqc_samtools_flagstat.txt", "multiqc/multiqc_data/multiqc_samtools_idxstats.txt", "multiqc/multiqc_data/multiqc_samtools_stats.txt", @@ -129,6 +130,7 @@ "multiqc/multiqc_data/multiqc_sources.txt", "multiqc/multiqc_data/multiqc_whatshap_phased_bp_plot.txt", "multiqc/multiqc_data/multiqc_whatshap_stats.txt", + "multiqc/multiqc_data/nanostat_fasta_stats_table.txt", "multiqc/multiqc_data/samtools-flagstat-pct-table.txt", "multiqc/multiqc_data/samtools-flagstat-table.txt", "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Normalised_Counts.txt", @@ -143,6 +145,7 @@ "multiqc/multiqc_plots/pdf/mosdepth-coverage-per-contig-single-pct.pdf", "multiqc/multiqc_plots/pdf/mosdepth-cumcoverage-dist-id.pdf", "multiqc/multiqc_plots/pdf/multiqc_whatshap_phased_bp_plot.pdf", + "multiqc/multiqc_plots/pdf/nanostat_fasta_stats_table.pdf", "multiqc/multiqc_plots/pdf/samtools-flagstat-pct-table.pdf", "multiqc/multiqc_plots/pdf/samtools-flagstat-table.pdf", "multiqc/multiqc_plots/pdf/samtools-idxstats-mapped-reads-plot_Normalised_Counts-cnt.pdf", @@ -160,6 +163,7 @@ "multiqc/multiqc_plots/png/mosdepth-coverage-per-contig-single-pct.png", "multiqc/multiqc_plots/png/mosdepth-cumcoverage-dist-id.png", "multiqc/multiqc_plots/png/multiqc_whatshap_phased_bp_plot.png", + "multiqc/multiqc_plots/png/nanostat_fasta_stats_table.png", "multiqc/multiqc_plots/png/samtools-flagstat-pct-table.png", "multiqc/multiqc_plots/png/samtools-flagstat-table.png", "multiqc/multiqc_plots/png/samtools-idxstats-mapped-reads-plot_Normalised_Counts-cnt.png", @@ -177,6 +181,7 @@ "multiqc/multiqc_plots/svg/mosdepth-coverage-per-contig-single-pct.svg", "multiqc/multiqc_plots/svg/mosdepth-cumcoverage-dist-id.svg", "multiqc/multiqc_plots/svg/multiqc_whatshap_phased_bp_plot.svg", + "multiqc/multiqc_plots/svg/nanostat_fasta_stats_table.svg", "multiqc/multiqc_plots/svg/samtools-flagstat-pct-table.svg", "multiqc/multiqc_plots/svg/samtools-flagstat-table.svg", "multiqc/multiqc_plots/svg/samtools-idxstats-mapped-reads-plot_Normalised_Counts-cnt.svg", @@ -219,13 +224,13 @@ "sample1/qc/normal/nanoplot_aln/sample1_normal_aln_WeightedLogTransformed_HistogramReadlength.html", "sample1/qc/normal/nanoplot_aln/sample1_normal_aln_Yield_By_Length.html", "sample1/qc/normal/nanoplot_ubam_rep1", - "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_ubam_NanoPlot-report.html", - "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_ubam_NanoStats.txt", - "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_ubam_Non_weightedHistogramReadlength.html", - "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_ubam_Non_weightedLogTransformed_HistogramReadlength.html", - "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_ubam_WeightedHistogramReadlength.html", - "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_ubam_WeightedLogTransformed_HistogramReadlength.html", - "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_ubam_Yield_By_Length.html", + "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_rep1_ubam_NanoPlot-report.html", + "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_rep1_ubam_NanoStats.txt", + "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_rep1_ubam_Non_weightedHistogramReadlength.html", + "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_rep1_ubam_Non_weightedLogTransformed_HistogramReadlength.html", + "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_rep1_ubam_WeightedHistogramReadlength.html", + "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_rep1_ubam_WeightedLogTransformed_HistogramReadlength.html", + "sample1/qc/normal/nanoplot_ubam_rep1/sample1_normal_rep1_ubam_Yield_By_Length.html", "sample1/qc/normal/samtools", "sample1/qc/normal/samtools/sample1.flagstat", "sample1/qc/normal/samtools/sample1.idxstats", @@ -250,13 +255,13 @@ "sample1/qc/tumor/nanoplot_aln/sample1_tumor_aln_WeightedLogTransformed_HistogramReadlength.html", "sample1/qc/tumor/nanoplot_aln/sample1_tumor_aln_Yield_By_Length.html", "sample1/qc/tumor/nanoplot_ubam_rep1", - "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_ubam_NanoPlot-report.html", - "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_ubam_NanoStats.txt", - "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_ubam_Non_weightedHistogramReadlength.html", - "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_ubam_Non_weightedLogTransformed_HistogramReadlength.html", - "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_ubam_WeightedHistogramReadlength.html", - "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_ubam_WeightedLogTransformed_HistogramReadlength.html", - "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_ubam_Yield_By_Length.html", + "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_rep1_ubam_NanoPlot-report.html", + "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_rep1_ubam_NanoStats.txt", + "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_rep1_ubam_Non_weightedHistogramReadlength.html", + "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_rep1_ubam_Non_weightedLogTransformed_HistogramReadlength.html", + "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_rep1_ubam_WeightedHistogramReadlength.html", + "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_rep1_ubam_WeightedLogTransformed_HistogramReadlength.html", + "sample1/qc/tumor/nanoplot_ubam_rep1/sample1_tumor_rep1_ubam_Yield_By_Length.html", "sample1/qc/tumor/samtools", "sample1/qc/tumor/samtools/sample1.flagstat", "sample1/qc/tumor/samtools/sample1.idxstats", @@ -334,13 +339,13 @@ "sample2/qc/normal/nanoplot_aln/sample2_normal_aln_WeightedLogTransformed_HistogramReadlength.html", "sample2/qc/normal/nanoplot_aln/sample2_normal_aln_Yield_By_Length.html", "sample2/qc/normal/nanoplot_ubam_rep1", - "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_ubam_NanoPlot-report.html", - "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_ubam_NanoStats.txt", - "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_ubam_Non_weightedHistogramReadlength.html", - "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_ubam_Non_weightedLogTransformed_HistogramReadlength.html", - "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_ubam_WeightedHistogramReadlength.html", - "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_ubam_WeightedLogTransformed_HistogramReadlength.html", - "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_ubam_Yield_By_Length.html", + "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_rep1_ubam_NanoPlot-report.html", + "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_rep1_ubam_NanoStats.txt", + "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_rep1_ubam_Non_weightedHistogramReadlength.html", + "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_rep1_ubam_Non_weightedLogTransformed_HistogramReadlength.html", + "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_rep1_ubam_WeightedHistogramReadlength.html", + "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_rep1_ubam_WeightedLogTransformed_HistogramReadlength.html", + "sample2/qc/normal/nanoplot_ubam_rep1/sample2_normal_rep1_ubam_Yield_By_Length.html", "sample2/qc/normal/samtools", "sample2/qc/normal/samtools/sample2.flagstat", "sample2/qc/normal/samtools/sample2.idxstats", @@ -365,13 +370,13 @@ "sample2/qc/tumor/nanoplot_aln/sample2_tumor_aln_WeightedLogTransformed_HistogramReadlength.html", "sample2/qc/tumor/nanoplot_aln/sample2_tumor_aln_Yield_By_Length.html", "sample2/qc/tumor/nanoplot_ubam_rep1", - "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_ubam_NanoPlot-report.html", - "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_ubam_NanoStats.txt", - "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_ubam_Non_weightedHistogramReadlength.html", - "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_ubam_Non_weightedLogTransformed_HistogramReadlength.html", - "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_ubam_WeightedHistogramReadlength.html", - "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_ubam_WeightedLogTransformed_HistogramReadlength.html", - "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_ubam_Yield_By_Length.html", + "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_rep1_ubam_NanoPlot-report.html", + "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_rep1_ubam_NanoStats.txt", + "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_rep1_ubam_Non_weightedHistogramReadlength.html", + "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_rep1_ubam_Non_weightedLogTransformed_HistogramReadlength.html", + "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_rep1_ubam_WeightedHistogramReadlength.html", + "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_rep1_ubam_WeightedLogTransformed_HistogramReadlength.html", + "sample2/qc/tumor/nanoplot_ubam_rep1/sample2_tumor_rep1_ubam_Yield_By_Length.html", "sample2/qc/tumor/samtools", "sample2/qc/tumor/samtools/sample2.flagstat", "sample2/qc/tumor/samtools/sample2.idxstats", @@ -447,13 +452,13 @@ "sample3/qc/tumor/nanoplot_aln/sample3_tumor_aln_WeightedLogTransformed_HistogramReadlength.html", "sample3/qc/tumor/nanoplot_aln/sample3_tumor_aln_Yield_By_Length.html", "sample3/qc/tumor/nanoplot_ubam_rep1", - "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_ubam_NanoPlot-report.html", - "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_ubam_NanoStats.txt", - "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_ubam_Non_weightedHistogramReadlength.html", - "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_ubam_Non_weightedLogTransformed_HistogramReadlength.html", - "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_ubam_WeightedHistogramReadlength.html", - "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_ubam_WeightedLogTransformed_HistogramReadlength.html", - "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_ubam_Yield_By_Length.html", + "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_rep1_ubam_NanoPlot-report.html", + "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_rep1_ubam_NanoStats.txt", + "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_rep1_ubam_Non_weightedHistogramReadlength.html", + "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_rep1_ubam_Non_weightedLogTransformed_HistogramReadlength.html", + "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_rep1_ubam_WeightedHistogramReadlength.html", + "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_rep1_ubam_WeightedLogTransformed_HistogramReadlength.html", + "sample3/qc/tumor/nanoplot_ubam_rep1/sample3_tumor_rep1_ubam_Yield_By_Length.html", "sample3/qc/tumor/samtools", "sample3/qc/tumor/samtools/sample3.flagstat", "sample3/qc/tumor/samtools/sample3.idxstats", diff --git a/workflows/lrsomatic.nf b/workflows/lrsomatic.nf index 211552d..abc7c5b 100644 --- a/workflows/lrsomatic.nf +++ b/workflows/lrsomatic.nf @@ -261,13 +261,15 @@ workflow LRSOMATIC { if (!params.skip_nanoplot) { // - // MODULE: NANOPLOT_PRE (label: process_medium) + // MODULE: NANOPLOT_PRE (label: process_low) // Input: CRAMINO_PRE.out.arrow -- [meta, arrow_file] // Output: nanoplot HTML/txt reports // NANOPLOT_PRE(CRAMINO_PRE.out.arrow) + ch_nanoplot_pre_txt = NANOPLOT_PRE.out.txt + } } @@ -844,13 +846,15 @@ workflow LRSOMATIC { if (!params.skip_nanoplot) { // - // MODULE: NANOPLOT_POST (label: process_medium) + // MODULE: NANOPLOT_POST (label: process_low) // Input: CRAMINO_POST.out.arrow -- [meta, arrow_file] // Output: HTML/txt QC reports (post-alignment) // NANOPLOT_POST(CRAMINO_POST.out.arrow) + ch_nanoplot_post_txt = NANOPLOT_POST.out.txt + }