Makefile 使用(GNU)make创建数据分析管道

Makefile 使用(GNU)make创建数据分析管道,makefile,gnu-make,data-analysis,Makefile,Gnu Make,Data Analysis,我是一名科学家,分析从多个学科收集的大脑数据。在分析过程中,数据通过多个步骤进行处理,有点像烹饪食谱。在这一行的末尾,有一个步骤,收集所有个体受试者的已处理数据,并创建摘要统计数据,以此类推 由于一个步骤可能需要一个小时才能完成,我希望有一种自动化的方式来运行所有主题的所有步骤并计算摘要统计信息,而不必重复过去已经完成的步骤 Make似乎是一个很好的实用工具,但我需要一些关于Makefile结构的帮助。以下是一个简化的示例: # Keep intermediate files! .SECONDA

我是一名科学家,分析从多个学科收集的大脑数据。在分析过程中,数据通过多个步骤进行处理,有点像烹饪食谱。在这一行的末尾,有一个步骤,收集所有个体受试者的已处理数据,并创建摘要统计数据,以此类推

由于一个步骤可能需要一个小时才能完成,我希望有一种自动化的方式来运行所有主题的所有步骤并计算摘要统计信息,而不必重复过去已经完成的步骤

Make似乎是一个很好的实用工具,但我需要一些关于
Makefile
结构的帮助。以下是一个简化的示例:

# Keep intermediate files!
.SECONDARY:

# In this simplified example, there are 3 subjects, in reality there are more 
SUBJECTS = subject_a subject_b subject_c

# In this simplified example there are 3 data processing steps, each one taking
# one file as input and emitting one file as output. In reality, there are more
# steps and each step takes multiple input files and emits multiple output
# files.
step1_%.dat : step1.py input_%.dat
    touch step1_$*.dat

step2_%.dat : step2.py step1_%.dat
    touch step2_$*.dat

# Let's say this step produces many output files
STEP3_PROD = step3_%_1.dat step3_%_2.dat step3_%_3.dat
$(STEP3_PROD) : step3.py step2_%.dat
    touch $(STEP3_PROD)

# Meta rule to perform the complete analysis for a single subject
.PHONY : $(SUBJECTS)
subject_% : step1_%.dat step2_%.dat $(STEP3_PROD)
    @echo 'Analysis complete for subject $*.'

# The summary depends on the analysis of all subjects being complete.
summary.dat : summary.py $(SUBJECTS)
    touch summary.dat
    @echo 'All analysis done!'

all : summary.dat
上述
Makefile
的问题是,即使没有任何更改,也始终执行摘要步骤
python summary.py
。这可能是因为它依赖于虚假的
subject%
规则,该规则始终是build


是否有方法构造此脚本,以避免不必要地执行摘要步骤?也许有某种方法可以扩展所有科目的
$(STEP3\u-PROD)

不要过度编译,否则会适得其反。尝试以下方法:

.SECONDARY:

all: summary.dat

SUBJECTS:=a b c
SUBJECT_RULES:=$(addprefix subject_, $(SUBJECTS))
.PHONY: $(SUBJECT_RULES)

subject_a: step3_a_1.dat
subject_b: step3_b_1.dat
subject_c: step3_c_1.dat

step1_%.dat: input_%.dat
    touch $@

step2_%.dat: step1_%.dat
    touch $@

step3_%_1.dat: step2_%.dat
    touch $@

STEP3_PRE:=$(addprefix step3_, $(SUBJECTS))
STEP3_1_OUT:=$(addsuffix _1.dat, $(STEP3_PRE))
STEP3_ALL_OUT:=$(STEP3_1_OUT) \
    $(addsuffix _2.dat, $(STEP3_PRE)) \
    $(addsuffix _3.dat, $(STEP3_PRE))

summary.dat: $(STEP3_1_OUT)
    @echo "summary: $(STEP3_ALL_OUT)"
    touch $@

我认为没有必要跟踪
step3%\u 2.dat
等等,因为它们是用
step3%\u 1.dat
重建的。

我以前用这种方式做我自己的数据分析。当心。我最终得到了一个包含190条模式规则的
Makefile
。我必须修补
make
,以允许同一规则在同一链中多次使用。我不得不做很多
包括
foreach
-
调用
-
求值
循环,后者完全无法维护。这个想法很好,但事实上它是无法维持的。我从来没有找到更好的替代品(毫无疑问,很多替代品都存在),但我很清楚,在某种程度上,将所有规则写入表单
make
所需的成本将高于收益。在寻找解决方案时,我偶然发现了“doit”工具。它似乎是一个构建系统,基本上是从一个简单的Python脚本到支持依赖项检查的一个步骤。它实际上非常适合我的需要:我最终将
addprefix
/
addsuffix
位重写为(
patsubst%,step3%.dat,$(主题))