Snakemake - 在调用外部脚本之前加载集群模块
Snakemake - load cluster modules before an external script is called
在snakemake中,你可以像这样调用外部脚本:
rule NAME:
input:
"path/to/inputfile",
"path/to/other/inputfile"
output:
"path/to/outputfile",
"path/to/another/outputfile"
script:
"path/to/script.R"
这样可以方便地访问 R 脚本中名为 snakemake
的 S4 对象。
现在在我的例子中,我在 SLURM 集群上 运行ning snakemake,我需要在执行 Rscript 之前用 module load R/3.6.0
加载 R,否则作业将 return:
/usr/bin/bash: Rscript: command not found
我如何告诉 snakemake 这样做?如果我 运行 将规则作为 shell 而不是脚本,不幸的是我的 R 脚本无法访问 snakemake
对象,因此这不是理想的解决方案:
shell:
"module load R/3.6.0;"
"Rscript path/to/script.R"
您不能使用 script
标签调用 shell 命令。您肯定必须使用 shell
标签。您始终可以将输入和输出添加为参数:
rule NAME:
input:
in1="path/to/inputfile",
in2="path/to/other/inputfile"
output:
out1="path/to/outputfile",
out2="path/to/another/outputfile"
shell:
"""
module load R/3.6.0
Rscript path/to/script.R {input.in1} {input.in2} {output.out1} {output.out2}
"""
并在 R 脚本中获取参数:
args=commandArgs(trailingOnly=TRUE)
inFile1=args[1]
inFile2=args[2]
outFile1=args[3]
outFile2=args[4]
conda环境的使用:
您可以指定用于特定规则的 conda 环境:
rule NAME:
input:
in1="path/to/inputfile",
in2="path/to/other/inputfile"
output:
out1="path/to/outputfile",
out2="path/to/another/outputfile"
conda: "r.yml"
script:
"path/to/script.R"
在你的 r.yml 文件中:
name: rEnv
channels:
- r
dependencies:
- r-base=3.6
然后当你 运行 snakemake:
snakemake .... --use-conda
Snakemake 将在 运行ning 之前安装所有环境,并且每个环境都将在发送到 slurm 的作业中激活。
如果您关心的是在 Rscript 命令中按名称调用参数,您可能有这样的东西(基本上是 Eric 的回答的扩展):
rule NAME:
input:
in1="path/to/inputfile",
in2="path/to/other/inputfile"
output:
out1="path/to/outputfile",
out2="path/to/another/outputfile"
shell:
r"""
module load R/3.6.0
Rscript path/to/script.R \
inFile1={input.in1} inFile2={input.in2} \
outFile1={output.out1} outFile2={output.out2}
"""
然后在 script.R
中通过解析命令行访问每个参数:
args <- commandArgs(trailingOnly= TRUE)
for(x in args){
if(grepl('^inFile1=', x)){
inFile1 <- sub('^inFile1=', '', x)
}
else if(grepl('^inFile2=', x)){
inFile2 <- sub('^inFile2=', '', x)
}
else if(grepl('^outFile1=', x)){
outFile1 <- sub('^outFile1=', '', x)
}
else if(grepl('^outFile2=', x)){
outFile2 <- sub('^outFile2=', '', x)
}
else {
stop(sprintf('Unrecognized argument %s', x))
}
}
# Do stuff with inFile1, inFile2, etc...
还要考虑一些专为解析命令行而设计的库,我自己对 argparse for R
非常满意
也许你正在寻找 envmodules,它是激活集群模块的 snakemake 指令,就像模块加载一样;
rule your_rule:
input:
output:
envmodules:
"R/3.6.0"
shell:
"some Rscript"
在snakemake中,你可以像这样调用外部脚本:
rule NAME:
input:
"path/to/inputfile",
"path/to/other/inputfile"
output:
"path/to/outputfile",
"path/to/another/outputfile"
script:
"path/to/script.R"
这样可以方便地访问 R 脚本中名为 snakemake
的 S4 对象。
现在在我的例子中,我在 SLURM 集群上 运行ning snakemake,我需要在执行 Rscript 之前用 module load R/3.6.0
加载 R,否则作业将 return:
/usr/bin/bash: Rscript: command not found
我如何告诉 snakemake 这样做?如果我 运行 将规则作为 shell 而不是脚本,不幸的是我的 R 脚本无法访问 snakemake
对象,因此这不是理想的解决方案:
shell:
"module load R/3.6.0;"
"Rscript path/to/script.R"
您不能使用 script
标签调用 shell 命令。您肯定必须使用 shell
标签。您始终可以将输入和输出添加为参数:
rule NAME:
input:
in1="path/to/inputfile",
in2="path/to/other/inputfile"
output:
out1="path/to/outputfile",
out2="path/to/another/outputfile"
shell:
"""
module load R/3.6.0
Rscript path/to/script.R {input.in1} {input.in2} {output.out1} {output.out2}
"""
并在 R 脚本中获取参数:
args=commandArgs(trailingOnly=TRUE)
inFile1=args[1]
inFile2=args[2]
outFile1=args[3]
outFile2=args[4]
conda环境的使用:
您可以指定用于特定规则的 conda 环境:
rule NAME:
input:
in1="path/to/inputfile",
in2="path/to/other/inputfile"
output:
out1="path/to/outputfile",
out2="path/to/another/outputfile"
conda: "r.yml"
script:
"path/to/script.R"
在你的 r.yml 文件中:
name: rEnv
channels:
- r
dependencies:
- r-base=3.6
然后当你 运行 snakemake:
snakemake .... --use-conda
Snakemake 将在 运行ning 之前安装所有环境,并且每个环境都将在发送到 slurm 的作业中激活。
如果您关心的是在 Rscript 命令中按名称调用参数,您可能有这样的东西(基本上是 Eric 的回答的扩展):
rule NAME:
input:
in1="path/to/inputfile",
in2="path/to/other/inputfile"
output:
out1="path/to/outputfile",
out2="path/to/another/outputfile"
shell:
r"""
module load R/3.6.0
Rscript path/to/script.R \
inFile1={input.in1} inFile2={input.in2} \
outFile1={output.out1} outFile2={output.out2}
"""
然后在 script.R
中通过解析命令行访问每个参数:
args <- commandArgs(trailingOnly= TRUE)
for(x in args){
if(grepl('^inFile1=', x)){
inFile1 <- sub('^inFile1=', '', x)
}
else if(grepl('^inFile2=', x)){
inFile2 <- sub('^inFile2=', '', x)
}
else if(grepl('^outFile1=', x)){
outFile1 <- sub('^outFile1=', '', x)
}
else if(grepl('^outFile2=', x)){
outFile2 <- sub('^outFile2=', '', x)
}
else {
stop(sprintf('Unrecognized argument %s', x))
}
}
# Do stuff with inFile1, inFile2, etc...
还要考虑一些专为解析命令行而设计的库,我自己对 argparse for R
非常满意也许你正在寻找 envmodules,它是激活集群模块的 snakemake 指令,就像模块加载一样;
rule your_rule:
input:
output:
envmodules:
"R/3.6.0"
shell:
"some Rscript"