Snakemake: путаница в том, как правильно получить доступ к файлам конфигурации - PullRequest
0 голосов
/ 06 мая 2018

Этот вопрос следует из вопроса , который я задавал ранее, и он касается понимания того, как правильно обращаться к файлам конфигурации с помощью Snakemake. У меня есть конкретная проблема, которую мне нужно решить, и я сначала задам вопрос, а также общая проблема понимания работы индексации, которую я задам второй.

Я использую snakemake для запуска и конвейер ATAC-seq от Alignment / QC до анализа мотива.

A: Конкретный вопрос

Я пытаюсь добавить правило под названием trim_galore_pe для обрезки адаптеров из моих файлов fastq перед выравниванием, и из snakemake выдается сообщение об ошибке, поскольку имена выходных файлов, генерируемых trim galore, не соответствуют ожидаемым змейкой. Это потому, что я не могу понять, как правильно написать оператор выходного файла в моем файле snakemake, чтобы имена совпадали.

Пример имен, генерируемых TRIM GALORE, содержит номера SRA, например:

trimmed_fastq_files/SRR2920475_1_val_1.fq.gz

Принимая во внимание, что файл, ожидаемый snakemake, содержит образец ссылок и должен читать:

trimmed_fastq_files/Corces2016_4983.7B_Mono_1_val_1.fq.gz

Это также влияет на последующие правила после правила trim_galore_pe. Мне нужно найти способ использовать информацию в моем файле конфигурации для генерации необходимых выходных файлов.

Для всех правил после тех, что показаны в Snakefile, мне нужно, чтобы файлы были названы sample name , т.е. Corces2016_4983.7A_Mono. Также было бы полезно, чтобы все правила FAST_QC и MULTIQC, показанные в приведенном ниже файле Snakefile, содержали примеров имен в структуре имен выходного файла, что они все уже делают в текущем файле Snakefile.

Однако входы для Bowtie2, правила FASTQC, а также ввод и вывод правил trim_galore_pe должны содержать номера SRA. Проблема начинается с выхода trim_galore и влияет на все последующие правила.

Хотя я извлек номера SRA в предыдущих правилах, я не уверен, как это сделать, если не использовать папку fastq_files, которая явно указана в файле конфигурации. Введя правило trim_galore_pe, я фактически переместил новый набор файлов SRA в новую папку trimmed_fastq_files. Как извлечь только номер SRA из списка конфигурационных файлов SRA-файлов, содержащих старые имена папок, а ссылка на новую папку trimmed_fastq_files в Snakefile - вот суть моей проблемы.

Надеюсь, это понятно.

Вот мой конфигурационный файл:

samples:
    Corces2016_4983.7A_Mono: fastq_files/SRR2920475
    Corces2016_4983.7B_Mono: fastq_files/SRR2920476
cell_types:
    Mono:
    - Corces2016_4983.7A
index: /home/genomes_and_index_files/hg19

Вот мой Snakefile:

# read config info into this namespace
configfile: "config.yaml"
print (config['samples'])

rule all:
    input:
        expand("FastQC/PRETRIM/{sample}_{num}_fastqc.zip", sample=config["samples"], num=['1', '2']),
        expand("bam_files/{sample}.bam", sample=config["samples"]),
        "FastQC/PRETRIM/fastq_multiqc.html",
        "FastQC/POSTTRIM/fastq_multiqc.html"

rule fastqc_pretrim:
    input:
        sample=lambda wildcards: f"{config['samples'][wildcards.sample]}_{wildcards.num}.fastq.gz"
    output:
        # Output needs to end in '_fastqc.html' for multiqc to work
        html="FastQC/PRETRIM/{sample}_{num}_fastqc.html",
        zip="FastQC/PRETRIM/{sample}_{num}_fastqc.zip"
    wrapper:
        "0.23.1/bio/fastqc"

rule multiqc_fastq_pretrim:
    input:
        expand("FastQC/PRETRIM/{sample}_{num}_fastqc.html", sample=config["samples"], num=['1', '2'])
    output:
        "FastQC/PRETRIM/fastq_multiqc.html"
    wrapper:
        "0.23.1/bio/multiqc"

