PackLab is a Python package for three-dimensional hard-sphere packings. It offers two intentionally distinct scientific workflows:
PackLab.monte_carlogenerates explicit random sequential adsorption (RSA) configurations and their statistics.PackLab.analyticalevaluates a Percus--Yevick hard-sphere-mixture reference.
Do not describe these methods as equivalent. RSA is an irreversible, history-dependent packing process; Percus--Yevick is an analytical reference model. Validation should match physical inputs and explain expected differences.
| Path | Purpose |
|---|---|
PackLab/monte_carlo/ |
Python-facing RSA workflow and result helpers. |
PackLab/analytical/ |
Python-facing Percus--Yevick workflow and grid helper. |
PackLab/samplers.* |
Native radius-distribution bindings. |
PackLab/scattering/ |
Optional PyMieSim-based scattering workflow. |
cpp/ |
C++20 implementations and pybind11 interfaces. |
tests/ |
Public-API, packing, sampler, analytical, and scattering tests. |
docs/source/ |
Sphinx documentation. |
docs/examples/ |
Executable gallery examples: monte_carlo, analytical, and validation. |
docs/manuscript/ |
Longer LaTeX scientific manuscript draft and bibliography. |
Native extension modules are installed alongside their Python APIs within
PackLab/ and its public subpackages. Keep this layout; do not introduce a
separate binary package or an interface_* naming layer.
Use Python 3.10 or newer. Native builds require CMake, a C++20 compiler,
pybind11, and OpenMP. On macOS, install libomp first if CMake cannot find
OpenMP.
python -m pip install -e ".[testing]"
python -m pytestInstall documentation dependencies before building docs:
python -m pip install -e ".[documentation,testing]"
python -m sphinx -E -b html docs/source docs/build/htmlUseful focused checks:
python -m pytest tests/test_monte_carlo.py
python -m pytest tests/test_analytical.py
python -m pytest tests/test_samplers.py
python -m pytest tests/test_scattering.pyAfter modifying C++ sources, rebuild the editable install before testing. Do
not hand-edit PackLab/_version.py; martinpdes-maintenance maintains it alongside explicit project metadata.
- Treat
PackLabimports and documented names as the public contract. - Make breaking renames cleanly: remove obsolete names rather than adding compatibility aliases or legacy wrappers.
- Keep Monte-Carlo and analytical APIs clearly separated. Shared utilities are acceptable only when they do not blur that distinction.
- Use
wavenumber, never the historical short namep, in new public Python, C++, type-stub, test, and documentation code. - Prefer
wavenumber="auto"in beginner-facing analytical examples. If a manual grid is used, explain the resolution choice and preserve the warning for inadequate Fourier sampling. - Inputs carrying physical dimensions should use
TypedUnit; convert units at the boundary and keep native kernels operating on explicit SI values. - Add NumPy-style docstrings to Python APIs and pybind11 docstrings plus useful
__repr__output to exposed C++ classes.
- CMake uses C++20 and builds extensions with pybind11.
- Put native implementation beside its binding interface under
cpp/. - Register a new native target in its local
CMakeLists.txt; make its install destination match the corresponding Python package. - Keep binding validation explicit: check shapes, units, finite values, and physical ranges before entering a numerical kernel.
- Tests must exercise the public Python API, not only a private native module.
- Add or update tests for every behaviour change. Numerical features require a convergence or accuracy test, not only a smoke test.
- Use deterministic seeds for Monte-Carlo tests. Avoid assertions that depend on an exact stochastic trajectory unless that trajectory is the behaviour under test.
- Keep gallery examples small enough to execute during a documentation build.
Put each example in the appropriate
monte_carlo,analytical, orvalidationcategory. - Explain assumptions and limitations in docs, especially the distinction between RSA and the analytical model.
- Do not commit generated documentation, coverage reports, build directories, or Python cache files unless a release workflow explicitly requires them.
- Runtime dependencies and build configuration live in
pyproject.toml. - cibuildwheel builds CPython 3.11--3.14 wheels for Linux, macOS, and Windows.
- Linux uses
manylinux_2_28so current scientific Python dependencies can be installed as binary wheels during isolated wheel tests. Do not downgrade this baseline without checking the complete dependency and wheel policy. - Wheel tests must run outside the source checkout, as configured in
pyproject.toml, so they test the installed wheel rather than imported local files.
Keep CITATION.cff and .zenodo.json aligned with release metadata. The
scientific manuscript draft lives in docs/manuscript/packlab.tex; its
bibliography is docs/manuscript/references.bib.
Compile the draft locally with:
cd docs/manuscript
latexmk -pdf packlab.texJOSS submissions use paper.md and paper.bib, not LaTeX. Treat the LaTeX
file as the fuller scientific source. When replacing a figure placeholder,
include parameters, units, uncertainty or convergence information, and a
caption that explains the scientific claim rather than merely naming the plot.
Keep changes focused and avoid unrelated formatting churn. Before handing off, run the narrowest relevant tests and then the full suite when native or public API behaviour changed. Report any dependency, compiler, platform, or numerical assumption that prevents verification.