Синтаксис для использования данных конфигурации в правилах

Есть ли какое-нибудь место, которое полностью описывает использование данных конфигурации в правилах создания змейки?

В руководстве пользователя есть пример этого в файле yaml:

samples:
    A: data/samples/A.fastq
    B: data/samples/B.fastq

Затем он используется в таком правиле:

bam=expand("sorted_reads/{sample}.bam", sample=config["samples"]),

Похоже, что приведенное выше заменит {sample} на "data / samples / A.fastq", а не на "A" (и "B" и т. Д.), Как это очевидно.

Как правильно использовать данные конфигурации в правилах вывода, например чтобы помочь сформировать имя выходного файла? Эта форма не работает:

output: "{config.dataFolder}/{ID}/{ID}.yyy"

Я ищу руководство по синтаксису, если я определяю сложные структурированные данные в файле yaml - как мне использовать их в правилах змеи? Когда я использую синтаксис Python, а когда - синтаксис SnakeMake?

Файлы конфигурации yaml и JSON сильно ограничены тем, что они не могут использовать значения, определенные ранее в файле, для определения новых значений, верно? И это то, что часто делается при настройке параметров конфигурации.

В чем преимущество использования файла конфигурации? Почему бы вместо этого просто не использовать include: включить файл python для определения параметров?

Полезно было бы справочное руководство, в котором подробно описаны детали SnakeMake. Текущий веб-сайт как бы разрознен, требуется время, чтобы найти то, что вы помните, где-то на нем видели ранее.


person tedtoal    schedule 03.08.2017    source источник
comment
Чтобы преодолеть ограничения yaml или JSON, вы можете читать вещи из конфигурации, а затем в файле snakefile (и перед правилами) применять код Python к вещам, считанным из файла конфигурации.   -  person bli    schedule 08.08.2017


Ответы (3)


Как следует использовать данные конфигурации в правилах "вывода"? Я обнаружил, что строка вывода не может содержать значений {config.}. Однако их можно включить с помощью кода Python следующим образом:

output: config["OutputDir"] + "/myfile.txt"

Но этот метод НЕ работает (на выходе: или на входе :):

params: config=config
output: "{params.config[OutputDir]}/myfile.txt"

Однако он ДЕЙСТВИТЕЛЬНО работает в "оболочке:":

params: config=config
output: config["OutputDir"] + "/myfile.txt"
shell: echo "OutputDir is {params.config[OutputDir]}" > {output}

Обратите внимание на отсутствие кавычек вокруг OutputDir внутри [] в cmd оболочки. В методе раскрытия значений в строке {} не используются кавычки вокруг ключей.

Могут ли данные конфигурации быть определены по змеевому файлу ИЛИ по питону? ДА!

Параметры могут быть определены в файле .yaml, включенном с помощью configfile, или в обычном файле Python, включенном с помощью include. Последнее, IMHO, лучше, поскольку файлы .yaml не позволяют определениям ссылаться на предыдущие, что было бы общим для всех, кроме простейших файлов конфигурации.

Чтобы определить параметр "OutputDir" выше с помощью yaml:

xxx.yaml:

OutputDir: DATA_DIR

snakefile:

configfile: 'xxx.yaml'

Чтобы определить его с помощью Python, чтобы он был точно совместим с приведенным выше:

xxx.py:

config['OutputDir'] = "DATA_DIR"

snakefile:

include: 'xxx.py'

Или, чтобы определить простую переменную OutputDir во включенном файле конфигурации Python, а затем использовать ее в правиле:

xxx.py:

OutputDir = "DATA_DIR"

snakefile:

include: 'xxx.py'
rule:
    output: OutputDir + "/myfile.txt"

Многоканальные словари и списки могут быть легко определены и доступны как через файлы .yaml, так и через файлы Python. Пример:

MACBOOK> cat cfgtest.yaml
cfgtestYAML:

    A: 10
    B: [1, 2, 99]
    C:
        nst1: "hello"
        nst2: ["big", "world"]

MACBOOK> cat cfgtest.py
cfgtestPY = {

    'X': -2,
    'Y': range(4,7),
    'Z': {
        'nest1': "bye",
        'nest2': ["A", "list"]
        }
    }

MACBOOK> cat cfgtest
configfile: "cfgtest.yaml"
include: "cfgtest.py"

