Background
The pipeline supports four aligners — STAR (star_salmon, star_rsem), HISAT2, and Bowtie2 (bowtie2_salmon). When a sample's percent_mapped falls below params.min_mapped_reads, the per-sample MultiQC report includes a "fail mapped" status row in the Sample status checks section.
The TSV that drives that row is built in subworkflows/local/multiqc_rnaseq/main.nf:71-79 with a hardcoded header that names STAR:
ch_fail_mapped_fail_by_id = ch_percent_mapped_pass
.filter { _id, _pm, pass -> pass != null && !pass }
.collectFile { id, percent_mapped, _pass ->
[
"${id}_fail_mapped_samples_mqc.tsv",
sample_status_header.text + "Sample\tSTAR uniquely mapped reads (%)\n${id}\t${percent_mapped}\n",
]
}
.map { f -> [f.baseName.replace('_fail_mapped_samples_mqc', ''), f] }
ch_percent_mapped_pass is fed by ch_percent_mapped, which is mixed from the active aligner's subworkflow output:
subworkflows/local/align_star/main.nf:69 — getStarPercentMapped(params, log)
subworkflows/local/align_bowtie2/main.nf:51 — getBowtie2PercentMapped(log_file)
- (HISAT2 is wired via the nf-core subworkflow
subworkflows/nf-core/fastq_align_hisat2/)
The percent value is computed correctly per-aligner, but the header label that surfaces in MultiQC always says "STAR uniquely mapped reads (%)". A Bowtie2 or HISAT2 user who triggers a fail-mapped row gets a misleading report.
Tasks
-
Plumb the aligner's display name through to MULTIQC_RNASEQ.
The clean fix is to make MULTIQC_RNASEQ accept the aligner display name as a take: input rather than hardcoding it. Plumbing:
- In
subworkflows/local/multiqc_rnaseq/main.nf, add a new take: entry near the top of the take block — call it aligner_display_name (string). Document it as "Display name of the aligner used for the percent_mapped metric, e.g. 'STAR uniquely mapped reads' or 'Bowtie2 overall alignment rate'."
- In the
collectFile closure at line 76, replace the hardcoded "STAR uniquely mapped reads (%)" with "${aligner_display_name} (%)".
-
Pick a display name per aligner.
STAR's getStarPercentMapped reports "uniquely mapped reads %"; Bowtie2's getBowtie2PercentMapped reports the overall alignment rate; HISAT2 reports "overall alignment rate". Suggested labels (verify the exact MultiQC General Statistics column name each tool emits and align with that, so the fail-mapped header is consistent with the rest of the report):
star_salmon, star_rsem → "STAR uniquely mapped reads"
bowtie2_salmon → "Bowtie2 overall alignment rate"
hisat2 → "HISAT2 overall alignment rate"
-
Pass the display name from workflows/rnaseq/main.nf when invoking MULTIQC_RNASEQ.
Find the MULTIQC_RNASEQ(...) call (around workflows/rnaseq/main.nf:413 — verify the exact line on the branch you're working from). Add the new argument. Derive the display name with a small helper, e.g.:
def aligner_display_name = [
'star_salmon' : 'STAR uniquely mapped reads',
'star_rsem' : 'STAR uniquely mapped reads',
'hisat2' : 'HISAT2 overall alignment rate',
'bowtie2_salmon' : 'Bowtie2 overall alignment rate',
].get(params.aligner, 'Aligned reads')
Place the helper near the other workflow-level definitions at the top of RNASEQ.
-
Update / regenerate snapshots.
Test fixtures with mappings below params.min_mapped_reads will see the header change in the per-sample fail-mapped TSV. Search for STAR uniquely mapped reads under tests/ and confirm whether any snapshot or expected fixture references it; regenerate those snapshots and review the diff carefully.
Verification
- Run
nf-test test --profile=+test,docker --tag default — confirm the STAR path still works and snapshots match (or are sensibly regenerated).
- Manually verify the Bowtie2 path: trigger a fail-mapped row by lowering
--min_mapped_reads to a high value (e.g. 99) on the Bowtie2 test profile, and confirm the resulting TSV says "Bowtie2 overall alignment rate (%)". Same for HISAT2.
- Open the MultiQC report and confirm the Sample status checks section reads consistently with the General Statistics column for the active aligner.
Acceptance criteria
Notes for the implementer
- Keep the helper map at the workflow level rather than in
MULTIQC_RNASEQ itself. The subworkflow should remain aligner-agnostic.
- If the
params.aligner enum gains a new value in future, the .get(... , 'Aligned reads') fallback prevents a runtime error — but please update the map at the same time as adding the aligner.
--use_rustqc doesn't change percent_mapped extraction (RustQC replaces post-alignment QC, not the alignment itself), so this fix is independent of RustQC.
Background
The pipeline supports four aligners — STAR (
star_salmon,star_rsem), HISAT2, and Bowtie2 (bowtie2_salmon). When a sample'spercent_mappedfalls belowparams.min_mapped_reads, the per-sample MultiQC report includes a "fail mapped" status row in the Sample status checks section.The TSV that drives that row is built in
subworkflows/local/multiqc_rnaseq/main.nf:71-79with a hardcoded header that names STAR:ch_percent_mapped_passis fed bych_percent_mapped, which is mixed from the active aligner's subworkflow output:subworkflows/local/align_star/main.nf:69—getStarPercentMapped(params, log)subworkflows/local/align_bowtie2/main.nf:51—getBowtie2PercentMapped(log_file)subworkflows/nf-core/fastq_align_hisat2/)The percent value is computed correctly per-aligner, but the header label that surfaces in MultiQC always says "STAR uniquely mapped reads (%)". A Bowtie2 or HISAT2 user who triggers a fail-mapped row gets a misleading report.
Tasks
Plumb the aligner's display name through to
MULTIQC_RNASEQ.The clean fix is to make
MULTIQC_RNASEQaccept the aligner display name as atake:input rather than hardcoding it. Plumbing:subworkflows/local/multiqc_rnaseq/main.nf, add a newtake:entry near the top of the take block — call italigner_display_name(string). Document it as "Display name of the aligner used for the percent_mapped metric, e.g. 'STAR uniquely mapped reads' or 'Bowtie2 overall alignment rate'."collectFileclosure at line 76, replace the hardcoded"STAR uniquely mapped reads (%)"with"${aligner_display_name} (%)".Pick a display name per aligner.
STAR's
getStarPercentMappedreports "uniquely mapped reads %"; Bowtie2'sgetBowtie2PercentMappedreports the overall alignment rate; HISAT2 reports "overall alignment rate". Suggested labels (verify the exact MultiQC General Statistics column name each tool emits and align with that, so the fail-mapped header is consistent with the rest of the report):star_salmon,star_rsem→"STAR uniquely mapped reads"bowtie2_salmon→"Bowtie2 overall alignment rate"hisat2→"HISAT2 overall alignment rate"Pass the display name from
workflows/rnaseq/main.nfwhen invokingMULTIQC_RNASEQ.Find the
MULTIQC_RNASEQ(...)call (aroundworkflows/rnaseq/main.nf:413— verify the exact line on the branch you're working from). Add the new argument. Derive the display name with a small helper, e.g.:Place the helper near the other workflow-level definitions at the top of
RNASEQ.Update / regenerate snapshots.
Test fixtures with mappings below
params.min_mapped_readswill see the header change in the per-sample fail-mapped TSV. Search forSTAR uniquely mapped readsundertests/and confirm whether any snapshot or expected fixture references it; regenerate those snapshots and review the diff carefully.Verification
nf-test test --profile=+test,docker --tag default— confirm the STAR path still works and snapshots match (or are sensibly regenerated).--min_mapped_readsto a high value (e.g.99) on the Bowtie2 test profile, and confirm the resulting TSV says"Bowtie2 overall alignment rate (%)". Same for HISAT2.Acceptance criteria
subworkflows/local/multiqc_rnaseq/main.nfno longer contains the literal string"STAR uniquely mapped reads"MULTIQC_RNASEQtakes an explicitaligner_display_nameinputstar_salmon,star_rsem,hisat2,bowtie2_salmon)Notes for the implementer
MULTIQC_RNASEQitself. The subworkflow should remain aligner-agnostic.params.alignerenum gains a new value in future, the.get(... , 'Aligned reads')fallback prevents a runtime error — but please update the map at the same time as adding the aligner.--use_rustqcdoesn't change percent_mapped extraction (RustQC replaces post-alignment QC, not the alignment itself), so this fix is independent of RustQC.