rule trim_galore_pe:
    input:
        sample=lambda wildcards: expand(f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])
    output:
        "trimmed_fastq_files/{sample}_1_val_1.fq.gz",
        "trimmed_fastq_files/{sample}_1.fastq.gz_trimming_report.txt",
        "trimmed_fastq_files/{sample}_2_val_2.fq.gz",
        "trimmed_fastq_files/{sample}_2.fastq.gz_trimming_report.txt"
    params:
        extra="--illumina -q 20"
    log:
        "logs/trim_galore/{sample}.log"
    wrapper:
        "0.23.1/bio/trim_galore/pe"

rule fastqc_posttrim:
    input:
        "trimmed_fastq_files/{sample}_1_val_1.fq.gz", "trimmed_fastq_files/{sample}_2_val_2.fq.gz"
    output:
        # Output needs to end in '_fastqc.html' for multiqc to work
        html="FastQC/POSTTRIM/{sample}_{num}_fastqc.html",
        zip="FastQC/POSTTRIM/{sample}_{num}_fastqc.zip"
    wrapper:
        "0.23.1/bio/fastqc"

rule multiqc_fastq_posttrim:
    input:
        expand("FastQC/POSTTRIM/{sample}_{num}.trim_fastqc.html", sample=config["samples"], num=['1', '2'])
    output:
        "FastQC/POSTTRIM/fastq_multiqc.html"
    wrapper:
        "0.23.1/bio/multiqc"

rule bowtie2:
    input:
        "trimmed_fastq_files/{sample}_1_val_1.fq.gz", "trimmed_fastq_files/{sample}_2_val_2.fq.gz"
    output:
        "bam_files/{sample}.bam"
    log:
        "logs/bowtie2/{sample}.txt"
    params:
       index=config["index"],  # prefix of reference genome index (built with bowtie2-build),
       extra=""
    threads: 8
    wrapper:
        "0.23.1/bio/bowtie2/align"

В настоящее время это выполняется и дает полный список заданий, используя snakemake -np, но выдает ошибку, упомянутую выше.

B: Общий вопрос

Существует ли онлайн-ресурс, в котором кратко объясняется, как ссылаться на файл конфигурации с помощью python, особенно со ссылкой на snakemake? Онлайновые документы довольно недостаточны и предполагают предварительные знания Python.

Мой опыт программирования в основном на bash и R, но мне нравится Snakemake, и я вообще понимаю, как работают словари и списки в python и как ссылаться на элементы, хранящиеся в них. Однако я нахожу, что сложное использование скобок, подстановочных знаков и кавычек в некоторых из приведенных выше правил Snakemake сбивает с толку, поэтому, как правило, возникают трудности при попытке обратиться к различным частям имен файлов в файле конфигурации. Я хочу полностью понять, как использовать эти элементы.

Например, в таком правиле из файла Snakefile, опубликованного выше:

sample=lambda wildcards: expand(f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2]) 

Что на самом деле происходит в этой команде? Насколько я понимаю, мы обращаемся к файлу конфигурации, используя config['samples'], и мы используем часть [wildcards.sample] для явного доступа к части fastq_files/SRR2920475 файла конфигурации. Развертывание позволяет нам перебирать каждый элемент в файле конфигурации, который соответствует параметрам в команде, то есть все файлы SRA и лямбда-символы, необходимые для использования в команде вызова wildcards. В чем я не уверен, так это:

  1. Что делает f сразу после расширения и зачем это нужно?
  2. Почему config['samples'] содержит кавычки в квадратных скобках, но кавычки не нужны в [wildcards.sample]?
  3. Почему используются одинарные и двойные фигурные скобки?
  4. Глядя на файл Snake выше, некоторые из правил содержат части, присваивающие последовательность чисел num, но опять же эти числа иногда заключаются в кавычки, а иногда нет ... почему?

Буду очень признателен за любые советы, советы, указатели.

C: Разъяснение предложений, сделанных ниже @ bli

