Я новичок в Nextflow и пытаюсь обработать несколько файлов в рабочем процессе. Количество этих файлов более 300, поэтому хотелось бы не вставлять его в командную строку как вариант. Итак, что я сделал, так это создал файл со всеми именами файлов, которые мне нужно обработать, но я не уверен, как передать его в процесс. Это то, что я пробовал:
params.SRRs = "srr_ids.txt"
process tmp {
input:
file ids
output:
path "*.txt"
script:
'''
while read id; do
touch ${id}.txt;
echo ${id} > ${id}.txt;
done < $ids
'''
}
workflow {
tmp(params.SRRs)
}
Предполагается, что скрипт читает файл srr_ids.txt
и создает файлы, в которых есть их идентификаторы (просто тестирование на небольшой задаче). В журнале ошибок написано, что переменная id не привязана, но я не понимаю, почему. Каков обычный способ передачи большого количества имен файлов в конвейер? Должен ли я написать какой-то другой процесс, который анализирует список?
Возможно, в вашем вопросе опечатка, но на самом деле ошибка в том, что переменная ids
не привязана:
Command error:
.command.sh: line 5: ids: unbound variable
Проблема в том, что когда вы используете строку скрипта с одинарными кавычками, вы не сможете получить доступ к переменным Nextflow в своем блоке скрипта. Вы можете либо определить свой скрипт, используя строку с двойными кавычками, либо экранировать переменные оболочки:
params.SRRs = "srr_ids.txt"
process tmp {
input:
path ids
output:
path "*.txt"
script:
"""
while read id; do
touch "\${id}.txt"
echo "\${id}" > "\${id}.txt"
done < "${ids}"
"""
}
workflow {
SRRs = file(params.SRRs)
tmp(SRRs)
}
Или используйте блок оболочки , который использует символ восклицательного знака !
в качестве заполнителя переменной для переменных Nextflow. Это позволяет использовать как переменные Nextflow, так и переменные оболочки в одном и том же фрагменте кода без необходимости экранирования каждой из переменных оболочки:
params.SRRs = "srr_ids.txt"
process tmp {
input:
path ids
output:
path "*.txt"
shell:
'''
while read id; do
touch "${id}.txt"
echo "${id}" > "${id}.txt"
done < "!{ids}"
'''
}
workflow {
SRRs = file(params.SRRs)
tmp(SRRs)
}
Каков обычный способ передачи большого количества имен файлов в трубопровод?
Обычный способ, я думаю, состоит в том, чтобы фактически предоставить один (или несколько) шаблонов глобусов методу фабрики каналов fromPath. Например:
params.SRRs = "./path/to/files/SRR*.fastq.gz"
workflow {
Channel
.fromPath( params.SRRs )
.view()
}
Результаты:
$ nextflow run main.nf
N E X T F L O W ~ version 22.04.4
Launching `main.nf` [sleepy_bernard] DSL2 - revision: 30020008a7
/home/steve/working/stackoverflow/73702711/path/to/files/SRR1910483.fastq.gz
/home/steve/working/stackoverflow/73702711/path/to/files/SRR1910482.fastq.gz
/home/steve/working/stackoverflow/73702711/path/to/files/SRR1448795.fastq.gz
/home/steve/working/stackoverflow/73702711/path/to/files/SRR1448793.fastq.gz
/home/steve/working/stackoverflow/73702711/path/to/files/SRR1448794.fastq.gz
/home/steve/working/stackoverflow/73702711/path/to/files/SRR1448792.fastq.gz
Если вместо этого вы предпочитаете передавать список имен файлов, как в вашем примере, используйте либо оператор splitCsv , либо оператор splitText, чтобы получить то, что вы хотите. Например:
params.SRRs = "srr_ids.txt"
workflow {
Channel
.fromPath( params.SRRs )
.splitText() { it.strip() }
.view()
}
Результаты:
$ nextflow run main.nf
N E X T F L O W ~ version 22.04.4
Launching `main.nf` [fervent_ramanujan] DSL2 - revision: 89a1771d50
SRR1448794
SRR1448795
SRR1448792
SRR1448793
SRR1910483
SRR1910482
Должен ли я написать какой-то другой процесс, который анализирует список?
Возможно, вам это не нужно. Я чувствую, что ваш код может выиграть от использования фабричного метода fromSRA , но у нас недостаточно деталей, чтобы сказать так или иначе. Если вам нужно, вы можете просто написать функцию, которая возвращает канал.