回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<h2>初始工作流程</h2>
<p>我有一个snakefile,可以从成对的结束数据生成一些输出。在</p>
<p>在这个snakefile中,我有一个规则“安装”存储在配置文件(<code>get_raw_data</code>)中的给定信息的数据。在</p>
<p>然后我有一个规则,它使用这些数据生成工作流其余部分依赖的中间文件(<code>run_tophat</code>)。在</p>
<p>以下是这些规则的输入和输出(<code>OPJ</code>代表<code>os.path.join</code>):</p>
<pre><code>rule get_raw_data:
output:
OPJ(raw_data_dir, "{lib}_1.fastq.gz"),
OPJ(raw_data_dir, "{lib}_2.fastq.gz"),
</code></pre>
<p>(稍后将详细介绍该规则的实施情况)</p>
^{pr2}$
<p>我的主要原则是:</p>
<pre><code>rule all:
input:
expand(OPJ(output_dir, "{lib}", "junctions.bed"), lib=LIBS),
</code></pre>
<h2>将工作流扩展到单端数据</h2>
<p>我现在必须在单端数据上运行我的工作流。在</p>
<p>我希望避免最终输出具有不同的名称模式,这取决于数据是单端还是成对端。在</p>
<p>我可以很容易地将上述两个规则的变体用于单端数据(<code>get_raw_data_single_end</code>和{<cd6>}),它们的输入和输出如下:</p>
<pre><code>rule get_raw_data_single_end:
output:
OPJ(raw_data_dir, "{lib}.fastq.gz")
rule run_tophat_single_end:
input:
transcriptome = OPJ(annot_dir, "dmel-all-r5.9.gff"),
fq = OPJ(raw_data_dir, "{lib}.fastq.gz"),
output:
junctions = OPJ(output_dir, "{lib}", "junctions.bed"),
bam = OPJ(output_dir, "{lib}", "accepted_hits.bam"),
</code></pre>
<h2>如何为snakemake提供足够的信息来选择正确的规则路径?在</h2>
<p>配置文件包含有关<code>lib</code>通配符是否与单端数据或成对结尾数据关联的信息:库名称是<code>lib2raw</code>或<code>lib2raw_single_end</code>字典中的键(这两个字典都是从配置文件中读取的)。在</p>
<p>我不希望同一个库名在两个字典中都是一个键。因此,在某种意义上,我希望执行工作流的单端分支还是成对端分支并不含糊。在</p>
<p><code>get_raw_data</code>和{<cd5>}都使用函数<code>lib2data</code>(使用这些字典)来确定运行哪个shell命令来“安装”数据。在</p>
<p>以下是此函数的简化版本(实际的函数包含一个额外的分支,用于从SRR标识符生成数据命令):</p>
<pre><code>def lib2data(wildcards):
lib = wildcards.lib
if lib in lib2raw:
raw = lib2raw[lib]
link_1 = "ln -s %s %s_1.fastq.gz" % (raw.format(mate="1"), lib)
link_2 = "ln -s %s %s_2.fastq.gz" % (raw.format(mate="2"), lib)
return "%s\n%s\n" % (link_1, link_2)
elif lib in lib2raw_single_end:
raw = lib2raw_single_end[lib]
return "ln -s %s %s.fastq.gz\n" % (raw, lib)
else:
raise ValueError("Procedure to get raw data for %s unknown." % lib)
</code></pre>
<p>除了它们的输出之外,这两个<code>get_raw_data*</code>规则是相同的,其工作方式如下:</p>
<pre><code>params:
shell_command = lib2data,
shell:
"""
(
cd {raw_data_dir}
{params.shell_command}
)
"""
</code></pre>
<p>snakemake是否能够确定正确的规则路径?给定的信息不是在规则输入和输出中编码的,而是只在配置文件和函数中编码的?在</p>
<p>看来情况并非如此。实际上,我正在尝试测试我的新snakefile(添加了<code>*_single_end</code>规则),<del>,但是在<code>get_raw_data</code>规则的执行过程中,<code>KeyError</code>发生了,而为其执行规则的库与单端数据关联</del>。在</p>
<p>如何实现所需的行为(一个双分支工作流能够使用配置中的信息来选择正确的分支)?在</p>
<h3>编辑:<code>KeyError</code>是由于<code>lib2data</code></h3>中的错误造成的
<p>在使用正确的字典获取与库名称关联的数据后,我出现了以下错误:</p>
<pre><code>AmbiguousRuleException:
Rules run_tophat and run_tophat_single_end are ambiguous for the file tophat_junction_discovery_revision_supplement/HWT3/junctions.bed.
Expected input files:
run_tophat: ./HWT3_1.fastq.gz ./HWT3_2.fastq.gz Annotations/dmel-all-r5.9.gff
run_tophat_single_end: ./HWT3.fastq.gz Annotations/dmel-all-r5.9.gff
</code></pre>
<h3>编辑2:向<code>get_raw_data*</code>规则添加输入</h3>
<p>在阅读了<a href="https://groups.google.com/d/msg/Snakemake/jVWApJ7gZA8/Euz3aV7THOsJ" rel="nofollow noreferrer">this post on the snakemake mailing list</a>之后,我试图在规则中添加一些输入以避免歧义。在</p>
<pre><code>def lib2data_input(wildcards):
lib = wildcards.lib
if lib in lib2raw:
raw = lib2raw[lib]
return [raw.format(mate="1"), raw.format(mate="2")]
elif lib in lib2raw_single_end:
raw = lib2raw_single_end[lib]
return [raw]
else:
raise ValueError("Procedure to get raw data for %s unknown." % lib)
rule get_raw_data:
input:
lib2data_input
# [same output, params and shell as before]
# [same modification for the single-end case]
</code></pre>
<p>这将产生一个<del><code>MissingInputException</code>。奇怪的是,据说丢失的文件确实存在。这个把戏有用吗?</del>(无法复制此项,现在将导致:)</p>
^{9}$
<p>我为“数据安装”规则指定输入的方法显然不足以引导snakemake找到正确的规则。在</p>