# uma-ase

[`uma-ase`](https://gitlab.com/carlesbo/uma-ase) combines UMA machine-learned interatomic potentials with ASE workflows for:

- single-point energies
- geometry optimization
- vibrational / thermochemical analysis
- transition-state search with ASE's dimer method
- molecular dynamics

It can be used from the command line or through the bundled webapp.

## Overview

- One CLI for `sp`, `geoopt`, `freqs`, `ts`, and `md`
- Webapp for structure loading, editing, job submission, visualization, analysis, and ioChem-BD interaction
- Persistent FIFO job queue stored server-side in `jobs.jsonl`
- Reproducible `.use` recipe files for every submitted job
- Automatic CML export after successful runs
- Live log streaming and MD trajectory capture

## Citation

If results obtained with `uma-ase` contribute to a publication, please cite the UMA-ASE software paper:

- C. Bo, G. Dias Da Silva, F. Hosseini, A. R. Mullukkandy, H. Salazar-Lozas, A. Sole-Daura, and Y. Wang, `UMA-ASE: A FAIR-Aware Environment for Machine-Learned Interatomic Potential Workflows with UMA and ASE`, *ChemRxiv* **2026**, DOI: `10.26434/chemrxiv.15001161/v1`

When preparing a manuscript, we also recommend stating the exact `uma-ase` version used in the calculations, together with the relevant UMA checkpoint and task settings, so the workflow can be reproduced accurately.

Download links:

- [Paper landing page](https://chemrxiv.org/doi/abs/10.26434/chemrxiv.15001161/v1)
- [Version 1 PDF](./manuscript/v1.pdf)
- [BibTeX entry](./manuscript/chemrxiv2026.bib)

If the calculation outputs are deposited through ioChem-BD and a dataset DOI is assigned, cite both the deposited dataset DOI and the ioChem-BD platform paper. The recommended ioChem-BD references are:

- M. Álvarez-Moreno, C. de Graaf, N. López, F. Maseras, J. M. Poblet, and C. Bo, `Managing the Computational Chemistry Big Data Problem: The ioChem-BD Platform`, *Journal of Chemical Information and Modeling* **2015**, *55*, 95-103. DOI: `10.1021/ci500593j`
- C. Bo, F. Maseras, and N. López, `The role of computational results databases in accelerating the discovery of catalysts`, *Nature Catalysis* **2018**, *1*, 809-810. DOI: `10.1038/s41929-018-0176-4`

In short:

- cite the UMA-ASE paper when the software is central to published results
- report the exact software version and key model settings
- if results are uploaded to ioChem-BD, cite the dataset DOI and the ioChem-BD platform paper

## Requirements

Validated with Python 3.12.

Core runtime:

- Python >= 3.10
- ASE >= 3.26
- numpy >= 2.2
- torch >= 2.6
- fairchem-core >= 2.10
- PyYAML >= 6.0
- requests >= 2.31
- ray[serve] >= 2.53.0

Optional features:

- Webapp and reports: `flask`, `matplotlib`, `python-docx`
- Analyze tab: `pandas`
- ioChem-BD tooling: `importlib_resources`, `lxml`, `saxonche`, `networkx`
- Local SMILES/InChI 3D generation: `RDKit` from `conda-forge`

Notes:

- On some Ubuntu installs, RDKit helper modules such as drawing or bond-inference extensions may be packaged separately. `uma-ase` now enables the core RDKit workflow as long as `Chem` and `AllChem` are available; optional features degrade gracefully when helper modules are missing.

## Installation

Choose one of these installation scenarios.

### Scenario 1: run directly from a source checkout

Use this when:

- you are developing UMA-ASE
- you do not want to install the package yet
- you are happy to start it with `PYTHONPATH=src`

Setup:

```bash
cd /path/to/UMA-ASE
pip install -r requirements.txt
conda install -c conda-forge rdkit
```

On Apple Silicon, you may also want:

```bash
export OMP_NUM_THREADS=1
```

Run:

```bash
export PYTHONPATH=src
python -m uma_ase.server
```

This is the workflow currently used in local development.

### Scenario 2: install from source in editable mode

Use this when:

- you want the `uma-ase` and `uma-ase-server` commands
- you are still developing locally
- you want code changes in the checkout to be reflected immediately

Typical setup with a virtual environment:

```bash
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
pip install -e ".[server,iochem,analysis]"
```

On Apple Silicon, you may also want:

```bash
export OMP_NUM_THREADS=1
```

For SMILES/InChI 3D generation:

```bash
conda install -c conda-forge rdkit
```

Then run:

```bash
uma-ase-server
```

### Scenario 3: install from a built wheel or tarball in `dist/`

Use this when:

- you want to deploy UMA-ASE on another machine
- you do not want to rely on a source checkout
- you want a repeatable installation from generated artifacts

This is the recommended deployment path.

Important:

- use one single `python` executable for the whole deployment
- do not check RDKit with one Python and then install or run UMA-ASE with another one
- after wheel installation, `PYTHONPATH` is no longer needed

In practice, this means:

1. find the Python executable that can import `rdkit`
2. use that exact executable path for installation
3. use that same executable path again to start the server

Example:

```bash
/usr/local/bin/python -c "from rdkit import Chem; from rdkit.Chem import AllChem; print('RDKit OK')"
/usr/local/bin/python -m pip install --user "uma-ase[server,iochem,analysis] @ file:///.../uma_ase-0.9.8-py3-none-any.whl"
/usr/local/bin/python -m uma_ase.server
```

If `python3` does not see RDKit, but a conda-managed Python does, use the conda Python path instead.

On the source machine, build fresh artifacts:

```bash
cd /path/to/UMA-ASE
python -m pip install --upgrade build
python -m build
```

Then copy these files to the target machine:

- `dist/uma_ase-0.9.8-py3-none-any.whl`
- `scripts/install_from_dist.sh`

On the target machine, install from the wheel:

```bash
./scripts/install_from_dist.sh \
  --python "$(command -v python3)" \
  --checkpoint-dir "$HOME/uma-checkpoints" \
  --results-dir "$HOME/.uma_ase/results"
```

The installer:

- checks Python `>= 3.10`
- aborts if RDKit is not importable in that Python
- installs `uma-ase` with `server`, `iochem`, and `analysis` extras
- writes `~/.uma_ase/uma_ase_env.sh`
- can append that env file to your shell startup file when `--persist-shell` is used

Load the generated shell snippet:

```bash
source ~/.uma_ase/uma_ase_env.sh
```

Then start UMA-ASE:

```bash
uma-ase-server
```

Alternative:

```bash
python -m uma_ase.server
```

Notes:

- default results directory: `~/.uma_ase/results`
- default checkpoint directory written by the installer: `~/uma-checkpoints`
- on macOS, the installer writes `OMP_NUM_THREADS=1` unless it is already set
- if you install with `--user`, the installer also exports the Python user `bin/` directory into `PATH`
- if the installer says the wheel is missing vendored ioChem stylesheet files, rebuild `dist/` first
- for a long-running Linux service, you can install `gunicorn` and run `gunicorn "uma_ase.server:create_app()" --bind 0.0.0.0:8000`

### Scenario 4: install from a package index

Use this when:

- UMA-ASE is already published to your package index
- you do not need a local `dist/`
- you want a normal `pip install`

Base install:

```bash
pip install uma-ase
```

Full webapp install:

```bash
pip install "uma-ase[server,iochem,analysis]"
```

Optional extras:

- `server`: webapp and reports
- `iochem`: ioChem-BD and CML/XSLT tooling
- `analysis`: Analyze-tab dependencies

If FairChem is not already present:

```bash
pip install fairchem-core
```

For SMILES/InChI 3D generation:

```bash
conda install -c conda-forge rdkit
```

## Quick Start

### CLI

```bash
export UMA_CUSTOM_CHECKPOINT_DIR=/abs/path/to/checkpoints
uma-ase -input geometry.xyz -chg 0 -spin 1 -run-type sp
```

From a source checkout without installing:

```bash
export PYTHONPATH=src
python -m uma_ase.cli -input geometry.xyz -chg 0 -spin 1 -run-type geoopt
```

### Webapp

Installed package:

```bash
uma-ase-server
```

From source:

```bash
export PYTHONPATH=src
python -m uma_ase.server
```

Then open <http://127.0.0.1:8000>.

## Configuration

### UMA checkpoints

- `UMA_CUSTOM_CHECKPOINT_DIR`: directory containing UMA checkpoints such as `uma-s-1p1.pt`

### Results and queue storage

- `UMA_RESULTS_DIR`: root directory for jobs, logs, bundles, and analysis reports
- job metadata is stored in `${UMA_RESULTS_DIR}/jobs.jsonl`


### ioChem-BD

- `UMA_ASE_IOCHEM_REST_URL`: default REST endpoint used for bare handles
- `UMA_ASE_IOCHEM_CREATE_BASE`: default Create REST endpoint
- `UMA_ASE_IOCHEM_VERIFY`: set to `0` to skip TLS verification
- `UMA_ASE_IOCHEM_REST_FALLBACKS`: fallback REST endpoints for bare handles only

Notes:

- when a full ioChem-BD URL is pasted in the webapp, the original host is preserved
- fallback hosts are used only for bare handles such as `100/6530`

### RDKit / PubChem

- `UMA_ASE_MAX_CONFORMERS` default: `2000`
- `UMA_ASE_RDKIT_MAX_BOND_ATOMS` default: `200`
- `UMA_ASE_RDKIT_MAX_2D_ATOMS` default: `250`
- `UMA_ASE_PUBCHEM_DEBUG=1`: enable PubChem conformer diagnostics
- to diagnose RDKit availability on a running server, query:

```bash
curl http://127.0.0.1:8000/api/uma-ase/chem/diagnostics
```

- the diagnostics payload reports whether core RDKit imports, drawing support, and `rdDetermineBonds` are available, and whether a test 2D PNG can actually be rendered on that machine
- `Generate 3D` from `SMILES` or `InChI` prefers local RDKit rendering for the 2D sketch, but falls back to a PubChem PNG when the local drawing stack is incomplete

## CLI

### Main behavior

- `-input` accepts an ASE-readable geometry file or a webapp-generated `.use` recipe
- charge and spin can be read automatically from XYZ comment lines
- `ts` runs perform:
  1. an initial vibrational calculation
  2. a dimer search
  3. a final vibrational validation
- `md` must be run alone

### Common options

- `-input`: geometry file or `.use` file
- `-chg`: molecular charge
- `-spin`: spin multiplicity
- `-run-type`: `sp`, `geoopt`, `freqs`, `ts`, `md`
- `-iter`: maximum optimization steps
- `-grad`: force threshold in eV/Å
- `-optimizer`: ASE optimizer for standard geometry optimization
- `-mlff-chk`: UMA checkpoint
- `-mlff-task`: UMA task
- `-temp` / `--temperature`: vibrational-analysis temperature in K
- `-press` / `--pressure`: vibrational-analysis pressure in Pa
- `-cpu`: force CPU execution
- `-visualize`: open the optimized structure in ASE's viewer

### TS options

- `--ts-displacement`
- `--ts-dimer-separation`
- `--ts-trial-step`
- `--ts-max-step`
- `--ts-max-rot`

### MD options

Selected groups:

- Core: `--md-engine`, `--md-steps`, `--md-timestep-fs`, `--md-temperature`, `--md-traj-interval`, `--md-log-interval`
- Thermostats: `--md-friction`, `--md-relax-fs`, `--md-nose-*`, `--md-bussi-taut-fs`, `--md-andersen-prob`
- Barostats / NPT: `--md-pressure-bar`, `--md-compressibility-bar`, `--md-barostat-relax-fs`, `--md-mtk-*`, `--md-baoab-*`, `--md-melchionna-*`
- PBC / cell: `--md-use-pbc`, `--md-cell-a/b/c`, `--md-cell-alpha/beta/gamma`
- Restart: `--md-restart-traj`

Use `uma-ase -h` for the full reference.

### XYZ charge / spin metadata

`uma-ase` reads charge and spin from XYZ comment lines when present, for example:

```text
199
https://iochem-bd.iciq.es/browse/handle/100/69781 charge=-1 spin=2
O  0.0 0.0 0.0
H  0.0 0.0 0.96
H  0.0 0.75 -0.48
```

Legacy signed-integer comment patterns are also accepted.

### `.use` recipe files

Every webapp job writes a `*.use` JSON recipe containing:

- full input geometry payload (`filename`, `format`, original saved path, and embedded content)
- run type / run sequence
- method metadata (`method = MLIP-UMA`, with the selected checkpoint stored as `checkpoint`)
- all run-type-specific parameters needed to reproduce the job
- generator metadata (`uma-ase` version and timestamp)

The webapp validates the parameter set before writing the `.use` file, so a recipe is only saved when the required fields for that run type are present. Older `.use` files that still use `mlff_chk` remain readable for backward compatibility.

Reuse from CLI:

```bash
uma-ase -input /path/to/job.use
```

Reuse from the webapp:

1. Open **Load/Edit**
2. Click **Load .use**
3. Review the restored parameters
4. Go to **Calculate** and launch again

### Logs and timing

Each run writes a `Run metadata` block with the minimal information needed to reproduce the job.

- `sp` and `geoopt` omit irrelevant thermochemistry metadata
- `freqs` and `ts` include temperature and pressure
- `md` includes only the active engine and active PBC / cell settings
- `freqs` and `ts` explicitly re-symmetrize the finite-difference Hessian with `(H + H^T) / 2` and project rigid translations/rotations before diagonalization
- `-FREQS-modes.zip` now includes every vibrational mode trajectory, including near-zero modes, and uses normalized fixed-amplitude mode animations for stable visualization

Timing policy:

- log blocks use a consistent sectioned layout for CLI arguments, atomic-system summary, run metadata, geometry tables, calculator setup, and final result summaries
- each CLI log starts with a UMA-ASE version banner before the argument block
- main run headers now use the same full-form naming style across `Single Point`, `Geometry Optimization`, `Vibrational Analysis`, `Transition State Search`, and `Molecular Dynamics`
- each context switch now inserts two blank lines before the next `=====` or `-----` banner block for easier visual scanning
- `Timing [...]` banner lines now print as closed separator blocks above and below the timing line, and bonding-energy sections include a short note describing the single-atom UMA reference setup
- per-phase timing reports wall time
- log events with timestamps are emitted in a highlighted banner style for run starts, completions, and major phase transitions
- setup phases now include explicit ASE-load timing, including geometry loading, UMA checkpoint loading, calculator setup, and MD restart-trajectory loading when applicable
- atomic reference energies now reuse the already loaded UMA predictor within each run instead of reloading the checkpoint per atom type
- single-atom reference calculations now use the neutral-atom ground-state multiplicity instead of forcing multiplicity `1`
- the packaged multiplicity table lives in [src/uma_ase/data/ground_state_atomic_multiplicities.json](./src/uma_ase/data/ground_state_atomic_multiplicities.json), and the bonding-energy log section prints the data provenance used for those references
- the final `Run total` line reports both CPU and wall time

## Webapp

The webapp combines geometry intake, submission, visualization, analysis, queue management, and ioChem-BD integration.

### Load/Edit

![UMA-ASE Load/Edit tab](./src/uma_ase/static/load-mosaic.png)

Use this tab to import or build the atomic system.

Supported sources:

- local files such as `.xyz`, `.pdb`, `.mol`, `.cif`
- ioChem-BD handles and full URLs
- PubChem CID or name
- PDBe entry ID
- SMILES / InChI via RDKit

Highlights:

- Atomic System Details summarizes charge, multiplicity, formula, atom count, 2D sketch, IUPAC name, and conformer state
- successful fetch/generation keeps the active source input and clears the other source fields
- loading or creating a new structure clears the Visualize tab state before the new system is previewed
- PubChem also copies the returned SMILES into the SMILES box
- non-periodic CML is kept as CML for viewing
- periodic CML is converted to CIF before loading into JSmol
- static jobs convert CML to XYZ for ASE; MD uses CIF if periodic, otherwise XYZ
- charge and multiplicity extracted from ioChem-BD CML are propagated to Calculate and MD
- RDKit-derived 2D sketch, IUPAC name, and inferred SMILES are skipped for systems larger than 150 atoms

Conformers:

- generate from SMILES or from the current structure
- navigate with the isomer / conformer controls above the viewer
- UFF energies are shown when available
- generation can be stopped from the UI

Editing:

- select an atom in JSmol
- change its element in the Edit card
- use `DO`, `UNDO`, and `REDO`

Periodic systems:

- MD PBC is off by default
- MD cell fields are filled only when the structure contains periodic data
- stale PBC values are cleared when a new non-periodic structure is loaded

### Calculate

![UMA-ASE Calculate tab](./src/uma_ase/static/calculate-1.png)
![UMA-ASE Molecular Dynamics setup](./src/uma_ase/static/calculate-2.png)

This tab combines static calculations, multi-job submission, and MD.

Modes:

- **Single Job**
- **Multi Jobs**
- **Molecular Dynamics**

Common layout:

- selected system filename shown in the System card
- charge and multiplicity on the next row
- method selector, UMA checkpoint, and UMA task

Static calculations:

- supports `sp`, `geoopt`, `freqs`, and `ts`
- the output panel streams the full log
- **Download Results** bundles all generated files

Vibrational settings:

- shown as **Vibrational Analysis Settings**
- webapp defaults: `300 K` and `1 atm`
- backend and CLI keep pressure in Pascals

TS behavior:

- TS reuses the same visible controls as `GeoOpt + Frequencies`
- optimizer, force threshold, max GeoOpt iterations, temperature, and pressure remain visible
- the optimizer is forced to **Dimer algorithm** while TS is selected

Multi Jobs:

- each selected input file becomes its own queued job
- results are bundled into a single ZIP

Molecular Dynamics:

- exposes ASE MD engines and their thermostat / barostat controls
- supports editable PBC and cell parameters
- live log output is shown in the MD output panel
- periodic inputs are passed to ASE as CIF

### Visualize

![UMA-ASE Visualize tab](./src/uma_ase/static/visualize-1.png)
![UMA-ASE Visualize tab with modes or trajectory controls](./src/uma_ase/static/visualize-2.png)

Use this tab to inspect completed or running results.

It provides:

- the main JSmol structure viewer
- a trajectory viewer for `.traj`, `.xyz`, and live MD capture
- a vibrational-mode loader for `*-FREQS-modes.zip` plus the matching log
- a completed-job loader through `.use` and `.log`

Important behavior:

- freqs and TS runs auto-populate the vibrational-mode controls after completion
- completed periodic MD jobs keep their cell during playback
- completed periodic MD playback is recentered to the frame center of mass
- opening a job from **My Jobs** preloads the relevant visualization data

### Analyze

![UMA-ASE Analyze tab](./src/uma_ase/static/analyze-1.png)
![UMA-ASE Analyze tab with results](./src/uma_ase/static/analyze-2.png)

The Analyze tab runs post-processing workflows directly in the browser.

Available analyses:

- **RMSD Report**
- **XYZ Pair Analysis**
- **Simple Geometry Analysis**

Shared workflow:

- choose an analysis card
- load the required file or folder directly in that card
- use the shared action bar to run and download the selected format
- monitor the shared progress bar during execution

Outputs:

- RMSD Report: plot plus HTML summary/tables
- XYZ Pair Analysis: 3D scatter, RMSD-vs-charge plot, and tables
- Simple Geometry Analysis: summary tables plus histogram

### My Jobs

![UMA-ASE My Jobs tab](./src/uma_ase/static/jobs.png)

This tab shows the persistent server-side queue and completed-job history.

Features:

- queued / running / completed / interrupted states
- submission time and elapsed runtime
- per-job actions for view, rename, restart MD, kill, download, delete
- bulk delete and download
- job-count and storage-usage badges
- retention countdown indicator per job

View behavior:

- SP: load the log into Calculate and stay there
- Freqs: load the log into Calculate and the normal-mode data into Visualize
- GeoOpt / TS: load the log into Calculate and the optimized trajectory into Visualize
- MD: load the log into both Calculate and MD output, and open Visualize with the trajectory
- running jobs opened from **My Jobs** switch to **Visualize** and update only the tracking / visualization widgets until completion
- when a tracked `Freqs` job reaches `completed`, its final log is also restored in **Calculate**
- when a running `Freqs` job auto-restores the initial structure for visualization, the Calculate log is preserved instead of being replaced by a generic `Loaded ...` message
- before a completed GeoOpt / Freqs / TS result is auto-loaded, the existing **Visualize** state is cleared so stale trajectory or mode controls do not persist
- loading a completed MD trajectory directly in **Visualize** also clears the tab state first, so stale trajectory or mode controls do not persist

Queue history persists across server restarts through `jobs.jsonl`.

### ioChem-BD

![UMA-ASE ioChem-BD tab](./src/uma_ase/static/iochem.png)

This tab provides browsing and upload support for ioChem-BD.

Workflow:

1. Log in to obtain a JWT token
2. Browse your tree or shared trees
3. Select a destination path
4. Upload results from a completed UMA job

Behavior:

- browse and upload cards stay inactive until a token is available
- upload activates only after a destination path is loaded
- one tree applet is used for both personal and shared content
- the filter below the applet filters the currently displayed tree
- when a full ioChem-BD URL is pasted, the original host is preserved

Recommended import flow:

1. Open the desired calculation in ioChem-BD
2. Copy the handle URL
3. Return to **Load/Edit**
4. Paste the handle and load it

### About

Displays this README inside the application.
The left-side section menu is generated dynamically from the README headings, opens first-level sections by default, keeps deeper subsections folded until expanded, tracks the current section while you scroll, and can be filtered live.
The `LICENSE` link opens the GPL text in an in-app overlay.

## Output Files

Generated files depend on the workflow that actually ran.

### Static runs

- `input.xyz`
- `<stem>.use`
- `<stem>-<LABELS>.log`
- `<stem>-<LABELS>.xml`
- `-geoopt-<LABELS>.xyz` and `-<LABELS>.traj` for GeoOpt / TS
- `<stem>-FREQS-modes.zip` for Freqs / TS

### MD runs

- `<stem>-MD.log`
- `<stem>-MD.xml`
- `<stem>.use`
- `input.cif` when periodic, otherwise `input.xyz`
- `<stem>-MD.traj`
- `<stem>-MD.xyz`
- `<stem>-MD-final.xyz`

### Multi Jobs

- one subfolder per input file
- each subfolder contains the same outputs as the corresponding single workflow

## Package Layout

```text
src/uma_ase/
├── __init__.py
├── __main__.py
├── cli.py
├── server.py
├── utils.py
├── workflows.py
└── static/uma-ase.html
```
## Development

Typical workflow:

1. create a virtual environment
2. install in editable mode with the needed extras
3. run tests or manual checks
4. build distributions

Build:

```bash
python -m build
```

Upload:

- GitLab Package Registry
  ```bash
  python -m twine upload \
    --repository-url "https://gitlab.com/api/v4/projects/<project-id>/packages/pypi" \
    dist/*
  ```
- PyPI
  ```bash
  python -m twine upload dist/*
  ```

## License

Copyright (c) This code was generated using OpenAI Codex agents following the guidance of humans. C. Bo, ICIQ, 2025-2026.
Distributed under the GNU General Public License v3.0. See [LICENSE](/LICENSE).
