我遇到了一个问题,这个问题在文件夹之间似乎并不一致。
从本质上讲,我认为我有一个Snakemake管道,可以将文件复制到文件夹中(不同子文件夹有不同的目的地)。我目前正在用一些Python字典以及2个通配符值来实现这一点。
但是,我目前遇到一个问题,我认为这是由于{outf}
和{sample}
通配符值不匹配造成的。
简述
我相信通配符是用rule all
:定义的
rule all:
input:
expand(os.path.join("{outf}","{sample}","methods.txt"), outf=OUTPREFIXES, sample=SAMPLES)
在我将在下面描述的例子中:
{outf}
和{sample}
的配对对于input
是正确的{outf}
和{sample}
的配对在output
的日志输出中不正确{outf}
和{sample}
的配对在wildcards
的日志输出中不正确
其他详细信息
我正在删除一些与确切格式相关的细节,但代码基本如下:
import pandas as pd
import os
import re
data = pd.read_csv("mapping_list.csv").set_index('Subfolder', drop=False)
SAMPLES = data["Subfolder"].tolist()
OUTPREFIXES = data["Output"].tolist()
def get_input_folder(wildcards):
return data.loc[wildcards.sample]["Input"]
def get_output_folder(wildcards):
return data.loc[wildcards.sample]["Output"]
rule all:
input:
expand(os.path.join("{outf}","{sample}","methods.txt"), outf=OUTPREFIXES, sample=SAMPLES)
rule copy_folders:
input:
infolder = directory(get_input_folder),
outfolder = directory(get_output_folder),
output:
os.path.join("{outf}","{sample}","methods.txt"),
resources:
mem_mb=2000,
cpus=1
shell:
'''
SHOUT1={input.outfolder}
...
cp -R {input.infolder} $SHOUT1
TEMPSAMPLE=$(basename {input.infolder})
SHEND={input.outfolder}/$TEMPSAMPLE
...
cp ../methods.txt $SHEND
'''
我收到以下错误消息:
Waiting at most 5 seconds for missing files.
MissingOutputException in line 22 of /path/to/Snakefile:
Missing files after 5 seconds:
[Variable Destination Folder B]/[Sample A]/methods.txt
我相信我可以在日志的早期部分看到问题:
rule copy_folders:
input: /common/folder/path/[Sample A], [Variable Destination Folder A]
output: [Variable Destination Folder B]/[Sample A]/methods.txt
jobid: 171
wildcards: outf=[Variable Destination Folder B], sample=[Sample A]
resources: mem_mb=2000, cpus=1
我有一个样本表,其中各种文件夹与一个唯一的样本ID配对。在给定的行中,您会发现[Sample A]
和[Variable Destination Folder A]
。在另一条线上,你会发现[Sample B]
和[Variable Destination Folder B]
等
换句话说,前一步中wildcards
的不匹配与错误消息相匹配,因为它描述了一个不应该在该点创建的文件(因为对于不同的行"a"one_answers"B",{outf}
和{sample}
的值没有正确匹配)
不严格需要方法.txt文件。但是,我在尝试使用目录作为端点时遇到了问题,所以我复制了一个额外的文件,并将其用作端点。如果有帮助,我可以共享早期的代码。然而,对于一个不同的文件夹,要复制的子文件夹数量较少,目标文件夹也不那么复杂,类似于当前代码的东西似乎可以成功地工作。
我有一个早期版本的代码,试图确保shell环境变量是";本地";到每个文件夹。我认为使用";本地";导致自身出现问题,错误消息指示只能在函数中使用。
然而,如果使用shell代码的类似简化部分,则路径被填充如下:
local SHOUT1=[Variable Destination Folder A]
...
cp -R /common/folder/path/[Sample A] $SHOUT1
local TEMPSAMPLE=$(basename /common/folder/path/[Sample A])
local SHEND=[Variable Destination Folder A]/$TEMPSAMPLE
...
cp ../methods.txt $SHEND
换句话说,shell命令的路径看起来是正确的(全部用于示例映射文件中的"A"行)。我认为这是因为他们只使用了input
通配符值,因为我注意到了变量不匹配的问题。添加了一些疑难解答,以便能够处理名称中有空格的文件夹,其中同一脚本的不同部分需要使用"\">对">以正确运行),但我排除了这些文件夹,以尝试简化最直接的故障排除。但是,如果不能正确指定output
值,则无法运行Snakemake脚本。
如有任何故障排除方面的帮助,我们将不胜感激
我认为这应该是一个相对简单的例子,可以开始学习基本上是cp -R $INPUTSUBFOLDER $OUTPUTFOLDER
的Snakemake,但可能比我意识到的更复杂。
真诚,
Charles
对我来说,它似乎正确地将输入与copy_folders
规则配对,因为您使用的输入函数只使用sample
通配符来获取它。不过,对于输出,存在不匹配,因为如果您在不指定其他目标的情况下运行Snakefile,它需要您在rule all
中指定的sample
和outf
的所有组合。
如果您只想将[Sample A]
与[Variable Destination Folder A]
配对,依此类推,则需要更改Snakemake在rule all
中处理expand()
的方式。
现在,你所拥有的是
rule all:
input:
expand(os.path.join("{outf}","{sample}","methods.txt"), outf=OUTPREFIXES, sample=SAMPLES)
这将OUTPREFIXES
中的所有前缀与SAMPLES
中的所有样本配对,这是expand()
的标准行为。不过,您可以在expand()
中指定一个不同的组合函数——如果您只想将第一个样本与第一个目的地、第二个样本与第二个目的地等组合,那么您的rule all
应该使用zip
,如下所示:
rule all:
input:
expand(os.path.join("{outf}","{sample}","methods.txt"), zip, outf=OUTPREFIXES, sample=SAMPLES)
如果您提供一个样本表和最小的Snakefile来重现错误,这将有所帮助。
据我所见,[Variable Destination Folder B]/[Sample A]/methods.txt
会出现丢失文件错误,因为您没有实际创建该文件的代码。此外,在input
中列出outfolder
有点奇怪,但这可能是由于管道早期发生的事情?我会做:
rule copy_folders:
input:
infolder = get_input_folder,
output:
outfolder = directory(get_output_folder),
touch(os.path.join("{outf}","{sample}","methods.txt")),
resources: ...
shell: ...
我使用touch
来创建伪文件methods.txt
,该文件表示规则完成——可能还有其他/更好的方法来处理这种情况。
请注意,directory
函数不应在输入指令中使用。