# ===============================================
# USER CONFIGURATION
# ===============================================
MAKEFLAGS += --output-sync

METHYLATION_SCALE ?= beta
SCALE_VARS ?= NULL
SCALE_VARS_GLM ?= $(SCALE_VARS)
SCALE_VARS_LME ?= $(SCALE_VARS)
optional_text_arg = $(if $(filter NULL null,$(strip $(1))),NULL,$(if $(strip $(1)),'$(strip $(1))',NULL))
COVARIATES_ARG = $(call optional_text_arg,$(COVARIATES))
FACTOR_VARS_ARG = $(call optional_text_arg,$(FACTOR_VARS))
SCALE_VARS_GLM_ARG = $(call optional_text_arg,$(SCALE_VARS_GLM))
SCALE_VARS_LME_ARG = $(call optional_text_arg,$(SCALE_VARS_LME))
LME_CORRELATION_VAR ?= NULL
PROBE_EXCLUSION_FILE ?= $(CROSS_REACTIVE_FILE)
REMOVE_SEX_MISMATCH ?= FALSE
PROBE_EXCLUSION_ID_COLUMN ?= $(CROSS_REACTIVE_ID_COLUMN)
USE_EPICV2_MANIFEST ?= FALSE
EPICV2_MANIFEST_CH_WGBS_EVIDENCE ?= TRUE
EPICV2_MANIFEST_CH_BLAT ?= TRUE
EPICV2_MANIFEST_MISSING_POS ?= TRUE
EPICV2_MANIFEST_MISMATCH_POS ?= FALSE
SEP_TYPE_ARG ?= '$(SEP_TYPE)'
PROBE_EXCLUSION_ID_COLUMN_ARG ?= '$(PROBE_EXCLUSION_ID_COLUMN)'
empty :=
space := $(empty) $(empty)
comma := ,
TIMEPOINT_LIST = $(strip $(subst $(comma), ,$(TIMEPOINTS)))
COMBINE_TIMEPOINT_LIST = $(strip $(subst $(comma), ,$(COMBINE_TIMEPOINTS)))
TIMEPOINT_SUFFIXES = $(addprefix T,$(TIMEPOINT_LIST))
COMBINED_TIMEPOINT_SUFFIX = T$(subst $(space),T,$(COMBINE_TIMEPOINT_LIST))
GLM_TIMEPOINT ?= $(firstword $(TIMEPOINT_LIST))
GLM_TIMEPOINT_SUFFIX = T$(GLM_TIMEPOINT)
ifeq ($(METHYLATION_SCALE),beta)
PHENO_METHYLATION_PREFIX = phenoB
else ifeq ($(METHYLATION_SCALE),m)
PHENO_METHYLATION_PREFIX = phenoM
else ifeq ($(METHYLATION_SCALE),cn)
PHENO_METHYLATION_PREFIX = phenoCN
else
$(error METHYLATION_SCALE must be one of beta, m, cn)
endif
TIMEPOINT_PHENO_TARGETS = $(addprefix $(DATA_DIR)/$(MODEL)/$(STEP3)/pheno,$(addsuffix .csv,$(TIMEPOINT_SUFFIXES)))
TIMEPOINT_PHENO_METHYLATION_TARGETS = $(addprefix $(RDATA_DIR)/$(MODEL)/$(STEP3)/$(MERGE_DIR)/$(PHENO_METHYLATION_PREFIX),$(addsuffix .RData,$(TIMEPOINT_SUFFIXES)))
COMBINED_PHENO_TARGET = $(DATA_DIR)/$(MODEL)/$(STEP3)/pheno$(COMBINED_TIMEPOINT_SUFFIX).csv
GLM_PHENO_METHYLATION = $(RDATA_DIR)/$(MODEL)/$(STEP3)/$(MERGE_DIR)/$(PHENO_METHYLATION_PREFIX)$(GLM_TIMEPOINT_SUFFIX).RData
COMBINED_PHENO_METHYLATION = $(RDATA_DIR)/$(MODEL)/$(STEP3)/$(MERGE_DIR)/$(PHENO_METHYLATION_PREFIX)$(COMBINED_TIMEPOINT_SUFFIX).RData
ifneq ($(strip $(SEED)),)
SET_SEED_EXPR = set.seed($(SEED));
else
SET_SEED_EXPR =
endif
ifeq ($(strip $(LME_CORRELATION_VAR)),)
LME_CORRELATION_VAR_ARG = NULL
else
ifeq ($(strip $(LME_CORRELATION_VAR)),NULL)
LME_CORRELATION_VAR_ARG = NULL
else
LME_CORRELATION_VAR_ARG = '$(LME_CORRELATION_VAR)'
endif
endif
PHENO_LC = $(DATA_DIR)/$(MODEL)/$(STEP1)/phenoLC.csv
SVA_MARKER = $(DATA_DIR)/$(MODEL)/$(STEP2)/.sva_complete
GLM_REPORT_ASSET_DIR = $(STEP6)/$(MODEL)/assets/results/glm_results
LME_REPORT_ASSET_DIR = $(STEP6)/$(MODEL)/assets/results/lme_results
GLM_WORKBOOK = $(DATA_DIR)/$(MODEL)/$(STEP4)/annotatedGLM.xlsx
LME_WORKBOOK = $(DATA_DIR)/$(MODEL)/$(STEP5)/annotatedLME.xlsx
GLM_REPORT_SIDECARS = \
	$(GLM_REPORT_ASSET_DIR)/annotatedGLM.tsv.gz \
	$(GLM_REPORT_ASSET_DIR)/annotatedGLM.report.tsv \
	$(GLM_REPORT_ASSET_DIR)/annotatedGLM.dictionary.tsv \
	$(GLM_REPORT_ASSET_DIR)/annotatedGLM.metadata.tsv
