Input param not working as conditional switch in Nextflow processes

Viewed 285

I am trying to pass in a parameter to Nextflow that I can use to turn a process on or off, to no avail.

Moreover, when I print the parameter in the log file the case always changes, which seems odd to me (i.e., TRUE turns to true). I have tried setting the conditional statement to match "TRUE" or "true", given this behavior, but neither seems to work.

Here is some code to illustrate the issue.

params.force = "FALSE"
params.in = 1

log.info """\
         Force: $params.force
         """
         .stripIndent()

process tester {
  input:
    val x from params.in

  output:
      stdout testerOut

  when:
    params.force == "TRUE"

  script:
      """
      echo "foo"
      """
  }

  testerOut.view()

If this file is saved as testnf and is run via "nextflow run testnf --force "TRUE" " the process will not run. The output is:

N E X T F L O W ~ version 21.10.0 Launching testnf [soggy_lorenz] - revision: a7399aad3c Force: true

[- ] process > tester -

The goal is for users to pass in parameters that turn off or on certain processes. This seems like a common use case, but I am stuck. Cheers for any help!

2 Answers

Pallie is correct:

Nextflow automatically converts the --force TRUE param to a boolean

This is because the Nextflow command-line parameter values TRUE and FALSE (case insensitive) are special and will return Boolean.TRUE and Boolean.FALSE, respectively1. When you print (or log) these parameters, you are really just accessing a Boolean that represents the special truth values: true and false.

Be aware that parameters defined inside your Nextflow script will not be coerced. For example, setting params.force = "FALSE" inside you script will just give you a plain old java.lang.String if --force is not specified on the command-line. The problem is that if you do specify --force on the command-line, you'll get a different type: a java.lang.Boolean. The solution is to set params.force to a Boolean value inside your script:

params.force = false

println("Force: ${params.force}")


process test {

    echo true

    when:
    params.force

    """
    echo "foo"
    """
}

Some tests, with expected results:

nextflow run test.nf 
N E X T F L O W  ~  version 21.04.3
Launching `test.nf` [clever_mccarthy] - revision: e7a5148ea1
Force: false
[-        ] process > test -

$ nextflow run test.nf --force
N E X T F L O W  ~  version 21.04.3
Launching `test.nf` [distraught_jepsen] - revision: e7a5148ea1
Force: true
executor >  local (1)
[d0/c9a3d2] process > test [100%] 1 of 1 ✔
foo

$ nextflow run test.nf --force FALSE
N E X T F L O W  ~  version 21.04.3
Launching `test.nf` [astonishing_feynman] - revision: e7a5148ea1
Force: false
[-        ] process > test -

$ nextflow run test.nf --force True
N E X T F L O W  ~  version 21.04.3
Launching `test.nf` [sleepy_sammet] - revision: e7a5148ea1
Force: true
executor >  local (1)
[b5/9fac0f] process > test [100%] 1 of 1 ✔
foo

This last example shows that non-empty strings are coerced to true according to Groovy truth:

$ nextflow run test.nf --force foobar
N E X T F L O W  ~  version 21.04.3
Launching `test.nf` [trusting_hilbert] - revision: e7a5148ea1
Force: foobar
executor >  local (1)
[d1/c1b190] process > test [100%] 1 of 1 ✔
foo

Nextflow automatically converts the --force TRUE param to a boolean, so just change it to:

params.force = "FALSE"
params.in = 1

log.info """\
         Force: $params.force
         """
         .stripIndent()

process tester {
  input:
    val x from params.in

  output:
      stdout testerOut

  when:
    params.force

  script:
      """
      echo "foo"
      """
  }

  testerOut.view()

output:

$ ~/nextflow run main.nf
N E X T F L O W  ~  version 21.10.6
Launching `main.nf` [high_hamilton] - revision: cac46af672
Force: FALSE

executor >  local (1)
[1e/5cb38e] process > tester [100%] 1 of 1 ✔
foo

Related