如何解决如何处理snakemake配置文件中提供的ftp链接?
我正在尝试构建一个 snakemake 工作流程,如果本地文件存在,它将提供指向本地文件的符号链接,或者如果文件不存在,则会下载该文件并将其集成到工作流程中。为此,我使用了两个具有相同输出的规则,并使用 ruleorder 优先考虑链接规则(下面的 ln_fastq_pe)。
在执行工作流之前知道文件是否存在。文件路径或 ftp 链接在制表符分隔的配置文件中提供,工作流使用该文件来读取示例。 例如samples.txt 的内容:
id sample_name fq1 fq2
b test_paired resources/SRR1945436_1.fastq.gz resources/SRR1945436_2.fastq.gz
c test_paired2 ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR194/005/SRR1945435/SRR1945435_1.fastq.gz ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR194/005/SRR1945435/SRR1945435_2.fastq.gz
此处工作流程中的相关代码:
import pandas as pd
from snakemake.remote.FTP import RemoteProvider as FTPRemoteProvider
FTP = FTPRemoteProvider()
configfile: "config/config.yaml"
samples = pd.read_table("config/samples.tsv").set_index("id",drop=False)
all_ids=list(samples["id"])
ruleorder: ln_fastq_pe > dl_fastq_pe
rule dl_fastq_pe:
"""
download file from ftp link
"""
input:
fq1=lambda wildcards: FTP.remote(samples.loc[wildcards.id,"fq1"],keep_local=True),fq2=lambda wildcards: FTP.remote(samples.loc[wildcards.id,"fq2"],keep_local=True)
output:
"resources/fq/{id}_1.fq.gz","resources/fq/{id}_2.fq.gz"
shell:
"""
mv {input.fq1} {output[0]}
mv {input.fq2} {output[1]}
"""
rule ln_fastq_pe:
"""
link file
"""
input:
fq1=lambda wildcards: samples.loc[wildcards.id,fq2=lambda wildcards: samples.loc[wildcards.id,"fq2"]
output:
"resources/fq/{id}_1.fq.gz","resources/fq/{id}_2.fq.gz"
shell:
"""
ln -sr {input.fq1} {output[0]}
ln -sr {input.fq2} {output[1]}
"""
运行此工作流时,我收到以下错误,指向描述 ln_fastq_pe 规则的行。
WorkflowError in line 58 of /path/to/Snakefile:
Function did not return str or list of str.
我认为错误在于我如何描述 dl_fastq_pe 规则中 samples.txt 配置文件中的 FTP 链接。描述表格配置文件中给出的 FTP 链接的正确方法是什么,以便 snakemake 理解它们并可以在工作流程中下载和使用这些文件?
另外,是否可以做我想做的事情,这种方法能让我到达那里吗?我尝试了其他解决方案(例如,使用 python 代码检查文件是否存在,如果存在则执行一组 shell 命令,如果不存在则执行另一组)均无济于事。
解决方法
您正在尝试将对象从 pandas
传递给 Snakemake。后者期望规则的输入部分中类型为 str
或 list[str]
的值,但您提供的值 (samples.loc[wildcards.id,"fq1"]
) 的类型为 pandas.core.frame.DataFrame
或 {{1 }}。您需要将它们转换为 Snamemake 所期望的。例如,这可能有帮助:pandas.core.series.Series
。
我想出了如何做到这一点,方法是省略输入,而是通过 params 从 samples.tsv 读取字段并将这两个规则合并为一个规则。与输入不同,Snakemake 对通过参数读取的内容并不挑剔。然后我使用 test
命令询问文件是否存在。如果存在,请继续使用符号链接,如果不存在,请使用 wget 下载。
解决方法如下:
import os
import pandas as pd
samples = pd.read_table("config/samples.tsv").set_index("id",drop=False)
all_ids=list(samples["id"])
rule all:
input:
expand("resources/fq/{id}_1.fq.gz",id=all_ids),expand("resources/fq/{id}_2.fq.gz",id=all_ids)
rule dl_fastq_pe:
"""
if file exists,symlink. If file doesn't exist,download to resources
"""
params:
fq1=lambda wildcards: samples.loc[wildcards.id,"fq1"],fq2=lambda wildcards: samples.loc[wildcards.id,"fq2"]
output:
"resources/fq/{id}_1.fq.gz","resources/fq/{id}_2.fq.gz"
shell:
"""
if test -f {params.fq1}
then
ln -sr {params.fq1} {output[0]}
ln -sr {params.fq2} {output[1]}
else
wget --no-check-certificate -O {output[0]} {params.fq1}
wget --no-check-certificate -O {output[1]} {params.fq2}
fi
"""
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。