Metadata-Version: 2.4
Name: pymovis
Version: 0.1.0
Summary: Molecular Orbital Visualization System - A Python package for visualizing molecular orbitals from quantum chemistry calculations
Project-URL: Repository, https://github.com/YusukeSugenami/pymovis
Author-email: Yusuke Sugenami <yusuke.sugenami@akane.waseda.jp>
License: MIT License
        
        Copyright (c) 2026 PyMovis Contributors
        
        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.
License-File: LICENSE
Keywords: 3D rendering,molecular orbitals,quantum chemistry,visualization
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Chemistry
Requires-Python: >=3.12
Provides-Extra: dev
Requires-Dist: black>=23.0; extra == 'dev'
Requires-Dist: isort>=5.0; extra == 'dev'
Requires-Dist: pytest-cov>=3.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Description-Content-Type: text/markdown

# PyMovis

PyMovis is a Python package for visualizing molecular orbitals from quantum chemistry calculations. It reads Gaussian formatted checkpoint files, cube files, and PySCF checkpoint files, then renders 3D orbital isosurfaces with PyVista.

## Features

- Visualize molecular orbitals from `fchk`, `cube`, and `chk` files
- Select orbitals by index or by labels such as `HOMO`, `LUMO`, `HOMO-1`, `LUMO+2`
- Render atoms, bonds, and orbital isosurfaces in 3D
- Use automatic camera placement with axis-based views
- Specify camera center and camera axes from atom indices
- Save high-quality images with transparent backgrounds

## Installation

### From source

```bash
git clone https://github.com/YusukeSugenami/pymovis.git
cd pymovis
pip install -e .
```

## Quick Start

### Command line

The package installs a `pymovis` command.

```bash
pymovis test.fchk HOMO
```

Visualize multiple orbitals:

```bash
pymovis test.fchk HOMO LUMO
```

Save to specific output files:

```bash
pymovis test.fchk HOMO LUMO -o homo.png lumo.png
```

### Python API

```python
from pymovis import savemo

savemo("test.fchk", ["HOMO", "LUMO"])
```

## Camera Control

PyMoVis supports three levels of camera control.

### 1. Manual camera settings

Use `camera_pos`, `camera_focal`, and `camera_up` directly:

```bash
pymovis test.fchk HOMO \
  -cp 10 10 10 \
  -cf 0 0 0 \
  -cu 0 1 0
```

### 2. Automatic axis-based camera

Use `--camera_axis` to place the camera so the molecule fits in the frame.
The current renderer defaults are used for this calculation:
- window size: `1024 x 768`
- aspect ratio: `4:3`
- vertical field of view: `30 deg`

```bash
pymovis test.fchk HOMO --camera_axis X
```

This option looks at the molecule from the negative side of the selected axis and uses the corresponding screen orientation:
- `X` view: right is `+Y`, up is `+Z`
- `Y` view: right is `+X`, up is `+Z`
- `Z` view: right is `+X`, up is `+Y`

You can invert the axis direction with prefix '-' (e.g. -X)

### 3. Atom-index based camera control

You can define the camera center and axes from atom indices. Indices are 0-based.

#### Camera center

Use `--camera_focal_atoms`.

- One atom index: the camera center is that atom position
- Two or more atom indices: the camera center is the centroid of those atoms

Example:

```bash
pymovis test.fchk HOMO --camera_focal_atoms 0
pymovis test.fchk HOMO --camera_focal_atoms 0 1 2
```

#### Camera axis and up direction

Use `--camera_axis_atoms` for the camera view axis and `--camera_up_atoms` for the screen up direction.

- Two atom indices: the axis is the line through those atoms
- Three or more atom indices: the axis is the normal vector of the best-fit plane through those atoms

Example:

```bash
pymovis test.fchk HOMO \
  --camera_focal_atoms 0 1 2 \
  --camera_axis_atoms 0 1 \
  --camera_up_atoms 0 1 3
```

#### Fixing axis sign with reference vectors

When using three or more atoms to define an axis (via best-fit plane normal), the sign of the resulting axis is ambiguous. You can fix this using `--camera_axis_reference` and `--camera_up_reference`.

Each reference option accepts:
- **Two atom indices**: `[idx1 idx2]` → the reference vector is `coords[idx2] - coords[idx1]`
- **Three floats**: `[X Y Z]` → the reference vector is given directly

The axis is flipped if its dot product with the reference vector is negative.

Example using atom indices:

```bash
pymovis test.fchk HOMO \
  --camera_axis_atoms 0 1 2 \
  --camera_up_atoms 3 4 5 \
  --camera_axis_reference 0 1 \
  --camera_up_reference 2 5
```