LME_REPORT_SIDECARS = \
	$(LME_REPORT_ASSET_DIR)/annotatedLME.tsv.gz \
	$(LME_REPORT_ASSET_DIR)/annotatedLME.report.tsv \
	$(LME_REPORT_ASSET_DIR)/annotatedLME.dictionary.tsv \
	$(LME_REPORT_ASSET_DIR)/annotatedLME.metadata.tsv
GLM_OUTPUTS = $(GLM_WORKBOOK) $(GLM_REPORT_SIDECARS)
LME_OUTPUTS = $(LME_WORKBOOK) $(LME_REPORT_SIDECARS)

# ===============================================
# Run all models 
# ===============================================
models:
	@echo "Running models in parallel: $(MODELS)"
	@$(MAKE) -j $(words $(MODELS)) $(addprefix run-, $(MODELS))

$(foreach m,$(MODELS),$(eval run-$(m):; \
	@echo ">>> Starting full pipeline for: $(m)"; \
	$(MAKE) -j1 all MODEL=$(m); \
	@echo "<<< Finished full pipeline for: $(m)" \
))

default: all

all: \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/m_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/beta_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/cn_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(SVA_MARKER) \
	$(PHENO_LC) \
	$(TIMEPOINT_PHENO_TARGETS) \
	$(TIMEPOINT_PHENO_METHYLATION_TARGETS) \
	$(COMBINED_PHENO_TARGET) \
	$(COMBINED_PHENO_METHYLATION) \
	$(GLM_OUTPUTS) \
	$(LME_OUTPUTS) \
	$(STEP6)/$(MODEL)/docs/index.html
	
# ===============================================
# Group target: first3 (Steps 1 to 3)
# ===============================================
.PHONY: f3
FIRST3 = \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/m_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/beta_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/cn_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(SVA_MARKER) \
	$(PHENO_LC) \
	$(TIMEPOINT_PHENO_TARGETS) \
	$(TIMEPOINT_PHENO_METHYLATION_TARGETS) \
	$(COMBINED_PHENO_TARGET) \
	$(COMBINED_PHENO_METHYLATION)

