Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- #286 - Replace the local `STAR_ALIGN_IGENOMES` module with the nf-core `star/align` module, aliased and pinned in `conf/modules.config` to the STAR 2.6.1d container that reads the AWS iGenomes indices. The `--seq_center` read group tag is set in `ext.args` and now applies to every STAR alignment, not only to the iGenomes path (by @piplus2)
- #287 - Replace the local `STAR_GENOMEGENERATE_IGENOMES` module with the nf-core `star/genomegenerate` module, aliased and pinned in `conf/modules.config` to the same STAR 2.6.1d container as `STAR_ALIGN_IGENOMES` (by @piplus2)
- #289 - Drop the STAR 2.6.1d pin. A supplied STAR index now goes through the new `STAR_GENOMEPARAMS_UPGRADE` module, which rewrites the `genomeParameters.txt` metadata that STAR 2.7.4a and later validate and copies the binary index files through untouched, so the AWS iGenomes indices work with a single STAR version. This removes the `STAR_ALIGN_IGENOMES` and `STAR_GENOMEGENERATE_IGENOMES` aliases, the legacy `--quantTranscriptomeBan` argument and the `is_aws_igenome` flag (suggested by @pinin4fjords, done by @piplus2)
- #290 - Move the `PREPARE_GENOME` subworkflow to the nf-core subworkflow template. It takes `--source`, `--aligner`, `--pseudo_aligner` and `--skip_alignment` as inputs instead of reading `params`, and the GTF converted from `--gff` is named after the GFF file instead of `null.gtf` (by @piplus2)

### Fixed

Expand Down Expand Up @@ -106,6 +107,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- #275 - Fix missing yaml from singularity container in `GTFGENEFILTER` (reported by @srira25, fix by @piplus2)
- #277 - Fix missing pyyaml from singularity container in `STRAND_JUNCTIONS`, `CLUSTERGROUPS` and `MISOPY_SETTINGS` (by @piplus2)
- #281 - Fix `ISOFORMSWITCHANALYZER` writing `common_switch_consequences.pdf` next to the `results` directory instead of inside it, so it was never published (by @piplus2)
- #290 - Fix an uncompressed `--salmon_index` or `--suppa_tpm`, which reached `SALMON_QUANT` and `SUPPA` still wrapped with an empty meta map (by @piplus2)

## v1.0.5 - 2024-11-03

Expand Down
4 changes: 4 additions & 0 deletions main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ workflow NFCORE_RNASPLICE {
params.gff_dexseq,
params.suppa_tpm,
params.gencode,
params.source,
params.aligner,
params.pseudo_aligner,
params.skip_alignment,
)

//
Expand Down
157 changes: 83 additions & 74 deletions subworkflows/local/prepare_genome/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -2,88 +2,94 @@
// Uncompress and prepare reference genome files
//

include { GUNZIP as GUNZIP_FASTA } from '../../../modules/nf-core/gunzip'
include { GUNZIP as GUNZIP_GTF } from '../../../modules/nf-core/gunzip'
include { GUNZIP as GUNZIP_GFF } from '../../../modules/nf-core/gunzip'
include { GUNZIP as GUNZIP_TRANSCRIPT_FASTA } from '../../../modules/nf-core/gunzip'
include { GUNZIP as GUNZIP_GFF_DEXSEQ } from '../../../modules/nf-core/gunzip'
include { GUNZIP as GUNZIP_SUPPA_TPM } from '../../../modules/nf-core/gunzip'

include { UNTAR as UNTAR_STAR_INDEX } from '../../../modules/nf-core/untar'
include { UNTAR as UNTAR_SALMON_INDEX } from '../../../modules/nf-core/untar'

include { SAMTOOLS_FAIDX } from '../../../modules/nf-core/samtools/faidx'
include { GFFREAD } from '../../../modules/nf-core/gffread'
include { STAR_GENOMEGENERATE } from '../../../modules/nf-core/star/genomegenerate'
include { SALMON_INDEX } from '../../../modules/nf-core/salmon/index'
include { GUNZIP as GUNZIP_FASTA } from '../../../modules/nf-core/gunzip'
include { GUNZIP as GUNZIP_GTF } from '../../../modules/nf-core/gunzip'
include { GUNZIP as GUNZIP_GFF } from '../../../modules/nf-core/gunzip'
include { GUNZIP as GUNZIP_TRANSCRIPT_FASTA } from '../../../modules/nf-core/gunzip'
include { GUNZIP as GUNZIP_GFF_DEXSEQ } from '../../../modules/nf-core/gunzip'
include { GUNZIP as GUNZIP_SUPPA_TPM } from '../../../modules/nf-core/gunzip'

