Skip to content

Commit 50bd1ee

Browse files
committed
Enhance documentation for dftio
- Updated contributing guide with clearer instructions on development setup, code style, and testing requirements. - Revised developer guide to provide detailed steps for adding new DFT software support, including parser implementation and registration. - Improved index and installation documentation for better clarity on installation methods and prerequisites. - Added a new tutorial for plotting band structures from VASP calculations, including step-by-step commands. - Expanded CLI reference with detailed command usage for parsing and band plotting. - Documented output data formats, including `dat`, `ase`, and `lmdb`, with examples of their structure. - Provided a comprehensive guide on parsing outputs from various DFT packages, including ABACUS, VASP, SIESTA, Gaussian, and RESCU. - Created a new section summarizing supported DFT packages and the specific data types each parser can handle.
1 parent a8e9e52 commit 50bd1ee

16 files changed

Lines changed: 670 additions & 395 deletions

GEMINI.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# GEMINI.md: AI-Assisted Development Guide for `dftio`
2+
3+
This document provides context and instructions for an AI assistant to effectively contribute to the `dftio` project.
4+
5+
## Project Overview
6+
7+
`dftio` is a Python library designed to parse and process output files from various Density Functional Theory (DFT) software packages. Its primary goal is to convert complex DFT outputs into standardized, machine-learning-ready formats. The library supports packages such as ABACUS, VASP, SIESTA, Gaussian, RESCU, and PYATB.
8+
9+
The project provides a command-line interface (CLI) for parsing operations and for plotting derived data like electronic band structures.
10+
11+
**Key Technologies:**
12+
- **Language:** Python 3.9+
13+
- **Core Libraries:** NumPy, SciPy, PyTorch, ASE (Atomic Simulation Environment), sisl
14+
- **Package Management:** `uv`
15+
- **Testing:** `pytest`
16+
17+
## Building and Running
18+
19+
### Installation
20+
21+
The project uses `uv` for dependency management. To set up a development environment, including testing dependencies, run:
22+
23+
```bash
24+
# Install all dependencies, including development tools
25+
uv sync --group dev
26+
```
27+
This command installs packages defined in `pyproject.toml`.
28+
29+
### Running the CLI
30+
31+
The main entry point is the `dftio` command. It has several subcommands, with `parse` being the most central one.
32+
33+
**Example for parsing ABACUS output:**
34+
```bash
35+
dftio parse --mode abacus --root /path/to/abacus/output --hamiltonian --overlap -o /path/to/save
36+
```
37+
38+
For a full list of commands and options, use the help flag:
39+
```bash
40+
dftio --help
41+
dftio parse --help
42+
```
43+
44+
### Running Tests
45+
46+
The project uses `pytest` for testing. The standard test suite can be run with the following command, which excludes slower "integration" tests:
47+
48+
```bash
49+
uv run pytest -v -m "not integration"
50+
```
51+
52+
To run the full suite including code coverage analysis (as done in CI):
53+
```bash
54+
uv run pytest -v -m "not integration" --cov=dftio
55+
```
56+
57+
## Development Conventions
58+
59+
### Project Structure
60+
61+
- **`dftio/`**: Main source code for the library.
62+
- **`io/`**: Contains the parsing logic for different DFT packages. Each package (e.g., `abacus`, `siesta`) has its own submodule.
63+
- **`data/`**: Data structures for handling atomic configurations and computational results.
64+
- **`__main__.py`**: Defines the CLI entry point and its arguments.
65+
- **`test/`**: Contains all `pytest` tests. The structure mirrors the main `dftio/` directory.
66+
- **`docs/`**: Project documentation, built with Jupyter Book.
67+
- **`pyproject.toml`**: Defines project metadata, dependencies, and tool configurations (including `pytest`).
68+
69+
### Coding Style
70+
71+
Follow the existing coding style in the file you are editing. While no specific linter is enforced in the project configuration, adhere to standard PEP 8 conventions.
72+
73+
### Adding a New Parser
74+
75+
To add support for a new DFT package, you would typically:
76+
1. Create a new module under `dftio/io/`, e.g., `dftio/io/new_package/`.
77+
2. Implement a parser class within that module.
78+
3. Register the new parser in `dftio/io/parse.py`'s `ParserRegister` to make it available via the CLI.
79+
4. Add corresponding tests in the `test/` directory to validate the parser's correctness.