rule:
    output: 'cfgtest.txt'
    params: YAML=config["cfgtestYAML"], PY=cfgtestPY
    shell:
        """
        echo "params.YAML[A]: {params.YAML[A]}"             >{output}
        echo "params.YAML[B]: {params.YAML[B]}"             >>{output}
        echo "params.YAML[B][2]: {params.YAML[B][2]}"       >>{output}
        echo "params.YAML[C]: {params.YAML[C]}"             >>{output}
        echo "params.YAML[C][nst1]: {params.YAML[C][nst1]}" >>{output}
        echo "params.YAML[C][nst2]: {params.YAML[C][nst2]}" >>{output}
        echo "params.YAML[C][nst2][1]: {params.YAML[C][nst2][1]}" >>{output}

        echo "" >>{output}

        echo "params.PY[X]: {params.PY[X]}"                 >>{output}
        echo "params.PY[Y]: {params.PY[Y]}"                 >>{output}
        echo "params.PY[Y][2]: {params.PY[Y][2]}"           >>{output}
        echo "params.PY[Z]: {params.PY[Z]}"                 >>{output}
        echo "params.PY[Z][nest1]: {params.PY[Z][nest1]}"     >>{output}
        echo "params.PY[Z][nest2]: {params.PY[Z][nest2]}"     >>{output}
        echo "params.PY[Z][nest2][1]: {params.PY[Z][nest2][1]}" >>{output}
        """

MACBOOK> snakemake -s cfgtest
Provided cores: 1
Rules claiming more threads will be scaled down.
Job counts:
    count   jobs
    1   1
    1

rule 1:
    output: cfgtest.txt
    jobid: 0

Finished job 0.
1 of 1 steps (100%) done

MACBOOK> cat cfgtest.txt
params.YAML[A]: 10
params.YAML[B]: 1 2 99
params.YAML[B][2]: 99
params.YAML[C]: {'nst1': 'hello', 'nst2': ['big', 'world']}
params.YAML[C][nst1]: hello
params.YAML[C][nst2]: big world
params.YAML[C][nst2][1]: world

params.PY[X]: -2
params.PY[Y]: range(4, 7)
params.PY[Y][2]: 6
params.PY[Z]: {'nest1': 'bye', 'nest2': ['A', 'list']}
params.PY[Z][nest1]: bye
params.PY[Z][nest2]: A list
params.PY[Z][nest2][1]: list
person tedtoal    schedule 03.08.2017
comment
Интересно, что к элементу params первого уровня можно получить доступ с помощью. или [], но все последующие уровни должны использовать []. Например. params.PY [X] и params [PY] [X] идентичны, но params.PY.X не работает. - person tedtoal; 04.08.2017
comment
Метод 2 в приведенном выше сообщении не может работать. Фигурные скобки в input, output, params, ... используются для обозначения подстановочных знаков. Напротив, фигурные скобки в директиве оболочки или функции расширения используются для форматирования строк, точно так же, как метод python str.format. - person Johannes Köster; 04.08.2017

Конфигурация YAML

Это связано с вложением файлов YAML, см. Пример здесь.

Запрос config ["samples"] вернет и "A", и "B". Я в своей голове, я думаю о том, что он возвращает список, но я не уверен в типе переменной.

Используя файл конфигурации, указанный здесь: https://snakemake.readthedocs.io/en/latest/tutorial/advanced.html

Вы можете сделать ссылку в следующих файлах конфигурации YAML в формате YAML.

settings / config.yaml:

samples:
    A
    B

OR

settings / config.yaml:

sampleID:
    123
    124
    125
baseDIR:
    data

Результирующий вызов с доступом к конфигурации YAML

Snakefile:

configfile: "settings/config.yaml"

rule all:
    input:
        expand("{baseDIR}/{ID}.bam", baseDIR=config["baseDIR"], ID=config["sampleID"]),


rule fastq2bam:
    input:
        expand("{{baseDIR}}/{{ID}}.{readDirection}.fastq", readDirection=['1','2'])
    output:
        "{baseDIR}/{ID}.bam"
        #Note different number of {}, 1 for wildcards not in expand.
        #Equivalent line with 'useless' expand call would be:
        #expand("{{baseDIR}}/{{ID}}.bam")

    shell:
    """
    bwa mem {input[0]} {input[1]} > {output}
    """

Пустые примеры, просто пытаюсь проиллюстрировать использование разных строк и переменных конфигурации. Я использую подстановочные знаки в правиле fastq2bam. Обычно я использую только переменные конфигурации, чтобы установить в своем правиле «все», когда это возможно, это лучшая практика. Я не могу сказать, действительно ли вызов оболочки работает для bwa mem, но я думаю, вы понимаете, о чем я говорю.

Увеличенную версию Snakefile можно увидеть здесь

После настройки файла конфигурации, чтобы ссылаться на что-либо в нем, используйте config. Его можно использовать для доступа к YAML по мере необходимости. Здесь я спущусь на 3 гипотетических уровня, вот так:

hypothetical_var = config["yamlVarLvl1"]["yamlVarLvl2"]["yamlVarLvl3"]

Приравнивается к (Я НЕ ПОЛОЖИТЕЛЬНО насчет набора текста, я думаю, что он преобразуется в строки)

 hypothetical_var = ['124', '125', '126', '127', '128', '129']

Если YAML:

yamlVarLvl1:
    yamlVarLvl2:
        yamlVarLvl3:
            '124'
            '125'
            '126'
            '127'
            '128'
            '129'

Организация кода