Example using direct coordinates:

```bash
pymovis test.fchk HOMO \
  --camera_axis_atoms 0 1 2 \
  --camera_up_atoms 3 4 5 \
  --camera_axis_reference 0 0 1 \
  --camera_up_reference 0 1 0
```

### Camera precedence

The current behavior is:

- If `--camera_axis_atoms` and `--camera_up_atoms` are provided, those atom-based axes are used
- Otherwise, if `--camera_axis` is provided, the axis-based automatic camera is used
- If `--camera_focal` is provided, it becomes the camera center used by the automatic camera calculation
- If `--camera_up` is provided, it overrides the final up vector
- If none of the automatic options are provided, manual `camera_pos`, `camera_focal`, and `camera_up` are used as-is

## CLI Options

```text
Usage: pymovis input_file [mo ...] [options]

Positional arguments:
  input_file              Gaussian fchk or cube file to visualize
  mo                      MO indices to visualize
                          Use integer indices starting from 0 or labels such as HOMO/LUMO

Options:
  -o, --out               Output file names
  -i, --iso               Isosurface value
  -t, --transparent       Transparent background flag
  -cp, --camera_pos       Manual camera position
  -cf, --camera_focal     Manual camera focal point
  -cu, --camera_up        Manual camera up vector
  -ca, --camera_axis      Automatic camera axis: X / Y / Z. Use '-' prefix (e.g. -X) to invert the axis direction.
  --camera_focal_atoms    Atom indices used to define the camera focal point
  --camera_axis_atoms     Atom indices used to define the camera view axis
  --camera_up_atoms       Atom indices used to define the camera up axis
  --camera_axis_reference Reference vector for camera view axis sign (2 atom indices or 3 coordinates)
  --camera_up_reference   Reference vector for camera up axis sign (2 atom indices or 3 coordinates)
  -womo, --without_mo     Only render molecule structure without MO isosurface
```

## Supported File Formats

| Format | Extension | Description |
| --- | --- | --- |
| Gaussian Formatted Checkpoint | `.fchk` | Gaussian MO and geometry data |
| Cube File | `.cube` | Cube grid data |
| PySCF checkpoint | `.chk` | PySCF SCF checkpoint |

## Python API

### `savemo`

```python
savemo(
    inp_file,
    mo_index,
    out_name=None,
    iso=0.03,
    camera_pos=None,
    camera_focal=None,
    camera_up=None,
    camera_axis=None,
    camera_focal_atoms=None,
    camera_axis_atoms=None,
    camera_up_atoms=None,
    camera_axis_reference=None,
    camera_up_reference=None,
    transparent_background=True,
    without_mo=False,
)
```

- `inp_file`: input file path
- `mo_index`: list of MO indices or labels
- `out_name`: output file names
- `iso`: isosurface value
- `camera_axis`: automatic axis-based view (`X`, `Y`, `Z`)
- `camera_focal_atoms`: atom indices for the camera focal point
- `camera_axis_atoms`: atom indices for the view axis
- `camera_up_atoms`: atom indices for the up axis
- `camera_axis_reference`: reference vector for camera axis sign (2 atom indices or 3D coordinates)
- `camera_up_reference`: reference vector for camera up axis sign (2 atom indices or 3D coordinates)
- `transparent_background`: save transparent background picture if True
- `without_mo`: save only molecular structure if True

### `load_inp`

```python
from pymovis import load_inp
mol = load_inp("test.fchk")
```

Returns a `MoleculeData` object with parsed geometry, basis, and MO data.

## Camera Utilities

If you want to use the camera logic directly, the package exposes helper functions such as:

```python
from pymovis import (
    infer_camera_from_coords,
    infer_axis_camera_fit_from_coords,
    infer_atom_axis_camera_fit_from_coords,
)
```

## Configuration

Default rendering and parser settings are defined in [pymovis/settings.py](pymovis/settings.py).

Important values include:

- `PADDING`
- `GRID_SETTING`
- `GRID_SHAPE`
- `IMAGE_QUALITY`
- `BACKGROUND_COLOR`
- `PARSER_ARGS`

## Example Workflows

### Visualize the HOMO from a file

```bash
pymovis water.fchk HOMO
```

### Visualize HOMO and LUMO with automatic axis view

```bash
pymovis water.fchk HOMO LUMO --camera_axis Z
```

### Visualize with atom-defined camera center and axes

```bash
pymovis water.fchk HOMO \
  --camera_focal_atoms 0 1 2 \
  --camera_axis_atoms 0 1 \
  --camera_up_atoms 0 1 3
```

### Save transparent output

```bash
pymovis water.fchk HOMO --transparent True
```

