Я хочу собирать результаты процесса Nextflow в том же порядке, в котором они были введены.
Я знаю, что могу просто передать значения со всех каналов через все процессы. Это гарантирует, что пары будут переданы всем процессам вместе. Однако это решение не работает, когда вы начинаете добавлять несколько процессов, потому что оно уничтожает способность этих процессов работать параллельно. Например, в представленном примере кода, если вы добавите процесс add_twenty, а затем соберете выходные данные как из add_ten, add_twenty, так и из vals2.
Другое возможное решение, с которым я играл, состояло в том, чтобы добавить ключ к каждому значению в исходных каналах, что по существу превращает исходные каналы в словарь (т.е. хэш). Но я не мог заставить это работать. При необходимости могу привести пример.
Я создал игрушечный пример, в котором я создаю два канала, отправляю один в процесс, а затем отправляю обработанный вывод и один из исходных каналов в новый процесс.
vals1 = Channel.from(1,2,3,4,5)
vals2 = Channel.from(1,2,3,4,5)
process add_ten {
input:
val(vals1)
output:
val(new_int) into new_vals1
exec:
new_int = vals1 + 10
}
process pair {
echo true
input:
val(new_vals1)
val(vals2)
script:
"""
echo "${new_vals1}, ${vals2}"
"""
}
То, что я надеялся увидеть, было чем-то вроде этого, когда цифры совпадают:
11, 1
12, 2
13, 3
14, 4
15, 5
Даже если бы эти строки были перепутаны, все было бы в порядке, пока пары сохранялись. Например,
14, 4
11, 1
13, 3
15, 5
12, 2
Однако то, что я вижу, это:
15, 1
13, 2
11, 3
12, 4
14, 5
Вы можете сделать это, используя кортежи и оператор объединения nextflow:
https://www.nextflow.io/docs/latest/operator.html#combine
Вот пример:
vals1 = Channel.from([1, 'the'], [2, 'brown'], [3, 'jumps'], [4, 'a'], [5, 'fox'])
vals2 = Channel.from([5,'.'], [4, 'lazy'], [3, 'over'], [2, 'fox'], [1, 'quick'])
vals1
.combine(vals2, by: 0)
.println()
Когда вы запустите это, используйте опцию -ansi-log false
.
Ваш пример с некоторыми изменениями выглядит так:
vals1 = Channel.from(1,2,3,4,5)
vals2 = Channel.from(1,2,3,4,5)
i=0; vals1.map{[i++, it]}.view().set{keyed_vals1}
j=0; vals2.map{[j++, it]}.view().set{keyed_vals2}
process add_ten {
input: set val(key), val(vals1) from keyed_vals1
output: set val(key), val(new_vals1) into new_vals1
exec: new_vals1 = vals1 + 10
}
process pair {
echo true
tag "$key $one $two"
input: set val(key), val(one), val(two) from new_vals1.combine(keyed_vals2, by: 0).view()
script: "echo '${key} ${one} ${two}'"
}