Metadata-Version: 2.3
Name: diffpes
Version: 2026.3.1
Summary: Differentiable ARPES simulations in JAX
Keywords: ARPES,MBE,JAX,Differentiable Programming
Author: Debangshu Mukherjee, Jacob Cook
Author-email: Debangshu Mukherjee <mukherjeed@ornl.gov>, Jacob Cook <cookjl2@ornl.gov>
License: MIT License
         
         Copyright (c) 2026 Debangshu Mukherjee, Oak Ridge National Laboratory
         
         Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
         
         The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
         
         THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Topic :: Scientific/Engineering :: Chemistry
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Dist: numpy>=2.2.1
Requires-Dist: matplotlib>=3.10.0
Requires-Dist: jax>=0.7.0 ; sys_platform == 'win64'
Requires-Dist: jax>=0.7.0 ; sys_platform == 'darwin'
Requires-Dist: jax>=0.7.0 ; sys_platform == 'linux'
Requires-Dist: jaxtyping>=0.3.0
Requires-Dist: chex>=0.1.85
Requires-Dist: beartype>=0.21.0
Requires-Dist: jupyter>=1.1.1
Requires-Dist: ipykernel>=7.2.0
Requires-Dist: h5py>=3.15.1
Requires-Dist: diffpes[docs,test,dev,notebooks,cuda] ; extra == 'all'
Requires-Dist: jax[cuda12]>=0.7.0 ; platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cuda'
Requires-Dist: nvidia-cudnn-cu12>=9.5.0 ; platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cuda'
Requires-Dist: diffpes[docs,test,notebooks] ; extra == 'dev'
Requires-Dist: black[jupyter]>=25.1.0 ; extra == 'dev'
Requires-Dist: build>=1.2.2.post1 ; extra == 'dev'
Requires-Dist: twine>=6.1.0 ; extra == 'dev'
Requires-Dist: ruff>=0.12.9 ; extra == 'dev'
Requires-Dist: pygount>=3.1.0 ; extra == 'dev'
Requires-Dist: pre-commit>=4.5.1 ; extra == 'dev'
Requires-Dist: isort>=6.0.1 ; extra == 'dev'
Requires-Dist: ty>=0.0.19 ; extra == 'dev'
Requires-Dist: black>=26.1.0 ; extra == 'dev'
Requires-Dist: jupyter-black>=0.4.0 ; extra == 'dev'
Requires-Dist: diffpes[dev,cuda] ; extra == 'dev-cuda'
Requires-Dist: sphinx>=7.0.0 ; extra == 'docs'
Requires-Dist: sphinx-rtd-theme>=3.0.2 ; extra == 'docs'
Requires-Dist: nbsphinx>=0.9.7 ; extra == 'docs'
Requires-Dist: myst-parser>=2.0.0 ; extra == 'docs'
Requires-Dist: ipykernel>=6.29.5 ; extra == 'docs'
Requires-Dist: nbconvert>=7.16.6 ; extra == 'docs'
Requires-Dist: furo>=2025.7.19 ; extra == 'docs'
Requires-Dist: sphinx-autodoc-typehints>=3.0.1 ; extra == 'docs'
Requires-Dist: numpydoc>=1.9.0 ; extra == 'docs'
Requires-Dist: pydoclint>=0.7.3 ; extra == 'docs'
Requires-Dist: interrogate>=1.7.0 ; extra == 'docs'
Requires-Dist: ipywidgets>=8.1.0 ; extra == 'notebooks'
Requires-Dist: ipykernel>=6.29.5 ; extra == 'notebooks'
Requires-Dist: nbconvert>=7.16.6 ; extra == 'notebooks'
Requires-Dist: pytest>=8.3.5 ; extra == 'test'
Requires-Dist: pytest-cov>=6.0.0 ; extra == 'test'
Requires-Dist: pytest-xdist>=3.0.0 ; extra == 'test'
Requires-Dist: chex>=0.1.89 ; extra == 'test'
Maintainer: Debangshu Mukherjee
Maintainer-email: Debangshu Mukherjee <mukherjeed@ornl.gov>
Requires-Python: >=3.12, <3.15
Provides-Extra: all
Provides-Extra: cuda
Provides-Extra: dev
Provides-Extra: dev-cuda
Provides-Extra: docs
Provides-Extra: notebooks
Provides-Extra: test
Description-Content-Type: text/markdown