Я отредактировал мой конфигурационный файл, как вы предложили в своем комментарии, и пропустил имена папок, оставив только номера SRA. Это имеет смысл для меня, но у меня есть пара других проблем, мешающих мне запустить этот Snakefile.

Новый файл конфигурации:

samples:
    Corces2016_4983.7A_Mono: SRR2920475
    Corces2016_4983.7B_Mono: SRR2920476
cell_types:
    Mono:
    - Corces2016_4983.7A
index: /home/c1477909/genomes_and_index_files/hg19

Новый Snakefile:

# read config info into this namespace
configfile: "config.yaml"
print (config['samples'])

rule all:
    input:
        expand("FastQC/PRETRIM/{sample}_{num}_fastqc.zip", sample=config["samples"], num=['1', '2']),
        expand("bam_files/{sample}.bam", sample=config["samples"]),
        "FastQC/PRETRIM/fastq_multiqc.html",
        "FastQC/POSTTRIM/fastq_multiqc.html",

rule fastqc_pretrim:
    input:
      lambda wildcards: f"fastq_files/{config['samples'][wildcards.sample]}_{wildcards.num}.fastq.gz"
    output:
        # Output needs to end in '_fastqc.html' for multiqc to work
        html="FastQC/PRETRIM/{sample}_{num}_fastqc.html",
        zip="FastQC/PRETRIM/{sample}_{num}_fastqc.zip"
    wrapper:
        "0.23.1/bio/fastqc"

rule multiqc_fastq_pretrim:
    input:
        expand("FastQC/PRETRIM/{sample}_{num}_fastqc.html", sample=config["samples"], num=['1', '2'])
    output:
        "FastQC/PRETRIM/fastq_multiqc.html"
    wrapper:
        "0.23.1/bio/multiqc"

