Thank you for your interest in contributing to measureit! This guide will help you set up your development environment and understand our development workflow.
- Python 3.8+
- Git
- NI DAQmx drivers: http://www.ni.com/en-us/support/downloads/drivers/download/unpackaged.ni-daqmx.291872.html
- NI VISA package: http://www.ni.com/download/ni-visa-18.5/7973/en/
We use uv (fast Python package manager) and ruff (fast Python linter and formatter) for the best development experience:
-
Install uv:
# On macOS and Linux curl -LsSf https://astral.sh/uv/install.sh | sh # On Windows powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # Or with pip pip install uv
-
Clone and install:
git clone https://github.com/nanophys/MeasureIt cd MeasureIt # Install with development dependencies uv pip install -e ".[dev,docs,jupyter]"
-
(Optional) Choose a custom data directory:
measureit automatically stores databases, logs, configuration files, and exports in a per-user data directory based on your OS. Override this location in your notebooks or scripts when you need a shared or versioned path:
import measureit measureit.set_data_dir("/path/to/measureit-data")
-
Set up pre-commit hooks:
pre-commit install
git clone https://github.com/nanophys/MeasureIt
cd MeasureIt
pip install -e ".[dev,docs,jupyter]"
pre-commit installconda create -n measureit python=3.9
conda activate measureit
git clone https://github.com/nanophys/MeasureIt
cd MeasureIt
pip install -e ".[dev,docs,jupyter]"We provide a Makefile with convenient commands for common development tasks:
# Install development dependencies
make install
# Code quality
make format # Format and fix code with ruff
make lint # Check code quality (format + lint + type check)
# Testing
make test # Run tests with coverage
# Documentation
make docs # Build documentation
# Maintenance
make clean # Clean build artifacts
# See all commands
make helpAlternatively, you can run tools directly:
# Format code with ruff
ruff format src/ tests/
# Lint and fix with ruff
ruff check --fix src/ tests/
# Type check with mypy
mypy src/
# Run tests
pytest
# Run tests with coverage
pytest --cov=src/measureit --cov-report=html --cov-report=term-missingWe use ruff for both code formatting and linting. Ruff replaces multiple tools:
- Formatting: Replaces
black - Import sorting: Replaces
isort - Linting: Replaces
flake8and includes many additional checks
Configuration is in pyproject.toml under [tool.ruff].
We use mypy for static type checking. While not all code is currently typed, we encourage adding type hints to new code.
Pre-commit hooks automatically run code quality checks before each commit:
- Trailing whitespace removal
- End-of-file fixing
- YAML validation
- Ruff formatting and linting
- MyPy type checking
# Run all tests
make test
# Run tests with coverage
make test-cov
# Run specific test file
pytest tests/test_specific.py
# Run tests with specific markers (when configured)
pytest -m "not slow"- Place tests in the
tests/directory - Use descriptive test names starting with
test_ - Use pytest fixtures for common setup
- Mock external dependencies (instruments, hardware)
- Test both success and failure cases
Example test structure:
import pytest
from measureit import Sweep1D
def test_sweep1d_creation():
"""Test that Sweep1D can be created with valid parameters."""
# Test implementation here
pass
def test_sweep1d_invalid_parameters():
"""Test that Sweep1D raises appropriate errors for invalid parameters."""
with pytest.raises(ValueError):
# Test implementation here
pass# Install documentation dependencies
uv pip install -e ".[docs]"
# Build HTML documentation
make docs
# Clean documentation build
make docs-cleanThe documentation is built using Sphinx and located in docs/source/. The built documentation will be in docs/source/_build/html/.
- Use Google-style docstrings for functions and classes
- Include examples in docstrings when helpful
- Update relevant documentation when adding features
- Keep the README focused on installation and basic usage
Example docstring:
def follow_param(self, *params: Parameter) -> None:
"""Add QCoDeS parameters to be tracked during measurement.
Args:
*params: Variable number of QCoDeS Parameter objects to track
Raises:
ParameterException: If parameter is already being followed
Example:
>>> sweep = Sweep1D(dac.voltage, 0, 1, 0.1)
>>> sweep.follow_param(dmm.voltage, lockin.x)
"""MeasureIt/
├── src/measureit/ # Main package source
│ ├── sweep0d.py # 0D measurements (time-based)
│ ├── sweep1d.py # 1D parameter sweeps
│ ├── sweep2d.py # 2D parameter sweeps
│ ├── base_sweep.py # Core sweep functionality
│ ├── sweep_queue.py # Batch experiment management
│ ├── GUI/ # PyQt5 user interface
│ ├── Drivers/ # Instrument drivers
│ └── util.py # Utility functions
├── tests/ # Test suite
├── docs/ # Documentation
├── scripts/ # Utility scripts
├── pyproject.toml # Project configuration
├── Makefile # Development commands
└── CONTRIBUTING.md # This file
- Run quality checks:
make quality-fix - Run tests:
make test - Update documentation if needed
- Test your changes with real instruments if possible
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make your changes
- Run quality checks and tests
- Commit with descriptive messages
- Push to your fork
- Create a pull request
- Use clear, descriptive commit messages
- Start with a verb in present tense
- Keep the first line under 50 characters
- Include more details in the body if needed
Examples:
Add support for new instrument driver
Fix issue with sweep interruption
- Handle keyboard interrupts gracefully
- Ensure proper cleanup of resources
Update documentation for new features
If you're migrating from the old conda + black/isort/flake8 setup:
# Use the migration script
make migrate
# Or manually
uv pip install -e ".[dev,docs,jupyter]"
pre-commit install- Issues: Report bugs and request features on GitHub Issues
- Discussions: Use GitHub Discussions for questions
- Slack: Join our Slack channel
Please be respectful and professional in all interactions. We're all here to advance scientific research and help each other succeed.