Search code examples
snakemake

Snakemake: functions as input not working as expected (InputFunctionException with KeyError)


In my case, there is no pattern in the names of input and output files, so I used a dict to map the output to the input file, and then used this dict in the function as input. Please see the codes of Snakemake file below:

in_files = ['in_a', 'in_b']
out_files = ['out_c', 'out_d']

out_to_in_dict = dict()
for in_file, out_file in zip(in_files, out_files):
    out_to_in_dict[out_file] = in_file

rule all:
    input:
        out_files

rule copy_file:
    input:
        lambda wildcards: out_to_in_dict[wildcards.outfile]
    output:
        '{outfile}'
    shell:
        '''
        cp {input} {output}
        '''

After executing Snakemake, I got this error:

InputFunctionException in line 8 of /home/test.snake:
KeyError: 'in_a'
Wildcards:
outfile=in_a

The version of Snakemake I am using is 5.5.3. Could anyone please help? Thanks!


Solution

  • I'm not 100% sure why but you can fix it by constraining the scope of the wildcards using wildcard_constraints:

    in_files = ['in_a', 'in_b']
    out_files = ['out_c', 'out_d']
    
    out_to_in_dict = dict()
    for in_file, out_file in zip(in_files, out_files):
        out_to_in_dict[out_file] = in_file
    
    wildcard_constraints:
        outfile= '|'.join([re.escape(x) for x in out_files]),
    
    rule all:
        input:
            out_files
    
    rule copy_file:
        input:
            lambda wildcards: out_to_in_dict[wildcards.outfile]
        output:
            '{outfile}'
        shell:
            '''
            cp {input} {output}
            '''
    

    It's probably related to this https://groups.google.com/forum/#!msg/snakemake/wVlJW9X-9EU/gSZh4U0_CQAJ but just now I don't see why it applies to your example. Personally, I use wildcard_constraints quite liberally as I don't like snakemake's default behaviour of interpreting strings as regexes.