volcengine-qcclient 0.1.22
A Python client for volcengine quantum chemistry service.
License: MIT
Requires Python: >=3.6

# volcengine-qcclient

A Python client for volcano engine quantum chemistry service.

## Installation

```bash
pip install volcengine-qcclient
```

## Usage

### High-level SDK.

1. run GPU4PySCF tasks.
```python
import os
import requests
import h5py
import tarfile

from volcengine_qcclient import QcBatchJob


# download_output download output of qc task to ./{task_id}/ dir.
def download_output(url, task_id):
    os.mkdir(f"./{task_id}")
    if ".h5" in url:
        output_h5 = f"./{task_id}/output.h5"
        open(output_h5, 'wb').write(requests.get(url).content)
    elif "tar.gz" in url:
        output_targz = f"./{task_id}/output.tar.gz"
        open(output_targz, 'wb').write(requests.get(url).content)
        with tarfile.open(output_targz, 'r:gz') as tar:
            tar.extractall(path=f"./{task_id}")
        os.remove(output_targz)
    else:
        print("unsupported file type")


if __name__ == '__main__':
    # init batch_job
    batch_job = QcBatchJob()

    # load molecules.
    molecules = [
        '''
3
Water molecule
O          0.00000        0.00000        0.11779
H          0.00000        0.75545       -0.47116
H          0.00000       -0.75545       -0.47116
        '''
    ]

    batch_job.load_molecules(from_list=molecules)

    # set task config.
    task_config = {
        "spin": 0,
        "charge": 0,
        "basis": "def2-tzvpp",
    }
    # submit task.
    task_type = "sp"
    task_ids = batch_job.submit(task_type=task_type, task_config=task_config)
    print(task_ids)

    # wait for task to finish.
    batch_job.wait()

    # get tasks when batch_job finished.
    tasks = batch_job.get_tasks()
    print(tasks)

    # download output to ./{task_id}/
    task = tasks[0]
    download_output(task["OutputUrl"], task["Id"])

    # operation with output.
    if task_type in ["sp", "opt"]:
        with h5py.File(f"./{task['Id']}/output.h5", 'r') as f:
            print(f.keys())
    elif task_type == "pysisyphus":
        # print keys in `final_hessian.h5`.
        with h5py.File(f"./{task['Id']}/final_hessian.h5", 'r') as f:
            print(f.keys())

        # print keys in `optimization.h5`
        with h5py.File(f"./{task['Id']}/final_hessian.h5", 'r') as f:
            print(f.keys())

        # print final_geometry.xyz
        with open(f"./{task['Id']}/final_geometry.xyz", 'r') as f:
            print(f.read())
```

To verify the correctness of the `task_config`, tasks can be run locally using
the command:
```bash
python -m volcengine_qcclient.drivers.sp_driver config_example.json
```
The `task_config` is specified in a config file
```
{
  "molecule": "h2o.xyz"
  "spin": 0,
  "charge": 0,
  "basis": "def2-tzvpp",
}
```
The molecular geometry is saved in the file specified by the field `molecule`,
which is `h2o.xyz` in this example:
```
3
Water molecule
O          0.00000        0.00000        0.11779
H          0.00000        0.75545       -0.47116
H          0.00000       -0.75545       -0.47116
```
When the local verification is passed, the same `task_config` specification can
be used in the QcBatchJob, while the geometries should be specified in a list
and passed to the QcBatchJob.

2. run pysisyphus tasks.
```python
import os
import requests
import h5py
import tarfile

from volcengine_qcclient import QcBatchJob


# download_output download output of qc task to ./{task_id}/ dir.
def download_output(url, task_id):
    os.mkdir(f"./{task_id}")
    if ".h5" in url:
        output_h5 = f"./{task_id}/output.h5"
        open(output_h5, 'wb').write(requests.get(url).content)
    elif "tar.gz" in url:
        output_targz = f"./{task_id}/output.tar.gz"
        open(output_targz, 'wb').write(requests.get(url).content)
        with tarfile.open(output_targz, 'r:gz') as tar:
            tar.extractall(path=f"./{task_id}")
        os.remove(output_targz)
    else:
        print("unsupported file type")


if __name__ == '__main__':
    # init batch_job
    batch_job = QcBatchJob()

    # load molecules.
    molecules = [
        '''
3
Water molecule
O          0.00000        0.00000        0.11779
H          0.00000        0.75545       -0.47116
H          0.00000       -0.75545       -0.47116
        '''
    ]

    batch_job.load_molecules(from_list=molecules)

    # set task config.
    task_config = {}
    # submit task.
    task_type = "pysisyphus"
    task_ids = batch_job.submit(task_type=task_type, task_config=task_config)
    print(task_ids)

    # wait for task to finish.
    batch_job.wait()

    # get tasks when batch_job finished.
    tasks = batch_job.get_tasks()
    print(tasks)

    # download output to ./{task_id}/
    task = tasks[0]
    download_output(task["OutputUrl"], task["Id"])

    # operation with output.
    if task_type in ["sp", "opt"]:
        with h5py.File(f"./{task['Id']}/output.h5", 'r') as f:
            print(f.keys())
    elif task_type == "pysisyphus":
        # print keys in `final_hessian.h5`.
        with h5py.File(f"./{task['Id']}/final_hessian.h5", 'r') as f:
            print(f.keys())

        # print keys in `optimization.h5`
        with h5py.File(f"./{task['Id']}/final_hessian.h5", 'r') as f:
            print(f.keys())

        # print final_geometry.xyz
        with open(f"./{task['Id']}/final_geometry.xyz", 'r') as f:
            print(f.read())
```

