Metadata-Version: 2.5
Name: md2reflect
Version: 3.1.1
Summary: A scientific package for the evaluation of neutron/X-ray reflectivity based on structures described by molecular dynamics simulations
Project-URL: Homepage, https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/
Project-URL: Issues, https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/-/issues
Project-URL: Documentation, https://daphne4nfdi.pages.hzdr.de/Made2Reflect/
Project-URL: Source, https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/
Project-URL: Changelog, https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/-/blob/master/CHANGELOG.md
Author-email: Jean-François Moulin <jean-francois.moulin@hereon.de>
License-Expression: GPL-3.0-or-later
License-File: AUTHORS.md
License-File: LICENSE.txt
Keywords: MD,Molecular Dynamics,neutron,reflectivity,scattering,x-ray
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Scientific/Engineering :: Chemistry
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: matplotlib>=3.8
Requires-Dist: mdanalysis>=2.6
Requires-Dist: numpy>=1.26
Requires-Dist: periodictable>=2.0
Requires-Dist: scipy>=1.12
Provides-Extra: app
Requires-Dist: marimo>=0.23; extra == 'app'
Requires-Dist: plotly>=6; extra == 'app'
Provides-Extra: bornagain
Requires-Dist: bornagain>=20; extra == 'bornagain'
Provides-Extra: dev
Requires-Dist: black; extra == 'dev'
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pre-commit; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest>=7; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Provides-Extra: docs
Requires-Dist: myst-parser; extra == 'docs'
Requires-Dist: sphinx; extra == 'docs'
Requires-Dist: sphinx-rtd-theme; extra == 'docs'
Provides-Extra: inference
Requires-Dist: arviz; extra == 'inference'
Requires-Dist: corner; extra == 'inference'
Requires-Dist: jax>=0.4; extra == 'inference'
Requires-Dist: numpyro>=0.13; extra == 'inference'
Provides-Extra: viz
Requires-Dist: jupyter-bokeh>=4; extra == 'viz'
Requires-Dist: panel>=1.9; extra == 'viz'
Requires-Dist: plotly>=6; extra == 'viz'
Description-Content-Type: text/markdown

# Made2Reflect

