2017-06-15 32 views
2

私はSnakemakeを使い始めていますが、私はsnakemakeチュートリアルで答えが見つからない非常に基本的な質問があります。複数の入力と出力を単一のルールでスネークメイクファイル

Linuxで複数のファイルを1つずつダウンロードするために、単一のルールsnakefileを作成します。 ファイルを1つずつダウンロードする必要があり、ターゲットルールであるためワイルドカードを使用できないため、 'expand'は出力に使用できません。

私の心には唯一の方法がありますが、これはうまく動作しません。私は、後の工程で使用されるように、{出力}を使用して、このような「downloaded_files.dwn」などの特定の名前を持つ特定のディレクトリにダウンロードアイテムを送信する方法を見つけ出すことはできません。

links=[link1,link2,link3,....] 
rule download:  
output: 
    "outdir/{downloaded_file}.dwn" 
params: 
    shellCallFile='callscript', 
run: 
    callString='' 
    for item in links: 
     callString+='wget str(item) -O '+{output}+'\n' 
    call('echo "' + callString + '\n" >> ' + params.shellCallFile, shell=True) 
    call(callString, shell=True) 

私はどのようにこの上の任意のヒントを理解するはずです解決しなければならないと私はsnakemakeのどの部分がうまく理解しませんでした。ここで

+1

'-j'オプションを指定してsnakemakeを実行しないと、指定した時間に1つのルールインスタンスしか実行されません。ファイルを正確な順序でダウンロードする必要がありますか? – bli

+0

また、入力のみを持つ最初の 'all'ルールを使うのが一般的です。そのためにexpandを使うことができます。これは残りのワークフローを推進します。 – bli

+0

ダウンロードしたファイルの名前を決定するために使用できるリンクの名前にパターンがありますか? Snakemakeはファイル名の規則性を保つことを目的としています。 – bli

答えて

3

はあなたの問題を解決するのに役立つ可能性がコメントした例である:

# Create some way of associating output files with links 
# The output file names will be built from the keys: "chain_{key}.gz" 
# One could probably directly use output file names as keys 
links = { 
    "1" : "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/liftOver/hg38ToAptMan1.over.chain.gz", 
    "2" : "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/liftOver/hg38ToAquChr2.over.chain.gz", 
    "3" : "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/liftOver/hg38ToBisBis1.over.chain.gz"} 


rule download: 
    output: 
     # We inform snakemake that this rule will generate 
     # the following list of files: 
     # ["outdir/chain_1.gz", "outdir/chain_2.gz", "outdir/chain_3.gz"] 
     # Note that we don't need to use {output} in the "run" or "shell" part. 
     # This list will be used if we later add rules 
     # that use the files generated by the present rule. 
     expand("outdir/chain_{n}.gz", n=links.keys()) 
    run: 
     # The sort is there to ensure the files are in the 1, 2, 3 order. 
     # We could use an OrderedDict if we wanted an arbitrary order. 
     for link_num in sorted(links.keys()): 
      shell("wget {link} -O outdir/chain_{n}.gz".format(link=links[link_num], n=link_num)) 

そしてここでは、ダウンロードしたファイルの任意の名前を使用し、(ビット人為が)outputを使用して行うための別の方法、次のとおりです。

links = [ 
    ("foo_chain.gz", "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/liftOver/hg38ToAptMan1.over.chain.gz"), 
    ("bar_chain.gz", "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/liftOver/hg38ToAquChr2.over.chain.gz"), 
    ("baz_chain.gz", "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/liftOver/hg38ToBisBis1.over.chain.gz")] 


rule download: 
    output: 
     # We inform snakemake that this rule will generate 
     # the following list of files: 
     # ["outdir/foo_chain.gz", "outdir/bar_chain.gz", "outdir/baz_chain.gz"] 
     ["outdir/{f}".format(f=filename) for (filename, _) in links] 
    run: 
     for i in range(len(links)): 
      # output is a list, so we can access its items by index 
      shell("wget {link} -O {chain_file}".format(
       link=links[i][1], chain_file=output[i])) 
     # using a direct loop over the pairs (filename, link) 
     # could be considered "cleaner" 
     # for (filename, link) in links: 
     #  shell("wget {link} -0 outdir/{filename}".format(
     #   link=link, filename=filename)) 

snakemake -j 3を使用して、3件のダウンロードを並行して行うことができる。例:

# To use os.path.join, 
# which is more robust than manually writing the separator. 
import os 

# Association between output files and source links 
links = { 
    "foo_chain.gz" : "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/liftOver/hg38ToAptMan1.over.chain.gz", 
    "bar_chain.gz" : "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/liftOver/hg38ToAquChr2.over.chain.gz", 
    "baz_chain.gz" : "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/liftOver/hg38ToBisBis1.over.chain.gz"} 


# Make this association accessible via a function of wildcards 
def chainfile2link(wildcards): 
    return links[wildcards.chainfile] 


# First rule will drive the rest of the workflow 
rule all: 
    input: 
     # expand generates the list of the final files we want 
     expand(os.path.join("outdir", "{chainfile}"), chainfile=links.keys()) 


rule download: 
    output: 
     # We inform snakemake what this rule will generate 
     os.path.join("outdir", "{chainfile}") 
    params: 
     # using a function of wildcards in params 
     link = chainfile2link, 
    shell: 
     """ 
     wget {params.link} -O {output} 
     """ 
+0

あなたの素晴らしいソリューションのおかげでbliを参照してください。もう1つの質問。このルールは、リンクを並行してダウンロードするように変更できますか? – user3015703

+1

並行して実行するには、 'all'ルールの' input'で 'expand'を動かし、' for'ループから 'for'ループを削除し、' -j'を使用します。 'all'ルールは' download'ルールをそれぞれの必要なファイルに対して一度実行させます。別の日に例を追加しますが、一方で試してみてください。 – bli

+1

@ user3015703私は、パラレルダウンロードの例を追加しました。 – bli

関連する問題