1

I would like to do something like the following in Snakemake:

rule RULE:
  input: ...
  output: "{tool}/{file}"
  shell: lambda wildcards: command_for_tool[wildcards.tool]

possibly with the shell command wrapped in a format(.., file=wildcards.file) to expand the {file} that will be inside the command_for_tool.

Currently I can do this using a run: calling shell(..), but I can't use this because I'm benchmarking the memory usage of the rule and going via python adds 30+MB overhead.

It is possible to use some python code inside the shell: rule that returns a string, but in this case I cannot figure out how to use the wildcards.

It is also possible to use wildcards directly in a string value, where they will be substituted automatically, but this doesn't allow for the map-lookup I need.

Is there a clean solution to this? (Currently I'm trying to work around it using params:.) To me it seems like an omission/inconsistency in how snakemake works.

1 Answer 1

1

Using your own suggestion, a solution using params seems quite clean:

rule RULE:
    input:
        'in.txt',
    output:
        '{foo}.txt',
    params:
        cmd= lambda wc: command_for_tool[wc.foo],
    shell:
        """
        {params.cmd} 
        """

although I can see that for consistency with the input and params directive, also shell: lambda wildcards: command_for_tool[wildcards.tool] should work.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, this is basically what I have now, but note that the shell: "{params.cmd}" does not do recursive expansion, so you have to manually expand (with .format()) wildcards/variables that are part of the command line to be invoked.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.