rule trim_galore_pe:
    input:
        lambda wildcards: expand(f"fastq_files/{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])
    output:
        "trimmed_fastq_files/{wildcards.sample}_1_val_1.fq.gz",
        "trimmed_fastq_files/{wildcards.sample}_1.fastq.gz_trimming_report.txt",
        "trimmed_fastq_files/{wildcards.sample}_2_val_2.fq.gz",
        "trimmed_fastq_files/{wildcards.sample}_2.fastq.gz_trimming_report.txt"
    params:
        extra="--illumina -q 20"
    log:
        "logs/trim_galore/{sample}.log"
    wrapper:
        "0.23.1/bio/trim_galore/pe"

rule fastqc_posttrim:
    input:
        lambda wildcards: expand(f"trimmed_fastq_files/{config['samples'][wildcards.sample]}_{{num}}_val_{{num}}.fq.gz", num=[1,2])
    output:
        # Output needs to end in '_fastqc.html' for multiqc to work
        html="FastQC/POSTTRIM/{sample}_{num}_fastqc.html",
        zip="FastQC/POSTTRIM/{sample}_{num}_fastqc.zip"
    wrapper:
        "0.23.1/bio/fastqc"

rule multiqc_fastq_posttrim:
    input:
        expand("FastQC/POSTTRIM/{sample}_{num}.trim_fastqc.html", sample=config["samples"], num=['1', '2'])
    output:
        "FastQC/POSTTRIM/fastq_multiqc.html"
    wrapper:
        "0.23.1/bio/multiqc"

rule bowtie2:
    input:
        lambda wildcards: expand(f"trimmed_fastq_files/{config['samples'][wildcards.sample]}_{{num}}_val_{{num}}.fq.gz", num=[1,2])
    output:
        "bam_files/{sample}.bam"
    log:
        "logs/bowtie2/{sample}.txt"
    params:
        index=config["index"],  # prefix of reference genome index (built with bowtie2-build),
        extra=""
    threads: 8
    wrapper:
        "0.23.1/bio/bowtie2/align"

При использовании этих новых файлов изначально все работало нормально, частичный список заданий был создан snakemake -np. Однако это связано с тем, что половина полного списка заданий уже была выполнена; то есть папка trimmed_fastq_files была сгенерирована, и внутри нее были установлены правильно названные обрезанные файлы fastq. Когда я удалил все ранее созданные файлы, чтобы посмотреть, будет ли работать вся новая версия Snakefile, snakemake -np завершился неудачно, заявив, что отсутствовали входные файлы для правил, следующих за правилом trim_galore_pe.

Как вы можете видеть, я пытаюсь вызвать набор переменных {wildcard.sample} в разделе ввода правила trim_galore_pe в разделе вывода, но snakemake это не нравится. Возможно ли это сделать?

Я также попробовал это, используя подсказки из ответов ниже, но это тоже не сработало:

rule trim_galore_pe:
    input:
        sample=lambda wildcards: expand(f"fastq_files/{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])
    output:
        expand(f"trimmed_fastq_files/{config['samples'][wildcards.sample]}_{{num}}_val_{{num}}.fq.gz", num=[1,2]),
        expand(f"trimmed_fastq_files/{config['samples'][wildcards.sample]}_{{num}}.fastq.gz_trimming_report.txt", num=[1,2])
    params:
        extra="--illumina -q 20"
    log:
        "logs/trim_galore/{sample}.log"
    wrapper:
        "0.23.1/bio/trim_galore/pe"

Ошибка тогда заявлена ​​wildcards not defined. Итак, логически я попытался поместить lambda wildcards: перед двумя операторами расширения в секции вывода, пытаясь определить подстановочные знаки, но это вызвало синтаксическую ошибку Only input files can be specified as functions. Я также попытался использовать некоторые из приведенных ниже рекомендаций по индексированию, но не смог получить правильную комбинацию.

Это, вероятно, вызвано другой вещью, в которой я не уверен насчет Snakefiles, и именно так работает область видимости.

  • Если я определю переменную в rule all, могут ли все остальные правила получить к ней доступ?
  • Если я определяю переменную в разделе ввода правила, доступна ли она для всех других разделов этого правила (т. Е. Вывод, команда оболочки и т. Д.), Но только для этого правила?
  • Если да, почему я не могу получить доступ к переменной {wildcard.sample}, если я определил ее в разделе ввода? Это потому, что эта переменная заключена в лямбда-функцию с закрытым объемом?

Любые (дальнейшие) предложения будут с благодарностью.

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Я постараюсь ответить на ваш вопрос B и приведу дополнительные подробности, которые, я надеюсь, могут быть полезны вам и другим.

Редактировать: в конце я добавил несколько попыток ответить на вопрос С.

Относительно кавычек

Во-первых, что касается того, что вы называете «кавычками», их обычно называют «одинарными кавычками», и они используются в python для построения строк. Двойные кавычки также могут быть использованы для той же цели. Основное отличие заключается в том, что вы пытаетесь создать строки, содержащие кавычки. Использование двойных кавычек позволяет создавать строки, содержащие одинарные кавычки, и наоборот. В противном случае вам нужно «экранировать» кавычку, используя обратную косую черту («\»):

s1 = 'Contains "double quotes"'
s1_bis = "Contains \"double quotes\""
s2 = "Contains 'single quotes'"
s2_bis = 'Contains \'single quotes\''

(Я предпочитаю двойные кавычки, это просто личный вкус.)

Разобрать пример

rule trim_galore_pe:
    input:
        sample=lambda wildcards: expand(f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])

Вы присваиваете функцию (lambda wildcards: ...) переменной (sample), которая принадлежит к входному разделу правила.

Это заставит snakemake использовать эту функцию, когда дело доходит до определения ввода конкретного экземпляра правила, основываясь на текущих значениях подстановочных знаков (исходя из текущего значения вывода, которое он хочет сгенерировать).

Для ясности, вполне вероятно, что это можно переписать, отделив определение функции от объявления правила, без использования конструкции lambda, и она будет работать идентично:

def determine_sample(wildcards):
    return expand(
        f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz",
        num=[1,2])

rule trim_galore_pe:
    input:
        sample = determine_sample

expand - это функция, специфичная для snakemake (но вы можете импортировать ее в любую программу на python или в интерактивный интерпретатор с from snakemake.io import expand), которая упрощает создание списков строк. В следующем интерактивном сеансе python3.6 мы попытаемся воспроизвести то, что происходит, когда вы его используете, используя различные нативные конструкции python.

Доступ к конфигурации

# We'll try to see how `expand` works, we can import it from snakemake
from snakemake.io import expand
    ​
# We want to see how it works using the following example
# expand(f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])

# To make the example work, we will first simulate the reading
# of a configuration file
import yaml

config_text = """
samples:
    Corces2016_4983.7A_Mono: fastq_files/SRR2920475
    Corces2016_4983.7B_Mono: fastq_files/SRR2920476
cell_types:
    Mono:
    - Corces2016_4983.7A
index: /home/genomes_and_index_files/hg19
"""
# Here we used triple quotes, to have a readable multi-line string.
​
# The following is equivalent to what snakemake does with the configuration file:
config = yaml.load(config_text)
config

Выход:

{'cell_types': {'Mono': ['Corces2016_4983.7A']},
 'index': '/home/genomes_and_index_files/hg19',
 'samples': {'Corces2016_4983.7A_Mono': 'fastq_files/SRR2920475',
  'Corces2016_4983.7B_Mono': 'fastq_files/SRR2920476'}}

Мы получили словарь, в котором ключ «samples» связан с вложенным словарем.

# We can access the nested dictionary as follows
config["samples"]
# Note that single quotes could be used instead of double quotes
# Python interactive interpreter uses single quotes when it displays strings

Выход:

{'Corces2016_4983.7A_Mono': 'fastq_files/SRR2920475',
 'Corces2016_4983.7B_Mono': 'fastq_files/SRR2920476'}
# We can access the value corresponding to one of the keys
# again using square brackets
config["samples"]["Corces2016_4983.7A_Mono"]

Выход:

'fastq_files/SRR2920475'
# Now, we will simulate a `wildcards` object that has a `sample` attribute
# We'll use a namedtuple for that
# https://docs.python.org/3/library/collections.html#collections.namedtuple
from collections import namedtuple
Wildcards = namedtuple("Wildcards", ["sample"])
wildcards = Wildcards(sample="Corces2016_4983.7A_Mono")
wildcards.sample

Выход:

'Corces2016_4983.7A_Mono'

Редактировать (15/11/2018) : Я нашел лучший способ создания подстановочных знаков:

from snakemake.io import Wildcards
wildcards = Wildcards(fromdict={"sample": "Corces2016_4983.7A_Mono"})

# We can use this attribute as a key in the nested dictionary
# instead of using directly the string
config["samples"][wildcards.sample]
# No quotes here: `wildcards.sample` is a string variable

Выход:

'fastq_files/SRR2920475'

Деконструкция expand

# Now, the expand of the example works, and it results in a list with two strings
expand(f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])    
# Note: here, single quotes are used for the string "sample",
# in order not to close the opening double quote of the whole string

