Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
60ff19f
WIP
bjmorgan Oct 28, 2025
95c4e45
WIP
bjmorgan Oct 29, 2025
2ab2e84
WIP
bjmorgan Oct 29, 2025
fbecc39
WIP
bjmorgan Oct 29, 2025
b27dc71
Added composition range enumeration
bjmorgan Oct 29, 2025
43321de
Updating docs
bjmorgan Oct 29, 2025
91af7c7
Bug fixes
bjmorgan Oct 29, 2025
e9f7563
Updated python versions
bjmorgan Oct 29, 2025
2db874c
Fixing CI action
bjmorgan Oct 29, 2025
3d41c6e
Updates
bjmorgan Oct 29, 2025
e8f0d88
Updated docs
bjmorgan Oct 29, 2025
62c0707
mypy fixes
bjmorgan Oct 29, 2025
e3576e8
bug fix
bjmorgan Oct 29, 2025
c77dd53
Fixing typing
bjmorgan Oct 29, 2025
4fdd461
mypy fixes
bjmorgan Oct 29, 2025
1af1568
bug fixes
bjmorgan Oct 29, 2025
3c9f5ce
Updated RTD config
bjmorgan Oct 29, 2025
0e3e211
Fixing docs
bjmorgan Oct 29, 2025
e6b9a0e
Fixing docs
bjmorgan Oct 29, 2025
e075af4
Fixing docs
bjmorgan Oct 29, 2025
feddbe0
Performance improvements
bjmorgan Oct 29, 2025
810849d
mypy tweaks
bjmorgan Oct 29, 2025
787248e
Fixing typos
bjmorgan Oct 29, 2025
c7bb4f0
Memory optimisations
bjmorgan Oct 29, 2025
1e9c51f
Bug fix
bjmorgan Oct 29, 2025
93a33da
Bug fix
bjmorgan Oct 29, 2025
b102bbf
Updated README
bjmorgan Oct 29, 2025
49abfda
WIP
bjmorgan Nov 2, 2025
28a23c4
Refactoring
bjmorgan Nov 2, 2025
169ea11
Updated docs
bjmorgan Nov 2, 2025
850a8fb
Added multi level enumeration example
bjmorgan Nov 2, 2025
6f114b1
Remove ColourOperation class (moved to feature/colour-operations branch)
bjmorgan Nov 2, 2025
e37de8e
Remove ColourOperation class (moved to feature/colour-operations branch)
bjmorgan Nov 2, 2025
ac50954
Preparing for v2.0
bjmorgan Nov 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions .coveragerc

This file was deleted.

80 changes: 45 additions & 35 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,45 +1,55 @@
name: Build

name: build
# Controls when the action will run
on: [push, pull_request]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
tests:
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
matrix:
python-version: ['3.9','3.10','3.11','3.12']
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install python dependencies
run: |
pip install --upgrade pip
pip install numpy
pip install -r requirements.txt
pip install mypy
pip install -r tests/notebook_tests/requirements.txt
pip install pytest
pip install pytest-cov
pip install .
pip list
- name: Run tests
run: |
pytest tests/integration_tests
pytest tests/notebook_tests
pytest tests/unit_tests --cov-config=.coveragerc --cov=bsym --cov-report lcov
- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v2.3.0
with:
file: ./coverage.lcov
github-token: ${{ secrets.COVERALLS_REPO_TOKEN }}
- name: Install type stubs
run: |
python -m pip install types-tqdm
- name: Static type checking
run: |
mypy bsym
- uses: actions/checkout@v4

- name: Set up Python ${{matrix.python-version}}
uses: actions/setup-python@v5
with:
python-version: ${{matrix.python-version}}
cache: 'pip'

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
# Install package with dev dependencies
pip install -e ".[dev]"
pip list

- name: Run tests
run: |
pytest --cov-config=.coveragerc --cov=bsym --cov-report lcov

- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v2.3.6
with:
path-to-lcov: ./coverage.lcov
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel: true
flag-name: python-${{ matrix.python-version }}

