I am constructing a snakemake pipeline. I have a config.yaml file in which I want to store wildcard constraints. Say I have this block in the config file:
wildcard_constraints:
sample: '[^_/]+'
reference: '[^/]+'
Then in my snakefile I have:
configfile: 'config/config.yaml'
print(config['wildcard_constraints']) # for debugging
wildcard_constraints: config['wildcard_constraints']
rule test:
output:
touch("{sample}.test")
This produces the following:
{'sample': '[^_/]+', 'reference': '[^/]+'}
TypeError in line 32 of /myfolder/snakefile:
global_wildcard_constraints() takes 1 positional argument but 2 were given
File "/myfolder/snakefile", line 32, in <module>
So snakemake is getting my wildcard_constraints dictionary just fine from config.yaml. But instead of just using it as the wildcards constraints dictionary, it's trying to parse it.
How can I get around this?
If I just include the following in the snakefile, instead of trying to get the constraints from config.yaml, there is no error. So this would suffice, but it would be nice to be able to separate out the constraints.
wildcard_constraints:
sample = '[^_/]+',
reference = '[^/]+'
You can do this dynamically by modifying the workflow._wildcard_constraints
dict. For example, the following works (on Snakemake 5.11.2
):
configfile: "config.yaml"
for wildcard, constraint in config["wildcard_constraints"].items():
workflow._wildcard_constraints[wildcard] = constraint
print(workflow._wildcard_constraints) # For debugging
rule test:
output:
touch("{sample}.test")
And prints {'reference': '[^/]+', 'sample': '[^_/]+'}
. I've also confirmed that the rule test
is able to create e.g. example.test
, but not _example.test
.
However, this is probably a bit of a hack, since it works on the "private" _wildcard_constraints
. At least, be aware that you have no guarantee that this is going to be stable across versions.