Выход:

['fastq_files/SRR2920475_1.fastq.gz', 'fastq_files/SRR2920475_2.fastq.gz']
# Internally, I think what happens is something similar to the following:
filename_template = f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz"

# This template is then used for each element of this "list comprehension"    
[filename_template.format(num=num) for num in [1, 2]]

Выход:

['fastq_files/SRR2920475_1.fastq.gz', 'fastq_files/SRR2920475_2.fastq.gz']
# This is equivalent to building the list using a for loop:
filenames = []
for num in [1, 2]:
    filename = filename_template.format(num=num)
    filenames.append(filename)
filenames

Выход:

['fastq_files/SRR2920475_1.fastq.gz', 'fastq_files/SRR2920475_2.fastq.gz']

Строковые шаблоны и форматирование

# It is interesting to have a look at `filename_template`    
filename_template

Выход:

'fastq_files/SRR2920475_{num}.fastq.gz'
# The part between curly braces can be substituted
# during a string formatting operation:
"fastq_files/SRR2920475_{num}.fastq.gz".format(num=1)

Выход:

'fastq_files/SRR2920475_1.fastq.gz'

Теперь давайте подробнее покажем, как можно использовать форматирование строки.

# In python 3.6 and above, one can create formatted strings    
# in which the values of variables are interpreted inside the string    
# if the string is prefixed with `f`.
# That's what happens when we create `filename_template`:
filename_template = f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz"    
filename_template    

