2015-10-19 2 views
0

У меня есть следующий файл и структуру директорий, которая содержит много файлов и каталогов:объединить файлы Makefile свинца не делать целей

$ tree 
input/ 
├── C-1-28558666 
│ ├── MGRF-C1_S10_L001_R1_001.fastq.gz 
│ ├── MGRF-C1_S10_L001_R2_001.fastq.gz 
│ ├── MGRF-C1_S10_L002_R1_001.fastq.gz 
│ ├── MGRF-C1_S10_L002_R2_001.fastq.gz 
│ ├── MGRF-C1_S10_L003_R1_001.fastq.gz 
│ ├── MGRF-C1_S10_L003_R2_001.fastq.gz 
│ ├── MGRF-C1_S10_L004_R1_001.fastq.gz 
│ └── MGRF-C1_S10_L004_R2_001.fastq.gz 
├── C-2-28577664 
│ ├── MGRF-C2_S11_L001_R1_001.fastq.gz 
│ ├── MGRF-C2_S11_L001_R2_001.fastq.gz 
│ ├── MGRF-C2_S11_L002_R1_001.fastq.gz 
│ ├── MGRF-C2_S11_L002_R2_001.fastq.gz 
│ ├── MGRF-C2_S11_L003_R1_001.fastq.gz 
│ ├── MGRF-C2_S11_L003_R2_001.fastq.gz 
│ ├── MGRF-C2_S11_L004_R1_001.fastq.gz 
│ └── MGRF-C2_S11_L004_R2_001.fastq.gz 
... 

Каждое имя файла содержит R1 или R2. Файлы с R1 и R2 принадлежат друг другу, а ниже commanand использует два файла и файл dm6.fasta.bwt.

bwa mem ref/dm6.fasta.bwt input/C-1-28558666/MGRF-C1_S10_L001_R1_001.fastq.gz input/C-1-28558666/MGRF-C1_S10_L001_R2_001.fastq.gz | samtools view -Sb - > BAMs/C-1-28558666/MGRF-C1_S10_L001.bam 

Я попытался написать следующее правило: Makefile

