unixbioinformaticssnakemake

If else for "temp" in snakemake


Let's say I have a snakemake rule something like this

rule xxx:
  output:
    temp(directory("atac_seq/"))
  shell:
    """
    snakemake --cores all
    """

and in my config file, I have an config["delete"] = #True or False

Can I make temp delete atac_seq based on whether delete is true or false?

e.g.

rule xxx:
  output:
   if config["delete"] = True:
    temp(directory("atac_seq/"))
   elif config["delete"] = False:
    directory("atac_seq/")
  shell:
    """
    snakemake --cores all
    """

I can't think of a way to do this other than adding rm in shell.


Solution

  • Rather than trying to encode this in your workflow, maybe you are better off just using the --notemp flag when running Snakmake. This will keep all the temporary files and you don't have to put any extra code in your Snakefile. You can then later use --delete-temp-output if you want to clean up all the temp files.

    If you really do want to achieve what you sketched out above, it's do-able. Since temp() is just a function you can wrap it in another function.

    def mytemp(filename):
        if config['delete']:
            return temp(filename)
        else:
            return filename
    
    rule xxx:
      output:
        mytemp(directory("foo"))
      shell:
        """
        mkdir {output} ; touch {output}/foo.out
        """
    

    I am a bit alarmed that you are calling snakemake from a snakemake rule. This is generally a bad idea and leads to locking issues as well as scrambled output on the screen. I'd generally just use a wrapper shell script, or maybe you just need a profile here to set the --cores all setting.