Код Python и Snakemake по большей части может чередоваться в определенных местах. Я бы не советовал этого делать, так как это затруднит поддержку кода. Пользователь сам решает, как это реализовать. Например, использование директивы run или shell изменяет способ доступа к переменным.

Файлы YAML и JSON являются предпочтительными файлами переменных конфигурации, поскольку я считаю, что они обеспечивают некоторую поддержку редактирования и отмены переменных в интерфейсе командной строки. Это было бы не так чисто, если бы оно было реализовано с использованием переменных Python, импортированных извне. Также это помогает моему мозгу, зная, что файлы Python делают что-то, а файлы YAML хранят вещи.

YAML - это всегда внешний файл, но ...

  1. Если вы используете один файл Snakefile, поместите вспомогательный питон вверху?
  2. Если вы используете многофайловую систему, рассмотрите возможность использования внешних сценариев Python.

Учебники

Я думаю, что создать идеальную виньетку сложно. Я пытаюсь рассказать своей группе о Snakemake, и у меня есть более 40 страниц лично написанной документации, я провел три презентации продолжительностью более 1 часа со слайд-шоу PowerPoint, я прочитал почти все руководство ReadTheDocs.io для Snakemake, и я просто недавно закончил просмотр списка дополнительных ресурсов, но я ' Я тоже учусь!

Замечание: мне тоже очень понравилось это руководство.

Обеспечивает ли это достаточный контекст?

person TBoyarski    schedule 03.08.2017
comment
Спасибо за информацию. Я помещаю много вопросов в один, так как могу задать только один вопрос за 90 минут. Вы не ответили на вопрос, как следует использовать данные конфигурации в правилах вывода? Я обнаружил, что это работает: - person tedtoal; 04.08.2017
comment
Не беспокойтесь, я также понимаю, что вы делаете все возможное, и благодарю вас за перенос этого обсуждения из групп Google сюда. Входной и выходной доступ к файлу конфигурации идентичен. Единственное различие между директивами ввода и вывода заключается в том, что директива ввода может использовать функции ввода, тогда как я не верю, что есть какая-либо возможность поместить функцию в вывод. - person TBoyarski; 04.08.2017
comment
Возможно, стоит упомянуть, что, независимо от использования YAML или JSON, Snakemake просто считывает соответствующий файл конфигурации в словарь Python, который глобально доступен как config. Чтение происходит через модуль json стандартной библиотеки или pyyaml библиотеки. Здесь ничего особенного. Это также означает, что целые числа и числа с плавающей запятой преобразуются правильно, и если вы не поместите их в кавычки в файле конфигурации, они будут правильными целыми числами или числами с плавающей запятой в результирующем словаре. - person Johannes Köster; 04.08.2017

Есть ли какое-нибудь место, которое полностью описывает использование данных конфигурации в правилах создания змейки?

Нет ограничений на то, что вы можете поместить в файл конфигурации, при условии, что он может быть проанализирован в объекты python. По сути, «ваше воображение - это предел».

Как правильно использовать данные конфигурации в правилах вывода, например чтобы помочь сформировать имя выходного файла?

Я извлекаю из конфига вещи вне правил, на простом питоне.

Вместо output: "{config.dataFolder}/{ID}/{ID}.yyy" я бы сделал:

data_folder = config.dataFolder

rule name_of_the_rule:
    output:unction
        os.path.join(data_folder, "{ID}", "{ID}.yyy")

Я предполагаю, что с тем, что вы пробовали, snakemake имеет проблемы с форматированием строки, когда есть смесь вещей, исходящих из подстановочных знаков и других. Но, возможно, следующее работает в python 3.6, используя форматированные строковые литеры: output: f"{config.dataFolder}/{ID}/{ID}.yyy". Я не проверял.

Я ищу руководство по синтаксису, если я определяю сложные структурированные данные в файле yaml - как мне использовать их в правилах змеи? Когда я использую синтаксис Python и когда я использую синтаксис SnakeMake?

В файле snakefile я обычно читаю файл конфигурации, чтобы извлечь информацию о конфигурации до правил. По сути, это чистый питон, за исключением того, что объект config для удобства напрямую предоставляется Snakemake. Вероятно, вы могли бы просто использовать простой стандартный питон, используя config = json.load("config.json") или config = yaml.load("config.yaml").

В файле snakefile, помимо правил, вы можете выполнять любые вычисления на Python. Это может быть как до чтения конфига, так и после. Вы можете определять функции, которые могут использоваться в правилах (например, для генерации входных данных правила), вычислять списки вещей, которые будут использоваться в качестве подстановочных знаков. Я думаю, единственное, что объект должен быть определен до правил, которые его используют.

Синтаксис Snakemake в основном используется для описания правил. В run части правила вы можете использовать любой питон, какой захотите, зная, что у вас есть доступ к wildcards объекту, который может вам помочь. Ввод и вывод правил представляют собой списки путей к файлам, и вы можете использовать python для их создания.

person bli    schedule 08.08.2017