curious
curious

Reputation: 730

Possible to have wildcard as dictionary key in snakemake rule output?

I need my output to be dynamic to input, the best way I thought to do is this by having output based on a dictionary. He is a stripped down example:

config.yaml:

    {'names' : ['foo', 'bar']}

Snakefile:

configfile: "config.yaml"

rule all:
    input:
         expand("{name}",name=config['names'])


rule make_file:
    output:
          lambda wildcards: config[wildcards.name]

    shell:
         """
         touch {output}
         """

I get Only input files can be specified as functions

I also tried adding making output of rule make_file config["{name}"]

Upvotes: 4

Views: 999

Answers (3)

Troy Comi
Troy Comi

Reputation: 2079

I need my output to be dynamic to input

I'll add that you can use multiple rules to have snakemake select what to run based on the input to generate a single output file. This may be what you are getting at, but do provide more details if not:

ruleorder:
    rule1 > rule2 > rule3

rule rule1:
    output: 'foo'
    input: 'bar'
    shell: 'echo rule1 > {output}'

rule rule2:
    output: 'foo'
    input: 'baz'
    shell: 'echo rule2 > {output}'

rule rule3:
    output: 'foo'
    shell: 'echo rule3 > {output}'

The rule order resolves ambiguity if bar and baz are both present. If neither are present than rule3 runs as a default (with no necessary input).

I've used something similar in cases where say a fasta file can be generated from a vcf, a bam file, or downloaded as a fallback.

Upvotes: 0

dariober
dariober

Reputation: 9062

Maybe you are making things more complicated than necessary or you simplified the example too much (or I'm misunderstanding the question...).

This will create files foo and bar by running rule make_file on each item in config['names']:

rule all:
    input:
         expand("{name}", name= config['names'])

rule make_file:
    output:
        '{name}'
    shell:
         """
         touch {output}
         """

Upvotes: 0

Dmitry Kuzminov
Dmitry Kuzminov

Reputation: 6600

Snakemake has the opposite logic: that is the output that is used to define the actual wildcards values which then are used in other sections.

If you need the output to depend on the input, you may define several rules, where each one would define one possible pattern of how an input is being converted to output. There are other possibilities to add a dynamic behavior like checkpoints and dynamic files. Anyway there is no one size fits all solution for every problem, so you need to clarify what you are trying to achieve.

Anyway, when designing a Snakemake pipeline you should think in terms of "what target is my goal", but not in terms of "what could I make out of what I have".

Upvotes: 1

Related Questions