1

I've a snakemake file containing rules to concatenate files listed in a samplesheet. Samplesheet looks like :

sample  unit    fq1 fq2
A   lane1   A.l1.1.R1.txt   A.l1.1.R2.txt
A   lane1   A.l1.2.R1.txt   A.l1.2.R2.txt
A   lane2   A.l2.R1.txt A.l2.R2.txt
B   lane1   B.l1.R1.txt B.l1.R2.txt
B   lane2   B.l2.R1.txt B.l2.R2.txt

My goal is to merge fq1 files from the same sample and same unit and put them in {sample}/fastq/ and to merge the resulting files from on sample (the ones in {sample}/fastq ) in {sample}/bam/

It works ok for the {sample}/fastq but for the {sample}/bam all files listed in {sample}/fastq unrearding the sample will be concatenate in {sample}/bam. Any idea to solve this ?

import pandas as pd
shell.executable("bash")

configfile: "config.yaml"

# open samplesheet
units = pd.read_table(config["units"], dtype=str)

# set df index
units=units.set_index(["sample","unit"])

rule all:
    input:
        expand("{sample}/bam/{sample}_bam.txt",
            sample=units.index.get_level_values('sample').unique().values),

# functions to return information in the samplesheet
def get_fastq_r1(wildcards):
    return units.loc[(wildcards.sample, wildcards.unit), ["fq1"]].dropna().values.flatten()

def get_fastq_r2(wildcards):
    return units.loc[(wildcards.sample, wildcards.unit), ["fq2"]].dropna().values.flatten()

# merge files from the same sample and unit
rule merge_fastq_lane:
    input:
        r1 = get_fastq_r1,
        r2 = get_fastq_r2
    output:
        r1_o = "{sample}/fastq/{sample}_{unit}_merge_R1.fastq",
        r2_o = "{sample}/fastq/{sample}_{unit}_merge_R2.fastq"
    message:
        "Merge fastq from the same sample and lane"
    shell:
        """
        cat {input.r1} > {output.r1_o}
        cat {input.r2} > {output.r2_o}
        """

# merge files from the same sample
rule align_lane:
    input:
        r1 = expand("{sample}/fastq/{sample}_{unit}_merge_R1.fastq",
            unit=units.index.get_level_values('unit').unique().values,
            sample=units.index.get_level_values('sample').unique().values),
        r2 = expand("{sample}/fastq/{sample}_{unit}_merge_R2.fastq",
            unit=units.index.get_level_values('unit').unique().values,
            sample=units.index.get_level_values('sample').unique().values)
    output:
        bam = "{sample}/bam/{sample}_bam.txt"
    message: 
        "Align lane with bwa mem"
    shell:
        """
        cat {input.r1} {input.r2} > {output.bam}
        """
Nicolas Rosewick
  • 1,938
  • 4
  • 24
  • 42

1 Answers1

2

In your rule align_lane, your input lists all the samples possible. Since you're using the sample wildcard in the ouput, I guess that you want to use it in the input. The way to use a wildcard in an expand function is to double the brackets. So I guess your rule should look like this (if I understood correctly):

rule align_lane:
    input:
        r1 = expand("{{sample}}/fastq/{{sample}}_{unit}_merge_R1.fastq",
            unit=units.index.get_level_values('unit').unique().values),
        r2 = expand("{{sample}}/fastq/{{sample}}_{unit}_merge_R2.fastq",
            unit=units.index.get_level_values('unit').unique().values)
    output:
        bam = "{sample}/bam/{sample}_bam.txt"
    message: 
        "Align lane with bwa mem"
    shell:
        """
        cat {input.r1} {input.r2} > {output.bam}
        """
Eric C.
  • 3,310
  • 2
  • 22
  • 29