shape-plotters 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.
- shape_plotters-0.1.0/.github/workflows/wheels.yml +77 -0
- shape_plotters-0.1.0/.gitignore +10 -0
- shape_plotters-0.1.0/CHANGELOG.md +48 -0
- shape_plotters-0.1.0/LICENSE +21 -0
- shape_plotters-0.1.0/PKG-INFO +120 -0
- shape_plotters-0.1.0/README.md +100 -0
- shape_plotters-0.1.0/conftest.py +5 -0
- shape_plotters-0.1.0/pyproject.toml +41 -0
- shape_plotters-0.1.0/setup.cfg +4 -0
- shape_plotters-0.1.0/shape_plotters/__init__.py +0 -0
- shape_plotters-0.1.0/shape_plotters/__main__.py +3 -0
- shape_plotters-0.1.0/shape_plotters/cli.py +19 -0
- shape_plotters-0.1.0/shape_plotters/core/__init__.py +0 -0
- shape_plotters-0.1.0/shape_plotters/core/energy.py +91 -0
- shape_plotters-0.1.0/shape_plotters/core/engine.py +451 -0
- shape_plotters-0.1.0/shape_plotters/core/fragments.py +63 -0
- shape_plotters-0.1.0/shape_plotters/core/neck.py +41 -0
- shape_plotters-0.1.0/shape_plotters/core/nodes.py +23 -0
- shape_plotters-0.1.0/shape_plotters/core/quadrature.py +41 -0
- shape_plotters-0.1.0/shape_plotters/core/result.py +92 -0
- shape_plotters-0.1.0/shape_plotters/core/widgets.py +68 -0
- shape_plotters-0.1.0/shape_plotters/renders/__init__.py +0 -0
- shape_plotters-0.1.0/shape_plotters/renders/beta.py +166 -0
- shape_plotters-0.1.0/shape_plotters/renders/fos.py +107 -0
- shape_plotters-0.1.0/shape_plotters.egg-info/PKG-INFO +120 -0
- shape_plotters-0.1.0/shape_plotters.egg-info/SOURCES.txt +42 -0
- shape_plotters-0.1.0/shape_plotters.egg-info/dependency_links.txt +1 -0
- shape_plotters-0.1.0/shape_plotters.egg-info/entry_points.txt +2 -0
- shape_plotters-0.1.0/shape_plotters.egg-info/requires.txt +8 -0
- shape_plotters-0.1.0/shape_plotters.egg-info/scm_file_list.json +39 -0
- shape_plotters-0.1.0/shape_plotters.egg-info/top_level.txt +1 -0
- shape_plotters-0.1.0/tests/__init__.py +0 -0
- shape_plotters-0.1.0/tests/test_beta_render.py +214 -0
- shape_plotters-0.1.0/tests/test_cli.py +41 -0
- shape_plotters-0.1.0/tests/test_energy.py +104 -0
- shape_plotters-0.1.0/tests/test_energy_local.py +61 -0
- shape_plotters-0.1.0/tests/test_engine.py +338 -0
- shape_plotters-0.1.0/tests/test_fos_render.py +114 -0
- shape_plotters-0.1.0/tests/test_fragments.py +44 -0
- shape_plotters-0.1.0/tests/test_neck.py +51 -0
- shape_plotters-0.1.0/tests/test_nodes.py +32 -0
- shape_plotters-0.1.0/tests/test_perf.py +64 -0
- shape_plotters-0.1.0/tests/test_quadrature.py +42 -0
- shape_plotters-0.1.0/tests/test_widgets.py +50 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
name: wheels
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
tags: ['[0-9]+.[0-9]+.[0-9]+']
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-24.04
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
with:
|
|
13
|
+
fetch-depth: 0 # tags for setuptools_scm
|
|
14
|
+
- uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: '3.12'
|
|
17
|
+
- name: Build sdist and wheel
|
|
18
|
+
env:
|
|
19
|
+
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_SHAPE_PLOTTERS: ${{ github.ref_name }}
|
|
20
|
+
run: |
|
|
21
|
+
python -m pip install --upgrade build
|
|
22
|
+
python -m build --outdir dist
|
|
23
|
+
- name: Verify wheel in clean venv
|
|
24
|
+
# Everything runs from a copy of the tests outside the checkout, so
|
|
25
|
+
# the tests import the installed wheel and not the source tree (and
|
|
26
|
+
# pip cannot mistake the checkout's egg-info for an installed copy).
|
|
27
|
+
# The timing budgets are skipped: they are calibrated for a developer
|
|
28
|
+
# machine, not a shared runner.
|
|
29
|
+
env:
|
|
30
|
+
MPLBACKEND: Agg
|
|
31
|
+
run: |
|
|
32
|
+
python -m venv /tmp/verify-wheel
|
|
33
|
+
mkdir /tmp/verify-tests
|
|
34
|
+
cp -r tests conftest.py /tmp/verify-tests/
|
|
35
|
+
cd /tmp/verify-tests
|
|
36
|
+
/tmp/verify-wheel/bin/pip install "$GITHUB_WORKSPACE"/dist/*.whl pytest
|
|
37
|
+
/tmp/verify-wheel/bin/python -m pytest tests -q --ignore=tests/test_perf.py
|
|
38
|
+
/tmp/verify-wheel/bin/shape-plotters --help
|
|
39
|
+
- name: Verify sdist installs from the tarball
|
|
40
|
+
run: |
|
|
41
|
+
python -m venv /tmp/verify-sdist
|
|
42
|
+
cd /tmp
|
|
43
|
+
/tmp/verify-sdist/bin/pip install "$GITHUB_WORKSPACE"/dist/*.tar.gz
|
|
44
|
+
/tmp/verify-sdist/bin/shape-plotters --help
|
|
45
|
+
- uses: actions/upload-artifact@v4
|
|
46
|
+
with:
|
|
47
|
+
name: dist
|
|
48
|
+
path: dist/*
|
|
49
|
+
release:
|
|
50
|
+
needs: build
|
|
51
|
+
runs-on: ubuntu-24.04
|
|
52
|
+
permissions:
|
|
53
|
+
contents: write # create/upload the Release
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/download-artifact@v4
|
|
56
|
+
with:
|
|
57
|
+
name: dist
|
|
58
|
+
path: dist
|
|
59
|
+
- uses: softprops/action-gh-release@v2
|
|
60
|
+
with:
|
|
61
|
+
files: dist/*
|
|
62
|
+
pypi:
|
|
63
|
+
needs: build
|
|
64
|
+
runs-on: ubuntu-24.04
|
|
65
|
+
environment:
|
|
66
|
+
name: pypi
|
|
67
|
+
url: https://pypi.org/p/shape-plotters
|
|
68
|
+
permissions:
|
|
69
|
+
id-token: write # PyPI Trusted Publishing (OIDC)
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/download-artifact@v4
|
|
72
|
+
with:
|
|
73
|
+
name: dist
|
|
74
|
+
path: dist
|
|
75
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
76
|
+
with:
|
|
77
|
+
packages-dir: dist
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Notable changes to shape-plotters. Versions follow semantic versioning.
|
|
4
|
+
|
|
5
|
+
## 0.1.0
|
|
6
|
+
|
|
7
|
+
First release.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Installable package.** `pip install shape-plotters` provides the
|
|
12
|
+
`shape-plotters` command; the parameterization libraries are pinned
|
|
13
|
+
dependencies.
|
|
14
|
+
- **Shared engine, one render per parameterization.** `shape-plotters beta`
|
|
15
|
+
and `shape-plotters fos` open the same interactive figure; everything
|
|
16
|
+
shape-specific comes from the render (contract in
|
|
17
|
+
`shape_plotters/core/result.py`).
|
|
18
|
+
- **Beta render** over beta-parameterization 4.0.1: sliders β1–β8, volume
|
|
19
|
+
conserved by the library. An orange overlay shows the centre-of-mass
|
|
20
|
+
corrected shape whenever its β1 differs from the slider value; a corrected
|
|
21
|
+
shape that turns out invalid is drawn greyed instead of vanishing.
|
|
22
|
+
- **FoS render** over fos-parameterization 3.0.0: sliders c and a3–a8 with
|
|
23
|
+
practical-limit markers, an extra ρ(z) panel with the library's dρ/dz, the
|
|
24
|
+
library's neck, and an orange overlay of the R(θ) star-convex representation
|
|
25
|
+
when its centre of mass is shifted. Separated shapes draw both fragments.
|
|
26
|
+
- **Energy-model grid.** R(θ) and the analytic dR/dθ are evaluated by the
|
|
27
|
+
libraries on a 2048-node Gauss-Legendre grid in cos θ, the dense grid of
|
|
28
|
+
the WMMM energy model, so the plot shows the shape the model evaluates.
|
|
29
|
+
- **Stats panel:** volume, surface and centre of mass by Gauss-Legendre
|
|
30
|
+
quadrature on that grid, neck position, radius and depth, and the fragment
|
|
31
|
+
volume and mass split at the neck.
|
|
32
|
+
- **Invalid shapes** stay visible: greyed, with the library's status name and
|
|
33
|
+
message as the panel title.
|
|
34
|
+
- **Display units:** fm / R₀ toggle with Z and N boxes (R₀ = 1.16 A^(1/3) fm).
|
|
35
|
+
- **Scission bands:** the neck-radius range 1.2–1.5 fm is shaded on the
|
|
36
|
+
cross-section panel.
|
|
37
|
+
- **Controls:** ± nudge buttons on every slider, Reset, and Save (300 dpi PNG
|
|
38
|
+
named after the parameters).
|
|
39
|
+
- **Optional Energy button.** Shown only when a local `wmmm` package is
|
|
40
|
+
importable; prints WMMM energies for the shape on screen. `wmmm` is not a
|
|
41
|
+
dependency and no model code, data or output is part of this repository.
|
|
42
|
+
- **Performance guards:** pytest budgets for artist mutation and frame time
|
|
43
|
+
(`tests/test_perf.py`).
|
|
44
|
+
|
|
45
|
+
## Before 0.1.0
|
|
46
|
+
|
|
47
|
+
No changelog was kept during initial development (from 2026-07-03). See the
|
|
48
|
+
git history.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aleksander Augustyn
|
|
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,120 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: shape-plotters
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Interactive matplotlib plotters for axially symmetric nuclear shapes (beta, FoS)
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/AleksanderAugustyn/shape-plotters
|
|
7
|
+
Project-URL: Repository, https://github.com/AleksanderAugustyn/shape-plotters
|
|
8
|
+
Project-URL: Changelog, https://github.com/AleksanderAugustyn/shape-plotters/blob/master/CHANGELOG.md
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: numpy>=2.0
|
|
13
|
+
Requires-Dist: scipy>=1.13
|
|
14
|
+
Requires-Dist: matplotlib>=3.8.4
|
|
15
|
+
Requires-Dist: beta-parameterization==4.0.1
|
|
16
|
+
Requires-Dist: fos-parameterization==3.0.0
|
|
17
|
+
Provides-Extra: test
|
|
18
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# shape-plotters
|
|
22
|
+
|
|
23
|
+
Interactive matplotlib plotters for axially symmetric nuclear shapes. Move a
|
|
24
|
+
slider and the shape, its derivative and its integral properties update. One
|
|
25
|
+
shared engine draws the figure; each shape parameterization is a render module.
|
|
26
|
+
|
|
27
|
+
| render | parameterization | sliders | library |
|
|
28
|
+
|---|---|---|---|
|
|
29
|
+
| `beta` | spherical-harmonic (Legendre) expansion | β1–β8 | [beta-parameterization](https://github.com/AleksanderAugustyn/beta-parameterization) |
|
|
30
|
+
| `fos` | Fourier-over-Spheroid | c, a3–a8 | [fos-parameterization](https://github.com/AleksanderAugustyn/fos-parameterization) |
|
|
31
|
+
|
|
32
|
+
The shapes are not re-implemented here. R(θ) and the analytic dR/dθ come from
|
|
33
|
+
the compiled libraries, evaluated on a 2048-node Gauss-Legendre grid in cos θ.
|
|
34
|
+
That is the dense grid of the WMMM macroscopic-microscopic energy model, so
|
|
35
|
+
the plot shows exactly the shape the model evaluates.
|
|
36
|
+
|
|
37
|
+
## What the figure shows
|
|
38
|
+
|
|
39
|
+
- **R(θ) and dR/dθ**, and the **cross-section** ρ(z) with equal axes. The FoS
|
|
40
|
+
render adds a ρ(z) panel with the library's dρ/dz.
|
|
41
|
+
- **Stats:** volume, surface and centre of mass by Gauss-Legendre quadrature,
|
|
42
|
+
the neck position, radius and depth, and the fragment volume and mass split
|
|
43
|
+
at the neck.
|
|
44
|
+
- **Overlays** (orange, dashed): for beta, the centre-of-mass corrected shape
|
|
45
|
+
when its β1 differs from the slider value; for FoS, the R(θ) star-convex
|
|
46
|
+
representation when its centre of mass is shifted.
|
|
47
|
+
- **Scission bands:** the neck-radius range 1.2–1.5 fm, shaded.
|
|
48
|
+
- **Invalid shapes** stay on screen, greyed, with the library's status as the
|
|
49
|
+
panel title.
|
|
50
|
+
|
|
51
|
+
Controls: ± nudge buttons on every slider, an fm / R₀ unit toggle with Z and N
|
|
52
|
+
boxes (R₀ = 1.16 A^(1/3) fm), Reset, and Save (300 dpi PNG named after the
|
|
53
|
+
parameters, written to the current directory). Red dotted marks on the FoS
|
|
54
|
+
sliders are practical limits.
|
|
55
|
+
|
|
56
|
+
## Requirements
|
|
57
|
+
|
|
58
|
+
- Linux x86-64. The parameterization libraries ship manylinux wheels only;
|
|
59
|
+
WSL2 with WSLg works.
|
|
60
|
+
- Python 3.10 or newer with a matplotlib GUI backend. Tk is the default
|
|
61
|
+
(`python3-tk` on Debian/Ubuntu).
|
|
62
|
+
|
|
63
|
+
## Install
|
|
64
|
+
|
|
65
|
+
pip install shape-plotters
|
|
66
|
+
|
|
67
|
+
or `pipx install shape-plotters` to get the command without touching another
|
|
68
|
+
environment. The parameterization libraries come along as prebuilt wheels
|
|
69
|
+
(Fortran shared library and libgfortran bundled), pinned to the exact versions
|
|
70
|
+
each render is written against.
|
|
71
|
+
|
|
72
|
+
Under WSL, keep the virtual environment on the Linux filesystem, not under
|
|
73
|
+
`/mnt/c`. The Windows drive is a 9P mount; a venv there makes matplotlib
|
|
74
|
+
rendering sluggish (~5× slower).
|
|
75
|
+
|
|
76
|
+
## Run
|
|
77
|
+
|
|
78
|
+
shape-plotters beta
|
|
79
|
+
shape-plotters fos
|
|
80
|
+
|
|
81
|
+
`python -m shape_plotters beta` does the same.
|
|
82
|
+
|
|
83
|
+
## Energy button
|
|
84
|
+
|
|
85
|
+
An Energy button appears when a Python package named `wmmm` is importable. It
|
|
86
|
+
prints the WMMM energies of the shape on screen. WMMM is not public yet and is
|
|
87
|
+
not a dependency: without it the button is absent and nothing else changes.
|
|
88
|
+
This repository contains the calling convention only, no model code, data or
|
|
89
|
+
output.
|
|
90
|
+
|
|
91
|
+
## Development
|
|
92
|
+
|
|
93
|
+
git clone https://github.com/AleksanderAugustyn/shape-plotters.git
|
|
94
|
+
cd shape-plotters
|
|
95
|
+
python3 -m venv ~/.venvs/shape-plotters
|
|
96
|
+
source ~/.venvs/shape-plotters/bin/activate
|
|
97
|
+
pip install -e ".[test]"
|
|
98
|
+
python -m pytest
|
|
99
|
+
|
|
100
|
+
The WMMM smoke tests skip when `wmmm` is not installed. The frame-time budgets
|
|
101
|
+
in `tests/test_perf.py` assume a venv on the Linux filesystem.
|
|
102
|
+
|
|
103
|
+
shape_plotters/cli.py entry point and render registry
|
|
104
|
+
shape_plotters/core/ engine, widgets, quadrature, neck and fragment helpers
|
|
105
|
+
shape_plotters/core/result.py the render contract (what a render gives the engine)
|
|
106
|
+
shape_plotters/renders/ one module per parameterization
|
|
107
|
+
tests/ pytest suite, including frame-time budgets
|
|
108
|
+
|
|
109
|
+
A new parameterization is a new module in `shape_plotters/renders/` that
|
|
110
|
+
implements the render contract, plus one registry entry in `cli.py` and a
|
|
111
|
+
pinned library in `pyproject.toml`. The engine needs no change.
|
|
112
|
+
|
|
113
|
+
Releases are cut by pushing a version tag such as `0.1.0`; the `wheels`
|
|
114
|
+
workflow builds, tests and publishes to PyPI.
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
|
|
118
|
+
MIT, see [LICENSE](https://github.com/AleksanderAugustyn/shape-plotters/blob/master/LICENSE).
|
|
119
|
+
Changes are recorded in
|
|
120
|
+
[CHANGELOG.md](https://github.com/AleksanderAugustyn/shape-plotters/blob/master/CHANGELOG.md).
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# shape-plotters
|
|
2
|
+
|
|
3
|
+
Interactive matplotlib plotters for axially symmetric nuclear shapes. Move a
|
|
4
|
+
slider and the shape, its derivative and its integral properties update. One
|
|
5
|
+
shared engine draws the figure; each shape parameterization is a render module.
|
|
6
|
+
|
|
7
|
+
| render | parameterization | sliders | library |
|
|
8
|
+
|---|---|---|---|
|
|
9
|
+
| `beta` | spherical-harmonic (Legendre) expansion | β1–β8 | [beta-parameterization](https://github.com/AleksanderAugustyn/beta-parameterization) |
|
|
10
|
+
| `fos` | Fourier-over-Spheroid | c, a3–a8 | [fos-parameterization](https://github.com/AleksanderAugustyn/fos-parameterization) |
|
|
11
|
+
|
|
12
|
+
The shapes are not re-implemented here. R(θ) and the analytic dR/dθ come from
|
|
13
|
+
the compiled libraries, evaluated on a 2048-node Gauss-Legendre grid in cos θ.
|
|
14
|
+
That is the dense grid of the WMMM macroscopic-microscopic energy model, so
|
|
15
|
+
the plot shows exactly the shape the model evaluates.
|
|
16
|
+
|
|
17
|
+
## What the figure shows
|
|
18
|
+
|
|
19
|
+
- **R(θ) and dR/dθ**, and the **cross-section** ρ(z) with equal axes. The FoS
|
|
20
|
+
render adds a ρ(z) panel with the library's dρ/dz.
|
|
21
|
+
- **Stats:** volume, surface and centre of mass by Gauss-Legendre quadrature,
|
|
22
|
+
the neck position, radius and depth, and the fragment volume and mass split
|
|
23
|
+
at the neck.
|
|
24
|
+
- **Overlays** (orange, dashed): for beta, the centre-of-mass corrected shape
|
|
25
|
+
when its β1 differs from the slider value; for FoS, the R(θ) star-convex
|
|
26
|
+
representation when its centre of mass is shifted.
|
|
27
|
+
- **Scission bands:** the neck-radius range 1.2–1.5 fm, shaded.
|
|
28
|
+
- **Invalid shapes** stay on screen, greyed, with the library's status as the
|
|
29
|
+
panel title.
|
|
30
|
+
|
|
31
|
+
Controls: ± nudge buttons on every slider, an fm / R₀ unit toggle with Z and N
|
|
32
|
+
boxes (R₀ = 1.16 A^(1/3) fm), Reset, and Save (300 dpi PNG named after the
|
|
33
|
+
parameters, written to the current directory). Red dotted marks on the FoS
|
|
34
|
+
sliders are practical limits.
|
|
35
|
+
|
|
36
|
+
## Requirements
|
|
37
|
+
|
|
38
|
+
- Linux x86-64. The parameterization libraries ship manylinux wheels only;
|
|
39
|
+
WSL2 with WSLg works.
|
|
40
|
+
- Python 3.10 or newer with a matplotlib GUI backend. Tk is the default
|
|
41
|
+
(`python3-tk` on Debian/Ubuntu).
|
|
42
|
+
|
|
43
|
+
## Install
|
|
44
|
+
|
|
45
|
+
pip install shape-plotters
|
|
46
|
+
|
|
47
|
+
or `pipx install shape-plotters` to get the command without touching another
|
|
48
|
+
environment. The parameterization libraries come along as prebuilt wheels
|
|
49
|
+
(Fortran shared library and libgfortran bundled), pinned to the exact versions
|
|
50
|
+
each render is written against.
|
|
51
|
+
|
|
52
|
+
Under WSL, keep the virtual environment on the Linux filesystem, not under
|
|
53
|
+
`/mnt/c`. The Windows drive is a 9P mount; a venv there makes matplotlib
|
|
54
|
+
rendering sluggish (~5× slower).
|
|
55
|
+
|
|
56
|
+
## Run
|
|
57
|
+
|
|
58
|
+
shape-plotters beta
|
|
59
|
+
shape-plotters fos
|
|
60
|
+
|
|
61
|
+
`python -m shape_plotters beta` does the same.
|
|
62
|
+
|
|
63
|
+
## Energy button
|
|
64
|
+
|
|
65
|
+
An Energy button appears when a Python package named `wmmm` is importable. It
|
|
66
|
+
prints the WMMM energies of the shape on screen. WMMM is not public yet and is
|
|
67
|
+
not a dependency: without it the button is absent and nothing else changes.
|
|
68
|
+
This repository contains the calling convention only, no model code, data or
|
|
69
|
+
output.
|
|
70
|
+
|
|
71
|
+
## Development
|
|
72
|
+
|
|
73
|
+
git clone https://github.com/AleksanderAugustyn/shape-plotters.git
|
|
74
|
+
cd shape-plotters
|
|
75
|
+
python3 -m venv ~/.venvs/shape-plotters
|
|
76
|
+
source ~/.venvs/shape-plotters/bin/activate
|
|
77
|
+
pip install -e ".[test]"
|
|
78
|
+
python -m pytest
|
|
79
|
+
|
|
80
|
+
The WMMM smoke tests skip when `wmmm` is not installed. The frame-time budgets
|
|
81
|
+
in `tests/test_perf.py` assume a venv on the Linux filesystem.
|
|
82
|
+
|
|
83
|
+
shape_plotters/cli.py entry point and render registry
|
|
84
|
+
shape_plotters/core/ engine, widgets, quadrature, neck and fragment helpers
|
|
85
|
+
shape_plotters/core/result.py the render contract (what a render gives the engine)
|
|
86
|
+
shape_plotters/renders/ one module per parameterization
|
|
87
|
+
tests/ pytest suite, including frame-time budgets
|
|
88
|
+
|
|
89
|
+
A new parameterization is a new module in `shape_plotters/renders/` that
|
|
90
|
+
implements the render contract, plus one registry entry in `cli.py` and a
|
|
91
|
+
pinned library in `pyproject.toml`. The engine needs no change.
|
|
92
|
+
|
|
93
|
+
Releases are cut by pushing a version tag such as `0.1.0`; the `wheels`
|
|
94
|
+
workflow builds, tests and publishes to PyPI.
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
MIT, see [LICENSE](https://github.com/AleksanderAugustyn/shape-plotters/blob/master/LICENSE).
|
|
99
|
+
Changes are recorded in
|
|
100
|
+
[CHANGELOG.md](https://github.com/AleksanderAugustyn/shape-plotters/blob/master/CHANGELOG.md).
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "setuptools_scm>=8"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "shape-plotters"
|
|
7
|
+
description = "Interactive matplotlib plotters for axially symmetric nuclear shapes (beta, FoS)"
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
license = "MIT"
|
|
10
|
+
license-files = ["LICENSE"]
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"numpy>=2.0",
|
|
14
|
+
# First releases that install alongside numpy 2.
|
|
15
|
+
"scipy>=1.13",
|
|
16
|
+
"matplotlib>=3.8.4",
|
|
17
|
+
# Exact pins: each render is written against one library API version.
|
|
18
|
+
"beta-parameterization==4.0.1",
|
|
19
|
+
"fos-parameterization==3.0.0",
|
|
20
|
+
]
|
|
21
|
+
dynamic = ["version"]
|
|
22
|
+
|
|
23
|
+
[project.optional-dependencies]
|
|
24
|
+
test = ["pytest>=7"]
|
|
25
|
+
|
|
26
|
+
[project.scripts]
|
|
27
|
+
shape-plotters = "shape_plotters.cli:main"
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://github.com/AleksanderAugustyn/shape-plotters"
|
|
31
|
+
Repository = "https://github.com/AleksanderAugustyn/shape-plotters"
|
|
32
|
+
Changelog = "https://github.com/AleksanderAugustyn/shape-plotters/blob/master/CHANGELOG.md"
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.packages.find]
|
|
35
|
+
include = ["shape_plotters*"]
|
|
36
|
+
|
|
37
|
+
# Version from git tags (setuptools_scm), as in the parameterization libraries.
|
|
38
|
+
[tool.setuptools_scm]
|
|
39
|
+
|
|
40
|
+
[tool.pytest.ini_options]
|
|
41
|
+
testpaths = ["tests"]
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Command-line entry point: shape-plotters beta|fos (or python -m shape_plotters)."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
from collections.abc import Sequence
|
|
6
|
+
|
|
7
|
+
from shape_plotters.core.engine import ShapePlotterApp
|
|
8
|
+
from shape_plotters.renders.beta import BetaRender
|
|
9
|
+
from shape_plotters.renders.fos import FoSRender
|
|
10
|
+
|
|
11
|
+
RENDERS = {"beta": BetaRender, "fos": FoSRender}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main(argv: Sequence[str] | None = None) -> None:
|
|
15
|
+
parser = argparse.ArgumentParser(
|
|
16
|
+
prog="shape-plotters", description="Interactive nuclear-shape plotter")
|
|
17
|
+
parser.add_argument("render", choices=sorted(RENDERS))
|
|
18
|
+
args = parser.parse_args(argv)
|
|
19
|
+
ShapePlotterApp(RENDERS[args.render]()).run()
|
|
File without changes
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""Optional WMMM energy adapter — the only module allowed to import wmmm.
|
|
2
|
+
|
|
3
|
+
The energy model is strictly local: wmmm is never a dependency of this
|
|
4
|
+
package (not even an optional extra) and is installed out-of-band as a local
|
|
5
|
+
editable install. This module carries the calling convention only — no model
|
|
6
|
+
code, data, or paths. The engine consults available() to decide whether the
|
|
7
|
+
Energy button exists; compute() returns EnergyResult, with failures in
|
|
8
|
+
EnergyResult.error rather than exceptions.
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import importlib.util
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
from typing import Sequence
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass(frozen=True)
|
|
18
|
+
class EnergyResult:
|
|
19
|
+
"""One WMMM point result (energies in MeV); zero-filled when error is set."""
|
|
20
|
+
is_valid: bool
|
|
21
|
+
mass_excess: float
|
|
22
|
+
total_energy: float
|
|
23
|
+
macro_energy: float
|
|
24
|
+
micro_energy: float
|
|
25
|
+
surface_energy: float
|
|
26
|
+
coulomb_energy: float
|
|
27
|
+
proton_pairing_gap: float
|
|
28
|
+
neutron_pairing_gap: float
|
|
29
|
+
proton_k: int
|
|
30
|
+
neutron_k: int
|
|
31
|
+
corrected_beta10: float # cross-check channel (vs the render scalar), not displayed
|
|
32
|
+
error: str | None = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# Model handles are configuration-immutable: one per (param_type,
|
|
36
|
+
# com_correction) for the app lifetime (~20 ms per compute thereafter).
|
|
37
|
+
_models: dict[tuple[str, bool], object] = {}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def available() -> bool:
|
|
41
|
+
"""True when the wmmm package is importable; performs no import."""
|
|
42
|
+
return importlib.util.find_spec("wmmm") is not None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _error(message: str) -> EnergyResult:
|
|
46
|
+
return EnergyResult(False, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
|
47
|
+
0, 0, 0.0, error=message)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _get_model(param_type: str, com_correction: bool):
|
|
51
|
+
key = (param_type, com_correction)
|
|
52
|
+
model = _models.get(key)
|
|
53
|
+
if model is None:
|
|
54
|
+
import wmmm # deferred: loads the Fortran library on first use only
|
|
55
|
+
model = wmmm.Model(param_type)
|
|
56
|
+
if not com_correction:
|
|
57
|
+
model.set("beta_10_com_shift", 0.0)
|
|
58
|
+
_models[key] = model
|
|
59
|
+
return model
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def compute(param_type: str, z: int, n: int, shape: Sequence[float],
|
|
63
|
+
com_correction: bool = True) -> EnergyResult:
|
|
64
|
+
"""One WMMM point computation; never raises.
|
|
65
|
+
|
|
66
|
+
Parameters
|
|
67
|
+
----------
|
|
68
|
+
param_type : str
|
|
69
|
+
"legendre" (20 shape params) or "fos" (7).
|
|
70
|
+
z, n : int
|
|
71
|
+
Proton and neutron numbers.
|
|
72
|
+
shape : Sequence[float]
|
|
73
|
+
Shape parameters in WMMM's convention (raw slider values).
|
|
74
|
+
com_correction : bool
|
|
75
|
+
WMMM's beta_10_com_shift flag. False evaluates beta10 as given
|
|
76
|
+
(legendre only — inert on the fos path).
|
|
77
|
+
"""
|
|
78
|
+
try:
|
|
79
|
+
model = _get_model(param_type, com_correction)
|
|
80
|
+
r = model.compute(int(z), int(n), list(shape))
|
|
81
|
+
except Exception as exc: # any wmmm failure becomes a stats-box message
|
|
82
|
+
return _error(f"{type(exc).__name__}: {exc}")
|
|
83
|
+
return EnergyResult(
|
|
84
|
+
is_valid=bool(r.is_valid), mass_excess=r.mass_excess,
|
|
85
|
+
total_energy=r.total_energy, macro_energy=r.macro_energy,
|
|
86
|
+
micro_energy=r.micro_energy, surface_energy=r.surface_energy,
|
|
87
|
+
coulomb_energy=r.coulomb_energy,
|
|
88
|
+
proton_pairing_gap=r.proton_pairing_gap,
|
|
89
|
+
neutron_pairing_gap=r.neutron_pairing_gap,
|
|
90
|
+
proton_k=int(r.proton_k), neutron_k=int(r.neutron_k),
|
|
91
|
+
corrected_beta10=r.corrected_beta10)
|