Contributing to Homodyne¶
Welcome to Homodyne development! This guide covers the contribution workflow, development setup, code quality standards, and best practices for working on the project.
Development Setup with uv¶
Homodyne uses uv for Python package management, optimized for Python 3.12+. This provides faster dependency resolution and installation compared to pip.
Installing Development Environment¶
Install uv (if not already installed):
curl -LsSf https://astral.sh/uv/install.sh | sh
Or using Homebrew on macOS:
brew install uv
Clone the repository:
git clone https://github.com/ORG/homodyne.git cd homodyne
Create virtual environment and install development dependencies:
uv venv --python 3.12 source .venv/bin/activate # On Windows: .venv\Scripts\activate
Install Homodyne in development mode:
uv syncThis installs all dependencies (core, dev tools, and documentation tools are consolidated into a single dependency set): - Core: JAX ≥0.8.2 (CPU-only), NumPyro, BlackJAX, NLSQ - Dev tools: pytest, ruff, mypy, pre-commit - Documentation: Sphinx, Furo, myst-parser
Verifying Installation¶
Verify your development environment is properly configured:
# Check Python and JAX versions
python --version # Should be 3.12+
python -c "import jax; print(f'JAX {jax.__version__}')"
# Validate system configuration
python -m homodyne.runtime.utils.system_validator --quick
# Run quick test to verify setup
make test-unit
Code Quality Standards¶
Homodyne maintains high code quality standards using three primary tools:
Black - Code Formatting¶
Black enforces consistent code formatting across the project.
Configuration in pyproject.toml:
[tool.black]
line-length = 100
target-version = ['py312']
include = '\.pyi?$'
extend-exclude = '''
/(
\.git
| \.venv
| _build
| dist
)/
'''
Format your code before committing:
black homodyne/
Check formatting without modifying:
black --check homodyne/
Ruff - Linting¶
Ruff performs fast linting and import sorting.
Key rules enforced: - F: PyFlakes (undefined names, unused imports) - E/W: pycodestyle (whitespace, indentation) - I: isort (import sorting) - N: pep8-naming (naming conventions) - UP: pyupgrade (Python 3.12+ features)
Lint your code:
ruff check homodyne/
Fix linting issues automatically:
ruff check --fix homodyne/
MyPy - Type Checking¶
MyPy validates type hints and catches type-related errors.
Configuration in pyproject.toml:
[tool.mypy]
python_version = "3.12"
warn_return_any = true
warn_unused_configs = true
disallow_incomplete_defs = true
disallow_untyped_defs = false
ignore_missing_imports = true
Type-check your code:
mypy homodyne/
Complete Quality Check¶
Run all quality checks together:
make quality
This runs: black format → ruff lint/fix → mypy type check
Before Committing¶
Always run the quality check before committing:
make quality
make test-unit # Ensure tests still pass
Testing with Pytest¶
Homodyne uses pytest for comprehensive testing across multiple test suites.
Test Organization¶
Tests are organized by type in tests/:
tests/
├── unit/ # Function-level tests (fast, <100ms each)
│ ├── test_*.py # Test modules
│ └── optimization/ # Module-specific subdirectories
├── integration/ # End-to-end workflow tests
├── performance/ # Benchmarks and optimization tests
├── mcmc/ # Statistical validation for MCMC
├── factories/ # Test data generators
└── conftest.py # Pytest configuration and fixtures
Running Tests¶
Run core unit tests (fastest):
make test
Run all tests including integration and performance:
make test-all
Run specific test suite:
make test-unit # Unit tests only
make test-integration # Integration tests
make test-nlsq # NLSQ optimization tests
make test-mcmc # MCMC validation tests
Run tests with coverage:
make test-all
# Coverage report written to htmlcov/index.html
Run specific test file or test:
pytest tests/unit/test_parameter_manager.py
pytest tests/unit/test_parameter_manager.py::test_specific_test_name -v
Writing Tests¶
Guidelines for writing tests:
1. Test Function Naming
Use descriptive names starting with test_:
# Good
def test_static_mode_parameter_validation():
pass
# Poor
def test_params():
pass
2. Test Structure (Arrange-Act-Assert)
def test_parameter_manager_bounds_validation():
# Arrange: Set up test data
param_mgr = ParameterManager(
parameter_names=['D0', 'alpha'],
bounds=[[100, 10000], [-2, 2]]
)
# Act: Execute the code being tested
result = param_mgr.validate_parameters([1000, 0.5])
# Assert: Verify the result
assert result is True
3. Use Fixtures for Reusable Data
import pytest
@pytest.fixture
def sample_config():
"""Fixture providing test configuration."""
return {
'analysis_mode': 'static',
'initial_parameters': {'D0': 1000, 'alpha': -1.2}
}
def test_with_config(sample_config):
# Use the fixture
assert sample_config['analysis_mode'] == 'static'
4. Test XPCS-Specific Behavior
def test_c2_computation_range():
"""Test that C2 values stay in physically valid range [1.0, 1.6]."""
c2_values = compute_c2(...)
assert np.all(c2_values >= 1.0), "C2 below 1.0 is non-physical"
assert np.all(c2_values <= 1.6), "C2 above 1.6 is unusual"
Code Coverage Requirements¶
Target coverage metrics:
Overall: ≥ 80% line coverage
Core modules: ≥ 85% (jax_backend, physics, parameter_manager)
Optimization: ≥ 75% (complex algorithms acceptable)
New code: ≥ 90% before merge
View coverage report:
coverage report
coverage html # Detailed HTML report in htmlcov/
JAX and CPU Debugging¶
Homodyne uses JAX ≥0.8.2 with CPU-only optimization.
Common JAX Debugging Commands¶
Enable compilation logging:
JAX_LOG_COMPILES=1 python script.py
Disable JIT compilation for easier debugging:
JAX_DISABLE_JIT=1 python script.py
Check JAX device configuration:
import jax
print(jax.devices()) # Should show CPU device
Monitor CPU usage during optimization:
# Terminal 1: Run homodyne optimization
homodyne --config config.yaml --method nlsq
# Terminal 2: Monitor CPU usage
top -H -p $(pgrep -f homodyne)
htop # Better alternative to top
CPU Performance Tips¶
JAX compiles once per unique shape/dtype - first run is slower
CPU threads controlled by:
JAX_PLATFORMS=cpuandOMP_NUM_THREADSFor reproducible results:
JAX_DEFAULT_PRNG_IMPL=threefry_prngProfile with:
python -m cProfile -s cumtime script.py
Pull Request Guidelines¶
Before Submitting¶
Ensure tests pass:
make test-allRun quality checks:
make qualityVerify documentation builds:
cd docs && make html
Check for common issues:
No print statements (use logging)
No hardcoded file paths (use pathlib and config)
No GPU-specific code (CPU-only architecture)
Docstrings for public functions
PR Description Template¶
Use this template for your PR description:
## Summary
Brief description of changes (1-2 sentences)
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Performance improvement
- [ ] Documentation
- [ ] Refactoring
## Testing
Describe tests added or modified:
- [ ] Unit tests added
- [ ] Integration tests added
- [ ] All tests passing
## Documentation
- [ ] Updated README/docs
- [ ] Added/updated docstrings
- [ ] Updated CHANGELOG
## Related Issues
Fixes #ISSUE_NUMBER
Commit Message Guidelines¶
Use clear, descriptive commit messages:
# Good
fix(mcmc): handle CMC subposterior weight normalization
Resolved issue where CMC subposterior weights didn't sum to 1.0
in edge cases, causing incorrect posterior combination.
Fixes #1234
# Poor
fixed bug
update
WIP: stuff
Standard Commit Prefixes¶
fix(scope): Bug fixes (e.g.,fix(mcmc): ...)feat(scope): New features (e.g.,feat(cli): ...)refactor(scope): Code reorganization (e.g.,refactor(core): ...)test(scope): Test additions (e.g.,test(nlsq): ...)docs(scope): Documentation (e.g.,docs(config): ...)perf(scope): Performance improvements (e.g.,perf(jax): ...)chore(scope): Maintenance (e.g.,chore(deps): ...)
Reference Material¶
For additional information on Homodyne development and commands, see:
Testing Guide - Detailed testing guide
Configuration - Configuration documentation
CLAUDE.md in project root - Development commands quick reference:
make test # Run core unit tests make test-all # Run all tests with coverage make quality # Format, lint, and type check make dev # Install development environment make clean # Clean build artifacts
Project README - High-level project overview and features
GitHub Issues - Known issues, features in progress, bug reports
Getting Help¶
Questions: Open a Discussion on GitHub
Bugs: File an Issue with reproduction steps
Ideas: Start a Discussion for feature requests
Development Help: Ask in the development Discussions
Thank you for contributing to Homodyne!