include { UNTAR as UNTAR_STAR_INDEX } from '../../../modules/nf-core/untar'
include { UNTAR as UNTAR_SALMON_INDEX } from '../../../modules/nf-core/untar'

include { SAMTOOLS_FAIDX } from '../../../modules/nf-core/samtools/faidx'
include { GFFREAD } from '../../../modules/nf-core/gffread'
include { STAR_GENOMEGENERATE } from '../../../modules/nf-core/star/genomegenerate'
include { SALMON_INDEX } from '../../../modules/nf-core/salmon/index'
include { RSEM_PREPAREREFERENCE as MAKE_TRANSCRIPTS_FASTA } from '../../../modules/nf-core/rsem/preparereference'

include { GTFGENEFILTER } from '../../../modules/local/gtfgenefilter'
include { PREPROCESS_TRANSCRIPTS_FASTA_GENCODE } from '../../../modules/local/preprocess_transcripts_fasta_gencode'
include { STAR_GENOMEPARAMS_UPGRADE } from '../../../modules/local/star_genomeparams_upgrade'
include { GTFGENEFILTER } from '../../../modules/local/gtfgenefilter'
include { PREPROCESS_TRANSCRIPTS_FASTA_GENCODE } from '../../../modules/local/preprocess_transcripts_fasta_gencode'
include { STAR_GENOMEPARAMS_UPGRADE } from '../../../modules/local/star_genomeparams_upgrade'