f3: $(FIRST3) $(STEP6)/$(MODEL)/docs/index.html

# ===============================================
# Run f3 (Steps 1 to 3) for all models in parallel
# ===============================================
f3_models:
	@echo "Running f3 (Steps 1â€“3) in parallel: $(MODELS)"
	@$(MAKE) -j $(words $(MODELS)) $(addprefix runf3-, $(MODELS))

$(foreach m,$(MODELS),$(eval runf3-$(m):;  \
	@echo ">>> Starting f3 for: $(m)"; \
	$(MAKE) -j1 f3 MODEL=$(m); \
	@echo "<<< Finished f3 for: $(m)" \
))

# ===============================================
# Group target: f4 (Steps 1 to 4)
# ===============================================
.PHONY: f4
FIRST4 = \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/m_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/beta_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/cn_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(SVA_MARKER) \
	$(PHENO_LC) \
	$(TIMEPOINT_PHENO_TARGETS) \
	$(TIMEPOINT_PHENO_METHYLATION_TARGETS) \
	$(COMBINED_PHENO_TARGET) \
	$(COMBINED_PHENO_METHYLATION) \
	$(GLM_OUTPUTS)

f4: $(FIRST4) $(STEP6)/$(MODEL)/docs/index.html

# ===============================================
# Run f4 (Steps 1 to 4 only) for all models in parallel
# ===============================================
f4_models:
	@echo "Running f4 (Steps 1â€“4) in parallel: $(MODELS)"
	@$(MAKE) -j $(words $(MODELS)) $(addprefix runf4-, $(MODELS))

$(foreach m,$(MODELS),$(eval runf4-$(m):; \
	@echo ">>> Starting f4 for: $(m)"; \
	$(MAKE) -j1 f4 MODEL=$(m); \
	@echo "<<< Finished f4 for: $(m)" \
))