- name: Static type checking
run: |
mypy bsym

# This job finalizes the parallel coverage reports
finish:
needs: tests
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Coveralls Finished
uses: coverallsapp/github-action@v2.3.6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel-finished: true
9 changes: 3 additions & 6 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ version: 2
build:
os: ubuntu-22.04
tools:
python: "3.9"
python: "3.10"
apt_packages:
- pandoc # Add pandoc as a system dependency

Expand All @@ -17,12 +17,9 @@ sphinx:
configuration: docs/source/conf.py
fail_on_warning: false

# Optionally build your docs in additional formats such as PDF
formats:
- pdf

python:
install:
- method: pip
path: .
- requirements: docs/requirements.txt
extra_requirements:
- docs
48 changes: 48 additions & 0 deletions CHANGELOG,md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.0.0] - 2025-11-02

### Added
- Varying composition enumeration via `unique_configurations_by_composition` method
- `generate_partitions` utility for integer partitioning
- `compute_mapping_vectors` for species permutation mapping
- `satisfies_bounds` for occupancy constraint validation
- Comprehensive progress tracking with nested progress bars
- Verbose output options for composition enumeration
- `unique_structure_substitutions_by_composition` in pymatgen interface
- Multi-level disorder enumeration documentation and examples
- Complete documentation restructure with separate Theory and User Guide sections
- Type hints throughout the codebase with mypy static type checking in CI

### Changed
- **BREAKING**: Minimum Python version raised to 3.10
- **BREAKING**: Removed `ColourOperation` class (moved to `feature/colour-operations` branch)
- Optimised Configuration storage using `np.int8` arrays
- Implemented batched symmetry operations with cached index mappings
- Migrated from individual loops to vectorised NumPy operations
- Updated CI to GitHub Actions with Python 3.10-3.14 support
- CI now uses pytest as test runner (unittest test suite maintained)
- Converted narrative documentation from reStructuredText to Markdown
- Species exchange symmetry optimisation reduces analyses by 40-50%

### Performance
- Substantially improved configuration enumeration performance
- Example: 2×2×2 supercell of TiOF₂ shows 4.7× speedup (35.6s → 7.6s) with 13% memory overhead
- Vectorised operations and optimised data types throughout

### Documentation
- Complete restructure: Getting Started, Theory, User Guide, API Reference
- New theory documents explaining mathematical foundations
- Practical Jupyter notebook tutorials with executable examples
- Expanded README with installation, testing, and usage examples
- Added multi-level disorder enumeration examples

### Development
- Added mypy static type checking to CI pipeline
- Modernised GitHub Actions workflow with pip caching and parallel coverage
- Updated to pyproject.toml-based configuration
79 changes: 57 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,91 @@
# bsym

