Snakemake Использование расширять со словарем

Пишу это правило:

rule process_files:
    input: 
        dataout=expand("{{dataset}}/{{sample}}.{{ref}}.{{state}}.{{case}}.myresult.{name}.tsv", name=my_list[wildcards.ref]) 
    output:
        "{dataset}/{sample}.{ref}.{state}.{case}.endresult.tsv"
    shell:
        do something ...

Were expand получит значение из словаря my_dictionary на основе значения ref. Я использовал wildcards вот так my_dictionary[wildcards.ref]. Но это заканчивается этой ошибкой name 'wildcards' is not defined

my_dictionary что-то вроде: {A:[1,2,3], B:[s1,s2..].....}

Я мог бы использовать

def myfun(wildcards):
    return expand("{{dataset}}/{{sample}}.{{ref}}.{{state}}.{{case}}.myresult.{name}.tsv", name=my_dictionary[wildcards.ref])

и использовать myfun в качестве ввода, но это не отвечает на вопрос, почему я не могу напрямую использовать расширение на месте

Есть предложения, как это исправить?


person Medhat    schedule 13.11.2018    source источник


Ответы (2)


Ваш вопрос похож на подстановочные знаки snakemake или команду расширения, а суть в том, что wildcards это не определено во входных данных. Итак, ваше решение с использованием функции ввода (или лямбда-функции) кажется правильным.

(Что касается почему wildcards не определено во вводе, я не знаю ...)

person dariober    schedule 14.11.2018
comment
Спасибо, функция сработала, но не разрешила переменную между двойными фигурными скобками, поэтому запросит ввод для {dataset}/{sample}.{ref}.{state}.{case} и вызовет ошибку. - person Medhat; 14.11.2018

Как упоминал @dariober, есть объекты wildcards, но они доступны только в части запуска / оболочки, но могут быть доступны с помощью функции ввода в input.

Вот пример реализации, которая расширяет ввод на основе wildcards.ref:

rule all:
    input: expand("{dataset}/{sample}.{ref}.{state}.{case}.endresult.tsv", dataset=["D1", "D2"], sample=["S1", "S2"], ref=["R1", "R2"], state=["STATE1", "STATE2"], case=["C1", "C2"])


my_list = {"R1": [1, 2, 3], "R2": ["s1", "s2"]}

rule process_files:
    input:
        lambda wildcards: expand(
            "{{dataset}}/{{sample}}.{{ref}}.{{state}}.{{case}}.myresult.{name}.tsv", name=my_list[wildcards.ref])
    output:
        "{dataset}/{sample}.{ref}.{state}.{case}.endresult.tsv"
    shell:
        "echo '{input}' > {output}"

Если вы реализуете его как приведенный выше пример функции lambda, это должно решить указанную вами проблему:

Функция сработала, но не разрешила переменную между двойными фигурными скобками, поэтому запросит ввод для {dataset} / {sample}. {Ref}. {State}. {Case} и вызовет ошибку.

person JohnnyBD    schedule 14.11.2018
comment
На самом деле моя функция такая же, как и ваша лямбда-функция, и вызывает эту ошибку. def myfun(wildcards): return expand("{{dataset}}/{{sample}}.{{ref}}.{{state}}.{{case}}.myresult.{name}.tsv", name=my_list[wildcards.ref]). чтобы решить эту проблему, мне нужно разрешить каждую переменную, например ref. будет wildcards.ref и так далее. - person Medhat; 14.11.2018
comment
На самом деле в этом не должно быть необходимости. Вы говорите, что переходите к расширению в случае {dataset}, dataset = wildcards.dataset? Кажется избыточным. В этом примере я использую snakemake 5.3.0, и он работает с вашим myfun или лямбда. - person JohnnyBD; 14.11.2018
comment
Проблема после использования расширения; переменная, переданная в sample, равна {sample}, поэтому она будет sample={sample} не фактическим значением выборки, что создает проблемы при обработке для следующего шага, потому что теперь во входном файле нет ничего, называемого {dataset}/{sample...} - person Medhat; 15.11.2018
comment
Извините, но я не могу воспроизвести эту проблему, о которой вы говорите. Не могли бы вы отредактировать свой вопрос и предоставить пример того, как будет выглядеть ввод для одной комбинации подстановочных знаков ввода? Либо я неправильно понимаю, что вы пытаетесь сделать, либо наши реализации отличаются? Вы хотите иметь одно значение для всех подстановочных знаков, кроме name? По существу сгруппировать набор name входов вместе? В этом случае у вас должно быть {sample} в результате расширения, так как этот подстановочный знак будет выведен из rule all и выведен. - person JohnnyBD; 15.11.2018