Search code examples
snakemake

Run one rule conditionally to the input files


I've just started to learn Snakemake so probably this is a naive question. I need for a rule to be launched in two different moments of the pipeline, using different inputs and producing different outputs.

Let me make a silly example. Let's say I have 3 rules:

rule A:
    input:
        "data/sample.1.txt"
    output:
        "data/sample.2.sorted.txt"
    shell:
        "somethingsomething sort {input}"



rule B:
    input:
        "data/sample.2.sorted.txt"
    output:
        "data/sample.3.man.txt"
    shell:
        "somethingsomething manipulate {input}"


rule C:
    input:
        "data/sample.3.man.txt"
    output:
        "data/sample.4.man.sorted.txt"
    shell:
        "somethingsomething sort {input}"

In this example, where the pipeline does A > B > C, A and C do exactly the same, but one uses the file 1 and outputs 2, while the other uses 3 and outputs 4. What is the best solution to just have a single sorting rule so the pipeline does A > B > A? (Probably there's some way to do it using the wildcards, maybe in combination with an if else, but I am not sure how)

Thank you for your time


Solution

  • Probably there's some way to re-use a rule but I suspect it's going to make the code more convoluted than necessary.

    If the shell call is the same for rule A and C and you don't want to copy and paste the code, just put the code in a variable and re-use that variable:

    sorter= "somethingsomething sort {input}"
    
    rule A:
        input:
            "data/sample.1.txt"
        output:
            "data/sample.2.sorted.txt"
        shell:
            sorter
    
    rule B:
        input:
            "data/sample.2.sorted.txt"
        output:
            "data/sample.3.man.txt"
        shell:
            "somethingsomething manipulate {input}"
    
    rule C:
        input:
            "data/sample.3.man.txt"
        output:
            "data/sample.4.man.sorted.txt"
        shell:
            sorter