My process returns a list of tuples. How to create a channel that yields each tuple separately?
Indeed, I want to use the tuple's item as input of another process (here the multiply
process). I would want the calls to multiply
(i.e. one for each tuple in my_list_of_tuple
) to be able to run in parallel.
However, if I use:
my_process.out.my_returned_list
: I get only one element ([[1, 2], [3, 4], [5, 6]]
);my_process.out.my_returned_list.flatten()
: I also flatten the tuples and get 6 elements (1, 2, 3, 4, 5, 6
).Question: How to define a channel that will get 3 elements: [1, 2], [3, 4], [5, 6]
?
nextflow.enable.dsl=2
process my_process {
output:
val myList, emit: my_returned_list
exec:
myList = []
myList.add(tuple(1, 2))
myList.add(tuple(3, 4))
myList.add(tuple(5, 6))
}
process multiply {
input:
val left
val right
output:
val left_times_right
exec:
left_times_rigth = left * right
}
workflow {
my_process()
my_process.out.my_returned_list.view()
my_process.out.my_returned_list.flatten().view()
// <channel_to_be_defined>.map { i, j ->
// multiply(i, j)
// }
}
You can just use the flatMap
operator for this, for example:
process my_process {
output:
val myList, emit: my_returned_list
exec:
myList = []
myList.add(tuple(1, 2))
myList.add(tuple(3, 4))
myList.add(tuple(5, 6, 7))
}
process multiply {
input:
val factors
output:
tuple val(factors), val(the_product)
exec:
the_product = factors.inject { acc, num -> acc *= num }
}
workflow {
my_process()
my_factors = my_process.out.flatMap()
my_products = multiply( my_factors )
my_products.view { factors, product ->
"The product of ${factors.join(',')} is: ${product}"
}
}
Results:
$ nextflow run main.nf
N E X T F L O W ~ version 23.04.1
Launching `main.nf` [admiring_hilbert] DSL2 - revision: 0bafefce32
executor > local (4)
[9d/292489] process > my_process [100%] 1 of 1 ✔
[ec/94643b] process > multiply (1) [100%] 3 of 3 ✔
The product of 3,4 is: 12
The product of 5,6,7 is: 210
The product of 1,2 is: 2