BAMs/%.bam: $(addsuffix .bwt,${REFERENCE}) $(foreach SIDE,R1 R2, ../MGRF_NGS_KUMARAN-25071046/*/*${SIDE}*.fq.gz) 
    bwa mem ${REFERENCE} $(filter %.fq.gz,$^) | samtools view -Sb - > @> 

Однако я получил:

$ make -n 
make: *** No targets. Stop. 

Как это можно исправить выше Makefile?

+1

Если это весь ваш Makefile, то ваша проблема в том, что вы не сказали сделать, чтобы фактически создавать любые файлы. Вы только что дали ему шаблон для сопоставления целевых имен файлов. Это сказано, что makefile target/etc. совсем не собирается делать то, что вы хотите. –

+0

Я только начал с первого правила. Как я могу описать приведенный выше пример для сборки файлов? – user977828

+0

Вам нужно на самом деле сказать make для создания целей: 'make BAMs/file.bam', например, или иметь цель как' all: BAMs/file.bam BAMs/otherfile.bam ... 'в вашем make-файле, поэтому make имеет по умолчанию. Но, как я сказал, ваше целевое правило имеет * хост * других проблем. –

ответ

1

Ваша первая проблема связана с тем, что правила шаблонов не создают цели, если они явно не запрашиваются. Таким образом, вам нужно явно указать цели для создания. В следующем примере они перечислены в переменной BAMS и затем используются в качестве зависимостей цели all, которая является первой из make-файла. all, таким образом, является целью по умолчанию и печатает make или make all будет строить все bams.

Ваша вторая проблема заключается в том, чтобы обрабатывать пары R1 и R2 зависимостей каждой цели bam. GNU сделать статические шаблонные правила действительно полезны в таких ситуациях:

REFERENCE := ref/dm6.fasta 
DIRS := $(wildcard input/*) 
R1S := $(foreach dir,$(DIRS),$(wildcard $(dir)/*_R1_001.fastq.gz)) 
RR1S := $(patsubst input/%_R1_001.fastq.gz,%,$(R1S)) 
BAMS := $(patsubst %,BAMs/%.bam,$(RR1S)) 

all: $(BAMS) 

$(BAMS): BAMs/%.bam: $(REFERENCE).bwt input/%_R1_001.fastq.gz input/%_R2_001.fastq.gz 
    @mkdir -p $(dir [email protected]); \ 
    bwa mem $^ | samtools view -Sb - > [email protected] 

target: target-pattern: prerequisite-pattern статическое шаблонное правило.

ГНУ сделать также имеет несколько функций (call, eval, foreach), которые могут быть использованы в более сложных примеров:

REFERENCE := ref/dm6.fasta 
DIRS := $(wildcard input/*) 
R1S := $(foreach dir,$(DIRS),$(wildcard $(dir)/*_R1_001.fastq.gz)) 
RR1S := $(patsubst input/%_R1_001.fastq.gz,%,$(R1S)) 
BAMS := $(patsubst %,BAMs/%.bam,$(RR1S)) 

all: $(BAMS) 

define BAM_rule 
BAMs/$(1).bam: $(REFERENCE).bwt input/$(1)_R1_001.fastq.gz input/$(1)_R2_001.fastq.gz 
    @mkdir -p $$(dir [email protected]); \ 
    bwa mem $$^ | samtools view -Sb - > [email protected] 
endef 

$(foreach r,$(RR1S),$(eval $(call BAM_rule,$(r)))) 

Пояснения:

В RR1S переменных перечислены все C-1-28558666/MGRF-C1_S10_L001 стебли. Затем он используется для создания переменной BAMS, в которой перечислены цели. Переменная BAM_rule является скелетом правила, которое строит цель bam из соответствующих ей зависимостей R1 и R2. $(1) - параметр, который будет расширен при использовании функции call: $(call BAM_rule,foo) расширяет BAM_rule и заменяет все $(1) событиями foo. Обратите внимание, что некоторые знаки $ должны быть удвоены, чтобы сохранить это первое расширение. Наконец,

$(foreach r,$(RR1S),$(eval $(call BAM_rule,$(r)))) 

перебирает все стебли и использует функцию eval экземпляр одного BAM_rule на стебле, расширенной и специализированной по call.

Нормальное расширение сделает затем трансформировать каждый экземпляр BAM_rule в правило можно было бы написать вручную для данной цели:

BAMs/C-1-28558666/MGRF-C1_S10_L001.bam: ref/dm6.fasta.bwt input/C-1-28558666/MGRF-C1_S10_L001_R1_001.fastq.gz input/C-1-28558666/MGRF-C1_S10_L001_R2_001.fastq.gz 
    @mkdir -p BAMs/C-1-28558666; \ 
    bwa mem ref/dm6.fasta.bwt input/C-1-28558666/MGRF-C1_S10_L001_R1_001.fastq.gz input/C-1-28558666/MGRF-C1_S10_L001_R2_001.fastq.gz | samtools view -Sb - > BAMs/C-1-28558666/MGRF-C1_S10_L001.bam 
+0

Спасибо, но я не могу понять, как 2 файла FASTQ (** R1 ** и ** R2 **) создают 1 файл BAM, например. 'input/C-1-28558666/MGRF-C1_S10_L001_R1_001.fastq.gz вход/C-1-28558666/MGRF-C1_S10_L001_R2_001.fastq.gz | samtools view -Sb -> BAMs/C-1-28558666/MGRF-C1_S10_L001.bam'? – user977828

+0

Является константой '_001.fastq.gz' или у вас есть' _002.fastq.gz' ...? –

+0

Да, '_001.fastq.gz' является константой, и нет' _002.fastq.gz'. – user977828

Смежные вопросы