Convert value channel of length > 1 into list inside process #3889
-
Is there a way to convert nextflow.enable.dsl = 2
process myProcess {
input:
val myVal
output:
file 'output.txt'
script:
def all_true = myVal.all()
"""
echo "${all_true}"
touch output.txt
"""
}
workflow {
valChannel = Channel.of(true, true, false).collect()
myProcess(valChannel)
} Error massage: nextflow run test_value_channel.nf
N E X T F L O W ~ version 22.10.1
Launching `test_value_channel.nf` [big_mercator] DSL2 - revision: baba729390
[- ] process > myProcess -
Error executing process > 'myProcess'
Caused by:
No signature of method: nextflow.util.ArrayBag.all() is applicable for argument types: () values: []
Possible solutions: tail(), tail(), any(), add(java.lang.Object), any(groovy.lang.Closure), any(groovy.lang.Closure) -- Check script 'test_value_channel.nf' at line: 12
Source block:
def all_true = myVal.all()
"""
echo "${all_true}"
touch output.txt
"""
Tip: view the complete command output by changing to the process work dir and entering the command `cat .command.out` updateI learnt that value channel should be of length 1, so I come up with this workaround, which I do not know if it's clean or neat. Any improving is welcome: nextflow.enable.dsl = 2
process myProcess {
input:
val sum
val count
output:
file 'output.txt'
script:
def all = sum == count
def any = sum != 0
"""
echo "${all}"
echo "${any}"
touch output.txt
"""
}
workflow {
valSum = Channel.of(1, 1, 0).sum()
valCount = Channel.of(1, 1, 0).count()
myProcess(valSum, valCount)
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
The Besides, within processes you deal with regular variables, not channels, so if you want to apply a function to a list or something, you just do Groovy and it should be fine. Instead of using
This change to your original code made it work here. Check the output: N E X T F L O W ~ version 23.03.0-edge
Launching `asd.nf` [gigantic_mestorf] DSL2 - revision: dfba3a0024
executor > local (1)
[db/8dcded] process > myProcess [100%] 1 of 1 ✔
➜ ~ tree work/db/8dcdedcd80f5965a44c84537e3fa1f/
work/db/8dcdedcd80f5965a44c84537e3fa1f/
└── output.txt
1 directory, 1 file |
Beta Was this translation helpful? Give feedback.
-
Your original solution was fine except that you should use So there are two valid approaches: // your approach
Channel.of(true, true, false).collect()
// Channel.value() approach (more concise)
Channel.value([true, true, false]) |
Beta Was this translation helpful? Give feedback.
The
Channel.of
channel factory creates a queue channel, not a value channel. To create a value channel, you either use theChannel.value
channel factory, or a channel operator that returns a single element, such asfirst
,collect
,sum
andcount
, so you did no workaround. You just did what you'd usually do if you want a value channel 😄Besides, within processes you deal with regular variables, not channels, so if you want to apply a function to a list or something, you just do Groovy and it should be fine. Instead of using
all
, use.every { it == true }
, e.g.:This change to your original code made it work here. Check the output: