This is a test version of Biostars. For the public version, visit https://www.biostars.org.
Code Review: Nextflow pipeline for phage-bacteria assembly from Nanopore data

GitHub: https://github.com/eya146/nanopore-bacterial-pipeline

I built a Nextflow pipeline for phage-bacteria assembly from Nanopore long-read data. I would appreciate a code review before my interview next week. This is my first metagenomics pipeline. My experience is usually with human genomic data and reference genomes. So any feedback will be greatly appreciated.

Pipeline steps:

QC: NanoPlot

Trimming: Porechop

Filtering: Chopper

Assembly: Flye (--meta)

Polishing: Medaka

Assembly QC: QUAST

Gene prediction: PHANOTATE

Annotation: BLAST (Staph/Strep + viral databases)

Reporting: MultiQC

Results from test data:

Complete circular phage genome: 58.8 kb, 714x coverage

563 predicted proteins

QUAST: 1 contig, N50 = total length, 0 N's

The paradox: The Sample ID says 38phages_SaSt (expects Staph/Strep phages). BLAST hits show Vibrio, Klebsiella, and Pseudomonas phages. Only 14 of 563 proteins matched Staph/Strep. And I found 213 viral phage proteins.

What I know is missing: Docker, CI testing, better error handling. And I need to make the README file

Any feedback appreciated. Thank you!

nanopore nextflow code-review phage assembly

Have you tried asking ChatGPT (or your favorite AI tool) to do a code review? It can generate good pointers.

Where are the samples coming for? Are these just phage sequences?

2 answers

Well great job! If i where you i would rather use prebuilt module from nf-core Module, Docker/Conda, enhance subworkflow to modularized the pipeline and enhance reusability. I would also have a look at nf-core best practice.

Thanks! I used local modules because nf-core integration caused issues for standalone execution. Conda was chosen for Codespace compatibility and Docker is also available as an option in this pipeline. The pipeline is modular, so refactoring to nf-core style would be easy. Appreciate the feedback!

while your workflow might work this is not the usual good practice to build a NF workflow.

You should have a 'meta' associative array next to your path, the argument should be defined in a config file (see any nf-core module for more information). This greatly helps to parallelize things.

for example:

process CHOPPER {
    tag "Chopper"

    input:
    path reads
    val min_length
    val min_quality

    output:
    path "filtered.fastq", emit: filtered
    path "chopper_stats.txt", emit: stats

would be defined as

process CHOPPER {
    label "process_single"
    tag "${meta.id}"
    input:
       tuple val(meta),path(reads)

    output:
       tuple val(meta),path("*.fastq"), emit: filtered
      tuple val(meta),path("*stats.txt"), emit: stats
script:
    def min_length= task.ext.min_length?:1234
    def min_quality= task.ext.min_quality?:1234
    def prefix =  task.ext.prefix?:"${meta.id}.chopper"
"""
(...)
chopper  (....) > ${prefix}.fastq
(...)
}
`

and in the nextflow_config:

params {
  min_length = 100
  min_quality = 20
  }

process  {
withName: "CHOPPER" {
 ext.min_length = {"${params.min_length}" as int }
ext.min_quality = {"${params.min_quality}" as int }
 }

}

EDIT:

(grep -c "^@" filtered.fastq)

this is a bad way to count the number of records in a fastq file because '@' is a valid quality symbol.

you could use:

cat filtered.fastq | paste - - - - |wc -l

Log in to answer this question.