# diffpes

JAX-based ARPES simulation toolkit with Python-native APIs.

## Expanded-input workflows

The package includes expanded-input wrappers that let you call the
simulator with plain arrays/scalars while still running JAX kernels.

### Function mapping

- `ARPES_simulation_Novice` -> `diffpes.simul.simulate_novice_expanded`
- `ARPES_simulation_Basic` -> `diffpes.simul.simulate_basic_expanded`
- `ARPES_simulation_Basicplus` -> `diffpes.simul.simulate_basicplus_expanded`
- `ARPES_simulation_Advanced` -> `diffpes.simul.simulate_advanced_expanded`
- `ARPES_simulation_Expert` -> `diffpes.simul.simulate_expert_expanded`
- `ARPES_simulation_SOC` -> `diffpes.simul.simulate_soc_expanded`
- Dynamic dispatch by level -> `diffpes.simul.simulate_expanded`
  (use `level="soc"` with `surface_spin` for SOC)

### Notes

- Default energy-axis padding behavior:
  `min(eigenbands)-1` to `max(eigenbands)+1`.
- Incident angles for expanded wrappers are interpreted in degrees.
- Wrappers return the standard `ArpesSpectrum` PyTree.

### Python indexing conventions

Use standard Python/NumPy indexing everywhere (zero-based, end-exclusive).

- Non-s orbitals: `slice(1, 9)` -> indices 1..8
- p orbitals: `slice(1, 4)` -> indices 1..3
- d orbitals: `slice(4, 9)` -> indices 4..8

Do not use MATLAB-style indexing notation in Python code.

### Example

```python
import jax.numpy as jnp

from diffpes.simul import simulate_expanded

# [nkpt, nband]
eigenbands = jnp.linspace(-2.0, 0.5, 100).reshape(20, 5)
# [nkpt, nband, natom, 9]
surface_orb = jnp.ones((20, 5, 2, 9)) * 0.1

spectrum = simulate_expanded(
    level="advanced",
    eigenbands=eigenbands,
    surface_orb=surface_orb,
    ef=0.0,
    sigma=0.04,
    fidelity=2500,
    temperature=15.0,
    photon_energy=11.0,
    polarization="unpolarized",
    incident_theta=45.0,
    incident_phi=0.0,
    polarization_angle=0.0,
)
```

## Test coverage

Test coverage measures which lines of source code are executed
during tests. Run it with:

```bash
source .venv/bin/activate
pytest tests/ --cov=src/diffpes --cov-report=term-missing
```

To get as close to 100% as possible:

1. **Simul and types** — Already well covered. Any new branch
   (e.g. new polarization or dispatch level) should have a
   corresponding test.
2. **Expanded dispatch** — Test every `simulate_expanded(level=...)`
   branch (novice, basic, basicplus, advanced, expert, soc) and
   the unknown-level `ValueError`.
3. **HDF5** — Round-trip all PyTree types; test error paths
   (unknown type on load, missing group, unsupported type on save).
4. **VASP file readers** (`read_doscar`, `read_eigenval`, `read_kpoints`,
   `read_poscar`, `read_procar`) — Add tests that call each reader
   on minimal in-repo fixture files (e.g. under `tests/fixtures/`)
   so the parsing code paths are executed.
5. **Plotting** — Exercise the public plotting API in tests (or
   accept lower coverage for GUI-oriented code).
6. **Edge branches** — Cover optional arguments (e.g.
   `make_band_structure(..., kpoint_weights=...)`) and error
   messages so one-off branches are hit.
