Snakemake: объединение входов с разными суффиксами в вывод с одинаковыми суффиксами

Хорошо, я целый день пытался решить эту проблему, но безрезультатно... Я работаю с загрузкой и анализом данных РНК-секвенирования, и мой анализ включает общедоступные наборы данных, которые бывают двух видов: одностороннее чтение и парное конец читает. По сути, каждый необработанный файл, с которым мой рабочий процесс начинает работать, может быть одним файлом с именем {sample}.fastq.gz или два файла с именем {sample}_1.fastq.gz а также {sample}_2.fastq.gzсоответственно.

У меня есть все образцы и их схемы чтения (и некоторая другая информация) в файле метаданных, который я анализирую с пандами в кадре данных. Мне нужно иметь возможность задавать параметры для моих сценариев (здесь просто touch {output}) для того, чтобы они могли выполнять свои функции в зависимости от схемы чтения (все они являются скриптами bash, использующими программное обеспечение командной строки, например sratools а также STAR). То, что я хочу достичь, это что-то вроде следующего snakemake псевдокод:

# Metadata in a pandas dataframe
metadata = data.frame(SAMPLES, LAYOUTS, ...)

# Function for retrieving metadata
def get_metadata(sample, column):
    result = metadata.loc[metadata['sample'] == sample][column].values[0]
    return result

# Rules
rule all:
    input:
        expand('{sample}.bam', sample = SAMPLES)

rule: download:
    output:
        '{sample}.fastq.gz' for 'SINGLE' in metadata[LAYOUT],
        '{sample}_1.fastq.gz' for 'PAIRED' in metadata[LAYOUT]
    params:
        layout = lambda wildcards:
            get_metadata(wildcards.sample, layout_col)
    shell:
        'touch {output}'

rule align:
    input:
        '{sample}.fastq.gz' for 'SINGLE' in metadata[LAYOUT],
        '{sample}_1.fastq.gz' for 'PAIRED' in metadata[LAYOUT]
    params:
        layout = lambda wildcards:
            get_metadata(wildcards.sample, layout_col)
    output:
        '{sample}.bam'
    shell:
        'touch {output}'

Во всех вариантах кода, которые я пробовал до сих пор, я либо создаю неоднозначные правила, либо создаю односторонние операции чтения для идентификаторов парных концов (и наоборот), либо все это просто не удается. Я предложил два очень неудовлетворительных решения:

  1. Иметь два совершенно отдельных рабочих процесса, один из которых работает на односторонних входах, а другой - на парном, требуя от пользователя ручного запуска обоих
  2. Иметь единый рабочий процесс, который разделяет прочитанные макеты, добавляя префикс 'single'/'paired' для каждого файла в рабочем процессе (т.е. single/{sample}.bam, так далее.)

Первый неудовлетворительный, потому что пользователь должен запустить два разных рабочих процесса, а второй, потому что он добавляет уровень абстракции входных данных, которого нет в выходных данных (так как выходной .bam-файлы создаются независимо от входных макетов чтения с помощью опций в моих скриптах).

У кого-нибудь есть идея, как этого добиться? Если неясно, за чем я буду, я с удовольствием уточню.

1 ответ

Вы можете использовать функцию в качестве ввода:

def align_input(wildcards):
   # Check if wildcards.sample is paired end or single end
   # If single end, return '{sample}.fastq.gz'.format(wildcards.sample)
   # Else, return '{sample}_1.fastq.gz'.format(wildcards.sample) and
   #              '{sample}_2.fastq.gz'.format(wildcards.sample) as list

rule align:
    input: align_input
    output: '{sample}.bam'
    shell: ...

Во-первых, у вас написано правило выравнивания, в котором на входе перечислены все файлы fastq для всех ваших семплов. Вы хотите написать свои правила, чтобы входные данные имели файл (ы) fastq только для одного сэмпла и команду для выравнивания этого сэмпла. Подстановочный знак {образец} означает, что он будет применять это правило ко всем имеющимся образцам, по одному за раз. Вы, вероятно, должны сделать что-то подобное с вашим правилом загрузки.

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

rule align_se:
    input: '{sample}.fastq.gz'
    output: '{sample}.bam'

rule align_pe:
    input: '{sample}_1.fastq.gz', '{sample}_2.fastq.gz'
    output: '{sample}.bam'

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

Другие вопросы по тегам