Contributing to Prismo
Thank you for your interest in contributing to Prismo! This guide will help you get started.
Quick Start
# 1. Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/prismo.git
cd prismo
# 2. Install development dependencies
pip install -e ".[dev]"
# 3. Create a branch for your changes
git checkout -b feature/my-new-feature
# 4. Make your changes and test
pytest tests/
black src/prismo/
ruff check src/prismo/
# 5. Commit and push
git add .
git commit -m "Add my new feature"
git push origin feature/my-new-feature
# 6. Open a pull request on GitHub
Development Setup
Prerequisites
Python 3.9+
Git
(Optional) CUDA for GPU support
Installation
# Clone repository
git clone https://github.com/rithulkamesh/prismo.git
cd prismo
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in editable mode with dev dependencies
pip install -e ".[dev,docs]"
# Verify installation
pytest tests/ -v
Code Style
We follow strict code style guidelines:
Python Style
PEP 8 compliance
Type hints for all public functions
NumPy docstrings format
Maximum line length: 88 characters (Black default)
Formatting Tools
# Auto-format with Black
black src/prismo/
# Check with ruff
ruff check src/prismo/
# Type checking with mypy
mypy src/prismo/
# All checks
make lint
Example
def compute_overlap(
Ex: np.ndarray,
Ey: np.ndarray,
mode: WaveguideMode,
dx: float,
dy: float,
) -> complex:
"""
Compute mode overlap integral.
Parameters
----------
Ex, Ey : ndarray
Electric field components.
mode : WaveguideMode
Waveguide mode for overlap.
dx, dy : float
Grid spacing.
Returns
-------
complex
Overlap coefficient.
Examples
--------
>>> overlap = compute_overlap(Ex, Ey, mode, 1e-8, 1e-8)
>>> assert abs(overlap) <= 1.0
"""
# Implementation with type hints and clear logic
overlap = 0.5 * np.sum((Ex * np.conj(mode.Ey) - Ey * np.conj(mode.Ex))) * dx * dy
return complex(overlap)
Testing
Running Tests
# Run all tests
pytest
# Run specific test file
pytest tests/test_modes.py
# Run with coverage
pytest --cov=prismo --cov-report=html
# Run only fast tests
pytest -m "not slow"
Writing Tests
Every new feature must include tests:
import pytest
import numpy as np
from prismo.modes.solver import ModeSolver
class TestModeSolver:
"""Test mode solver functionality."""
@pytest.fixture
def simple_waveguide(self):
"""Create a simple test waveguide."""
x = np.linspace(-2e-6, 2e-6, 50)
y = np.linspace(-2e-6, 2e-6, 50)
epsilon = np.ones((50, 50)) * 1.5**2
return x, y, epsilon
def test_mode_solver_creation(self, simple_waveguide):
"""Test that ModeSolver can be created."""
x, y, eps = simple_waveguide
solver = ModeSolver(1.55e-6, x, y, eps)
assert solver is not None
def test_fundamental_mode(self, simple_waveguide):
"""Test solving for fundamental mode."""
x, y, eps = simple_waveguide
solver = ModeSolver(1.55e-6, x, y, eps)
modes = solver.solve(num_modes=1)
assert len(modes) > 0
assert modes[0].neff.real > 1.0
assert modes[0].neff.real < 3.5
Test Categories
Use markers for different test types:
@pytest.mark.slow
def test_large_simulation():
"""This test takes a while."""
pass
@pytest.mark.gpu
def test_gpu_backend():
"""Requires GPU."""
pass
@pytest.mark.integration
def test_full_workflow():
"""Tests multiple components together."""
pass
Documentation
Docstring Format
Use NumPy style docstrings:
def function_name(param1: type, param2: type) -> return_type:
"""
Short one-line summary.
Longer description explaining what the function does,
how it works, and any important details.
Parameters
----------
param1 : type
Description of param1.
param2 : type
Description of param2.
Returns
-------
return_type
Description of return value.
Raises
------
ValueError
When invalid input is provided.
See Also
--------
related_function : Related functionality.
Examples
--------
>>> result = function_name(1.0, 2.0)
>>> print(result)
3.0
Notes
-----
Additional mathematical or implementation details.
References
----------
.. [1] Author, "Title", Journal, Year.
"""
pass
Building Documentation
# Build HTML documentation
cd docs
make html
# View documentation
open build/html/index.html # macOS
xdg-open build/html/index.html # Linux
start build/html/index.html # Windows
# Clean and rebuild
make clean html
Pull Request Process
1. Before Submitting
Code follows style guidelines (Black, Ruff)
All tests pass (
pytest)New tests added for new features
Documentation updated
CHANGELOG.md updated (if applicable)
Type hints added
No linter warnings
2. PR Description
Include:
What: Brief description of changes
Why: Motivation for changes
How: Technical approach
Testing: How you tested
Screenshots: If UI/visualization changes
Example:
## Add Mode Port Boundary Condition
### What
Implements mode port boundaries for waveguide simulations with mode injection and extraction.
### Why
Enables accurate S-parameter calculations for waveguide devices.
### How
- Created `ModePort` class in `boundaries/mode_port.py`
- Implemented mode overlap integrals
- Added S-parameter extraction methods
### Testing
- Unit tests in `tests/validation/test_mode_ports.py`
- Validated against analytical waveguide solution
- Example in `examples/mode_port_demo.py`
### Related Issues
Closes #6
3. Review Process
Automated checks run (CI/CD)
Maintainer review
Address feedback
Merge when approved
Commit Messages
Follow conventional commits:
type(scope): subject
body
footer
Types:
feat: New featurefix: Bug fixdocs: Documentation onlystyle: Code style (formatting, etc.)refactor: Code refactoringtest: Adding/updating testschore: Maintenance tasks
Examples:
feat(modes): add mode port boundary condition
Implement mode ports for waveguide S-parameter extraction.
Includes mode injection, extraction, and overlap integrals.
Closes #6
---
fix(solver): correct Courant condition for 3D
The 3D Courant limit calculation was incorrect.
Now properly accounts for all three dimensions.
---
docs(tutorials): add S-parameter extraction tutorial
New tutorial showing how to extract S-parameters using
mode expansion monitors.
Code Review Guidelines
When reviewing PRs:
What to Look For
Correctness: Does it work as intended?
Tests: Are there adequate tests?
Documentation: Is it well documented?
Performance: Any performance concerns?
Style: Follows code style?
Breaking changes: Any API changes?
Providing Feedback
Be constructive and specific:
Good:
The mode overlap calculation looks correct, but could be optimized
by pre-computing the mode normalization. Consider moving line 45
to the __init__ method.
Not as helpful:
This is slow.
Feature Requests
Proposing New Features
Check existing issues/PRs
Open a feature request issue
Describe use case and proposed API
Discuss with maintainers
Implement after approval
Template
## Feature Request: [Feature Name]
### Use Case
Describe what you want to accomplish.
### Proposed API
```python
# Example of how it would be used
sim.add_feature(...)
```
Alternatives Considered
Other approaches you’ve thought about.
Additional Context
Any other relevant information.
## Getting Help
- **Documentation**: Check docs first
- **Discussions**: Use GitHub Discussions for questions
- **Issues**: Report bugs via GitHub Issues
- **Chat**: Join our developer chat (if available)
## Code of Conduct
- Be respectful and inclusive
- Provide constructive feedback
- Focus on the code, not the person
- Help newcomers feel welcome
## License
By contributing, you agree that your contributions will be licensed under the MIT License.
## Recognition
Contributors are recognized in:
- README.md contributors section
- Release notes
- Documentation credits
Thank you for contributing to Prismo! 🎉