3. run pygsm tasks.
```python
import os
import requests
import tarfile

from volcengine_qcclient import QcBatchJob

def download_output(url, task_id):
    os.mkdir(f"./{task_id}")
    output_targz = f"./{task_id}/output.tar.gz"
    open(output_targz, 'wb').write(requests.get(url).content)
    with tarfile.open(output_targz, 'r:gz') as tar:
        tar.extractall(path=f"./{task_id}")
    os.remove(output_targz)


if __name__ == '__main__':
    batch_job = QcBatchJob()

    # For pygsm, the xyz file may contain multiple frames (reactant/product).
    batch_job.load_molecules(from_file='./DA.xyz')
    # load molecules.
    molecules = [
        '''
16
        -17.82297828 , 
  C  0.91909100  1.85696943  0.03846378
  C  1.52762104 -1.30011495  0.85471343
  C  0.94789896 -1.66409663 -0.28398130
  C -0.47535137 -1.62094269 -0.57562250
  C -1.43365519 -1.21017117  0.24785069
  C -0.37019447  1.89660161 -0.22395989
  H  1.64830087  1.62253007 -0.71896525
  H  1.30809543  2.05258383  1.02409276
  H  0.96583910 -0.92807273  1.69351603
  H  2.59382268 -1.36427501  0.98892066
  H  1.56800961 -2.03150537 -1.09237676
  H -0.74814467 -1.96139922 -1.56693627
  H -2.46859407 -1.21063403 -0.04848600
  H -1.22607159 -0.86130203  1.24424551
  H -0.75814743  1.69649513 -1.20877340
  H -1.10095429  2.12664571  0.53375126
16
        -17.92483682 , 
  C  0.95805326  0.91408126  0.26178811
  C  1.44471258 -0.49441903  0.63998324
  C  0.89452506 -1.49783716 -0.32237415
  C -0.40163315 -1.45834092 -0.58785715
  C -1.22604100 -0.41323444  0.09316372
  C -0.54882160  0.96002716 -0.04594300
  H  1.51606345  1.23971104 -0.61780358
  H  1.20120000  1.60117887  1.07392801
  H  1.08621676 -0.73040675  1.64730199
  H  2.53461597 -0.51528098  0.65990945
  H  1.56267940 -2.21238212 -0.77784165
  H -0.87769424 -2.13805382 -1.27764901
  H -2.23535821 -0.37013492 -0.31689046
  H -1.30652939 -0.65810014  1.15733896
  H -0.69759605  1.30830025 -1.06949288
  H -1.05021690  1.66901159  0.61492097
        '''
    ]

    batch_job.load_molecules(from_list=molecules)

    task_type = 'pygsm'
    # set task config.
    task_config = {}
    task_ids = batch_job.submit(task_type=task_type, task_config=task_config)
    print(task_ids)

    batch_job.wait()
    tasks = batch_job.get_tasks()
    task = tasks[0]

    download_output(task['OutputUrl'], task['Id'])
    print(f"Downloaded output to ./{task['Id']}/")
```

4. run confgen tasks.
> make sure that you have a cpu qcservice id. here we only show the difference between confgen tasks and other tasks.

```python
# init batch_job
batch_job = QcBatchJob(is_cpu=True) # use cpu resources

# load smiles
smiles_list = ["[OH2+]C1C=CC=CC=C1"]
molecule_names = ["unipKa-11"]

batch_job.load_smiles(from_list=smiles_list, with_molecule_names=molecule_names)
print(batch_job.molecules)

task_type = "confgen"

task_ids = batch_job.submit(task_type=task_type, task_config=[{}]) # method1 
task_ids = batch_job.submit(task_type=task_type, task_config={}) # method2
print(task_ids)
```

### Low level SDK:
see [low-level.md](low-level.md)

### Credentials

### Environment variables