nextflow-io / patterns

A curated collection of Nextflow implementation patterns
http://nextflow-io.github.io/patterns/
MIT License
332 stars 71 forks source link

Example for optional input in tuple? #42

Open ScottNortonPhD opened 1 year ago

ScottNortonPhD commented 1 year ago

I am trying to run a configuration where the input is a tuple of paths, some of which are optional. The pattern in this repository works for separate path inputs (or, so says the author), but extending it to my use case results in the error Not a valid path value: NO_FILE.

In this simple example demonstrating the issue, the input is a CSV file defining RNA-seq sample names, forward and reverse read fastqs, and a STAR genome index to align them to. The reverse read is optional.

My question to the community is how I can work around this issue.

Repository setup

nextflow.config

params {
manifest = null  // csv file name,R1,R2?,index
outdir = "outs"  // save output bams
}
profiles {
conda {
conda.enabled = true
process.conda = "star samtools"
}
}

main.nf


process MyProcess {
publishDir outdir, mode: "copy"
input:
tuple val(name), path(R1), path(R2), path(index)
path outdir
output:
path "${name}_Aligned.out.sortedByCoord.bam"
path "${name}_Aligned.out.sortedByCoord.bam.bai"
script:
R2_arg = R2.name == "NO_FILE" ? "" : R2
"""
STAR --readFilesIn $R1 $R2_arg --readFilesCommand gunzip -c \
--genomeDir $index --outSAMtype BAM SortedByCoordinate \
--outFileNamePrefix ${name}_
samtools index ${name}_Aligned.out.sortedByCoord.bam
"""
}

workflow { MyProcess( file(manifest).read().splitCsv(header: ["name", "R1", "R2", "index"]).map{it.R2 = it.R2 ?: "NO_FILE"}, params.outdir ) }


## Run
```bash
nextflow run main.nf [-profile conda] --manifest path/to/manifest.csv
mribeirodantas commented 1 year ago

Hello, Scott.

"NO_FILE" is a value, not a path. If you pass file("NO_FILE"), the process will accept the channel as valid. Check the code below. It does one thing is the input is a file, and something else if it's a string that equals NO_FILE:

process FOO {
  debug true
  input:
    path x
  output:
    stdout
  script:
    if (x.name == 'NO_FILE')
      """
      echo $x
      """
    else
      """
      cat $x
      """
}

workflow {
  // FOO(file('NO_FILE'))
  FOO(file('asd.nf'))
}