0

我正在编写一个 GNUmakefile 来创建一个工作流来分析一些生物序列数据。数据采用名为 fastq 的格式,然后经过许多清理和分析工具。我附上了我目前写的内容,从清洁前的质量控制到之后的质量控制,我一路走来。我的问题是我不确定如何运行“fastqc”命令,因为它的目标不依赖于工作流中的任何其他步骤。

 %_sts_fastqc.html %_sts_fastqc.zip: %_sts.fastq
    # perform quality control after cleaning reads
    fastqc $^

%_sts.fastq: %_st.fastq
    # trim reads based on quality
    sickle se -f $^ -t illumina -o $@

%_st.fastq: %_s.fastq
    # remove contaminated reads
    tagdust -s adapters.fa $^

%_s.fastq: %.fastq
    # trim adapters
    scythe -a <adapters.fa> -o $@ $^

%_fastqc.html %_fastqc.zip: %.fastq
    # perform quality control before cleaning reads
    fastqc $^

%.fastq: %.sra
    # convert .fastq to .sra
    fastq-dump $^
4

2 回答 2

1

我相信将这些行添加到 Makefile 的开头会满足您的要求:

SOURCES:=$(wildcard *.sra)
TARGETS:=$(SOURCES:.sra=_fastqc.html) $(SOURCES:.sra=_fastqc.zip)\
     $(SOURCES:.sra=_sts_fastqc.html) $(SOURCES:.sra=_sts_fastqc.zip)

.PHONY: all
all: $(TARGETS)

这样做是从文件系统中获取所有.sra文件,并通过将扩展替换为生成目标所需的任何字符串来构建要构建的目标列表。(注意htmlandzip目标是由同一个命令产生的,我可以有一个或另一个,但我决定把两者都放,以防规则改变并且hmtlandzip目标是分开产生的。)然后它将假all目标设置为构建所有计算的目标。这是我通过添加从您修改的 Makefile@echo我用来检查一切是否正常的所有地方,而无需在 Makefile 中运行实际命令。您可以将其复制并粘贴到一个文件中,以首先检查一切是否正常,然后再使用上面的行修改您自己的 Makefile。这里是:

SOURCES:=$(wildcard *.sra)
TARGETS:=$(SOURCES:.sra=_fastqc.html) $(SOURCES:.sra=_fastqc.zip)\
     $(SOURCES:.sra=_sts_fastqc.html) $(SOURCES:.sra=_sts_fastqc.zip)

.PHONY: all
all: $(TARGETS)

%_sts_fastqc.html %_sts_fastqc.zip: %_sts.fastq
# perform quality control after cleaning reads
    @echo fastqc $^

%_sts.fastq: %_st.fastq
# trim reads based on quality
    @echo sickle se -f $^ -t illumina -o $@

%_st.fastq: %_s.fastq
# remove contaminated reads
    @echo tagdust -s adapters.fa $^

%_s.fastq: %.fastq
# trim adapters
    @echo 'scythe -a <adapters.fa> -o $@ $^'

%_fastqc.html %_fastqc.zip: %.fastq
# perform quality control before cleaning reads
    @echo fastqc $^

%.fastq: %.sra
# convert .fastq to .sra
    @echo fastq-dump $^

我在这里通过运行touch a.sra b.sra然后运行来测试它make。它运行了两个文件的命令。

于 2014-10-17T16:34:15.277 回答
0

而不是使用模式,我会使用“定义”:

 # 'all' is not a file 
.PHONY: all 
# a list of 4 samples
SAMPLES=S1 S2 S3 S4

#define a macro named analyzefastq. It takes one argument $(1). we need to protect the '$' for later expension using $(eval)
define analyzefastq 
# create a .st.fastq from fastq for file $(1)
$(1).st.fastq  : $(1).fastq
    tagdust -s adapters.fa $$^
# create a .fastq from seq for file $(1)
$(1).fastq : $(1).sra
    fastq-dump $$^

endef

#all : final target  dependency is all samples with a suffix '.st.fastq'
all: $(addsuffix ${S}.st.fastq, ${SAMPLES} )

## loop over each sample , name of variable is 'S' call and eval the previous macro, using 'S'=sample for the argument
$(foreach S,${SAMPLES},$(eval $(call analyzefastq,$(S))) )

我还使用我的工具 jsvelocity https://github.com/lindenb/jsvelocity为 NGS 生成大型 Makefile:

https://gist.github.com/lindenb/3c07ca722f793cc5dd60

于 2014-10-17T14:20:13.643 回答