[![PyPI version](https://badge.fury.io/py/bsym.svg)](https://badge.fury.io/py/bsym)
[![DOI](https://zenodo.org/badge/19279643.svg)](https://zenodo.org/badge/latestdoi/19279643)
[![status](http://joss.theoj.org/papers/6696543fc631bf66feb99a9cde808a39/status.svg)](http://joss.theoj.org/papers/6696543fc631bf66feb99a9cde808a39)
[![Coverage Status](https://coveralls.io/repos/github/bjmorgan/bsym/badge.svg?branch=master)](https://coveralls.io/github/bjmorgan/bsym?branch=master)
[![Documentation Status](https://readthedocs.org/projects/bsym/badge/?version=latest)](http://bsym.readthedocs.io/en/latest/?badge=latest)


`bsym` is a basic Python symmetry module. It consists of core classes that describe configuration vector spaces, their symmetry operations, and specific configurations of objects within these spaces. The module also contains an interface for working with [`pymatgen`](http://pymatgen.org) `Structure` objects, to allow simple generation of disordered symmetry-inequivalent structures from a symmetric parent crystal structure.

Usage examples are provided in the [documentation](http://bsym.readthedocs.io/en/latest)
API documentation is [here][API].
Usage examples are provided in the [documentation](http://bsym.readthedocs.io/en/latest).
API documentation is [here][API].
Source code is available at [https://github.com/bjmorgan/bsym][github].

## Requirements

`bsym` requires Python 3.10 or later.

## Installation

```
### Standard Installation

Install from PyPI:
```bash
pip install bsym
```

Or download the latest release from [GitHub](httpsL//github.com/bjmorgan/bsym/releases), and install
```
### Installation from Source

Download the latest release from [GitHub](https://github.com/bjmorgan/bsym/releases), and install:
```bash
cd bsym
python setup.py install
pip install .
```

Or clone the latest development version
```
Or clone the latest development version:
```bash
git clone git@github.com:bjmorgan/bsym.git
cd bsym
pip install .
```
and install the same way.
```

### Development Installation

To install with development dependencies (for running tests, type checking, building docs, etc.):
```bash
git clone git@github.com:bjmorgan/bsym.git
cd bsym
python setup.py install
pip install -e ".[dev]"
```

This installs `bsym` in editable mode with additional tools for development.

## Tests

Manual tests can be run using
Tests use pytest. After installing with development dependencies, run:
```bash
pytest
```
python -m unittest discover

For verbose output:
```bash
pytest -v
```

To run specific test files:
```bash
pytest tests/unit_tests/test_symmetry_group.py
```

The code has been tested with Python versions 3.5 and above.
## Example Usage

### Enumerating Symmetry-Inequivalent Structures

`bsym` can enumerate symmetry-inequivalent structures for disordered materials. Here's an example using a `pymatgen` `Structure` as input:
```python
from bsym.interface.pymatgen import unique_structure_substitutions
unique_structures = unique_structure_substitutions(
parent_structure,
'X', # Sites to substitute
{'O': 8, 'F': 16} # 8 oxygen, 16 fluorine
)
print(f"Found {len(unique_structures)} unique structures")
```

## Documentation
An overview of the capabilities of `bsym` along with example code is provided in the [codumentation](http://bsym.readthedocs.io/en/latest/).

## I want to generate a set of symmetry-inequivalent crystal structures
`bsym` can enumerate symmetry-inequivalent crystal structures generated by partial substitutions, starting from a parent structure described by a `pymatgen` `Structure` object.
Example code is in the [documentation](http://bsym.readthedocs.io/en/latest/).
Also refer to the [`bsym.interface.pymatgen.unique_structure_substitutions`](http://bsym.readthedocs.io/en/latest/api/interface/pymatgen.html#bsym.interface.pymatgen.unique_structure_substitutions) documentation.
An overview of the capabilities of `bsym` along with example code is provided in the [documentation](http://bsym.readthedocs.io/en/latest/).

## Citing `bsym`

Expand All @@ -58,8 +94,7 @@ This code can be cited as:
Morgan, Benjamin J. (2017). *bsym - a Basic Symmetry Module*. The Journal of Open Source Software. http://doi.org/10.21105/joss.00370

### BibTeX

```
```bibtex
@article{Morgan_JOSS2017b,
doi = {10.21105/joss.00370},
url = {https://doi.org/10.21105/joss.00370},
Expand Down
1 change: 0 additions & 1 deletion bsym/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from bsym.configuration import Configuration
from bsym.configuration_space import ConfigurationSpace
from bsym.coordinate_config_space import CoordinateConfigSpace
from bsym.colour_operation import ColourOperation

from bsym.version import __version__

2 changes: 1 addition & 1 deletion bsym/bsym.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import warnings
import sys

warnings.warn( "\nYou are trying to import bsym.bsym, which is not compatible with this version of bsym.\nPlease check the updated API information at https://github.com/bjmorgan/bsym,\n or download a compatible 0.1.* release at https://github.com/bjmorgan/bsym/releases.\n" )
warnings.warn( "\nYou are trying to import bsym.bsym, which is not compatible with this version of bsym.\nPlease check the updated API information at https://github.com/bjmorgan/bsym,\n or download a compatible release at https://github.com/bjmorgan/bsym/releases.\n" )

sys.exit()
Loading