jeudi 24 octobre 2019

name input/output files in snakemake according to variable (not wildcard) in config.yaml

I am trying to edit and run a snakemake pipeline. In a nutshell, the snakemake pipeline calls a default genome aligner (minimap) and produces output files with this name. I am trying to add a variable aligner to config.yaml to specify the aligner I want to call. Also (where I am actually stuck), the output files should have the name of the aligner specified in config.yaml.

My config.yaml looks like this:

# this config.yaml is passed to Snakefile in pipeline-structural-variation subfolder.
# Snakemake is run from this pipeline-structural-variation folder; it is necessary to
# pass an appropriate path to the input-files (the ../ prefix is sufficient for this demo)

aligner: "ngmlr" # THIS IS THE VARIABLE I AM ADDING TO THIS FILE. VALUES COULD BE minimap or ngmlr

# FASTQ file or folder containing FASTQ files
# check if this has to be gzipped
input_fastq: "/nexusb/Gridion/20190917PGD2staal2/PD170815/PD170815_cat_all.fastq.gz" # original is ../RawData/GM24385_nf7_chr20_af.fastq.gz

# FASTA file containing the reference genome
# note that the original reference sequence contains only the sequence of chr20
reference_fasta: "/nexus/bhinckel/19/ONT_projects/PGD_breakpoint/ref_hg19_local/hg19_chr1-y.fasta" # original is ../ReferenceData/human_g1k_v37_chr20_50M.fasta

# Minimum SV length
min_sv_length: 300000 # original value was 40

# Maximum SV length
max_sv_length: 1000000 # original value was 1000000. Note that the value I used to run the pipeline for the sample PD170677 was 100000000000, which will be coerced to NA in the R script (/home/bhinckel/ont_tutorial_sv/ont_tutorial_sv.R)

# Min read length. Shorter reads will be discarded
min_read_length: 1000

# Min mapping quality. Reads will lower mapping quality will be discarded
min_read_mapping_quality: 20

# Minimum read support required to call a SV (auto for auto-detect)
min_read_support: 'auto'

# Sample name
sample_name: "PD170815" # original value was GM24385.nf7.chr20_af. Note that this can be a list

I am posting below the sections of my snakefile which generate output files with the extension _minimap2.bam, which I would like to replace by either _minimap2.bam or _ngmlr.bam, depending on aligner on config.yaml

# INPUT BAM folder
bam = None
if "bam" in config:
    bam = os.path.join(CONFDIR, config["bam"])

# INPUT FASTQ folder
FQ_INPUT_DIRECTORY = []
if not bam:
    if not "input_fastq" in config:
        print("\"input_fastq\" not specified in config file. Exiting...")

    FQ_INPUT_DIRECTORY = os.path.join(CONFDIR, config["input_fastq"])
    if not os.path.exists(FQ_INPUT_DIRECTORY):
        print("Could not find {}".format(FQ_INPUT_DIRECTORY))

    MAPPED_BAM = "{sample}/alignment/{sample}_minimap2.bam" # Original
    #MAPPED_BAM = "{sample}/alignment/{sample}_{alignerName}.bam" # this did not work
    #MAPPED_BAM = f"{sample}/alignment/{sample}_{config['aligner']}.bam" # this did nor work either
else:
    MAPPED_BAM = find_file_in_folder(bam, "*.bam", single=True)

...

if config['aligner'] == 'minimap':
    rule index_minimap2:
        input:
            REF = FA_REF
        output:
            "{sample}/index/minimap2.idx"
        threads: config['threads']
        conda: "env.yml"
        shell:
            "minimap2 -t {threads} -ax map-ont --MD -Y {input.REF} -d {output}"


    rule map_minimap2:
        input:
            FQ = FQ_INPUT_DIRECTORY,
            IDX = rules.index_minimap2.output,
            SETUP = "init"
        output:
            BAM = "{sample}/alignment/{sample}_minimap2.bam",
            BAI = "{sample}/alignment/{sample}_minimap2.bam.bai"

        conda: "env.yml"
        threads: config["threads"]
        shell:
            "cat_fastq {input.FQ} | minimap2 -t {threads} -K 500M -ax map-ont --MD -Y {input.IDX} - | samtools sort -@ {threads} -O BAM -o {output.BAM} - && samtools index -@ {threads} {output.BAM}"

else:
    print(f"Aligner is {config['aligner']} - skipping indexing step for minimap2")

    rule map_ngmlr:
        input:
            REF = FA_REF,
            FQ = FQ_INPUT_DIRECTORY,
            SETUP = "init"
        output:
            BAM = "{sample}/alignment/{sample}_minimap2.bam",
            BAI = "{sample}/alignment/{sample}_minimap2.bam.bai"
        conda: "env.yml"
        threads: config["threads"]
        shell:
            "cat_fastq {input.FQ} | ngmlr -r {input.REF} -t {threads} -x ont - | samtools sort -@ {threads} -O BAM -o {output.BAM} - && samtools index -@ {threads} {output.BAM}"

I initially tried to create a alignerName parameter, similar to the sample parameter, as shown below:

# Parameter: sample_name
sample = "sv_sample01"
if "sample_name" in config:
    sample = config['sample_name']

###############
#
# code below created by me
#
###############
# Parameter: aligner_name
alignerName = "defaultAligner"
if "aligner" in config:
    alignerName = config['aligner']

Then I tried to input {alignerName} wherever I have minimap2 on my input/ output files (see commented MAPPED_BAM variable definition above), though this is throwing an error. I guess snakemake will interpret {alignerName} as a wildcard, though what I want is simply to pass the variable name defined in config['aligner'] to input/ output files. I also tried with f-string (MAPPED_BAM = f"{sample}/alignment/{sample}_{config['aligner']}.bam"), though I guess this it did not work either.

Aucun commentaire:

Enregistrer un commentaire