Contributing

We welcome contributions to L-SURF! This document provides guidelines for contributing.

Getting Started

Development Setup

  1. Fork the repository on GitHub

  2. Clone your fork:

    git clone https://github.com/YOUR_USERNAME/lsurf.git
    cd lsurf
    
  3. Create development environment:

    conda env create -f environment.yml
    conda activate lsurf
    
  4. Install in development mode:

    pip install -e ".[dev]"
    
  5. Install pre-commit hooks (optional):

    pre-commit install
    

Code Style

Python Style

We follow PEP 8 with some modifications:

  • Line length: 88 characters (Black default)

  • Use type hints for all public functions

  • Docstrings: NumPy style

Format code with Black:

black src/ tests/

Check with Ruff:

ruff check src/ tests/

Type check with mypy:

mypy src/

Docstring Format

Use NumPy-style docstrings:

def fresnel_coefficients(theta_i, n1, n2, polarization="unpolarized"):
    """
    Compute Fresnel reflection and transmission coefficients.

    Parameters
    ----------
    theta_i : float
        Incident angle in radians (from normal).
    n1 : float
        Refractive index of incident medium.
    n2 : float
        Refractive index of transmission medium.
    polarization : {'s', 'p', 'unpolarized'}, optional
        Polarization state. Default is 'unpolarized'.

    Returns
    -------
    R : float
        Reflection coefficient (intensity).
    T : float
        Transmission coefficient (intensity).

    Notes
    -----
    Uses Fresnel equations [1]_ for interface between two dielectric media.

    References
    ----------
    .. [1] Born, M., & Wolf, E. (1999). Principles of Optics (7th ed.).

    Examples
    --------
    >>> R, T = fresnel_coefficients(np.pi/4, 1.0, 1.33)
    >>> print(f"Reflectance: {R:.3f}, Transmittance: {T:.3f}")
    Reflectance: 0.090, Transmittance: 0.910
    """

Testing

Running Tests

Run all tests:

pytest tests/ -v

Run specific test file:

pytest tests/test_surfaces.py -v

Run with coverage:

pytest tests/ --cov=lsurf --cov-report=html

Writing Tests

  • Place tests in tests/ directory

  • Name test files test_*.py

  • Name test functions test_*

  • Use descriptive test names

  • Include docstrings explaining what is tested

Example test:

def test_planar_surface_reflection_angle():
    """Test that reflection angle equals incidence angle."""
    surface = PlanarSurface(
        point=(0, 0, 0),
        normal=(0, 0, 1),
        material_front=AIR_STP,
        material_back=WATER,
    )

    # 45° incident ray
    incident_dir = np.array([1, 0, -1]) / np.sqrt(2)
    ray = RayBatch(num_rays=1)
    ray.positions[0] = [0, 0, 1]
    ray.directions[0] = incident_dir

    # Reflect
    reflected = surface.reflect(ray)

    # Check angle
    expected_dir = np.array([1, 0, 1]) / np.sqrt(2)
    np.testing.assert_allclose(
        reflected.directions[0],
        expected_dir,
        rtol=1e-10
    )

Documentation

Building Documentation

Install documentation dependencies:

pip install sphinx sphinx-rtd-theme

Build HTML documentation:

cd docs
make html

View in browser:

open _build/html/index.html

Writing Documentation

  • Use reStructuredText (.rst files)

  • Include code examples

  • Add cross-references with :doc: and :py:class:

  • Build and check before committing

Adding Examples

New example scripts should:

  1. Be placed in scripts/ directory

  2. Be numbered sequentially (XX_name.py)

  3. Include comprehensive docstring

  4. Generate output in plots/ directory

  5. Have corresponding .rst documentation in docs/examples/

Pull Request Process

  1. Create a feature branch:

    git checkout -b feature/your-feature-name
    
  2. Make your changes

  3. Add tests for new functionality

  4. Update documentation

  5. Run tests and linting:

    pytest tests/
    black src/ tests/
    ruff check src/ tests/
    mypy src/
    
  6. Commit with descriptive message:

    git commit -m "Add: New feature description"
    
  7. Push to your fork:

    git push origin feature/your-feature-name
    
  8. Open Pull Request on GitHub

Commit Message Format

Use conventional commits:

  • Add: New feature or capability

  • Fix: Bug fix

  • Docs: Documentation changes

  • Test: Test additions or modifications

  • Refactor: Code restructuring without behavior change

  • Perf: Performance improvements

Example:

Add: Fresnel reflection for curved surfaces

Implements Fresnel reflection calculation for arbitrary curved
surfaces using local normal vectors. Includes tests and examples.

Closes #42

Code Review Checklist

Before submitting PR, verify:

  • [ ] All tests pass

  • [ ] Code follows style guidelines (Black, Ruff)

  • [ ] Type hints added for public functions

  • [ ] Docstrings added/updated

  • [ ] Documentation built successfully

  • [ ] Examples run without errors

  • [ ] CHANGELOG.md updated (for user-facing changes)

  • [ ] No unnecessary debug print statements

  • [ ] No commented-out code blocks

Reporting Issues

Bug Reports

Include:

  • L-SURF version (import lsurf; print(lsurf.__version__))

  • Python version

  • Operating system

  • CUDA/GPU information (if relevant)

  • Minimal code example reproducing bug

  • Expected vs. actual behavior

  • Error messages and tracebacks

Feature Requests

Include:

  • Use case description

  • Proposed API (if applicable)

  • Example usage code

  • Any relevant papers or references

Questions

For questions:

  • Check documentation first

  • Search existing issues

  • Provide context and code examples

License

By contributing, you agree that your contributions will be licensed under the MIT License.