# ===============================================
# Group target: f3lme (Steps 1 to 3 + LME)
# ===============================================
.PHONY: f3lme
F3LME = \
  $(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/m_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/beta_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/cn_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(SVA_MARKER) \
	$(PHENO_LC) \
	$(TIMEPOINT_PHENO_TARGETS) \
	$(TIMEPOINT_PHENO_METHYLATION_TARGETS) \
	$(COMBINED_PHENO_TARGET) \
	$(COMBINED_PHENO_METHYLATION) \
	$(LME_OUTPUTS)

f3lme: $(F3LME) $(STEP6)/$(MODEL)/docs/index.html

# ===============================================
# Run f3lme (Steps 1 to 3 + LME) for all models in parallel
# ===============================================

f3lme_models:
	@echo "Running f3lme (Steps 1â€“3 + LME) in parallel: $(MODELS)"
	@$(MAKE) -j $(words $(MODELS)) $(addprefix runf3lme-, $(MODELS))

$(foreach m,$(MODELS),$(eval runf3lme-$(m):; \
	@echo ">>> Starting f3lme for: $(m)"; \
	$(MAKE) -j1 f3lme MODEL=$(m); \
	@echo "<<< Finished f3lme for: $(m)" \
))

# =================================================================================================================================
# Step 1: Minfi Preprocessing
# =================================================================================================================================
MODEL_LOG_DIR = $(abspath $(LOGS_DIR)/$(MODEL))
STEP1_PRIMARY = $(RDATA_DIR)/$(MODEL)/$(STEP1)/$(OBJ_DIR)/RGSet.RData
STEP1_DERIVED = \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/m_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/beta_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/cn_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(QC_DIR)/detP_RGSet.RData \
	$(PHENO_LC)

step1:
	@echo "Running Step 1 for $(MODEL)"
	@$(MAKE) -j1 \
	  $(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/m_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	  $(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/beta_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	  $(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/cn_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	  $(RDATA_DIR)/$(MODEL)/$(STEP1)/$(QC_DIR)/detP_RGSet.RData \
	  $(PHENO_LC) \
	  MODEL=$(MODEL)

$(STEP1_PRIMARY): $(PHENO_FILE)
	@Rscript -e "$(SET_SEED_EXPR) suppressPackageStartupMessages(library(dnaEPICO)); invisible(preprocessingMinfiEwasWater( \
	  phenoFile = '$(PHENO_FILE)', \
	  sepType = $(SEP_TYPE_ARG), \
	  idatFolder = '$(DATA_DIR)/$(STEP1)/$(IDAT_DIR)/', \
	  outputLogs = '$(MODEL_LOG_DIR)', \
	  nSamples = $(N_SAMPLES), \
	  SampleID = '$(SAMPLE_ID)', \
	  arrayType = '$(ARRAY_TYPE)', \
	  annotationVersion = '$(ANNOTATION_VERSION)', \
	  idatForce = $(IDAT_FORCE), \
	  scriptLabel = '$(MODEL)/$(STEP1)', \
	  baseDataFolder = '$(RDATA_DIR)', \
	  figureBaseDir = '$(FIGURES_DIR)', \
	  tiffWidth = $(TIFF_WIDTH), \
	  tiffHeight = $(TIFF_HEIGHT), \
	  tiffRes = $(TIFF_RES), \
	  qcCutoff = $(QC_CUTOFF), \
	  detPtype = '$(DET_PTYPE)', \
	  detPThreshold = $(DET_PTHRESHOLD), \
	  sexColumn = '$(SEX_COLUMN)', \
	  removeSexMismatch = $(REMOVE_SEX_MISMATCH), \
	  pvalThreshold = $(PVAL_THRESHOLD), \
	  chrToRemove = '$(CHR_TO_REMOVE)', \
	  snpsToRemove = '$(SNPS_TO_REMOVE)', \
	  probeExclusionPath = '$(PROBE_EXCLUSION_FILE)', \
	  probeExclusionIdColumn = $(PROBE_EXCLUSION_ID_COLUMN_ARG), \
	  useEpicV2Manifest = $(USE_EPICV2_MANIFEST), \
	  epicV2ManifestFlags = c( \
	    CH_WGBS_evidence = $(EPICV2_MANIFEST_CH_WGBS_EVIDENCE), \
	    CH_BLAT = $(EPICV2_MANIFEST_CH_BLAT), \
	    MissingPos = $(EPICV2_MANIFEST_MISSING_POS), \
	    MismatchPos = $(EPICV2_MANIFEST_MISMATCH_POS)), \
	  mafThreshold = $(MAF_THRESHOLD), \
	  plotGroupVar = '$(PLOT_GROUP_VAR)', \
	  lcRef = '$(LC_REF)', \
	  phenoOrder = '$(PHENO_ORDER)', \
	  lcPhenoDir = '$(DATA_DIR)/$(MODEL)/$(STEP1)', \
	  logs = TRUE, \
	  saveOutputs = TRUE ))"

$(STEP1_DERIVED): $(STEP1_PRIMARY)
	@test -e "$@" || { echo "Step 1 did not create expected output: $@"; exit 1; }

# =================================================================================================================================
# Step 2: Surrogate Variable Analysis
# =================================================================================================================================
step2:
	@echo "Running Step 2 for $(MODEL)"
	@$(MAKE) -j1 $(SVA_MARKER) MODEL=$(MODEL)

$(SVA_MARKER): $(PHENO_LC) $(RDATA_DIR)/$(MODEL)/$(STEP1)/$(OBJ_DIR)/RGSet.RData
	@Rscript -e "if (file.exists('$(SVA_MARKER)')) unlink('$(SVA_MARKER)')"
	@Rscript -e "suppressPackageStartupMessages(library(dnaEPICO)); invisible(svaEnmix( \
	  phenoFile = '$(PHENO_LC)', \
	  rgsetData = '$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(OBJ_DIR)/RGSet.RData', \
	  sepType = $(SEP_TYPE_ARG), \
	  outputLogs = '$(MODEL_LOG_DIR)', \
	  nSamples = $(N_SAMPLES), \
	  SampleID = '$(SAMPLE_ID)', \
	  arrayType = '$(ARRAY_TYPE)', \
  	  annotationVersion = '$(ANNOTATION_VERSION)', \
  	  SentrixIDColumn = '$(SENTRIX_ID_COLUMN)', \
	  SentrixPositionColumn = '$(SENTRIX_POSITION_COLUMN)', \
	  ctrlSvaPercVar = $(CTRL_SVA_PERC_VAR), \
  	  ctrlSvaFlag = $(CTRL_SVA_FLAG), \
	  scriptLabel = '$(MODEL)/$(STEP2)', \
	  figureBaseDir = '$(FIGURES_DIR)', \
	  dataBaseDir = '$(DATA_DIR)', \
	  rBaseDir = '$(RDATA_DIR)', \
	  tiffWidth = $(TIFF_WIDTH), \
	  tiffHeight = $(TIFF_HEIGHT), \
	  tiffRes = $(TIFF_RES), \
	  logs = TRUE, \
	  saveOutputs = TRUE ))"
	@Rscript -e "if (!file.exists('$(PHENO_LC)')) stop('SVA phenotype file is missing.', call. = FALSE); dir.create(dirname('$(SVA_MARKER)'), recursive = TRUE, showWarnings = FALSE); if (!file.create('$(SVA_MARKER)')) stop('Could not create the SVA completion marker.', call. = FALSE)"

# =================================================================================================================================
# Step 3: Merge Phenotype
# =================================================================================================================================
STEP3_PRIMARY = $(COMBINED_PHENO_METHYLATION)
STEP3_DERIVED = \
	$(TIMEPOINT_PHENO_TARGETS) \
	$(TIMEPOINT_PHENO_METHYLATION_TARGETS) \
	$(COMBINED_PHENO_TARGET)

step3:
	@echo "Running Step 3 for $(MODEL)"
	@$(MAKE) -j1 \
	  $(TIMEPOINT_PHENO_TARGETS) \
	  $(TIMEPOINT_PHENO_METHYLATION_TARGETS) \
	  $(COMBINED_PHENO_TARGET) \
	  $(COMBINED_PHENO_METHYLATION) \
	  MODEL=$(MODEL)

$(STEP3_PRIMARY): $(SVA_MARKER) $(PHENO_LC) \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/beta_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/m_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/cn_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData
	@Rscript -e "suppressPackageStartupMessages(library(dnaEPICO)); invisible(preprocessingPheno( \
	  phenoFile = '$(PHENO_LC)', \
	  sepType = $(SEP_TYPE_ARG), \
	  betaPath = '$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/beta_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData', \
	  mPath = '$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/m_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData', \
	  cnPath = '$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/cn_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData', \
	  SampleID = '$(SAMPLE_ID)', \
	  timeVar = '$(TIME_VAR)', \
	  timepoints = '$(TIMEPOINTS)', \
	  combineTimepoints = '$(COMBINE_TIMEPOINTS)', \
	  methylationScale = '$(METHYLATION_SCALE)', \
	  outputPheno = '$(DATA_DIR)/$(MODEL)/$(STEP3)', \
	  outputRData = '$(RDATA_DIR)/$(MODEL)/$(STEP3)/$(METRICS_DIR)', \
	  outputRDataMerge = '$(RDATA_DIR)/$(MODEL)/$(STEP3)/$(MERGE_DIR)', \
	  outputLogs = '$(MODEL_LOG_DIR)', \
	  sexColumn = '$(SEX_COLUMN)', \
	  outputDir = '$(DATA_DIR)/$(MODEL)/$(STEP3)', \
	  logs = TRUE, \
	  saveOutputs = TRUE ))"  

$(STEP3_DERIVED): $(STEP3_PRIMARY)
	@test -e "$@" || { echo "Step 3 did not create expected output: $@"; exit 1; }
	  
# =================================================================================================================================
# Step 4: methylationGLM
# =================================================================================================================================
$(GLM_OUTPUTS) &: $(GLM_PHENO_METHYLATION)
	@Rscript -e "suppressPackageStartupMessages(library(dnaEPICO)); invisible(methylationGLM( \
	  inputPheno = '$(GLM_PHENO_METHYLATION)', \
	  outputLogs = '$(MODEL_LOG_DIR)', \
	  outputRData = '$(RDATA_DIR)/$(MODEL)/$(STEP4)/$(MODEL_DIR)', \
	  outputPlots = '$(FIGURES_DIR)/$(MODEL)/$(STEP4)/', \
	  phenotypes = '$(PHENOTYPES_GLM)', \
	  covariates = $(COVARIATES_ARG), \
	  factorVars = $(FACTOR_VARS_ARG), \
	  scaleVars = $(SCALE_VARS_GLM_ARG), \
	  cpgPrefix = '$(CPG_PREFIX)', \
	  cpgLimit = $(CPG_LIMIT), \
	  methylationScale = '$(METHYLATION_SCALE)', \
	  nCores = $(N_CORES), \
	  plotWidth = $(TIFF_WIDTH), \
	  plotHeight = $(TIFF_HEIGHT), \
	  plotDPI = $(TIFF_RES), \
	  interactionTerm = $(INTERACTION_GLM_ARG), \
	  libPath = $(R_DIR_ARG), \
	  glmLibs = '$(GLM_LIBS)', \
	  prsMap = $(PRS_MAP_ARG), \
	  summaryPval = $(SUMMARY_PVAL), \
	  summaryResidualSD = $(SUMMARY_RESIDUAL_SD), \
	  saveSignificantCpGs = $(SAVE_SIGNIFICANT_CPGS), \
	  significantCpGDir = '$(RESULTS_DIR)/$(MODEL)/$(CPG_DIR)/$(STEP4)', \
	  significantCpGPval = $(SIGNIFICANT_CPG_PVAL), \
	  saveTxtSummaries = $(SAVE_TXT_SUMMARIES), \
	  chunkSize = $(CHUNK_SIZE), \
	  summaryTxtDir = '$(RESULTS_DIR)/$(MODEL)/$(SUMMARY_DIR)/$(STEP4)', \
	  fdrThreshold = $(FDR_THRESHOLD), \
	  padjmethod = '$(PADJ_METHOD)', \
	  annotationPackage = '$(ANNOTATION_PACKAGE)', \
	  annotationCols = '$(ANNOTATION_COLS)', \
	  annotatedGLMOut = '$(DATA_DIR)/$(MODEL)/$(STEP4)', \
	  reportAssetsDir = '$(GLM_REPORT_ASSET_DIR)', \
	  logs = TRUE, \
	  saveOutputs = TRUE )) "

# =================================================================================================================================
# Step 5: methylationLME
# =================================================================================================================================
$(LME_OUTPUTS) &: $(COMBINED_PHENO_METHYLATION)
	@Rscript -e "suppressPackageStartupMessages(library(dnaEPICO)); invisible(methylationLME( \
	  inputPheno = '$(COMBINED_PHENO_METHYLATION)', \
	  outputLogs = '$(MODEL_LOG_DIR)', \
	  outputRData = '$(RDATA_DIR)/$(MODEL)/$(STEP5)/$(MODEL_DIR)', \
	  outputPlots = '$(FIGURES_DIR)/$(MODEL)/$(STEP5)', \
	  personVar = '$(PERSON_VAR)', \
	  timeVar = '$(TIME_VAR)', \
	  phenotypes = '$(PHENOTYPES_LME)', \
	  covariates = $(COVARIATES_ARG), \
	  factorVars = $(FACTOR_VARS_ARG), \
	  scaleVars = $(SCALE_VARS_LME_ARG), \
	  lmeLibs = '$(LME_LIBS)', \
	  correlationStructure = '$(LME_CORRELATION_STRUCTURE)', \
	  correlationVar = $(LME_CORRELATION_VAR_ARG), \
	  prsMap = $(PRS_MAP_ARG), \
	  libPath = $(R_DIR_ARG), \
	  cpgPrefix = '$(CPG_PREFIX)', \
	  cpgLimit = $(CPG_LIMIT), \
	  methylationScale = '$(METHYLATION_SCALE)', \
	  nCores = $(N_CORES), \
	  summaryPval = $(SUMMARY_PVAL), \
	  plotWidth = $(TIFF_WIDTH), \
	  plotHeight = $(TIFF_HEIGHT), \
	  plotDPI = $(TIFF_RES), \
	  interactionTerm = $(INTERACTION_LME_ARG), \
	  saveSignificantInteractions = $(SAVE_SIGNIFICANT_INTERACTIONS), \
	  significantInteractionDir = '$(RESULTS_DIR)/$(MODEL)/$(CPG_DIR)/$(STEP5)', \
	  significantInteractionPval = $(SIGNIFICANT_INTERACTION_PVAL), \
	  saveTxtSummaries = $(SAVE_TXT_SUMMARIES), \
	  chunkSize = $(CHUNK_SIZE), \
	  summaryTxtDir = '$(RESULTS_DIR)/$(MODEL)/$(SUMMARY_DIR)/$(STEP5)', \
	  fdrThreshold = $(FDR_THRESHOLD), \
	  padjmethod = '$(PADJ_METHOD)', \
	  annotationPackage = '$(ANNOTATION_PACKAGE)', \
	  annotationCols = '$(ANNOTATION_COLS)', \
	  annotatedLMEOut = '$(DATA_DIR)/$(MODEL)/$(STEP5)', \
	  reportAssetsDir = '$(LME_REPORT_ASSET_DIR)', \
	  logs = TRUE, \
	  saveOutputs = TRUE ))"

# =================================================================================================================================
# Step 6: Final Report
# =================================================================================================================================
REPORT_INPUTS = \
	$(GLM_PHENO_METHYLATION) \
	$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(QC_DIR)/detP_RGSet.RData \
	$(SVA_MARKER) \
	$(PHENO_LC) \
	$(GLM_OUTPUTS) \
	$(LME_OUTPUTS)

$(STEP6)/$(MODEL)/docs/index.html: $(REPORT_INPUTS)
	mkdir -p "$(STEP6)/$(MODEL)" "$(MODEL_LOG_DIR)"
	@Rscript -e "suppressPackageStartupMessages(library(dnaEPICO)); result <- dnamReport( \
	  outputDir = '$(STEP6)/$(MODEL)', \
	  phenoTab = '$(PHENO_LC)', \
	  enmixTab = '$(FIGURES_DIR)/$(MODEL)/$(STEP1)/$(ENMIX_DIR)', \
	  qcTab = '$(FIGURES_DIR)/$(MODEL)/$(STEP1)/$(QC_DIR)', \
	  svaTab = '$(FIGURES_DIR)/$(MODEL)/$(STEP2)', \
	  metricTab = '$(FIGURES_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)', \
	  glmTab = '$(DATA_DIR)/$(MODEL)/$(STEP4)/annotatedGLM.xlsx', \
	  lmeTab = '$(DATA_DIR)/$(MODEL)/$(STEP5)/annotatedLME.xlsx', \
	  detPPath = '$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(QC_DIR)/detP_RGSet.RData', \
	  detPThreshold = '$(PVAL_THRESHOLD)', \
	  verbose = FALSE, \
	  logs = TRUE, \
	  logTab = '$(MODEL_LOG_DIR)' ); \
	  if (!identical(result[['status']], 'rendered') || !file.exists(result[['outputFile']])) { \
	    stop('Report rendering failed. See $(MODEL_LOG_DIR)/log_dnamReport.txt for details.', call. = FALSE); \
	  }"
	@echo "Report built: $(STEP6)/$(MODEL)/docs/index.html"

# =================================================================================================================================
# Clean up outputs
# =================================================================================================================================
clean_models:
	@echo "===== Cleaning all models ====="
	@for m in $(MODELS); do \
	  echo "Cleaning model $$m ..."; \
	  rm -rf \
	    $(DATA_DIR)/$$m \
	    $(RDATA_DIR)/$$m \
	    $(STEP6)/$$m \
	    $(LOGS_DIR)/$$m \
		$(FIGURES_DIR)/$$m \
	    $(RESULTS_DIR)/$$m; \
	done
	@rmdir $(RDATA_DIR) $(STEP6) $(LOGS_DIR) $(FIGURES_DIR) $(RESULTS_DIR) 2>/dev/null || true
	@echo "Clean completed for all models. Kept $(DATA_DIR)/$(STEP1)/."

clean:
ifeq ($(MODEL),all)
	@echo "===== Cleaning all models ====="
	@for m in $(MODELS); do \
	  echo "Cleaning model $$m ..."; \
	  rm -rf \
	    $(DATA_DIR)/$$m \
	    $(RDATA_DIR)/$$m \
	    $(STEP6)/$$m \
	    $(LOGS_DIR)/$$m \
		$(FIGURES_DIR)/$$m \
	    $(RESULTS_DIR)/$$m; \
	done
	@rmdir $(RDATA_DIR) $(STEP6) $(LOGS_DIR) $(FIGURES_DIR) $(RESULTS_DIR) 2>/dev/null || true
	@echo "Clean completed for all models. Kept $(DATA_DIR)/$(STEP1)/."
else
	@echo "Cleaning outputs for: $(MODEL)"
	rm -rf \
		$(DATA_DIR)/$(MODEL) \
		$(RDATA_DIR)/$(MODEL) \
		$(STEP6)/$(MODEL) \
		$(LOGS_DIR)/$(MODEL) \
		$(FIGURES_DIR)/$(MODEL) \
		$(RESULTS_DIR)/$(MODEL)
	@rmdir $(RDATA_DIR) $(STEP6) $(LOGS_DIR) $(FIGURES_DIR) $(RESULTS_DIR) 2>/dev/null || true
	@echo "Clean completed for: $(MODEL)"
endif

# =================================================================================================================================
# Status Check Target
# =================================================================================================================================
status:
	@echo "===== Pipeline Status ====="
	@test -e "$(RDATA_DIR)/$(MODEL)/$(STEP1)/$(METRICS_DIR)/beta_NomFilt_MSetF_Flt_Rxy_Ds_Rc.RData" && echo "[OK] Step 1: preprocessingMinfiEwasWater done" || echo "[MISSING] Step 1: preprocessingMinfiEwasWater output"
	@test -e "$(SVA_MARKER)" && test -e "$(PHENO_LC)" && echo "[OK] Step 2: SVA done" || echo "[MISSING] Step 2: SVA output"
	@test -e "$(COMBINED_PHENO_TARGET)" && echo "[OK] Step 3: preprocessingPheno done" || echo "[MISSING] Step 3: preprocessingPheno output"
	@test -e "$(GLM_WORKBOOK)" && test -e "$(GLM_REPORT_ASSET_DIR)/annotatedGLM.tsv.gz" && echo "[OK] Step 4: methylationGLM done" || echo "[MISSING] Step 4: methylationGLM output"
	@test -e "$(LME_WORKBOOK)" && test -e "$(LME_REPORT_ASSET_DIR)/annotatedLME.tsv.gz" && echo "[OK] Step 5: methylationLME done" || echo "[MISSING] Step 5: methylationLME output"
	@test -e "$(STEP6)/$(MODEL)/docs/index.html" && echo "[OK] Step 6: Report generated" || echo "[MISSING] Step 6: Report output"
	@echo "============================"

.PHONY: all clean clean_models status models step1 step2 step3 f3 f4 f3lme f3_models f4_models f3lme_models