Выход:

'fastq_files/SRR2920475_{num}.fastq.gz'

При форматировании строки произошли две замены:

  1. Значение config['samples'][wildcards.sample] использовалось для создания первой части строки. (Одиночные кавычки использовались около sample, потому что это выражение Python находилось внутри строки, построенной из двойных кавычек.)

  2. Двойные скобки вокруг num были уменьшены до единичных в рамках операции форматирования. Вот почему мы можем использовать это снова в дальнейших операциях форматирования, включая num.

# Equivalently, without using 3.6 syntax:    
filename_template = "{filename_prefix}_{{num}}.fastq.gz".format(
    filename_prefix = config["samples"][wildcards.sample])
filename_template

Выход:

'fastq_files/SRR2920475_{num}.fastq.gz'
# We could achieve the same by first extracting the value
# from the `config` dictionary    
filename_prefix = config["samples"][wildcards.sample]
filename_template = f"{filename_prefix}_{{num}}.fastq.gz"
filename_template

Выход:

'fastq_files/SRR2920475_{num}.fastq.gz'
# Or, equivalently:
filename_prefix = config["samples"][wildcards.sample]
filename_template = "{filename_prefix}_{{num}}.fastq.gz".format(
    filename_prefix=filename_prefix)
filename_template

Выход:

'fastq_files/SRR2920475_{num}.fastq.gz'
# We can actually perform string formatting on several variables
# at the same time:
filename_prefix = config["samples"][wildcards.sample]
num = 1
"{filename_prefix}_{num}.fastq.gz".format(
    filename_prefix=filename_prefix, num=num)

Выход:

'fastq_files/SRR2920475_1.fastq.gz'
# Or, using 3.6 formatted strings
filename_prefix = config["samples"][wildcards.sample]
num = 1
f"{filename_prefix}_{num}.fastq.gz"

Выход:

'fastq_files/SRR2920475_1.fastq.gz'
# We could therefore build the result of the expand in a single step:
[f"{config['samples'][wildcards.sample]}_{num}.fastq.gz" for num in [1, 2]]

Выход:

['fastq_files/SRR2920475_1.fastq.gz', 'fastq_files/SRR2920475_2.fastq.gz']

Комментарии к вопросу C

Следующее немного сложнее с точки зрения того, как Python будет строить строку:

