s2conv 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. s2conv-0.1.0/.all-contributorsrc +31 -0
  2. s2conv-0.1.0/.coveragerc +7 -0
  3. s2conv-0.1.0/.github/workflows/build.yml +71 -0
  4. s2conv-0.1.0/.github/workflows/docs.yml +72 -0
  5. s2conv-0.1.0/.github/workflows/linting.yml +33 -0
  6. s2conv-0.1.0/.github/workflows/tests.yml +80 -0
  7. s2conv-0.1.0/.gitignore +50 -0
  8. s2conv-0.1.0/.pre-commit-config.yaml +6 -0
  9. s2conv-0.1.0/CITATION.cff +41 -0
  10. s2conv-0.1.0/CONTRIBUTING.md +109 -0
  11. s2conv-0.1.0/LICENCE.txt +21 -0
  12. s2conv-0.1.0/MANIFEST.in +4 -0
  13. s2conv-0.1.0/PKG-INFO +265 -0
  14. s2conv-0.1.0/README.md +218 -0
  15. s2conv-0.1.0/benchmarks/__init__.py +1 -0
  16. s2conv-0.1.0/benchmarks/equivariance.py +881 -0
  17. s2conv-0.1.0/benchmarks/results/README.md +66 -0
  18. s2conv-0.1.0/benchmarks/results/equivariance.json +1403 -0
  19. s2conv-0.1.0/benchmarks/results/equivariance.md +77 -0
  20. s2conv-0.1.0/benchmarks/results/equivariance.tex +29 -0
  21. s2conv-0.1.0/benchmarks/results/scaling.json +484 -0
  22. s2conv-0.1.0/benchmarks/results/scaling.md +21 -0
  23. s2conv-0.1.0/benchmarks/results/scaling.pdf +0 -0
  24. s2conv-0.1.0/benchmarks/scaling.py +384 -0
  25. s2conv-0.1.0/codecov.yml +6 -0
  26. s2conv-0.1.0/docs/Makefile +21 -0
  27. s2conv-0.1.0/docs/api/convolutions/classical.rst +5 -0
  28. s2conv-0.1.0/docs/api/convolutions/diagonal.rst +5 -0
  29. s2conv-0.1.0/docs/api/convolutions/index.rst +38 -0
  30. s2conv-0.1.0/docs/api/convolutions/lifted.rst +5 -0
  31. s2conv-0.1.0/docs/api/convolutions/physics.rst +5 -0
  32. s2conv-0.1.0/docs/api/convolutions/sampled.rst +5 -0
  33. s2conv-0.1.0/docs/api/convolutions/section.rst +5 -0
  34. s2conv-0.1.0/docs/api/index.rst +54 -0
  35. s2conv-0.1.0/docs/api/kernels.rst +5 -0
  36. s2conv-0.1.0/docs/api/lifting.rst +5 -0
  37. s2conv-0.1.0/docs/api/transforms.rst +6 -0
  38. s2conv-0.1.0/docs/api/utils/equivariance.rst +5 -0
  39. s2conv-0.1.0/docs/api/utils/evaluation.rst +5 -0
  40. s2conv-0.1.0/docs/api/utils/index.rst +30 -0
  41. s2conv-0.1.0/docs/api/utils/indexing.rst +5 -0
  42. s2conv-0.1.0/docs/api/utils/rotation.rst +5 -0
  43. s2conv-0.1.0/docs/assets/make_s2conv_logo.py +175 -0
  44. s2conv-0.1.0/docs/assets/s2conv_logo.png +0 -0
  45. s2conv-0.1.0/docs/assets/s2conv_logo.svg +222 -0
  46. s2conv-0.1.0/docs/assets/s2conv_logo_dark.png +0 -0
  47. s2conv-0.1.0/docs/assets/s2conv_logo_dark.svg +222 -0
  48. s2conv-0.1.0/docs/conf.py +73 -0
  49. s2conv-0.1.0/docs/index.rst +116 -0
  50. s2conv-0.1.0/docs/user_guide/equivariance.rst +115 -0
  51. s2conv-0.1.0/docs/user_guide/install.rst +98 -0
  52. s2conv-0.1.0/docs/user_guide/notebooks.rst +50 -0
  53. s2conv-0.1.0/docs/user_guide/scaling.rst +42 -0
  54. s2conv-0.1.0/notebooks/data/README.md +39 -0
  55. s2conv-0.1.0/notebooks/data/cmb_planck_polarisation.npz +0 -0
  56. s2conv-0.1.0/notebooks/data/cmb_planck_temperature.npz +0 -0
  57. s2conv-0.1.0/notebooks/data/coastlines.npz +0 -0
  58. s2conv-0.1.0/notebooks/data/convergence.npz +0 -0
  59. s2conv-0.1.0/notebooks/data/earth_topography.npz +0 -0
  60. s2conv-0.1.0/notebooks/data/geoid.npz +0 -0
  61. s2conv-0.1.0/notebooks/data/geomagnetic_potential.npz +0 -0
  62. s2conv-0.1.0/notebooks/data/make_example_fields.py +521 -0
  63. s2conv-0.1.0/notebooks/data/ocean_currents.npz +0 -0
  64. s2conv-0.1.0/notebooks/data/wind.npz +0 -0
  65. s2conv-0.1.0/notebooks/export_real_fields_figures.py +186 -0
  66. s2conv-0.1.0/notebooks/lifted_convolutions.py +1749 -0
  67. s2conv-0.1.0/notebooks/real_fields.py +966 -0
  68. s2conv-0.1.0/pyproject.toml +161 -0
  69. s2conv-0.1.0/s2conv/__init__.py +35 -0
  70. s2conv-0.1.0/s2conv/_version.py +24 -0
  71. s2conv-0.1.0/s2conv/convolutions/__init__.py +40 -0
  72. s2conv-0.1.0/s2conv/convolutions/classical.py +175 -0
  73. s2conv-0.1.0/s2conv/convolutions/diagonal.py +41 -0
  74. s2conv-0.1.0/s2conv/convolutions/lifted.py +221 -0
  75. s2conv-0.1.0/s2conv/convolutions/physics.py +185 -0
  76. s2conv-0.1.0/s2conv/convolutions/sampled.py +99 -0
  77. s2conv-0.1.0/s2conv/convolutions/section.py +176 -0
  78. s2conv-0.1.0/s2conv/kernels.py +371 -0
  79. s2conv-0.1.0/s2conv/lifting.py +177 -0
  80. s2conv-0.1.0/s2conv/transforms.py +321 -0
  81. s2conv-0.1.0/s2conv/utils/__init__.py +32 -0
  82. s2conv-0.1.0/s2conv/utils/equivariance.py +386 -0
  83. s2conv-0.1.0/s2conv/utils/evaluation.py +113 -0
  84. s2conv-0.1.0/s2conv/utils/indexing.py +160 -0
  85. s2conv-0.1.0/s2conv/utils/rotation.py +199 -0
  86. s2conv-0.1.0/s2conv.egg-info/PKG-INFO +265 -0
  87. s2conv-0.1.0/s2conv.egg-info/SOURCES.txt +110 -0
  88. s2conv-0.1.0/s2conv.egg-info/dependency_links.txt +1 -0
  89. s2conv-0.1.0/s2conv.egg-info/requires.txt +23 -0
  90. s2conv-0.1.0/s2conv.egg-info/scm_file_list.json +164 -0
  91. s2conv-0.1.0/s2conv.egg-info/scm_version.json +8 -0
  92. s2conv-0.1.0/s2conv.egg-info/top_level.txt +1 -0
  93. s2conv-0.1.0/setup.cfg +4 -0
  94. s2conv-0.1.0/tests/conftest.py +48 -0
  95. s2conv-0.1.0/tests/reference.py +630 -0
  96. s2conv-0.1.0/tests/test_api.py +58 -0
  97. s2conv-0.1.0/tests/test_autodiff.py +352 -0
  98. s2conv-0.1.0/tests/test_broadcasting.py +254 -0
  99. s2conv-0.1.0/tests/test_classical.py +291 -0
  100. s2conv-0.1.0/tests/test_diagonal.py +66 -0
  101. s2conv-0.1.0/tests/test_equivariance.py +265 -0
  102. s2conv-0.1.0/tests/test_equivariance_metric.py +362 -0
  103. s2conv-0.1.0/tests/test_kernels.py +385 -0
  104. s2conv-0.1.0/tests/test_lifted.py +422 -0
  105. s2conv-0.1.0/tests/test_lifting.py +200 -0
  106. s2conv-0.1.0/tests/test_physics.py +196 -0
  107. s2conv-0.1.0/tests/test_reference.py +94 -0
  108. s2conv-0.1.0/tests/test_scaling_benchmark.py +81 -0
  109. s2conv-0.1.0/tests/test_section.py +243 -0
  110. s2conv-0.1.0/tests/test_spin_change.py +192 -0
  111. s2conv-0.1.0/tests/test_transforms.py +235 -0
  112. s2conv-0.1.0/tests/test_utils.py +278 -0
