Contributing Guide
We welcome contributions to the heterodyne package! This guide explains how to contribute effectively.
Getting Started
1. Fork and Clone
# Fork the repository on GitHub, then:
git clone https://github.com/YOUR_USERNAME/heterodyne.git
cd heterodyne
# Add upstream remote
git remote add upstream https://github.com/imewei/heterodyne.git
2. Development Setup
# Create development environment
conda create -n heterodyne-dev python=3.12
conda activate heterodyne-dev
# Install in development mode
pip install -e .[dev]
# Install pre-commit hooks
pre-commit install
3. Verify Setup
# Run tests to verify everything works
pytest heterodyne/tests/ -v
# Check code quality and security tools
black --check heterodyne/
isort --check-only heterodyne/
flake8 heterodyne/
mypy heterodyne/
bandit -r heterodyne/
pip-audit
Development Workflow
1. Create Feature Branch
# Sync with upstream
git fetch upstream
git checkout main
git merge upstream/main
# Create feature branch
git checkout -b feature/your-feature-name
2. Make Changes
Follow the coding standards (see below)
Add tests for new functionality
Update documentation as needed
Keep commits focused and atomic
3. Test Changes
# Run relevant tests
pytest heterodyne/tests/test_your_changes.py -v
# Run full test suite
pytest heterodyne/tests/
# Check coverage
pytest heterodyne/tests/ --cov=heterodyne --cov-report=html
4. Code Quality Checks
# Format code
black heterodyne/
# Check linting
flake8 heterodyne/
# Type checking
mypy heterodyne/
# Check documentation
cd docs/
make html
5. Commit and Push
# Stage changes
git add .
# Commit with descriptive message
git commit -m "Add feature: brief description
- Detailed description of changes
- Why the change was made
- Any breaking changes or compatibility notes"
# Push to your fork
git push origin feature/your-feature-name
6. Create Pull Request
Open PR against the main branch
Use the PR template
Link related issues
Request review from maintainers
Coding Standards
Python Style
Follow PEP 8 with these specifics:
# Line length: 88 characters (Black default)
# Use Black for formatting
# Use meaningful variable names
# Good
def compute_correlation_function(tau_values, model_parameters, scattering_vector):
"""Compute correlation function with given parameters."""
pass
# Avoid
def compute_g1(t, p, q):
pass
Type Hints
Use type hints for all public functions:
from typing import List, Optional, Tuple, Union
import numpy as np
def optimize_parameters(
initial_params: List[float],
bounds: Optional[List[Tuple[float, float]]] = None,
method: str = "Nelder-Mead"
) -> Union[np.ndarray, None]:
"""Optimize model parameters."""
pass
Documentation
Use NumPy-style docstrings:
def compute_chi_squared(
experimental_data: np.ndarray,
theoretical_data: np.ndarray,
uncertainties: Optional[np.ndarray] = None
) -> float:
"""
Compute chi-squared goodness of fit.
Parameters
----------
experimental_data : np.ndarray
Experimental correlation data.
theoretical_data : np.ndarray
Theoretical model predictions.
uncertainties : np.ndarray, optional
Experimental uncertainties. If None, assumes uniform weighting.
Returns
-------
float
Chi-squared value.
Examples
--------
>>> exp_data = np.array([1.0, 0.8, 0.6])
>>> theory_data = np.array([0.98, 0.79, 0.61])
>>> chi2 = compute_chi_squared(exp_data, theory_data)
>>> print(f"Chi-squared: {chi2:.4f}")
Chi-squared: 0.0014
"""
pass
Error Handling
Use specific exception types:
from heterodyne.utils import ConfigurationError, DataFormatError
def load_configuration(config_path: str) -> dict:
"""Load and validate configuration file."""
if not os.path.exists(config_path):
raise FileNotFoundError(f"Configuration file not found: {config_path}")
try:
with open(config_path) as f:
config = json.load(f)
except json.JSONDecodeError as e:
raise ConfigurationError(f"Invalid JSON in config file: {e}")
if "analysis_settings" not in config:
raise ConfigurationError("Missing required 'analysis_settings' section")
return config
Testing Guidelines
Test Coverage
Aim for >90% test coverage for new code:
# Test all public functions
# Test edge cases and error conditions
# Test with realistic data
class TestNewFeature:
def test_basic_functionality(self):
"""Test basic feature operation."""
pass
def test_edge_cases(self):
"""Test boundary conditions."""
pass
def test_error_handling(self):
"""Test error conditions."""
with pytest.raises(ValueError):
invalid_operation()
@pytest.mark.parametrize("param,expected", [
(1.0, 2.0),
(2.0, 4.0),
(3.0, 6.0)
])
def test_parameterized(self, param, expected):
"""Test with multiple parameter sets."""
assert function(param) == expected
Performance Tests
Include performance tests for computationally intensive features:
@pytest.mark.benchmark
def test_optimization_performance(self, benchmark):
"""Benchmark optimization performance."""
result = benchmark(run_optimization, test_data)
assert result.success
Integration Tests
Test complete workflows:
def test_complete_analysis_workflow(self, tmp_path):
"""Test end-to-end analysis workflow."""
from heterodyne.optimization.classical import ClassicalOptimizer
import json
# Create test configuration
config_file = create_test_config(tmp_path)
# Run complete analysis
with open(config_file) as f:
config = json.load(f)
core = HeterodyneAnalysisCore(config)
core.load_experimental_data()
optimizer = ClassicalOptimizer(core, config)
params, result = optimizer.run_classical_optimization_optimized(
phi_angles=phi_angles,
c2_experimental=c2_data
)
# Verify results
assert result.success
assert result.chi_squared < threshold
Documentation Guidelines
API Documentation
Document all public functions and classes
Include examples in docstrings
Use proper cross-references
Keep documentation up-to-date with code changes
User Guide Updates
When adding new features:
Update relevant user guide sections
Add examples to the examples section
Update configuration documentation
Consider adding troubleshooting entries
Developer Documentation
For significant architectural changes:
Update architecture documentation
Document new design patterns
Update performance guidelines
Add troubleshooting information
Types of Contributions
Bug Fixes
Reproduce the issue with a minimal example
Add a test that fails before the fix
Implement the fix with minimal changes
Verify the test passes after the fix
Update documentation if needed
New Features
Discuss the feature in an issue first
Design the API carefully
Implement with tests and documentation
Consider backward compatibility
Update examples if relevant
Performance Improvements
Benchmark current performance before changes
Implement optimization with tests
Verify performance improvement with benchmarks
Ensure correctness is maintained
Document the improvement
Documentation Improvements
Identify unclear sections or missing information
Add examples and clarifications
Update for accuracy with current code
Test documentation builds locally
Check for broken links or references
Pull Request Guidelines
PR Title and Description
Use clear, descriptive titles:
Include comprehensive descriptions:
## Summary
Brief description of changes
## Changes Made
- Specific change 1
- Specific change 2
## Testing
- How was this tested?
- Any new test cases added?
## Breaking Changes
- Any backward compatibility issues?
## Related Issues
- Fixes #123
- Related to #456
Code Review Process
Self-review your changes before submitting
Respond to feedback constructively
Make requested changes promptly
Keep the PR focused on a single feature/fix
Rebase and squash commits if requested
Checklist
Before submitting a PR:
[ ] Tests pass locally
[ ] Code follows style guidelines
[ ] Documentation is updated
[ ] Change is backward compatible (or breaking changes are documented)
[ ] Commit messages are clear and descriptive
[ ] PR description explains the change and why it’s needed
Release Process
Versioning
We follow semantic versioning (SemVer):
Major (X.0.0): Breaking changes
Minor (0.X.0): New features, backward compatible
Patch (0.0.X): Bug fixes, backward compatible
Release Checklist
For maintainers:
Update version numbers
Update CHANGELOG.md
Run full test suite
Build and test documentation
Create release tag
Publish to PyPI
Update GitHub release notes
Community Guidelines
Code of Conduct
Be respectful and inclusive
Focus on constructive feedback
Help newcomers learn
Acknowledge contributions
Communication
GitHub Issues: Bug reports, feature requests
Pull Requests: Code contributions
Discussions: General questions and ideas
Recognition
Contributors are recognized through:
Git commit history
CONTRIBUTORS.md file
Release notes
GitHub contributor statistics
Getting Help
If you need help contributing:
Read the documentation thoroughly
Search existing issues for similar problems
Ask questions in GitHub Discussions
Start with small contributions to learn the workflow
Join the community and learn from other contributors
We appreciate all contributions, from bug reports to major features!