docs/_toc.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ chapters:
1010
- file: user-guide/parsing
1111
- file: user-guide/data-formats
1212
- file: user-guide/cli-reference
13+
- file: user-guide/supported_packages
1314
- file: tutorials/index
15+
sections:
16+
- file: tutorials/plot_bands
1417
- file: api/index
18+
sections:
19+
- file: api/io
20+
- file: api/data
1521
- file: developer-guide
1622
- file: contributing

docs/api/data.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Data Structures (`dftio.data`)
2+
3+
The `dftio.data` module provides the fundamental data structures for storing and managing atomic information and computational results. These structures are designed to be flexible, efficient, and compatible with machine learning workflows.
4+
5+
## `AtomicData`
6+
7+
The `dftio.data.AtomicData` class is the primary container for data associated with a single atomic structure. It is a dictionary-like object that stores properties of the system, such as atomic numbers, positions, and cell parameters, as PyTorch tensors.
8+
9+
### Key Features
10+
11+
- **Tensor-Based:** All data is stored as `torch.Tensor` objects, enabling seamless integration with PyTorch and other machine learning libraries.
12+
- **Extensible:** You can add any custom data to an `AtomicData` object, allowing for flexible and detailed representations of your system.
13+
- **Property-Based Access:** Accessing a key on an `AtomicData` object (e.g., `data['positions']`) returns the corresponding tensor.
14+
15+
### Core Properties
16+
17+
The following are some of the standard keys defined in `dftio.data._keys`:
18+
19+
- `cell`: The lattice vectors of the simulation cell.
20+
- `positions`: The coordinates of each atom.
21+
- `atomic_numbers`: The atomic number of each atom.
22+
- `pbc` (Periodic Boundary Conditions): A boolean tensor indicating which directions are periodic.
23+
- `eigs`: The eigenvalues of the electronic structure.
24+
- `kpoints`: The coordinates of the k-points.
25+
26+
## `AtomicDataDict`
27+
28+
The `dftio.data.AtomicDataDict` class is a specialized dictionary designed to hold multiple `AtomicData` objects. It is the primary data structure returned by the parsers when processing multiple frames or structures.
29+
30+
### Key Features
31+
32+
- **Batching:** Provides methods for collating multiple `AtomicData` objects into a single batch for efficient processing.
33+
- **Transformation Support:** Can be used with the `dftio.data.transforms` module to apply transformations to all `AtomicData` objects in the dictionary.
34+
- **Serialization:** Can be saved to and loaded from disk, typically in `.dat` files (PyTorch's serialization format).
35+
36+
## Example Usage
37+
38+
```python
39+
import torch
40+
from dftio.data import AtomicData
41+
42+
# Create an AtomicData object for a simple system
43+
data = AtomicData(
44+
positions=torch.tensor([[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]]),
45+
atomic_numbers=torch.tensor([14, 14]), # Silicon
46+
cell=torch.eye(3) * 5.43,
47+
pbc=torch.tensor([True, True, True]),
48+
)
49+
50+
# Access properties
51+
print(data.positions)
52+
print(data.cell)
53+
```

docs/api/index.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
# API Reference
22

3-
API documentation for dftio modules.
3+
This section provides detailed, auto-generated documentation for the `dftio` Python API. Use this reference to understand the internal components, data structures, and parser implementations.
44

5-
(To be auto-generated from docstrings using Sphinx autodoc)
5+
The API is organized into several key modules:
66

7-
## Main Modules
7+
- **[I/O and Parsers (`dftio.io`)](./io.md):** The core parsing engine, including the abstract base parser and specific implementations for each supported DFT code.
88

9-
- `dftio.io` - DFT parsers
10-
- `dftio.data` - Dataset classes
11-
- `dftio.datastruct` - Data structures
12-
- `dftio.op` - Operations and utilities
9+
- **[Data Structures (`dftio.data`)](./data.md):** The internal data containers used to store and manage atomic structures and calculation results.
10+
11+
For details on how to use these components, please refer to the pages linked above.

docs/api/io.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# I/O and Parsers (`dftio.io`)
2+
3+
The `dftio.io` module is the core of the library's parsing capabilities. It contains the `ParserRegister` class, which manages the registration and selection of parsers for different DFT codes, as well as the implementations of the parsers themselves.
4+
5+
## `ParserRegister`
6+
7+
The `ParserRegister` class is a singleton that holds a registry of all available parsers. When you run `dftio parse` from the command line, this class is responsible for selecting the appropriate parser based on the `--mode` argument.
8+
9+
### Key Methods
10+
11+
- **`register(name, parser_cls)`:** Adds a new parser to the registry.
12+
- **`get_parser(name)`:** Retrieves a parser class from the registry by name.
13+
14+
## Available Parsers
15+
16+
`dftio` supports the following DFT codes. Each parser is implemented in its own submodule within `dftio.io`.
17+
18+
- **ABACUS (`abacus`):** Parses output from the ABACUS DFT code. See `dftio.io.abacus.abacus_parser`.
19+
- **Gaussian (`gaussian`):** Parses output from the Gaussian quantum chemistry software. See `dftio.io.gaussian.gaussian_parser`.
20+
- **PYATB (`pyatb`):** Parses output from the PYATB library. See `dftio.io.pyatb.pyatb_parser`.
21+
- **RESCU (`rescu`):** Parses output from the RESCU DFT code. See `dftio.io.rescu.rescu_parser`.
22+
- **SIESTA (`siesta`):** Parses output from the SIESTA DFT code. See `dftio.io.siesta.siesta_parser`.
23+
- **VASP (`vasp`):** Parses output from the Vienna Ab initio Simulation Package (VASP). See `dftio.io.vasp.vasp_parser`.
24+
25+
Below is a more detailed breakdown of each parser's functionality.
26+
27+
### ABACUS Parser
28+
29+
The ABACUS parser (`dftio.io.abacus.AbacusParser`) is designed to handle the output files generated by the ABACUS software.
30+
31+
**Key Responsibilities:**
32+
33+
- Parses atomic structures (`STRU` files).
34+
- Extracts Hamiltonian and overlap matrices from sparse matrix files (`data-HR-sparse_SPIN0.csr`, `data-SR-sparse_SPIN0.csr`).
35+
- Reads band structure data from `BANDS_1.dat`.
36+
- Extracts other information from the main log file (`running_scf.log`).
37+
38+
### Gaussian Parser
39+
40+
The Gaussian parser (`dftio.io.gaussian.GaussianParser`) processes `.log` files from Gaussian calculations.
41+
42+
**Key Responsibilities:**
43+
44+
- Extracts atomic structures and coordinates.
45+
- Parses basis set information.
46+
- Reads molecular orbital energies (eigenvalues).
47+
48+
### VASP Parser
49+
50+
The VASP parser (`dftio.io.vasp.VaspParser`) is responsible for parsing the various output files from VASP.
51+
52+
**Key Responsibilities:**
53+
54+
- Reads atomic positions from `POSCAR` or `CONTCAR`.
55+
- Parses eigenvalues from `EIGENVAL`.
56+
- Extracts k-points and weights from `KPOINTS`.
57+
- Gathers additional information from `OUTCAR`, such as lattice parameters and forces.

docs/contributing.md

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,72 @@
11
# Contributing to dftio
22

3-
Thank you for your interest in contributing to dftio!
3+
Thank you for your interest in contributing to dftio! We welcome contributions of all kinds, from bug fixes to new features.
44

55
## Development Setup
66

7-
1. Clone the repository:
8-
```bash
9-
git clone https://github.com/deepmodeling/dftio.git
10-
cd dftio
11-
```
7+
1. **Clone the repository:**
8+
```bash
9+
git clone https://github.com/deepmodeling/dftio.git
10+
cd dftio
11+
```
1212

13-
2. Install with development dependencies:
14-
```bash
15-
./install.sh # or specify GPU version
16-
uv sync --group dev
17-
```
13+
2. **Install dependencies:**
14+
This project uses `uv` for package management. To install all required dependencies, including those for development and testing, run:
15+
```bash
16+
uv sync --group dev
17+
```
1818

19-
3. Run tests:
20-
```bash
21-
uv run pytest
22-
```
19+
3. **Run tests:**
20+
To make sure everything is set up correctly, run the test suite:
21+
```bash
22+
uv run pytest -m "not integration"
23+
```
2324

2425
## Code Style
2526

26-
- Follow PEP 8 guidelines
27-
- Use meaningful variable and function names
28-
- Add docstrings to all public functions and classes
27+
- Follow PEP 8 guidelines for Python code.
28+
- Use clear and meaningful names for variables, functions, and classes.
29+
- Add docstrings to all public functions and classes, explaining their purpose, arguments, and return values.
2930

3031
## Testing
3132

32-
- Write tests for new features
33-
- Ensure all tests pass before submitting PR
34-
- Use pytest markers for integration tests
33+
- All new features and bug fixes should be accompanied by tests.
34+
- Ensure that the full test suite passes before submitting a pull request.
35+
- Use `pytest` markers (e.g., `@pytest.mark.integration`) for tests that are slow or require external resources.
3536

3637
## Pull Request Process
3738

38-
1. Fork the repository
39-
2. Create a feature branch
40-
3. Make your changes
41-
4. Run tests
42-
5. Submit a pull request
39+
1. Fork the repository on GitHub.
40+
2. Create a new feature branch from the `main` branch.
41+
3. Make your changes in the new branch.
42+
4. Add or update tests as needed.
43+
5. Run the tests to ensure everything passes.
44+
6. Submit a pull request to the `main` branch of the original repository.
4345

44-
## Adding Support for New DFT Software
46+
## Implementing a New Parser
4547

46-
See the [Developer Guide](developer-guide.md) for details on implementing parsers for new DFT packages.
48+
If you are adding support for a new DFT package, please see the [Developer Guide](developer-guide.md) for a general overview. When implementing the parser class, you will need to provide several key methods. Below are the details of what each method should return.
49+
50+
### `get_structure(idx)`
51+
52+
This method should return a dictionary containing the atomic structure for the `idx`-th calculation. The dictionary should have the following keys (defined in `dftio.data._keys`):
53+
54+
- `_keys.ATOMIC_NUMBERS_KEY`: Atomic numbers as a 1D tensor (`[natom]`).
55+
- `_keys.PBC_KEY`: Periodic boundary conditions as a boolean tensor (`[3]`).
56+
- `_keys.POSITIONS_KEY`: Atomic positions in Ångströms (`[nframe, natom, 3]`).
57+
- `_keys.CELL_KEY`: Lattice vectors in Ångströms (`[nframe, 3, 3]`).
58+
59+
### `get_eigenvalues(idx)`
60+
61+
This method should return a dictionary containing the eigenvalues and k-points:
62+
63+
- `_keys.KPOINT_KEY`: K-point coordinates (`[nk, 3]`).
64+
- `_keys.ENERGY_EIGENVALUE_KEY`: Eigenvalues (`[nframe, nk, nband]`).
65+
66+
### `get_basis(idx)`
67+
68+
This method should return a dictionary describing the basis set, for example: `{"Si": "2s2p1d"}`.
69+
70+
### `get_blocks(idx, ...)`
71+
72+
This method should parse the real-space Hamiltonian, overlap, and/or density matrices. It should return a tuple of three lists: `(hamiltonians, overlaps, density_matrices)`. Each list should contain one dictionary per frame, where each dictionary's keys are strings like `"i_j_Rx_Ry_Rz"` (representing the matrix element between orbital `i` and orbital `j` in a neighboring cell at `(Rx, Ry, Rz)`) and the values are the corresponding matrix blocks as NumPy arrays.

0 commit comments

Comments
 (0)