Reputation: 172
In my Snakemake workflow, I have defined a function that uses a file produced previously during the workflow, parses it and returns a list of 2 elements, for example :
def get_param_value(wildcards) :
# do stuff with the wildcards and some files
return ["element1","element2"]
I would then like to use each value of the returned list as independent params
in a subsequent rule, such as :
rule example :
input :
'input_file.txt'
output :
'output_file.txt'
params :
param1 = "element1", # First element of the list returned by get_param_value function
param2 = "element2" # Second element of the list returned by get_param_value function
shell :
'somecommand -i {input} -smth1 {params.param1} -smth2 {params.param2} -o {output} ;'
I have tried using the function directly in the rule, with
params :
param1 = get_param_value[0],
param2 = get_param_value[1]
but I get a TypeError : 'function' object is not subscriptable
(which is expected because it's a function).
Do you have a workaround for this ?
Upvotes: 1
Views: 536
Reputation: 172
After a bit of tinkering and thanks to Mario Abbruscato's suggestions, this did the trick : I used lambda functions in the params
directive of the rule to extract the elements of the list and assign them to different parameters :
rule example :
input :
'input_file.txt'
output :
'output_file.txt'
params :
params = lambda wildcards : get_param_value(wildcards)
shell :
'somecommand -i {input} -smth1 {params.param1[0]} -smth2 {params.param2[1]} -o {output} ;'
Upvotes: 1
Reputation: 8158
You were close. You can avoid lambdas and use a function just by placing its name without parentheses or brackets like params: funcname
. The function with that name is then automatically called by Snakemake and the wildcards are passed along, too.
This can be applied in your context as follows:
def get_param_value(wildcards) :
return ["elem1","elem2"]
rule example :
output :
'output_file.txt'
params :
string_list = get_param_value
shell :
'echo -param1 {params.string_list[0]} -param2: {params.string_list[1]}'
You can run this yourself, it's a minimal (working) example that yields the following results when executed:
$ snakemake -np -c1
rule example:
output: output_file.txt
jobid: 0
resources: tmpdir=/var/folders/5_/6_lmbd65717dly07dk7r7q200000gn/T
echo "param1: elem1" "param2: elem2"
Read more about using functions in rule attributes in the documentation.
Upvotes: 1
Reputation: 819
you can do :
def get_param_value(wildcards,index) :
with open('file_from_workflow_using_wildcards') as file :
# do stuff
res = ["element1","element2"]
return res[index]
rule example :
input :
'input_file.txt'
output :
'output_file.txt'
params :
param1 = get_param_value(wildcards,0), # First
param2 = get_param_value(wildcards,1) # Second
shell :
'somecommand -i {input} -smth1 {params.param1} -smth2 {params.param2} -o {output} ;'
or better way using your function as it is in your code :
res = get_param_value(wildcards)
params :
param1 = res[0],
param2 = res[1]
Upvotes: 0