diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..d06b445d0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,298 @@ +# Contributing to HEDTools + +Thank you for your interest in contributing to HEDTools! This document provides guidelines and instructions for contributing to the project. + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [How Can I Contribute?](#how-can-i-contribute) +- [Development Setup](#development-setup) +- [Coding Standards](#coding-standards) +- [Testing Guidelines](#testing-guidelines) +- [Pull Request Process](#pull-request-process) +- [Reporting Bugs](#reporting-bugs) +- [Suggesting Enhancements](#suggesting-enhancements) + +## Code of Conduct + +This project adheres to a code of conduct that we expect all contributors to follow. Please be respectful and constructive in all interactions. + +## How Can I Contribute? + +### Types of Contributions + +- **Bug Reports:** Help us identify and fix issues +- **Feature Requests:** Suggest new functionality +- **Code Contributions:** Submit bug fixes or new features +- **Documentation:** Improve guides, examples, or API docs +- **Testing:** Add test coverage or report test failures +- **Examples:** Share use cases and example code + +## Development Setup + +### Prerequisites + +- Python 3.9 or higher +- Git +- pip (Python package manager) + +### Setting Up Your Development Environment + +1. **Fork and clone the repository:** + ```bash + git clone https://github.com/YOUR_USERNAME/hed-python.git + cd hed-python + ``` + +2. **Create a virtual environment (recommended):** + ```bash + python -m venv venv + source venv/bin/activate # On Windows: venv\Scripts\activate + ``` + +3. **Install in development mode:** + ```bash + pip install -e . + pip install -r requirements.txt + pip install -r docs/requirements.txt + ``` + +4. **Run tests to verify setup:** + ```bash + python -m unittest discover tests + ``` + +## Coding Standards + +### Python Style Guide + +- Follow [PEP 8](https://pep8.org/) style guidelines +- Maximum line length: 120 characters +- Use descriptive variable and function names +- Add docstrings to all public classes and functions + +### Code Quality Tools + +We use several tools to maintain code quality: + +- **flake8:** For linting and style checking + ```bash + flake8 hed/ tests/ + ``` + +- **codespell:** For spell checking + ```bash + codespell + ``` + +### Documentation Style + +- Use Google-style docstrings for all public APIs +- Include type hints where appropriate +- Provide examples for complex functionality + +Example docstring: +```python +def validate_hed_string(hed_string, schema): + """Validate a HED string against a schema. + + Args: + hed_string (str): The HED string to validate. + schema (HedSchema): The schema to validate against. + + Returns: + list: A list of validation issues, empty if valid. + + Example: + >>> schema = load_schema() + >>> issues = validate_hed_string("Event", schema) + >>> if not issues: + ... print("Valid!") + """ + pass +``` + +## Testing Guidelines + +### Test Structure + +- Place tests in the `tests/` directory, mirroring the `hed/` structure +- Name test files with `test_` prefix +- Use descriptive test method names + +### Writing Tests + +- Each test should be independent and isolated +- Use unittest framework (the project standard) +- Test both success and failure cases +- Include edge cases + +Example test: +```python +import unittest +from hed import HedString, load_schema + +class TestHedValidation(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.schema = load_schema() + + def test_valid_hed_string(self): + hed_string = HedString("Event", self.schema) + issues = hed_string.validate(self.schema) + self.assertEqual(len(issues), 0) + + def test_invalid_hed_string(self): + hed_string = HedString("InvalidTag", self.schema) + issues = hed_string.validate(self.schema) + self.assertGreater(len(issues), 0) + +if __name__ == '__main__': + unittest.main() +``` + +### Running Tests + +Run all tests: +```bash +python -m unittest discover tests +``` + +Run specific test file: +```bash +python -m unittest tests/models/test_hed_string.py +``` + +Run specific test case: +```bash +python -m unittest tests.models.test_hed_string.TestHedString.test_constructor +``` + +## Pull Request Process + +### Before Submitting + +1. **Update your branch:** + ```bash + git fetch origin + git rebase origin/main + ``` + +2. **Run all tests:** + ```bash + python -m unittest discover tests + ``` + +3. **Check code style:** + ```bash + flake8 hed/ tests/ + ``` + +4. **Update documentation** if you've added/changed functionality + +### Submitting a Pull Request + +1. **Create a feature branch:** + ```bash + git checkout -b feature/your-feature-name + ``` + +2. **Make your changes** with clear, focused commits + +3. **Write descriptive commit messages:** + ``` + Add validation for temporal extent + + - Implement temporal extent validation logic + - Add unit tests for temporal validation + - Update documentation with temporal examples + ``` + +4. **Push to your fork:** + ```bash + git push origin feature/your-feature-name + ``` + +5. **Open a Pull Request** on GitHub: + - Target the `main` branch + - Fill out the PR template completely + - Link related issues + - Add meaningful description of changes + +### PR Review Process + +- A maintainer will review your PR within a few days +- Address any requested changes +- Once approved, a maintainer will merge your PR + +## Reporting Bugs + +### Before Submitting a Bug Report + +- Check the [existing issues](https://github.com/hed-standard/hed-python/issues) +- Update to the latest version +- Verify the bug is reproducible + +### How to Submit a Bug Report + +Create an issue with: + +1. **Clear title** describing the problem +2. **Environment details:** OS, Python version, hedtools version +3. **Steps to reproduce** the issue +4. **Expected behavior** +5. **Actual behavior** +6. **Code sample** demonstrating the problem (if applicable) +7. **Error messages** or stack traces + +Example: +```markdown +## Bug: Schema validation fails with custom schema + +**Environment:** +- OS: Ubuntu 22.04 +- Python: 3.10.5 +- hedtools: 0.5.0 + +**Steps to Reproduce:** +1. Load custom schema from file +2. Validate HED string with tag "Event" +3. Observe error + +**Expected:** Validation succeeds +**Actual:** Raises KeyError + +**Code:** +\```python +from hed import load_schema, HedString +schema = load_schema('/path/to/schema.xml') +hed = HedString("Event") +issues = hed.validate(schema) # KeyError here +\``` + +**Error:** +\``` +KeyError: 'Event' + at line 123 in validator.py +\``` +``` + +## Suggesting Enhancements + +### How to Suggest an Enhancement + +Create an issue with: + +1. **Clear title** describing the enhancement +2. **Use case:** Why is this enhancement needed? +3. **Proposed solution:** How should it work? +4. **Alternatives considered:** Other approaches you've thought about +5. **Additional context:** Screenshots, mockups, or examples + +## Questions? + +- **Documentation:** [https://www.hedtags.org/hed-python](https://www.hedtags.org/hed-python) +- **Issues:** [GitHub Issues](https://github.com/hed-standard/hed-python/issues) +- **Email:** Kay.Robbins@utsa.edu + +Thank you for contributing to HEDTools! 🎉 diff --git a/README.md b/README.md index f7989c916..a18744fc6 100644 --- a/README.md +++ b/README.md @@ -6,94 +6,184 @@ [![Documentation](https://img.shields.io/badge/docs-hedtags.org-blue.svg)](https://www.hedtags.org/hed-python) # HEDTools - Python -HED (Hierarchical Event Descriptors) is a framework for systematically describing -both laboratory and real-world events as well as other experimental metadata. -HED tags are comma-separated path strings. -HED, itself, is platform-independent, extendable, and data-neutral. -This repository contains the underlying python tools that support validation, -summarization, and analysis of datasets using HED tags. +> Python tools for validation, analysis, and transformation of HED (Hierarchical Event Descriptors) tagged datasets. -Most people will simply annotate their events by creating a spreadsheet -or a BIDS JSON sidecar that associates HED tags with event codes or the events themselves. -If you have such a spreadsheet or a JSON, -you can use the HED Online Validator currently available at -[https://hedtools.org](https://hedtools.org) to validate or transform -your files without downloading any tools. +## Overview -A version of the online tools corresponding to the `develop` branch can be found at: -[https://hedtools.org/hed_dev](https://hedtools.org/hed_dev). +HED (Hierarchical Event Descriptors) is a framework for systematically describing both laboratory and real-world events as well as other experimental metadata. HED tags are comma-separated path strings that provide a standardized vocabulary for annotating events and experimental conditions. -### Installation -Use `pip` to install `hedtools` from PyPI: +**Key Features:** +- ✅ Validate HED annotations against schema specifications +- 📊 Analyze and summarize HED-tagged datasets +- 🔄 Transform and remodel event data +- 📁 Full BIDS (Brain Imaging Data Structure) dataset support +- 🌐 Platform-independent and data-neutral +- 🔧 Command-line tools and Python API - ``` - pip install hedtools - ``` +## Quick Start -To install directly from the -[GitHub](https://github.com/hed-standard/hed-python) repository `main` branch: +### Online Tools (No Installation Required) - ``` - pip install git+https://github.com/hed-standard/hed-python/@main - ``` +For simple validation or transformation tasks, use the online tools at [https://hedtools.org](https://hedtools.org) - no installation needed! -The HEDTools in this repository require Python 3.8 or greater. +A development version is available at: [https://hedtools.org/hed_dev](https://hedtools.org/hed_dev) -### Relationship to other repositories +### Python Installation -The `hed-python` repository contains the Python infrastructure for validating -and analyzing HED. This repository has several companion repositories: -- [`hed-web`](https://github.com/hed-standard/hed-web) contains the web interface -for HED as well as a deployable docker module that supports web services for HED. -- [`hed-examples`](https://github.com/hed-standard/hed-examples) contains examples of -using HED in Python and MATLAB. This repository also houses the HED resources. -See [https://www.hed-resources.org](https://www.hed-resources.org) for access to these. -- [`hed-specification`](https://github.com/hed-standard/hed-specification) contains -the HED specification documents. The `hed-python` validator is keyed to error codes -in this document. -- [`hed-schemas`](https://github.com/hed-standard/hed-schemas) contains -the official HED schemas. The tools access this repository to retrieve and cache schema versions -during execution. Starting with `hedtools 0.2.0` local copies of the most recent schema versions -are stored within the code modules for easy access. +**Requirements:** Python 3.9 or higher -#### Develop versus main versus stable branches +Install from PyPI: +```bash +pip install hedtools +``` + +Or install from GitHub (latest): +```bash +pip install git+https://github.com/hed-standard/hed-python/@main +``` + +### Basic Usage + +```python +from hed import HedString, load_schema + +# Load the latest HED schema +schema = load_schema() + +# Create and validate a HED string +hed_string = HedString("Sensory-event, Visual-presentation, (Onset, (Red, Square))") +issues = hed_string.validate(schema) + +if issues: + print("Validation issues found:") + for issue in issues: + print(f" - {issue}") +else: + print("✓ HED string is valid!") +``` -The `hed-python` repository +### Command-Line Tools -| Branch | Meaning | Synchronized with | -|---------| -------- | ------------------ | -| stable | Officially released on PyPI as a tagged version. | `stable@hed-web`
`stable@hed-specification`
`stable@hed-examples` | -| main | Most recent usable version. | `latest@hed-web`
`latest@hed-specification`
`latest@hed-examples` | +HEDTools includes several command-line utilities: -#### To contribute +```bash +# Validate a BIDS dataset +validate_bids /path/to/bids/dataset + +# Run remodeling operations on event files +run_remodel /path/to/remodel_config.json /path/to/data -Contributions are welcome. -Please use the [Github issues](https://github.com/hed-standard/hed-python/issues) -for suggestions or bug reports. -The [Github pull request](https://github.com/hed-standard/hed-python/pulls) -may also be used for contributions. -These PRs should be made to the `main` branch but should have a branch name other than `main`. +# Validate HED schemas +hed_validate_schemas /path/to/schema.xml +``` -#### Local Settings Storage -Cached Schemas by default are stored in "home/.hedtools/" -Location of "home" directory varies by OS. +For more examples, see the [user guide](https://www.hedtags.org/hed-python/user_guide.html). -Use `hed.schema.set_cache_directory` to change the location. -The HED cache can be shared across processes. +## Documentation -Starting with `hedtools 0.2.0` local copies of the most recent schema versions -are stored within the code modules for easy access. +📖 **Full Documentation:** [https://www.hedtags.org/hed-python](https://www.hedtags.org/hed-python) -### Building the docs locally +- [User Guide](https://www.hedtags.org/hed-python/user_guide.html) - Comprehensive usage instructions +- [API Reference](https://www.hedtags.org/hed-python/api/index.html) - Detailed API documentation +- [HED Specification](https://hed-specification.readthedocs.io/) - Full HED standard specification -You can build the documentation locally by executing the following commands in the hed-python repository root directory: +### Building Documentation Locally ```bash +# Install documentation dependencies +pip install -r docs/requirements.txt + # Build the documentation mkdocs build -# Serve locally with live reload +# Serve locally with live reload at http://localhost:8000 mkdocs serve ``` -The API documentation can be viewed at [ http://localhost:8000]( http://localhost:8000). + +## Related Repositories + +The HED ecosystem consists of several interconnected repositories: + +| Repository | Description | +|------------|-------------| +| [hed-python](https://github.com/hed-standard/hed-python) | Python validation and analysis tools (this repo) | +| [hed-web](https://github.com/hed-standard/hed-web) | Web interface and deployable Docker services | +| [hed-examples](https://github.com/hed-standard/hed-examples) | Example code in Python and MATLAB + HED resources | +| [hed-specification](https://github.com/hed-standard/hed-specification) | Official HED specification documents | +| [hed-schemas](https://github.com/hed-standard/hed-schemas) | Official HED schema repository | + +### Branch Strategy + +| Branch | Purpose | Synchronized With | +|--------|---------|-------------------| +| `stable` | Officially released on PyPI as tagged versions | `stable@hed-web`, `stable@hed-specification`, `stable@hed-examples` | +| `main` | Latest stable development version | `latest@hed-web`, `latest@hed-specification`, `latest@hed-examples` | + +## Contributing + +We welcome contributions! Here's how you can help: + +1. **Report Issues:** Use [GitHub Issues](https://github.com/hed-standard/hed-python/issues) for bug reports and feature requests +2. **Submit Pull Requests:** PRs should target the `main` branch +3. **Improve Documentation:** Help us make HED easier to use +4. **Share Examples:** Contribute example code and use cases + +**Development Setup:** +```bash +# Clone the repository +git clone https://github.com/hed-standard/hed-python.git +cd hed-python + +# Install in development mode with dependencies +pip install -e . +pip install -r requirements.txt + +# Run tests +python -m unittest discover tests + +# Run specific test file +python -m unittest tests/path/to/test_file.py +``` + +For detailed contribution guidelines, please see [CONTRIBUTING.md](CONTRIBUTING.md) (coming soon). + +## Configuration + +### Schema Caching + +By default, HED schemas are cached in `~/.hedtools/` (location varies by OS). + +```python +# Change the cache directory +import hed +hed.schema.set_cache_directory('/custom/path/to/cache') +``` + +Starting with `hedtools 0.2.0`, local copies of recent schema versions are bundled within the package for offline access. + +## Citation + +If you use HEDTools in your research, please cite: + +```bibtex +@software{hedtools, + author = {Robbins, Kay and others}, + title = {HEDTools: Python tools for HED}, + year = {2024}, + publisher = {GitHub}, + url = {https://github.com/hed-standard/hed-python}, + doi = {10.5281/zenodo.8056010} +} +``` + +## License + +HEDTools is licensed under the MIT License. See [LICENSE](LICENSE) for details. + +## Support + +- 📖 [Documentation](https://www.hedtags.org/hed-python) +- 💬 [GitHub Issues](https://github.com/hed-standard/hed-python/issues) +- 🌐 [HED Homepage](https://www.hedtags.org) +- 📧 Contact: Kay.Robbins@utsa.edu diff --git a/docs/user_guide.md b/docs/user_guide.md index cf418dc18..ca3477974 100644 --- a/docs/user_guide.md +++ b/docs/user_guide.md @@ -1,6 +1,13 @@ -# User Guide +# HED Python Tools - User Guide -This guide provides step-by-step instructions for using HED Python tools in various scenarios. +This comprehensive guide provides step-by-step instructions for using HED Python tools in various scenarios, from basic validation to advanced analysis workflows. + +## Quick Links + +- 📚 [API Reference](api/index.md) +- 🐛 [GitHub Issues](https://github.com/hed-standard/hed-python/issues) +- 📖 [HED Specification](https://hed-specification.readthedocs.io/) +- 🌐 [Online Tools](https://hedtools.org) ## Table of Contents @@ -10,19 +17,29 @@ This guide provides step-by-step instructions for using HED Python tools in vari 4. [Working with BIDS Datasets](#working-with-bids-datasets) 5. [Spreadsheet Integration](#spreadsheet-integration) 6. [Advanced Usage](#advanced-usage) +7. [Best Practices](#best-practices) +8. [Troubleshooting](#troubleshooting) ## Getting Started ### Installation +Install HEDTools from PyPI: ```bash pip install hedtools ``` +For the latest development version from GitHub: +```bash +pip install git+https://github.com/hed-standard/hed-python/@main +``` + ### Basic Example +Here's a simple example to get you started with HED validation: + ```python -from hed import HedString, load_schema_version +from hed import HedString, load_schema # Load the latest HED schema schema = load_schema() @@ -35,9 +52,9 @@ issues = hed_string.validate(schema) if issues: print("Validation issues found:") for issue in issues: - print(f"- {issue}") + print(f" - {issue}") else: - print("HED string is valid!") + print("✓ HED string is valid!") ``` ## Working with HED Schemas diff --git a/pyproject.toml b/pyproject.toml index 9ee0d2fcc..ad0d01bc8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "hedtools" dynamic = ["version"] -description = "HED validation, summary, and analysis tools." +description = "HED validation, summary, and analysis tools for annotating events and experimental metadata." readme = "README.md" authors = [ { name = "VisLab" }, @@ -16,14 +16,25 @@ authors = [ { name = "Owen Winterberg" }, { name = "Kay Robbins", email = "Kay.Robbins@utsa.edu" }, ] +maintainers = [ + { name = "Kay Robbins", email = "Kay.Robbins@utsa.edu" }, +] license = {text = "MIT"} -keywords = [] # Add keywords here if any +keywords = ["HED", "hierarchical event descriptors", "validation", "neuroscience", "BIDS", "events", "metadata", "annotation"] classifiers = [ "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering", + "Topic :: Software Development :: Libraries :: Python Modules", + "License :: OSI Approved :: MIT License", ] requires-python = ">=3.9" @@ -47,12 +58,28 @@ dependencies = [ [project.urls] "Homepage" = "https://www.hedtags.org/" -"Repo" = "https://github.com/hed-standard/hed-python/" +"Documentation" = "https://www.hedtags.org/hed-python/" +"Repository" = "https://github.com/hed-standard/hed-python/" "Bug Tracker" = "https://github.com/hed-standard/hed-python/issues" -"API docs" = "https://www.hedtags.org/hed-python/" +"Changelog" = "https://github.com/hed-standard/hed-python/blob/main/CHANGELOG.md" +"HED Resources" = "https://www.hed-resources.org" [project.optional-dependencies] -# Define any optional dependencies here +dev = [ + "flake8>=6.0.0", + "codespell>=2.2.0", +] +docs = [ + "sphinx>=7.0.0", + "furo>=2023.9.10", + "sphinx-copybutton>=0.5.2", + "myst-parser>=2.0.0", + "sphinx-autodoc-typehints>=1.24.0", + "linkify-it-py>=2.0.0", +] +test = [ + "coverage>=7.0.0", +] [project.scripts] run_remodel = "hed.tools.remodeling.cli.run_remodel:main"