Я пытаюсь запустить конвейер nextflow, но выходной файл не создается.
Файл main.nf выглядит так:
#!/usr/bin/env nextflow
nextflow.enable.dsl=2
process my_script {
"""
Rscript script.R
"""
}
workflow {
my_script
}
В моем nextflow.config у меня есть:
process {
executor = 'k8s'
container = 'rocker/r-ver:4.1.3'
}
Скрипт.R выглядит так:
FUN <- readRDS("function.rds");
input = readRDS("input.rds");
output = FUN(
singleCell_data_input = input[[1]], savePath = input[[2]], tmpDirGC = input[[3]]
);
saveRDS(output, "output.rds")
После запуска nextflow run main.nf output.rds не создается
Процессы Nextflow запускаются независимо и изолированы друг от друга внутри рабочего каталога. Чтобы ваш скрипт мог найти необходимые входные файлы, они должны быть локализованы внутри рабочего каталога процесса. Это должно быть сделано путем определения блока input и объявления файлов с использованием квалификатора пути, например:
params.function_rds = './function.rds'
params.input_rds = './input.rds'
process my_script {
input:
path my_function_rds
path my_input_rds
output:
path "output.rds"
"""
#!/usr/bin/env Rscript
FUN <- readRDS("${my_function_rds}");
input = readRDS("${my_input_rds}");
output = FUN(
singleCell_data_input=input[[1]], savePath=input[[2]], tmpDirGC=input[[3]]
);
saveRDS(output, "output.rds")
"""
}
workflow {
function_rds = file( params.function_rds )
input_rds = file( params.input_rds )
my_script( function_rds, input_rds )
my_script.out.view()
}
Точно так же сам скрипт нужно будет локализовать внутри рабочего каталога процесса. Чтобы избежать указания абсолютного пути к вашему R-скрипту (что вообще не сделало бы ваш рабочий процесс переносимым), можно просто встроить свой код, обязательно указав шебанг Rscript. Это работает, потому что скрипты процессов не ограничиваются Bash1.
Другой способ — сделать исполняемый файл Rscript и переместить его в каталог с именем bin
в корневом каталоге репозитория вашего проекта (то есть в том же каталоге, что и ваш сценарий «main.nf» Nextflow). Nextflow автоматически добавит эту папку в переменную среды $PATH
, и ваш скрипт станет автоматически доступным для каждого из ваших конвейерных процессов. Чтобы это работало, вам нужно каким-то образом передать входные файлы в качестве аргументов командной строки. Например:
params.function_rds = './function.rds'
params.input_rds = './input.rds'
process my_script {
input:
path my_function_rds
path my_input_rds
output:
path "output.rds"
"""
script.R "${my_function_rds}" "${my_input_rds}" output.rds
"""
}
workflow {
function_rds = file( params.function_rds )
input_rds = file( params.input_rds )
my_script( function_rds, input_rds )
my_script.out.view()
}
И ваш R-скрипт может выглядеть так:
#!/usr/bin/env Rscript
args <- commandArgs(trailingOnly = TRUE)
FUN <- readRDS(args[1]);
input = readRDS(args[2]);
output = FUN(
singleCell_data_input=input[[1]], savePath=input[[2]], tmpDirGC=input[[3]]
);
saveRDS(output, args[3])
@DenisaBuzan Не беспокойтесь! Пока он исполняемый (и находится в папке bin
), все, что вам нужно, это script.R
в вашем блоке сценария. Кроме того, не забудьте включить #!/usr/bin/env Rscript
shebang в верхней части вашего R-скрипта.
Таким образом, файл nf должен выглядеть так: #!/usr/bin/env Rscript nextflow.enable.dsl=2 process INDEX { """ Rscript script.R """ } workflow { // процесс вызывается как функция в блок рабочего процесса INDEX() }
@DenisaBuzan, упс... извините, я забыл о вводе файлов! Я обновил свой ответ, надеюсь, он имеет больше смысла!
Прежде всего большое спасибо за комплексный ответ. Я хотел бы спросить, как должен выглядеть файл nf для другой стороны? Сценарий R меняется каждый месяц, и было бы полезно также не менять файл nf.