input:
    lambda wildcards: expand(f"fastq_files/{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])

Но это должно работать, как мы можем видеть в следующей симуляции:

from collections import namedtuple
from snakemake.io import expand

Wildcards = namedtuple("Wildcards", ["sample"])
wildcards = Wildcards(sample="Corces2016_4983.7A_Mono")
config = {"samples": {
    "Corces2016_4983.7A_Mono": "SRR2920475",
    "Corces2016_4983.7B_Mono": "SRR2920476"}}
expand(
    f"fastq_files/{config['samples'][wildcards.sample]}_{{num}}.fastq.gz",
    num=[1,2])

Выход:

['fastq_files/SRR2920475_1.fastq.gz', 'fastq_files/SRR2920475_2.fastq.gz']

Проблема в правиле trim_galore_pe на самом деле в его разделе output: вам не следует использовать {wildcards.sample} там, а просто {sample}.

В разделе output правила вы сообщаете snakemake о том, какими будут атрибуты подстановочных знаков для данного экземпляра правила, путем сопоставления файла, который он хочет получить, с данными шаблонами. Части, соответствующие фигурным скобкам, будут использоваться для установки значений имени соответствующего атрибута.

Например, если snakemake хочет файл с именем "trimmed_fastq_files/Corces2016_4983.7A_Mono_1_val_1.fq.gz", он попытается сопоставить его со всеми шаблонами, присутствующими во всех выходных разделах правила, и в конечном итоге найдет этот: "trimmed_fastq_files/{sample}_1_val_1.fq.gz"

К счастью, он сможет сопоставить имя файла с шаблоном, установив соответствие между Corces2016_4983.7A_Mono и частью {sample}. Затем он поместит атрибут sample в локальный экземпляр подстановочных знаков, как если бы я вручную делал следующее:

Wildcards = namedtuple("Wildcards", ["sample"])
wildcards = Wildcards(sample="Corces2016_4983.7A_Mono")

Я не знаю, что именно происходит в snakemake, если вы используете {wildcards.sample} вместо {wildcards}, но давайте попробуем с моей платформой моделирования:

Wildcards = namedtuple("Wildcards", ["sample"])
wildcards = Wildcards(wildcards.sample="Corces2016_4983.7A_Mono")
  File "<ipython-input-12-c02ce12bff85>", line 1
    wildcards = Wildcards(wildcards.sample="Corces2016_4983.7A_Mono")
                         ^
SyntaxError: keyword can't be an expression

А как насчет вашей следующей попытки?

output:
    expand(f"trimmed_fastq_files/{config['samples'][wildcards.sample]}_{{num}}_val_{{num}}.fq.gz", num=[1,2]),

Здесь я понимаю, что Python сначала пытается применить форматирование f к f"trimmed_fastq_files/{config['samples'][wildcards.sample]}_{{num}}_val_{{num}}.fq.gz". Для этого ему нужно будет оценить config['samples'][wildcards.sample], но объект wildcards еще не существует. Отсюда wildcards not defined. wildcards будет сгенерировано только после сопоставления имени файла, необходимого для "нижестоящего" правила, со строкой, содержащей шаблоны {attribute_name}. Но это та строка, которую змеиный в настоящее время пытается построить.

Вот несколько важных моментов, которые следует помнить:

  • wildcards на самом деле существуют только локально, в экземпляре правила, после сопоставления его вывода с файлом, который требуется другому «нижестоящему» экземпляру правила.
  • Вы не определяете переменные во входных секциях. Вы используете переменные для построения конкретных имен файлов, которые понадобятся экземпляру правила (или, точнее, того, что вы говорите, что хотите существовать до того, как экземпляр правила может быть запущен: правилу на самом деле не нужно использовать эти файлы). Эти переменные определены вне области действия правил, непосредственно на уровне земли файла змеи, в чистом режиме Python и локальном объекте wildcards. По умолчанию заполнители {attribute_name} будут заменены атрибутами локального объекта wildcards ("{sample}" становится "Corces2016_4983.7A_Mono"), но если вы хотите сделать более сложные вещи для построения имен файлов, вам нужно сделать это через функцию, которая должна явно обрабатывать этот объект wildcards (lambda wildcards: f"{wildcards.sample}" становится "Corces2016_4983.7A_Mono").
0 голосов
/ 06 мая 2018

В части вашего вопроса я бы предложил использовать файлы с разделителями табуляции для хранения информации о пробах, идентификатора и т. Д., Независимо от количества проб, которые у вас есть. Затем вы можете сохранить путь к этому файлу в вашем конфигурационном файле и получить к нему доступ, используя идентификаторы столбцов в библиотеке pandas. См. эту тему для более подробной информации.

Что касается части B:

  1. Похоже, это новый способ форматирования строки в python, см. эту ссылку для примера.

  2. config['samples'] предназначен для доступа к «образцам» ключа файла конфигурации, а [wildcards.sample] предназначен для доступа к шаблону {sample}, как определено в вашем рабочем процессе (в rule all).

  3. Двойные скобки обычно используются для избежания простых скобок. Здесь он избегает расширения {{num}} (не могу взять пример из документации змеиного мастера).

  4. num=['1', '2'] назначает список значений для подстановочного знака {num}, поэтому позже к нему можно получить доступ с помощью {wildcards.num}. Если все входы и выходы правил связаны, вам не нужно определять эти значения более одного раза.

Надеюсь, это прояснит некоторые ваши проблемы, удачи!

...