workflow PREPARE_GENOME {
take:
fasta // file: /path/to/genome.fasta
gtf // file: /path/to/genome.gtf
gff // file: /path/to/genome.gff
transcript_fasta // file: /path/to/transcript.fasta
star_index // directory: /path/to/star/index/
salmon_index // directory: /path/to/salmon/index/
gff_dexseq // file: /path/to/dexseq/genome.gff
suppa_tpm // file: /path/to/suppa/quant.tpm
gencode // boolean: whether gene annotation is from gencode
fasta // string: path to the genome FASTA, may be gzipped
gtf // string: path to the GTF annotation, may be gzipped
gff // string: path to the GFF3 annotation, used when no GTF is given, may be gzipped
transcript_fasta // string: path to the transcript FASTA, may be gzipped
star_index // string: path to the STAR index directory, may be a .tar.gz archive
salmon_index // string: path to the Salmon index directory, may be a .tar.gz archive
gff_dexseq // string: path to the flattened DEXSeq GFF annotation, may be gzipped
suppa_tpm // string: path to the SUPPA transcript TPM table, may be gzipped
gencode // boolean: whether the annotation is from GENCODE
source // string: type of input data [fastq, genome_bam, transcriptome_bam, salmon_results]
aligner // string: genome aligner [star, star_salmon]
pseudo_aligner // string: pseudo aligner [salmon]
skip_alignment // boolean: whether the genome alignment is skipped

main:

//
// Uncompress genome fasta file if required
// MODULE: GUNZIP_FASTA
//

if (fasta.endsWith('.gz')) {
GUNZIP_FASTA([[:], fasta])
ch_fasta = GUNZIP_FASTA.out.gunzip
ch_fasta = GUNZIP_FASTA([[:], file(fasta, checkIfExists: true)]).gunzip
}
else {
ch_fasta = channel.value([[:], file(fasta, checkIfExists: true)])
}

//
// Uncompress GTF annotation file or create from GFF3 if required
// MODULE: GUNZIP_GTF, GUNZIP_GFF and GFFREAD
//

// A GTF annotation is used as is, a GFF3 one is converted to GTF
if (gtf) {
if (gtf.endsWith('.gz')) {
GUNZIP_GTF([[:], gtf])
ch_gtf = GUNZIP_GTF.out.gunzip
ch_gtf = GUNZIP_GTF([[:], file(gtf, checkIfExists: true)]).gunzip
}
else {
ch_gtf = channel.value([[:], file(gtf, checkIfExists: true)])
}
}
else if (gff) {
if (gff.endsWith('.gz')) {
GUNZIP_GFF([[:], gff])
ch_gff = GUNZIP_GFF.out.gunzip
ch_gff = GUNZIP_GFF([[:], file(gff, checkIfExists: true)]).gunzip
}
else {
ch_gff = channel.value([[:], file(gff, checkIfExists: true)])
}
ch_gtf = GFFREAD(ch_gff, null).gtf
// GFFREAD names its output after `meta.id`, so give it the annotation name
ch_gtf = GFFREAD(ch_gff.map { _meta, gff_file -> [[id: gff_file.baseName], gff_file] }, []).gtf
}

//
// Uncompress transcript fasta file / create if required
// MODULE: GUNZIP_TRANSCRIPT_FASTA, PREPROCESS_TRANSCRIPTS_FASTA_GENCODE, GTFGENEFILTER and MAKE_TRANSCRIPTS_FASTA
//

// Without a transcript FASTA, one is built from the genome and the annotation, keeping
// only the genes on sequences present in the genome FASTA
if (transcript_fasta) {
if (transcript_fasta.endsWith('.gz')) {
GUNZIP_TRANSCRIPT_FASTA([[:], transcript_fasta])
ch_transcript_fasta = GUNZIP_TRANSCRIPT_FASTA.out.gunzip
ch_transcript_fasta = GUNZIP_TRANSCRIPT_FASTA([[:], file(transcript_fasta, checkIfExists: true)]).gunzip
}
else {
ch_transcript_fasta = channel.value([[:], file(transcript_fasta, checkIfExists: true)])
}
if (gencode) {
PREPROCESS_TRANSCRIPTS_FASTA_GENCODE(ch_transcript_fasta)
ch_transcript_fasta = PREPROCESS_TRANSCRIPTS_FASTA_GENCODE.out.fasta
ch_transcript_fasta = PREPROCESS_TRANSCRIPTS_FASTA_GENCODE(ch_transcript_fasta).fasta
}
}
else {
Expand All @@ -95,21 +101,24 @@ workflow PREPARE_GENOME {
}

//
// Create chromosome sizes file
// MODULE: SAMTOOLS_FAIDX
//

SAMTOOLS_FAIDX(ch_fasta.map { meta, fa -> [meta, fa, []] }, true)
ch_fai = SAMTOOLS_FAIDX.out.fai
ch_chrom_sizes = SAMTOOLS_FAIDX.out.sizes

//
// Uncompress STAR index or generate from scratch if required
// MODULE: UNTAR_STAR_INDEX, STAR_GENOMEPARAMS_UPGRADE and STAR_GENOMEGENERATE
//

ch_star_index = channel.empty()
if (params.source == 'fastq' && !params.skip_alignment && (params.aligner == 'star' || params.aligner == 'star_salmon')) {
if (source == 'fastq' && !skip_alignment && aligner in ['star', 'star_salmon']) {
if (star_index) {
def ch_star_index_raw = star_index.endsWith('.tar.gz')
? UNTAR_STAR_INDEX([[:], star_index]).untar
: channel.value([[:], file(star_index, checkIfExists: true)])
if (star_index.endsWith('.tar.gz')) {
ch_star_index_raw = UNTAR_STAR_INDEX([[:], file(star_index, checkIfExists: true)]).untar
}
else {
ch_star_index_raw = channel.value([[:], file(star_index, checkIfExists: true)])
}

// A supplied index may have been built with STAR 2.6.x, as the AWS iGenomes ones were,
// which STAR 2.7.4a and later refuse to read. `STAR_GENOMEPARAMS_UPGRADE` rewrites the
Expand All @@ -122,65 +131,65 @@ workflow PREPARE_GENOME {
}

//
// Uncompress Salmon index or generate from scratch if required
// MODULE: UNTAR_SALMON_INDEX and SALMON_INDEX
//

// `star_salmon` quantifies the STAR transcriptome alignments, which needs no index, so an
// index is only built for the `salmon` pseudo aligner
ch_salmon_index = channel.empty()
if (params.source == 'fastq' && (params.pseudo_aligner == 'salmon' || params.aligner == 'star_salmon')) {
if (source == 'fastq' && (pseudo_aligner == 'salmon' || aligner == 'star_salmon')) {
if (salmon_index) {
if (salmon_index.endsWith('.tar.gz')) {
ch_salmon_index = UNTAR_SALMON_INDEX([[:], salmon_index]).untar.map { _meta, index -> index }
ch_salmon_index = UNTAR_SALMON_INDEX([[:], file(salmon_index, checkIfExists: true)]).untar
}
else {
ch_salmon_index = channel.value([[:], file(salmon_index, checkIfExists: true)])
}
}
else {
if (params.pseudo_aligner == 'salmon') {
SALMON_INDEX(
ch_fasta.map { _meta, fa -> fa },
ch_transcript_fasta.map { _meta, tr -> tr },
)
ch_salmon_index = SALMON_INDEX.out.index
}
else if (pseudo_aligner == 'salmon') {
ch_salmon_index = SALMON_INDEX(
ch_fasta.map { _meta, fa -> fa },
ch_transcript_fasta.map { _meta, tr -> tr },
).index.map { index -> [[:], index] }
}
}

//
// Uncompress DEXSeq GFF annotation file if required
// MODULE: GUNZIP_GFF_DEXSEQ
//

ch_dexseq_gff = channel.empty()
if (gff_dexseq) {
if (gff_dexseq.endsWith('.gz')) {
GUNZIP_GFF_DEXSEQ([[:], gff_dexseq])
ch_dexseq_gff = GUNZIP_GFF_DEXSEQ.out.gunzip
ch_dexseq_gff = GUNZIP_GFF_DEXSEQ([[:], file(gff_dexseq, checkIfExists: true)]).gunzip
}
else {
ch_dexseq_gff = channel.value([[:], file(gff_dexseq, checkIfExists: true)])
}
}

//
// Uncompress SUPPA TPM file if required
// MODULE: GUNZIP_SUPPA_TPM
//

ch_suppa_tpm = channel.empty()
if (suppa_tpm) {
if (suppa_tpm.endsWith('.gz')) {
GUNZIP_SUPPA_TPM([[:], suppa_tpm])
ch_suppa_tpm = GUNZIP_SUPPA_TPM.out.gunzip.map { _meta, tpm -> tpm }
ch_suppa_tpm = GUNZIP_SUPPA_TPM([[:], file(suppa_tpm, checkIfExists: true)]).gunzip
}
else {
ch_suppa_tpm = channel.value([[:], file(suppa_tpm, checkIfExists: true)])
}
}

emit:
fasta = ch_fasta.map { _meta, fa -> fa } // path: genome.fasta
fai = ch_fai // path: genome.fai
chrom_sizes = ch_chrom_sizes // path: genome.sizes
gtf = ch_gtf.map { _meta, out_gtf -> out_gtf } // path: genome.gtf
transcript_fasta = ch_transcript_fasta.map { _meta, fa -> fa } // path: transcript.fasta
star_index = ch_star_index.map { _meta, index -> index } // path: star/index/
salmon_index = ch_salmon_index // path: salmon/index/
dexseq_gff = ch_dexseq_gff.map { _meta, dexseq_gff -> dexseq_gff } // path: dexseq.gff
suppa_tpm = ch_suppa_tpm // path: suppa.tpm
fasta = ch_fasta.map { _meta, fa -> fa } // channel: path(genome.fasta)
fai = SAMTOOLS_FAIDX.out.fai // channel: [ val(meta), path(genome.fasta.fai) ]
chrom_sizes = SAMTOOLS_FAIDX.out.sizes // channel: [ val(meta), path(genome.fasta.sizes) ]
gtf = ch_gtf.map { _meta, out_gtf -> out_gtf } // channel: path(genome.gtf)
transcript_fasta = ch_transcript_fasta.map { _meta, fa -> fa } // channel: path(transcripts.fasta)
star_index = ch_star_index.map { _meta, index -> index } // channel: path(star/index/)
salmon_index = ch_salmon_index.map { _meta, index -> index } // channel: path(salmon/index/)
dexseq_gff = ch_dexseq_gff.map { _meta, dexseq_gff -> dexseq_gff } // channel: path(dexseq.gff)
suppa_tpm = ch_suppa_tpm.map { _meta, tpm -> tpm } // channel: path(suppa.tpm)
}
Loading
Loading