Thank you for your interest in contributing to the python-intan package! We welcome contributions from the community and are grateful for your support.
- Code of Conduct
- How Can I Contribute?
- Development Setup
- Contribution Workflow
- Style Guidelines
- Testing
- Documentation
- Questions
This project follows a Code of Conduct. By participating, you are expected to uphold this code. Please be respectful, constructive, and professional in all interactions.
Key principles:
- Be welcoming and inclusive
- Be respectful of different viewpoints
- Accept constructive criticism gracefully
- Focus on what is best for the community
- Show empathy towards other community members
There are many ways to contribute to python-intan:
If you find a bug, please create an issue with:
- Clear title - Brief description of the problem
- Environment details:
- Python version
- Package version (
import intan; print(intan.__version__)) - Operating system
- Relevant hardware (if applicable)
- Minimal reproducible example - Simplest code that demonstrates the bug
- Expected behavior - What you expected to happen
- Actual behavior - What actually happened
- Error messages - Full traceback if applicable
- Screenshots - If relevant (GUI issues, plots, etc.)
Example:
**Bug**: IntanRHXDevice fails to connect on Ubuntu 22.04
**Environment**:
- Python 3.10.12
- python-intan 0.0.3
- Ubuntu 22.04
**Code**:
\```python
from intan.interface import IntanRHXDevice
device = IntanRHXDevice() # Fails here
\```
**Error**:
\```
ConnectionRefusedError: [Errno 111] Connection refused
\```
**Expected**: Should connect to RHX software running on localhost
**Actual**: Connection refused
**Notes**: RHX software is running with TCP servers enabledWe welcome feature suggestions! Please create an issue with:
- Clear use case - Why is this feature needed?
- Proposed solution - How should it work?
- Alternatives considered - Other approaches you've thought about
- Examples - Code examples of how you'd use it
Documentation improvements are always welcome:
- Fix typos or clarify explanations
- Add examples
- Improve API documentation
- Create tutorials
- Translate documentation
New examples help users learn the package:
- Real-world use cases
- Integration with other tools
- Novel applications
- Benchmark comparisons
Place examples in the appropriate examples/ subdirectory and add documentation in docs/source/examples/.
See Contribution Workflow below.
# Fork the repository on GitHub, then:
git clone https://github.com/YOUR_USERNAME/python-intan.git
cd python-intan# Using conda
conda create -n intan-dev python=3.10
conda activate intan-dev
# Or using venv
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate# Install package in editable mode with development dependencies
pip install -e .
# Install development tools (optional)
pip install pytest black flake8 mypypip install pre-commit
pre-commit installgit checkout -b feature/your-feature-name
# or
git checkout -b fix/issue-descriptionBranch naming conventions:
feature/- New featuresfix/- Bug fixesdocs/- Documentation changesrefactor/- Code refactoringtest/- Adding tests
- Write clear, readable code
- Follow style guidelines (see below)
- Add tests for new functionality
- Update documentation as needed
- Keep commits focused and atomic
# Run tests (if available)
pytest tests/
# Check code style
black intan/
flake8 intan/
# Type checking (optional)
mypy intan/Write clear commit messages:
git add .
git commit -m "Add feature: real-time RMS calculation
- Implement window_rms function in processing module
- Add unit tests for window_rms
- Update documentation with usage examples
- Closes #123"Commit message format:
- First line: Brief summary (50 chars or less)
- Body: Detailed explanation (wrap at 72 chars)
- Footer: Reference issues (e.g., "Closes #123", "Fixes #456")
git push origin feature/your-feature-nameThen create a Pull Request on GitHub with:
- Clear title - What does this PR do?
- Description:
- What problem does it solve?
- How does it solve it?
- Any breaking changes?
- Related issues?
- Checklist:
- Code follows style guidelines
- Tests added/updated
- Documentation updated
- No breaking changes (or documented if unavoidable)
- Respond to reviewer feedback
- Make requested changes
- Push updates to your branch
Once approved, maintainers will merge your PR. Thank you for contributing!
We follow PEP 8 with some modifications:
Line length: 100 characters (not 79)
Formatting: Use black for automatic formatting
black intan/Imports: Organize imports as:
- Standard library
- Third-party packages
- Local imports
import os
import sys
import numpy as np
import matplotlib.pyplot as plt
from intan.io import load_rhd_file
from intan.processing import filter_emgNaming conventions:
snake_casefor functions and variablesPascalCasefor classesUPPER_CASEfor constants_leading_underscorefor private/internal functions
Docstrings: Use NumPy-style docstrings
def filter_emg(data, filter_type, sample_rate, lowcut=None, highcut=None):
"""
Apply filtering to EMG data.
Parameters
----------
data : np.ndarray
EMG data array (channels, samples).
filter_type : str
Type of filter ('lowpass', 'highpass', 'bandpass').
sample_rate : float
Sampling rate in Hz.
lowcut : float, optional
Low cutoff frequency for bandpass/highpass.
highcut : float, optional
High cutoff frequency for bandpass/lowpass.
Returns
-------
np.ndarray
Filtered EMG data.
Examples
--------
>>> emg_filtered = filter_emg(emg_data, filter_type='bandpass',
... lowcut=20, highcut=500, fs=4000)
"""
# Implementation- Use reStructuredText (.rst) for Sphinx documentation
- Include code examples
- Link to relevant API references
- Keep explanations clear and concise
- Use proper heading hierarchy
- Examples should be self-contained when possible
- Include comments explaining non-obvious steps
- Handle errors gracefully
- Show expected output
We use pytest for testing (when tests exist):
# Run all tests
pytest
# Run specific test file
pytest tests/test_io.py
# Run with coverage
pytest --cov=intan tests/Writing tests:
import pytest
import numpy as np
from intan.processing import window_rms
def test_window_rms_basic():
"""Test basic RMS calculation."""
# Create test data
data = np.array([[1, 2, 3, 4, 5]])
# Calculate RMS
result = window_rms(data, window_size=3)
# Assert expected behavior
assert result.shape == data.shape
assert np.all(result >= 0)
def test_window_rms_zeros():
"""Test RMS of zeros."""
data = np.zeros((2, 100))
result = window_rms(data, window_size=10)
assert np.all(result == 0)cd docs
pip install sphinx sphinx-autodoc-typehints myst-parser
make htmlView at docs/build/html/index.html
- API docs: Docstrings are auto-generated
- Examples: Add .rst files to
docs/source/examples/ - Guides: Add .rst files to
docs/source/info/
- All public functions have docstrings
- Parameters and returns documented
- Examples included where helpful
- Cross-references to related functions
- Added to appropriate toctree
Before submitting a PR, ensure:
- Code follows style guidelines (run
blackandflake8) - All tests pass (if tests exist)
- New functionality has tests
- Documentation updated
- Examples added/updated if applicable
- Commit messages are clear
- No merge conflicts
- PR description is complete
If you have questions about contributing:
- Check the FAQ
- Search existing GitHub Issues
- Open a new issue with your question
- Email: jshulgac@andrew.cmu.edu
All contributors will be acknowledged in:
- GitHub contributors page
- Release notes
- Documentation (where appropriate)
We appreciate your time and effort in making python-intan better!
By contributing, you agree that your contributions will be licensed under the MIT License.
Thank you for contributing to python-intan! 🎉