# ============================================
# SciTeX Template Research - Makefile
# ============================================
# Scientific research project workflow automation
# Location: /Makefile
#
# Key Features:
# - Script execution and pipeline management
# - Dependency installation and environment setup
# - Output cleaning and data management
# - Code formatting and quality checks
# - Testing automation
#
# Usage:
# make help # Show this help
# make install # Install dependencies
# make run-mnist # Run MNIST example pipeline
# make clean # Clean outputs
# make format # Format code
# make test # Run tests
.PHONY: \
help \
install \
install-dev \
setup \
setup-writer \
run-mnist \
run-mnist-download \
run-mnist-plot-digits \
run-mnist-plot-umap \
run-mnist-clf-svm \
run-mnist-conf-mat \
clean \
clean-mnist \
clean-outputs \
clean-data \
clean-logs \
clean-all \
clean-python \
clean-writer \
test \
test-verbose \
test-sync \
format \
format-python \
format-shell \
lint \
lint-python \
check \
info \
tree \
verify \
show-config
.DEFAULT_GOAL := help
# ============================================
# Configuration
# ============================================
PYTHON := python3
PIP := pip3
SCRIPTS_DIR := scripts
MNIST_DIR := $(SCRIPTS_DIR)/mnist
CONFIG_DIR := config
DATA_DIR := data
TESTS_DIR := tests
SCITEX_DIR := scitex
WRITER_DIR := $(SCITEX_DIR)/writer
# Colors
GREEN := \033[0;32m
YELLOW := \033[0;33m
RED := \033[0;31m
CYAN := \033[0;36m
BLUE := \033[0;34m
NC := \033[0m
# ============================================
# Help
# ============================================
help:
@echo ""
@echo "$(GREEN)############################################################$(NC)"
@echo "$(GREEN)# SciTeX Template Research - Makefile $(NC)"
@echo "$(GREEN)############################################################$(NC)"
@echo ""
@echo "$(CYAN)Setup & Installation:$(NC)"
@echo " make install # Install Python dependencies"
@echo " make install-dev # Install dev dependencies (testing, linting)"
@echo " make setup # Complete setup (install + verify)"
@echo " make setup-writer # Clone writer template project (example_paper)"
@echo ""
@echo "$(CYAN)Running Scripts:$(NC)"
@echo " make run-mnist # Run complete MNIST pipeline"
@echo " make run-mnist-download # Download MNIST data"
@echo " make run-mnist-plot-digits # Plot MNIST digits"
@echo " make run-mnist-plot-umap # Create UMAP visualization"
@echo " make run-mnist-clf-svm # Train SVM classifier"
@echo " make run-mnist-conf-mat # Plot confusion matrix"
@echo ""
@echo "$(CYAN)Cleaning:$(NC)"
@echo " make clean # Clean script outputs"
@echo " make clean-mnist # Clean MNIST outputs only"
@echo " make clean-outputs # Clean all *_out directories"
@echo " make clean-data # Clean generated data files"
@echo " make clean-logs # Clean log files"
@echo " make clean-writer # Remove writer projects (use with caution!)"
@echo " make clean-all # Clean everything (outputs + data + cache)"
@echo " make clean-python # Clean Python cache files"
@echo ""
@echo "$(CYAN)Code Quality:$(NC)"
@echo " make format # Format all code (Python + Shell)"
@echo " make format-python # Format Python with ruff"
@echo " make format-shell # Format shell with shfmt + shellcheck"
@echo " make lint # Lint code with ruff"
@echo " make check # Run format + lint + test"
@echo ""
@echo "$(CYAN)Testing:$(NC)"
@echo " make test # Run all tests"
@echo " make test-verbose # Run tests with verbose output"
@echo " make test-sync # Sync test structure with scripts"
@echo ""
@echo "$(CYAN)Information:$(NC)"
@echo " make info # Show project information"
@echo " make tree # Show project structure"
@echo " make verify # Verify installation and config"
@echo " make show-config # Display configuration files (requires yq)"
@echo ""
# ============================================
# Installation & Setup
# ============================================
install:
@echo "$(CYAN)Installing Python dependencies...$(NC)"
@if [ -f requirements.txt ]; then \
$(PIP) install -r requirements.txt; \
echo "$(GREEN)Dependencies installed$(NC)"; \
else \
echo "$(RED)requirements.txt not found$(NC)"; \
exit 1; \
fi
install-dev:
@echo "$(CYAN)Installing development dependencies...$(NC)"
@$(PIP) install pytest pytest-cov ruff black isort mypy
@echo "$(GREEN)Development dependencies installed$(NC)"
setup: install
@echo "$(CYAN)Setting up project...$(NC)"
@mkdir -p $(DATA_DIR)
@mkdir -p $(DATA_DIR)/mnist/figures
@mkdir -p $(DATA_DIR)/mnist/models
@mkdir -p $(DATA_DIR)/mnist/raw
@echo "$(GREEN)Project setup complete$(NC)"
@$(MAKE) verify
@echo ""
@echo "$(YELLOW)To create a writer project, run:$(NC)"
@echo " make setup-writer"
@echo " $(YELLOW)or manually:$(NC) scitex writer clone $(WRITER_DIR)/your_paper_name"
@echo ""
setup-writer:
@echo "$(CYAN)Setting up writer project...$(NC)"
@if [ -d "$(WRITER_DIR)/example_paper" ]; then \
echo "$(YELLOW)Writer project already exists at $(WRITER_DIR)/example_paper$(NC)"; \
echo "$(YELLOW)To create a new project, use:$(NC)"; \
echo " scitex writer clone $(WRITER_DIR)/your_paper_name"; \
echo ""; \
echo "$(YELLOW)Git strategies available:$(NC)"; \
echo " --git-strategy child (default: independent git repo)"; \
echo " --git-strategy parent (track in main repo)"; \
echo " --git-strategy origin (preserve template history)"; \
echo " --git-strategy none (no git initialization)"; \
else \
echo "$(CYAN)Cloning writer template to $(WRITER_DIR)/example_paper...$(NC)"; \
scitex writer clone $(WRITER_DIR)/example_paper; \
echo "$(GREEN)Writer project created successfully!$(NC)"; \
echo ""; \
echo "$(CYAN)To compile the manuscript:$(NC)"; \
echo " cd $(WRITER_DIR)/example_paper"; \
echo " scitex writer compile manuscript"; \
echo ""; \
echo "$(YELLOW)Note: Uses 'child' git strategy (independent repository)$(NC)"; \
echo "$(YELLOW)To use parent repo instead:$(NC)"; \
echo " scitex writer clone $(WRITER_DIR)/your_paper --git-strategy parent"; \
echo ""; \
fi
verify:
@echo "$(CYAN)Verifying installation...$(NC)"
@echo ""
@echo "$(CYAN)Python version:$(NC)"
@$(PYTHON) --version
@echo ""
@echo "$(CYAN)Checking required packages:$(NC)"
@for pkg in scitex torch torchvision scikit-learn umap-learn seaborn numpy pandas matplotlib; do \
if $(PYTHON) -c "import $$pkg" 2>/dev/null; then \
echo " $(GREEN)[OK]$(NC) $$pkg"; \
else \
echo " $(RED)[MISSING]$(NC) $$pkg"; \
fi; \
done
@echo ""
@echo "$(CYAN)Checking configuration files:$(NC)"
@for cfg in PATH.yaml MNIST.yaml; do \
if [ -f $(CONFIG_DIR)/$$cfg ]; then \
echo " $(GREEN)[OK]$(NC) $$cfg"; \
else \
echo " $(YELLOW)[WARNING]$(NC) $$cfg $(YELLOW)(missing)$(NC)"; \
fi; \
done
@echo ""
# ============================================
# Running MNIST Scripts
# ============================================
run-mnist: run-mnist-download run-mnist-plot-digits run-mnist-plot-umap run-mnist-clf-svm run-mnist-conf-mat
@echo ""
@echo "$(GREEN)MNIST pipeline complete!$(NC)"
@echo ""
@echo "$(CYAN)Results available in:$(NC)"
@echo " - $(DATA_DIR)/mnist/figures/"
@echo " - $(MNIST_DIR)/*_out/"
run-mnist-download:
@echo "$(CYAN)Downloading MNIST dataset...$(NC)"
@cd $(MNIST_DIR) && $(PYTHON) 01_download.py
@echo "$(GREEN)Download complete$(NC)"
run-mnist-plot-digits:
@echo "$(CYAN)Plotting MNIST digits...$(NC)"
@cd $(MNIST_DIR) && $(PYTHON) 02_plot_digits.py
@echo "$(GREEN)Plots generated$(NC)"
run-mnist-plot-umap:
@echo "$(CYAN)Creating UMAP visualization...$(NC)"
@cd $(MNIST_DIR) && $(PYTHON) 03_plot_umap_space.py
@echo "$(GREEN)UMAP visualization complete$(NC)"
run-mnist-clf-svm:
@echo "$(CYAN)Training SVM classifier...$(NC)"
@cd $(MNIST_DIR) && $(PYTHON) 04_clf_svm.py
@echo "$(GREEN)SVM training complete$(NC)"
run-mnist-conf-mat:
@echo "$(CYAN)Plotting confusion matrix...$(NC)"
@cd $(MNIST_DIR) && $(PYTHON) 05_plot_conf_mat.py
@echo "$(GREEN)Confusion matrix generated$(NC)"
# ============================================
# Cleaning
# ============================================
clean: clean-outputs clean-logs clean-python
@echo "$(GREEN)Cleaned outputs and logs$(NC)"
clean-mnist:
@echo "$(YELLOW)Cleaning MNIST outputs...$(NC)"
@rm -rf $(MNIST_DIR)/*_out/
@echo "$(GREEN)MNIST outputs cleaned$(NC)"
clean-outputs:
@echo "$(YELLOW)Cleaning all script outputs...$(NC)"
@find $(SCRIPTS_DIR) -type d -name "*_out" -exec rm -rf {} + 2>/dev/null || true
@echo "$(GREEN)All outputs cleaned$(NC)"
clean-data:
@echo "$(RED)WARNING: This will delete all generated data files!$(NC)"
@printf "Type 'yes' to confirm: "; \
read confirm; \
if [ "$$confirm" = "yes" ]; then \
echo "$(YELLOW)Cleaning data directory...$(NC)"; \
rm -rf $(DATA_DIR)/mnist/*.npy 2>/dev/null || true; \
rm -rf $(DATA_DIR)/mnist/*.pkl 2>/dev/null || true; \
rm -rf $(DATA_DIR)/mnist/figures/*.jpg 2>/dev/null || true; \
rm -rf $(DATA_DIR)/mnist/figures/*.csv 2>/dev/null || true; \
rm -rf $(DATA_DIR)/mnist/models/*.pkl 2>/dev/null || true; \
echo "$(GREEN)Data cleaned$(NC)"; \
else \
echo "$(YELLOW)Cancelled$(NC)"; \
fi
clean-logs:
@echo "$(YELLOW)Cleaning log files...$(NC)"
@find $(SCRIPTS_DIR) -type f -name "*.log" -delete 2>/dev/null || true
@find $(SCRIPTS_DIR) -type d -name "RUNNING" -exec rm -rf {}/logs \; 2>/dev/null || true
@find $(SCRIPTS_DIR) -type d -name "FINISHED_SUCCESS" -exec rm -rf {}/*/logs \; 2>/dev/null || true
@find $(SCRIPTS_DIR) -type d -name "FINISHED_FAILED" -exec rm -rf {}/*/logs \; 2>/dev/null || true
@echo "$(GREEN)Logs cleaned$(NC)"
clean-all: clean-outputs clean-data clean-logs clean-python
@echo "$(RED)WARNING: This will delete ALL generated files!$(NC)"
@printf "Type 'DELETE ALL' to confirm: "; \
read confirm; \
if [ "$$confirm" = "DELETE ALL" ]; then \
echo "$(YELLOW)Deep cleaning...$(NC)"; \
rm -rf $(DATA_DIR)/mnist/raw/* 2>/dev/null || true; \
echo "$(GREEN)Complete cleanup done$(NC)"; \
else \
echo "$(YELLOW)Cancelled$(NC)"; \
fi
clean-python:
@echo "$(YELLOW)Cleaning Python cache files...$(NC)"
@find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
@find . -type f -name "*.pyc" -delete 2>/dev/null || true
@find . -type f -name "*.pyo" -delete 2>/dev/null || true
@find . -type d -name "*.egg-info" -exec rm -rf {} + 2>/dev/null || true
@find . -type d -name ".pytest_cache" -exec rm -rf {} + 2>/dev/null || true
@find . -type d -name ".ruff_cache" -exec rm -rf {} + 2>/dev/null || true
@find . -type d -name ".mypy_cache" -exec rm -rf {} + 2>/dev/null || true
@echo "$(GREEN)Python cache cleaned$(NC)"
clean-writer:
@echo "$(RED)WARNING: This will DELETE all writer projects!$(NC)"
@echo "$(RED)Each writer project is an independent git repository.$(NC)"
@echo "$(RED)Make sure you have pushed any uncommitted changes!$(NC)"
@printf "Type 'DELETE WRITER PROJECTS' to confirm: "; \
read confirm; \
if [ "$$confirm" = "DELETE WRITER PROJECTS" ]; then \
echo "$(YELLOW)Removing all writer projects...$(NC)"; \
if [ -d "$(WRITER_DIR)" ]; then \
rm -rf $(WRITER_DIR)/*/; \
echo "$(GREEN)Writer projects removed$(NC)"; \
else \
echo "$(YELLOW)No writer directory found$(NC)"; \
fi; \
else \
echo "$(YELLOW)Cancelled$(NC)"; \
fi
# ============================================
# Testing
# ============================================
test:
@echo "$(CYAN)Running tests...$(NC)"
@if command -v pytest >/dev/null 2>&1; then \
pytest $(TESTS_DIR) -q; \
else \
echo "$(YELLOW)pytest not installed. Run: make install-dev$(NC)"; \
exit 1; \
fi
test-verbose:
@echo "$(CYAN)Running tests (verbose)...$(NC)"
@if command -v pytest >/dev/null 2>&1; then \
pytest $(TESTS_DIR) -v; \
else \
echo "$(YELLOW)pytest not installed. Run: make install-dev$(NC)"; \
exit 1; \
fi
test-sync:
@echo "$(CYAN)Synchronizing test structure with scripts...$(NC)"
@$(TESTS_DIR)/sync_tests_with_scripts.sh
@echo "$(GREEN)Test synchronization complete$(NC)"
# ============================================
# Code Quality
# ============================================
format: format-python format-shell
@echo ""
@echo "$(GREEN)All formatting and linting complete!$(NC)"
format-python:
@echo "$(CYAN)Formatting Python code with ruff...$(NC)"
@if command -v ruff >/dev/null 2>&1; then \
ruff format $(SCRIPTS_DIR) $(TESTS_DIR) --quiet || echo "$(YELLOW)Ruff formatting completed with warnings$(NC)"; \
echo "$(GREEN)Python formatting complete$(NC)"; \
else \
echo "$(RED)Ruff not found. Install with: pip install ruff$(NC)"; \
exit 1; \
fi
format-shell:
@echo "$(CYAN)Formatting and linting shell scripts...$(NC)"
@if command -v shfmt >/dev/null 2>&1; then \
find $(SCRIPTS_DIR) -name "*.sh" \
! -path "*/node_modules/*" \
! -path "*/.venv/*" \
-exec shfmt -w -i 4 -bn -ci -sr {} + \
2>&1 || echo "$(YELLOW)shfmt formatting completed with warnings$(NC)"; \
echo "$(GREEN)Shell formatting complete!$(NC)"; \
else \
echo "$(YELLOW)shfmt not found. Install with: go install mvdan.cc/sh/v3/cmd/shfmt@latest$(NC)"; \
echo "$(YELLOW)Skipping shell formatting...$(NC)"; \
fi
@if command -v shellcheck >/dev/null 2>&1; then \
find $(SCRIPTS_DIR) -name "*.sh" \
! -path "*/node_modules/*" \
! -path "*/.venv/*" \
-exec shellcheck --severity=error {} + \
2>&1 || echo "$(RED)ShellCheck found errors$(NC)"; \
echo "$(GREEN)Shell linting complete!$(NC)"; \
else \
echo "$(YELLOW)shellcheck not found. Install with: sudo apt-get install shellcheck$(NC)"; \
echo "$(YELLOW)Skipping shell linting...$(NC)"; \
fi
lint: lint-python
lint-python:
@echo "$(CYAN)Linting Python code with ruff...$(NC)"
@if command -v ruff >/dev/null 2>&1; then \
ruff check $(SCRIPTS_DIR) $(TESTS_DIR) --quiet || echo "$(RED)Ruff found issues$(NC)"; \
echo "$(GREEN)Linting complete$(NC)"; \
else \
echo "$(RED)Ruff not found. Install with: pip install ruff$(NC)"; \
exit 1; \
fi
check: format lint test
@echo ""
@echo "$(GREEN)All checks passed!$(NC)"
# ============================================
# Information & Diagnostics
# ============================================
info:
@echo "$(CYAN)Project Information:$(NC)"
@echo ""
@echo " $(CYAN)Project:$(NC) SciTeX Template Research"
@echo " $(CYAN)Python:$(NC) $$($(PYTHON) --version 2>&1)"
@echo " $(CYAN)Scripts:$(NC) $$(find $(SCRIPTS_DIR) -name "*.py" | wc -l) Python files"
@echo " $(CYAN)Config:$(NC) $$(ls -1 $(CONFIG_DIR)/*.yaml 2>/dev/null | wc -l) YAML files"
@echo ""
@echo " $(CYAN)MNIST Scripts:$(NC)"
@echo " - $$(ls -1 $(MNIST_DIR)/*.py 2>/dev/null | wc -l) scripts"
@echo " - $$(ls -1d $(MNIST_DIR)/*_out 2>/dev/null | wc -l) output directories"
@echo ""
@if [ -d $(DATA_DIR)/mnist/figures ]; then \
echo " $(CYAN)Generated Figures:$(NC) $$(ls -1 $(DATA_DIR)/mnist/figures/*.jpg 2>/dev/null | wc -l)"; \
fi
@if [ -d $(DATA_DIR)/mnist/models ]; then \
echo " $(CYAN)Saved Models:$(NC) $$(ls -1 $(DATA_DIR)/mnist/models/*.pkl 2>/dev/null | wc -l)"; \
fi
tree:
@echo "$(CYAN)Project Structure:$(NC)"
@if command -v tree >/dev/null 2>&1; then \
tree -L 3 -I '__pycache__|*.pyc|.git|.venv|*.egg-info|.pytest_cache|.ruff_cache|.mypy_cache' -C; \
else \
echo "$(YELLOW)tree command not found. Install with: sudo apt-get install tree$(NC)"; \
ls -R; \
fi
show-config:
@echo "$(CYAN)Configuration Files:$(NC)"
@echo ""
@if command -v yq >/dev/null 2>&1; then \
for cfg in $(CONFIG_DIR)/*.yaml; do \
if [ -f "$$cfg" ]; then \
echo "$(GREEN)$$cfg:$(NC)"; \
yq -C '.' "$$cfg" 2>/dev/null || cat "$$cfg"; \
echo ""; \
fi; \
done; \
else \
echo "$(YELLOW)yq not installed. Showing raw YAML files:$(NC)"; \
echo "$(YELLOW)(Install yq for colored output: sudo apt-get install yq or brew install yq)$(NC)"; \
echo ""; \
for cfg in $(CONFIG_DIR)/*.yaml; do \
if [ -f "$$cfg" ]; then \
echo "$(GREEN)$$cfg:$(NC)"; \
cat "$$cfg"; \
echo ""; \
fi; \
done; \
fi
# ============================================
# Utility Targets
# ============================================
.SILENT: help install verify
# EOF