@@ -0,0 +1,31 @@
1
+ {
2
+ "files": [
3
+ "README.md"
4
+ ],
5
+ "imageSize": 100,
6
+ "commit": false,
7
+ "commitConvention": "angular",
8
+ "contributors": [
9
+ {
10
+ "login": "jasonmcewen",
11
+ "name": "Jason McEwen",
12
+ "avatar_url": "https://avatars.githubusercontent.com/u/3181701?v=4",
13
+ "profile": "http://www.jasonmcewen.org",
14
+ "contributions": [
15
+ "code",
16
+ "ideas",
17
+ "research",
18
+ "doc",
19
+ "maintenance",
20
+ "review"
21
+ ]
22
+ }
23
+ ],
24
+ "contributorsPerLine": 7,
25
+ "skipCi": true,
26
+ "repoType": "github",
27
+ "repoHost": "https://github.com",
28
+ "projectName": "s2conv",
29
+ "projectOwner": "astro-informatics",
30
+ "commitType": "docs"
31
+ }
@@ -0,0 +1,7 @@
1
+ [report]
2
+ omit =
3
+ *test_*
4
+ *_version.py
5
+ exclude_also =
6
+ if TYPE_CHECKING:
7
+ raise NotImplementedError
@@ -0,0 +1,71 @@
1
+ name: Build (and upload to PyPI for published releases)
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ pull_request:
6
+ push:
7
+ branches:
8
+ - main
9
+ release:
10
+ types:
11
+ - published
12
+
13
+ jobs:
14
+ build:
15
+ name: Build source distribution and wheel
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v6.0.3
19
+ with:
20
+ # setuptools-scm needs the full history and the tags to determine the version
21
+ fetch-depth: 0
22
+ fetch-tags: true
23
+
24
+ # s2conv is pure Python, so a single wheel serves every platform
25
+ - name: Build sdist and wheel
26
+ run: pipx run build
27
+
28
+ - name: Check distributions
29
+ run: pipx run twine check --strict dist/*
30
+
31
+ - uses: actions/upload-artifact@v7
32
+ with:
33
+ name: dist
34
+ path: dist/
35
+
36
+ upload_test_pypi:
37
+ needs: build
38
+ runs-on: ubuntu-latest
39
+ environment: test-pypi
40
+ permissions:
41
+ id-token: write
42
+ # Try publishing to Test PyPI first: a problem then stops the release before PyPI.
43
+ # Development versions from pushes to main are uploaded only while the repository
44
+ # is public, since an upload publishes the source.
45
+ if: |
46
+ (github.event_name == 'release' && github.event.action == 'published') ||
47
+ (github.event_name == 'push' && github.ref == 'refs/heads/main' && !github.event.repository.private)
48
+ steps:
49
+ - uses: actions/download-artifact@v8
50
+ with:
51
+ name: dist
52
+ path: dist
53
+ - name: Publish package distributions to Test PyPI
54
+ uses: pypa/gh-action-pypi-publish@release/v1
55
+ with:
56
+ repository-url: https://test.pypi.org/legacy/
57
+
58
+ upload_pypi:
59
+ needs: [build, upload_test_pypi]
60
+ runs-on: ubuntu-latest
61
+ environment: pypi
62
+ permissions:
63
+ id-token: write
64
+ if: github.event_name == 'release' && github.event.action == 'published'
65
+ steps:
66
+ - uses: actions/download-artifact@v8
67
+ with:
68
+ name: dist
69
+ path: dist
70
+ - name: Publish package distributions to PyPI
71
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,72 @@
1
+ name: Docs
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - .github/workflows/docs.yml
9
+ - pyproject.toml
10
+ - s2conv/**
11
+ - docs/**
12
+ push:
13
+ branches:
14
+ - main
15
+
16
+ concurrency:
17
+ group: ${{ github.workflow }}-${{ github.ref }}
18
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
19
+
20
+ jobs:
21
+ build:
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - name: Checkout source
25
+ uses: actions/checkout@v6.0.3
26
+ with:
27
+ # setuptools-scm needs the full history and the tags to determine the version
28
+ fetch-depth: 0
29
+ fetch-tags: true
30
+
31
+ - name: Set up Python
32
+ uses: actions/setup-python@v6
33
+ with:
34
+ python-version: "3.12"
35
+ cache: pip
36
+ cache-dependency-path: pyproject.toml
37
+
38
+ # The package is installed so that autodoc can import it
39
+ - name: Install dependencies
40
+ run: |
41
+ python -m pip install --upgrade pip
42
+ python -m pip install ".[docs]"
43
+
44
+ # Warnings are errors, so that pages whose API reference failed to import are
45
+ # never deployed
46
+ - name: Build documentation
47
+ run: |
48
+ cd docs
49
+ make html SPHINXOPTS="-W --keep-going"
50
+
51
+ - name: Upload built docs as artifact
52
+ uses: actions/upload-pages-artifact@v5
53
+ with:
54
+ path: docs/_build/html
55
+ retention-days: 30
56
+
57
+ deploy:
58
+ # Publish to GitHub Pages on pushes to main only. This requires GitHub Pages
59
+ # to be enabled with "GitHub Actions" as the source in the repository settings.
60
+ environment:
61
+ name: github-pages
62
+ url: ${{ steps.deployment.outputs.page_url }}
63
+ permissions:
64
+ pages: write
65
+ id-token: write
66
+ runs-on: ubuntu-latest
67
+ needs: build
68
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
69
+ steps:
70
+ - name: Deploy to GitHub Pages
71
+ id: deployment
72
+ uses: actions/deploy-pages@v5
@@ -0,0 +1,33 @@
1
+ name: Linting
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+
9
+ jobs:
10
+ linting:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout source
14
+ uses: actions/checkout@v6.0.3
15
+
16
+ - name: Cache pre-commit
17
+ uses: actions/cache@v5
18
+ with:
19
+ path: ~/.cache/pre-commit
20
+ key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
21
+
22
+ - name: Set up Python
23
+ uses: actions/setup-python@v6
24
+ with:
25
+ python-version: "3.x"
26
+ cache: pip
27
+ cache-dependency-path: pyproject.toml
28
+
29
+ - name: Install dependencies
30
+ run: python -m pip install pre-commit
31
+
32
+ - name: Run pre-commit
33
+ run: pre-commit run --all-files --color always --verbose
@@ -0,0 +1,80 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ paths:
9
+ - .github/workflows/tests.yml
10
+ - pyproject.toml
11
+ - s2conv/**
12
+ - tests/**
13
+ - .coveragerc
14
+ schedule:
15
+ - cron: 0 0 * * 0
16
+ # Run on demand from the Actions tab, including the slow tests
17
+ workflow_dispatch:
18
+
19
+ concurrency:
20
+ group: ${{ github.workflow }}-${{ github.ref }}
21
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
22
+
23
+ jobs:
24
+ tests:
25
+ runs-on: ${{ matrix.os }}
26
+ # id-token lets the Codecov step authenticate by OpenID Connect, without a token
27
+ permissions:
28
+ contents: read
29
+ id-token: write
30
+ strategy:
31
+ matrix:
32
+ python-version: ["3.11", "3.12", "3.13"]
33
+ os: [ubuntu-latest, macos-latest]
34
+ s2fft: [latest]
35
+ # The oldest supported s2fft too, which pip would otherwise never install
36
+ # (on Python 3.13 it fails to import, so s2conv requires s2fft>=1.5.0 there)
37
+ include:
38
+ - python-version: "3.11"
39
+ os: ubuntu-latest
40
+ s2fft: "1.4.0"
41
+ fail-fast: false
42
+
43
+ steps:
44
+ - name: Checkout source
45
+ uses: actions/checkout@v6.0.3
46
+ with:
47
+ # setuptools-scm needs the full history and the tags to determine the version
48
+ fetch-depth: 0
49
+ fetch-tags: true
50
+
51
+ - name: Set up Python ${{ matrix.python-version }}
52
+ uses: actions/setup-python@v6
53
+ with:
54
+ python-version: ${{ matrix.python-version }}
55
+ cache: pip
56
+ cache-dependency-path: pyproject.toml
57
+
58
+ - name: Install dependencies
59
+ # The ssht extra (pyssht and ducc0) provides the "jax_ssht" backend, and
60
+ # pyssht has wheels for all of the platforms and Python versions above
61
+ run: |
62
+ python -m pip install --upgrade pip
63
+ python -m pip install ".[tests,ssht]"
64
+ if [ "${{ matrix.s2fft }}" != latest ]; then python -m pip install "s2fft==${{ matrix.s2fft }}"; fi
65
+
66
+ # Run as a module so that the working tree, rather than the installed copy of
67
+ # the package, is imported, and hence measured for coverage
68
+ - name: Run tests (skipping slow tests on pull requests)
69
+ if: github.event_name == 'pull_request'
70
+ run: python -m pytest --cov=s2conv --cov-report=xml --cov-config=.coveragerc -m "not slow"
71
+
72
+ - name: Run tests
73
+ if: github.event_name != 'pull_request'
74
+ run: python -m pytest --cov=s2conv --cov-report=xml --cov-config=.coveragerc
75
+
76
+ - name: Upload coverage reports to Codecov
77
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
78
+ uses: codecov/codecov-action@v6
79
+ with:
80
+ use_oidc: true
@@ -0,0 +1,50 @@
1
+ # Byte-compiled files and caches
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.cache/
6
+
7
+ # Packaging and build output
8
+ build/
9
+ dist/
10
+ wheelhouse/
11
+ *.egg-info/
12
+ *.egg
13
+ .eggs/
14
+
15
+ # Version file written by setuptools_scm at build time
16
+ s2conv/_version.py
17
+
18
+ # Tests and coverage
19
+ .pytest_cache/
20
+ .coverage
21
+ .coverage.*
22
+ coverage.xml
23
+ htmlcov/
24
+ .tox/
25
+
26
+ # Linters and type checkers
27
+ .ruff_cache/
28
+ .mypy_cache/
29
+
30
+ # Virtual environments
31
+ .venv/
32
+ venv/
33
+
34
+ # Notebooks (Jupyter and Marimo)
35
+ .ipynb_checkpoints/
36
+ __marimo__/
37
+
38
+ # Documentation build
39
+ docs/_build/
40
+ docs/api/generated/
41
+
42
+ # Editors and operating system files
43
+ .vscode/
44
+ .idea/
45
+ *.swp
46
+ *~
47
+ .DS_Store
48
+
49
+ # Logs
50
+ *.log
@@ -0,0 +1,6 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.6.9
4
+ hooks:
5
+ - id: ruff
6
+ - id: ruff-format
@@ -0,0 +1,41 @@
1
+ cff-version: 1.2.0
2
+ title: >-
3
+ s2conv: differentiable and accelerated spherical convolutions
4
+ message: >-
5
+ If you use this software, please cite it using the metadata from this file.
6
+ type: software
7
+ authors:
8
+ - given-names: Jason D.
9
+ family-names: McEwen
10
+ orcid: 'https://orcid.org/0000-0002-5852-8890'
11
+ repository-code: 'https://github.com/astro-informatics/s2conv'
12
+ license: MIT
13
+ references:
14
+ - type: unpublished
15
+ authors:
16
+ - given-names: Jason D.
17
+ family-names: McEwen
18
+ orcid: 'https://orcid.org/0000-0002-5852-8890'
19
+ title: Unifying spherical convolutions through lifting
20
+ year: 2026
21
+ status: in-press
22
+ notes: >-
23
+ Forthcoming article describing the generalised lifted spherical
24
+ convolution implemented in s2conv.
25
+ - type: article
26
+ authors:
27
+ - given-names: Matthew A.
28
+ family-names: Price
29
+ - given-names: Jason
30
+ family-names: McEwen
31
+ orcid: 'https://orcid.org/0000-0002-5852-8890'
32
+ title: Differentiable and accelerated spherical harmonic and Wigner transforms
33
+ journal: Journal of Computational Physics
34
+ volume: 510
35
+ issue: 1
36
+ start: 113109
37
+ month: 8
38
+ year: 2024
39
+ doi: 10.1016/j.jcp.2024.113109
40
+ notes: >-
41
+ s2fft, the software on which the harmonic transforms of s2conv are built.
@@ -0,0 +1,109 @@
1
+ # Contributing
2
+
3
+ Thank you for your interest in contributing to s2conv!
4
+ We welcome contributions of all forms, including bug reports, feature requests, documentation, tests and code.
5
+
6
+ ## Reporting bugs or requesting new features
7
+
8
+ If you have a question, please first check the [documentation](https://astro-informatics.github.io/s2conv) and the [existing issues](https://github.com/astro-informatics/s2conv/issues).
9
+ If neither answers it, please [raise an issue](https://github.com/astro-informatics/s2conv/issues/new).
10
+
11
+ When reporting a bug, describe the behaviour you expected, what you observe instead, and provide enough information for someone else to reproduce the problem.
12
+ Ideally this is a [_minimal reproducible example_](https://en.wikipedia.org/wiki/Minimal_reproducible_example): a short script that reproduces the error and is as small and simple as possible.
13
+ Please include the versions of s2conv, s2fft, JAX and Python you are using.
14
+
15
+ ## Setting up a development environment
16
+
17
+ Clone the repository and install the package in editable mode with the test and documentation dependencies:
18
+
19
+ ```bash
20
+ git clone https://github.com/astro-informatics/s2conv.git
21
+ cd s2conv
22
+ pip install -e ".[tests,docs]"
23
+ ```
24
+
25
+ The package version is determined from the git history by [setuptools-scm](https://setuptools-scm.readthedocs.io), so install from a clone of the repository rather than from an archive of the source files.
26
+
27
+ Two further sets of optional dependencies are available:
28
+
29
+ - `ssht` (pyssht and ducc0), required by the `"jax_ssht"` backend and by the tests marked `ssht`;
30
+ - `notebooks` (marimo and matplotlib), required to run the notebook in `notebooks/`.
31
+
32
+ ## Running the tests
33
+
34
+ Run the test suite from the root of the repository with
35
+
36
+ ```bash
37
+ pytest
38
+ ```
39
+
40
+ Some tests are slow or need optional dependencies, and are marked accordingly.
41
+ You can deselect them with, for example,
42
+
43
+ ```bash
44
+ pytest -m "not slow and not ssht"
45
+ ```
46
+
47
+ New functionality should come with tests, and bug fixes with a test that fails without the fix.
48
+
49
+ ## Code style and linting
50
+
51
+ The Python code in s2conv follows the [Black code style](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html), and we use [Ruff](https://docs.astral.sh/ruff/) to lint and autoformat it.
52
+ The Ruff configuration is in `pyproject.toml`.
53
+ The Marimo notebooks in `notebooks/` have their own format and are excluded from Ruff.
54
+
55
+ We use [pre-commit](https://pre-commit.com/) hooks to check that changes respect the formatting and linting rules.
56
+ You can install the hooks in your local repository by [installing pre-commit](https://pre-commit.com/#install) and running
57
+
58
+ ```bash
59
+ pre-commit install
60
+ ```
61
+
62
+ from the root of the repository.
63
+ The hooks then run on any staged changes when you commit.
64
+ If there are problems with the changes, these are reported in the terminal, and where possible they are fixed automatically, in which case the updated files need to be staged and committed again.
65
+ You can also check every file in the repository with `pre-commit run --all-files`.
66
+
67
+ ## Building the documentation
68
+
69
+ The documentation is built with [Sphinx](https://www.sphinx-doc.org).
70
+ From the root of the repository, run
71
+
72
+ ```bash
73
+ cd docs
74
+ make html
75
+ ```
76
+
77
+ and open `docs/_build/html/index.html` in a browser.
78
+
79
+ ## Proposing changes to the repository
80
+
81
+ We use a branch and pull request model.
82
+ Before opening a pull request that proposes substantial changes, for example a new feature or a change to the public interface, please first [raise an issue](https://github.com/astro-informatics/s2conv/issues/new) outlining the problem the changes would address, so that the problem and the proposed solution can be discussed before significant time is invested.
83
+
84
+ If you have not made an open-source contribution via a pull request before, you may find this [detailed guide](https://www.asmeurer.com/git-workflow/) by [asmeurer](https://github.com/asmeurer) helpful.
85
+ The main steps are as follows:
86
+
87
+ 1. Create a branch with a descriptive name.
88
+ Contributors without write access to the repository should first [fork the repository](https://github.com/astro-informatics/s2conv/fork) and create the branch in a local clone of their fork.
89
+ 2. Make the proposed changes on the branch, giving each commit a descriptive commit message.
90
+ 3. Push the branch to GitHub.
91
+ 4. Create a [pull request](https://github.com/astro-informatics/s2conv/compare) against `main`, giving it a descriptive title and explaining what you are changing and why.
92
+ If the pull request resolves a specific issue, use [keywords](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests) to link the issue.
93
+ 5. Make sure that all the automated checks (tests, linting and documentation build) pass on the pull request.
94
+ 6. Await a review by one of the maintainers and address any comments.
95
+ 7. Once the checks pass and a maintainer has approved the changes, the pull request can be (squash) merged.
96
+
97
+ ## Recognising contributions
98
+
99
+ We recognise every kind of contribution, not just code, following the [all-contributors](https://allcontributors.org) specification: the contributors are listed in the [Contributors section of the README](https://github.com/astro-informatics/s2conv#contributors-), with an emoji for each [type of contribution](https://allcontributors.org/docs/en/emoji-key), for example code, documentation, tests, bug reports, ideas, research or review.
100
+
101
+ To add someone, a maintainer comments on an issue or pull request with
102
+
103
+ ```text
104
+ @all-contributors please add @<username> for <contributions>
105
+ ```
106
+
107
+ for example `@all-contributors please add @jasonmcewen for code, doc`.
108
+ The [all-contributors bot](https://allcontributors.org/docs/en/bot/overview) then opens a pull request that updates `.all-contributorsrc` and the table in `README.md`.
109
+ If you think you or someone else should be listed, please say so in an issue or pull request.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Authors & Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ # The sdist takes every file tracked by git (setuptools-scm); leave out the
2
+ # figures exported from the notebooks, which are rebuilt by
3
+ # notebooks/export_real_fields_figures.py
4
+ prune notebooks/figures