[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.21805169.svg)](https://doi.org/10.5281/zenodo.21805169)
[![PyPI](https://img.shields.io/pypi/v/md2reflect.svg)](https://pypi.org/project/md2reflect/)
[![License: GPL-3.0-or-later](https://img.shields.io/badge/License-GPLv3%2B-blue.svg)](https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/-/blob/master/LICENSE.txt)

A Python package for calculating neutron and X-ray reflectivity
profiles from molecular dynamics simulations.

Developed at Helmholtz-Zentrum Hereon, German Engineering Materials
Science Centre (GEMS) at Heinz Maier-Leibnitz Zentrum (MLZ), Garching.

## Overview

md2reflect reads MD simulation trajectories, computes element-resolved
concentration profiles along the z-axis, and converts them to scattering
length density (SLD) profiles. Semi-infinite substrate and bulk layers
are added to the simulation data, interfacial roughness is applied, and
the expected reflectivity curve is calculated via the Abeles matrix
method.

Key capabilities:

- **Trajectory reading** via MDAnalysis (PDB, XTC, DCD, GRO, ...)
- **Isotopic substitution** on arbitrary atom selections
- **Dual-probe SLD**: neutron and X-ray profiles from the same
  simulation, switchable at any point
- **Convolution and Nevot-Croce roughness** models
- **Optimal step-function discretisation** of continuous SLD profiles
  (penalised Potts and constrained min-bin objectives)
- **BornAgain export** for advanced fitting workflows (optional)
- **Interactive visualisation** of SLD, reflectivity, and element
  density profiles

## Requirements

- Python >= 3.12
- numpy >= 1.26
- scipy >= 1.12
- matplotlib >= 3.8
- periodictable >= 2.0
- MDAnalysis >= 2.6

Optional extras: `viz` (interactive Panel widget), `app` (marimo
front-end), `inference` (JAX/NumPyro fitting), `bornagain` (BornAgain
export), `docs`, `dev`.

`pyproject.toml` is authoritative. The exact resolved stack that CI
tests, and that the container images are built from, is pinned in
`requirements-lock.txt`. What each dependency is for, how it is
monitored, and the known gaps are documented in
`docs/dependencies.md`.

## Installation

```console
pip install md2reflect
```

Optional extras are installed by name, e.g. `pip install
"md2reflect[viz]"` for the interactive widget.

From a local clone:

```console
pip install .
```

For development:

```console
pip install -e ".[dev]"
```

### Container (no local Python needed)

Ready-to-run images are built and published by CI to the project's
container registry on every release. Nothing but a container runtime is
required:

```console
# JupyterLab with the package, the examples and their data
docker run --rm -p 8888:8888 \
  registry.hzdr.de/daphne4nfdi/made2reflect:latest-jupyter
# then open http://localhost:8888

# A Python shell with md2reflect importable
docker run --rm -it \
  registry.hzdr.de/daphne4nfdi/made2reflect:latest python
```

Images are tagged `X.Y.Z` per release and `latest` from `master`. The
`jupyter` image starts JupyterLab **without a token** — it is meant for
a local, trusted machine and must not be exposed on a shared host. See
`SECURITY.md`.

Building the images yourself — three targets:

```console
docker build --target base    -t md2reflect .              # runtime
docker build --target jupyter -t md2reflect:jupyter .      # + JupyterLab
docker build --target ci      -t md2reflect:ci .           # test runner
```

Or use docker-compose:

```console
docker compose up jupyter    # JupyterLab on localhost:8888
docker compose run test      # run test suite
```

## Quick start

```python
import numpy as np
import md2reflect as m2r

# Build a sample: silicon substrate, a thin oxide, D2O bulk.
# The two semi-infinite media have their own slots -- add_region is
# for the stack in between.
sample = m2r.Sample()
sample.set_substrate(formula="Si", density=2.33, roughness=3)
sample.add_region(
    m2r.HomogeneousLayer(
        name="SiO2", formula="SiO2", density=2.2,
        thickness=15, roughness=3,
    )
)
sample.set_bulk(formula="D2O", density=1.1)

sample.display_sld(probe="n")

# Measure it. The probe and the q grid belong to the instrument, not
# to the sample, so two reflectometers can share one sample.
q = np.linspace(0.005, 0.25, 500)
reflectometer = m2r.Reflectometer(probe="n", q=q, dq=0.03 * q)
reflectometer.sample = sample
reflectometer.display_Rmeas()
```

See `examples/demo_MD2Reflect.ipynb` for a full tutorial using
MD simulation data, and `docs/scientific_context.md` for the scientific
setting and an index of all worked examples.

## Repository layout

```
src/md2reflect/    Source code
tests/             Test suite (pytest), physics validation in tests/physics/
docs/              Sphinx documentation sources
examples/          Demo notebooks, scripts and sample data
benchmarks/        Performance measurements (not tests)
scripts/           Maintenance scripts (not shipped)
```

The layout follows the PyPA src-layout template. It is declared
machine-readably in `repo_structure.toml`, together with every
deliberate deviation from that template, and checked in CI by
`scripts/check_repo_structure.py` — so a new top-level file must be
declared with a reason or the pipeline fails. See
`docs/repository_structure.md`.

## Documentation

Sphinx documentation can be built from the `docs/` directory:

```console
pip install sphinx sphinx-rtd-theme myst-parser
sphinx-build -b html docs docs/_build/html
```

## Contributing

Contributions are welcome. Start with
[`CONTRIBUTING.md`](https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/-/blob/master/CONTRIBUTING.md)
for the development setup, coding standards and merge-request workflow,
and
[`GOVERNANCE.md`](https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/-/blob/master/GOVERNANCE.md)
for how issues are triaged, how code
review works, and who decides what.

This project uses pre-commit hooks for code style (black, ruff — which
replaces flake8 and isort — mypy, and notebook-output stripping):

```console
pip install pre-commit
pre-commit install
```

After that, staged files are checked automatically on commit.

- Report a bug or request a feature:
  [issue tracker](https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/-/issues)
  (issue templates are offered in the form).
- Report a security problem: **not** via a public issue — see
  [`SECURITY.md`](https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/-/blob/master/SECURITY.md).
- Participation is governed by
  [`CODE_OF_CONDUCT.md`](https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/-/blob/master/CODE_OF_CONDUCT.md).

## Citing

Made2Reflect is archived on Zenodo and has a DOI. Cite the **concept
DOI**, [10.5281/zenodo.21805169](https://doi.org/10.5281/zenodo.21805169),
unless you specifically mean one release — it resolves to the latest
version, whereas a version DOI (3.1.0 is
[10.5281/zenodo.21805170](https://doi.org/10.5281/zenodo.21805170))
pins the one you used. If reproducibility is the point, cite the version
DOI and record the `periodictable` version too: the scattering lengths
it supplies are an input to every SLD this package reports, not a
constant of the package (see
[`docs/dependencies.md`](https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/-/blob/master/docs/dependencies.md)).

Citation metadata is in
[`CITATION.cff`](https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/-/blob/master/CITATION.cff)
(read directly by
GitLab and most reference managers); `codemeta.json` carries the same
information for software harvesters and is generated from it.

The DMPC bilayer trajectory used by the large-dataset example is
deposited separately as
[10.5281/zenodo.21980300](https://doi.org/10.5281/zenodo.21980300) and
should be cited alongside this software if you use it.

## License

Made2Reflect is distributed under the terms of the
[GPL-3.0-or-later](https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/-/blob/master/LICENSE.txt)
license.

## Funding Acknowledgement

Development of Made2Reflect is primarily funded by the Helmholtz Association via Helmholtz-Zentrum hereon GmbH.

This work was partially funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation) under the project number 460248799 within the framework of the consortium DAPHNE4NFDI DAta from PHoton and Neutron Experiments) in association with the German National Research Data Infrastructure (NFDI) e.V.

## Links

- [Documentation](https://daphne4nfdi.pages.hzdr.de/Made2Reflect/)
- [PyPI](https://pypi.org/project/md2reflect/)
- [Source](https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/)
- [Issues](https://codebase.helmholtz.cloud/DAPHNE4NFDI/Made2Reflect/-/issues)

Copyright 2020 - 2026, Helmholtz-Zentrum Hereon
