Skip to content

Commit

Permalink
Update calcfunction tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kmlefran committed Sep 11, 2024
1 parent b28ceda commit 94ff837
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 42 deletions.
65 changes: 24 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@
[![Documentation Status](https://readthedocs.org/projects/aiida-aimall/badge/?version=latest)](https://aiida-aimall.readthedocs.io/en/latest/?badge=latest)
[![PyPI version](https://badge.fury.io/py/aiida-aimall.svg)](https://badge.fury.io/py/aiida-aimall)

!This README and all documentation is a work in progress!

# Copyright notice

This repository contains modified versions of the calculations and parsers presented in [Aiida-Gaussian](https://github.com/nanotech-empa/aiida-gaussian). Copyright (c) 2020 Kristjan Eimre. The modifications basically amount to adding the wfx file to the retrieved nodes and adding some groups/extras to calculation output.

Also, the (incomplete) testing framework is heavily influenced by the infrastructure presented in [aiida-quantumespresso](https://github.com/aiidateam/aiida-quantumespresso). Copyright (c), 2015-2020, ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE
(Theory and Simulation of Materials (THEOS) and National Centre for
Computational Design and Discovery of Novel Materials (NCCR MARVEL))

# aiida-aimall

A plugin to interface AIMAll with AiiDA
Expand All @@ -21,22 +11,24 @@ A plugin to interface AIMAll with AiiDA

* [`.github/`](.github/): [Github Actions](https://github.com/features/actions) configuration
* [`workflows/`](.github/workflows/)
* [`ci.yml`](.github/workflows/ci.yml): runs tests, checks test coverage and builds documentation at every new commit
* [`ci.yml`](.github/workflows/ci.yml): runs tests, checks test coverage and continuous integration at every new commit
* [`publish-on-pypi.yml`](.github/workflows/publish-on-pypi.yml): automatically deploy git tags to PyPI - just generate a [PyPI API token](https://pypi.org/help/#apitoken) for your PyPI account and add it to the `pypi_token` secret of your github repository
* [`config/`](.github/config) config files for testing/docs environment
* [`code-aim.yaml`](.github/workflows/config/code-aim.yaml) config file for building precommit and test envs
* [`code-gwfx.yaml`](.github/workflows/config/code-gwfx.yaml) config file for building precommit and test envs
* [`profile.yaml`](.github/workflows/config/profile.yaml) config file for aiida profile
* [`profile.yaml`](.github/workflows/config/localhost-config.yaml) config file for localhost computer
* [`profile.yaml`](.github/workflows/config/localhost-setup.yaml) setup file for localhost computer
* [`localhost-config.yaml`](.github/workflows/config/localhost-config.yaml) config file for localhost computer
* [`localhost-setup.yaml`](.github/workflows/config/localhost-setup.yaml) setup file for localhost computer
* [`aiida_aimall/`](aiida_aimall/): The main source code of the plugin package
* [`data/`](aiida_aimall/data/): A new `AimqbParameters` data class, used as input to the `AimqbCalculation` `CalcJob` class
* [`calculations.py`](aiida_aimall/calculations.py): A new `AimqbCalculation` `CalcJob` class, and `GaussianWFXCalculation`, a modified version of `GaussianCalculation` from [AiiDA Gaussian](https://github.com/nanotech-empa/aiida-gaussian)
* [`parsers.py`](aiida_aimall/parsers.py): A new `Parser` for the `AimqbCalculation`, and `GaussianWFXParser`, a modified version of `GaussianBaseParser` from [AiiDA Gaussian](https://github.com/nanotech-empa/aiida-gaussian)
* [`workchains.py`](aiida_aimall/workchains.py): New `WorkChains`.
* `MultiFragmentWorkChain` to fragment molecules using cml files from the Retrievium database and submit Gaussian calculations for the fragments using functions in `frag_functions` from [subproptools Github](https:github.com/kmlefran/group_decomposition)
* `G16OptWorkchain` to take output from `MultiFragmentWorkChain` and submit Gaussian optimization calculations
* `AimAllReorWorkChain` to run `AimqbCalculation` on output from `GaussianWFXCalculations`, then reorient to coordinate systems defined in `subreor` from [subproptools Github](https:github.com/kmlefran/subproptools)
* [`data.py`](aiida_aimall/data.py): A new `AimqbParameters` data class, used as input to the `AimqbCalculation` `CalcJob` class
* [`calculations.py`](aiida_aimall/calculations.py): A new `AimqbCalculation` `CalcJob` class
* [`parsers.py`](aiida_aimall/parsers.py): Two parsers (`AimqbBaseParser` and `AimqbGroupParser`) for `AimqbCalculation` results
* [`workchains/`](aiida_aimall/workchains/): New `WorkChains`.
* [`calcfunctions.py`](aiida_aimall/workchains/calcfunctions.py): `calcfunction`s that are used in the workchains
* [`input.py`](aiida_aimall/workchains/input.py): `BaseInputWorkChain` that is used in other workchains to validate multiple input options
* [`param_parts.py`](aiida_aimall/workchains/param_parts.py): `SmilesToGaussianWorkChain` and `AIMAllReorWorkChain`: two workchains representing individual steps of the `SubstituentParameterWorkchain`
* [`qc_programs.py`](aiida_aimall/workchains/qc_programs.py): `QMToAIMWorkChain` and `GaussianToAIMWorkChain` linking quantum chemical software output to an AIMQB calculation
* [`subparam.py`](aiida_aimall/workchains/subparam.py): `SubstituentParameterWorkchain` to automate calculation substituent properties in a multistep calculation.
* [`controllers.py`](aiida_aimall/controllers.py): Workflow controllers to limit number of running jobs on localhost computers.
* `AimReorSubmissionController` to control `AimReorWorkChain`s. These use `parent_group_label` for the wavefunction file nodes from `GaussianWFXCalculation`s
* `AimAllSubmissionController` to control `AimqbCalculations``. These use `parent_group_label` for the wavefunction file nodes from `GaussianWFXCalculation`s
Expand All @@ -53,8 +45,6 @@ A plugin to interface AIMAll with AiiDA
* [`README.md`](PythonPackages/aiida-aimall/README.md): This file
* [`pyproject.toml`](setup.json): Python package metadata for registration on [PyPI](https://pypi.org/) and the [AiiDA plugin registry](https://aiidateam.github.io/aiida-registry/) (including entry points)



## Features

### Feature specificity
Expand Down Expand Up @@ -87,30 +77,17 @@ Many of the workflows provided are specific to my field of study, but the calcul
submit(builder)
```

*

## Installation

The aiida-dataframe dependency tables requires h5 headers on your system. You may already have this, or not. One easy way that allows installation of the headers using the h5py package
## Documentation

```shell
(conda-env) conda install h5py
(conda-env) pip install aiida-aimall
verdi quicksetup # better to set up a new profile
verdi plugin list aiida.calculations # should now show your calclulation plugins
```
Documentation is hosted at [ReadTheDocs](http://aiida-aimall.readthedocs.io/).

## Installation

## Usage

Here goes a complete example of how to submit a test calculation using this plugin.

A quick demo of how to submit a calculation:
```shell
verdi daemon start # make sure the daemon is running
cd examples
./example_01.py # run test calculation
verdi process list -a # check record of calculation
(env) pip install aiida-aimall
(env) verdi quicksetup # better to set up a new profile
(env) verdi plugin list aiida.calculations # should now show your calclulation plugins
```

## Development
Expand All @@ -126,9 +103,15 @@ pytest -v # discover and run all tests

See the [developer guide](http://aiida-aimall.readthedocs.io/en/latest/developer_guide/index.html) for more information.

## Copyright notice

The testing and documentation framework is heavily influenced by the infrastructure presented in [aiida-quantumespresso](https://github.com/aiidateam/aiida-quantumespresso). Copyright (c), 2015-2020, ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE (Theory and Simulation of Materials (THEOS) and National Centre for
Computational Design and Discovery of Novel Materials (NCCR MARVEL))

## License

MIT

## Contact

kgagnon@lakeheadu.ca
Expand Down
2 changes: 1 addition & 1 deletion src/aiida_aimall/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Integration of AIMQB and aiida
"""

__version__ = "0.7.5"
__version__ = "1.0.0"
4 changes: 4 additions & 0 deletions tests/workchains/inputs/ch4.xyz
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
2

H 1.0 0.0 0.0
H 0.0 0.0 0.0
108 changes: 108 additions & 0 deletions tests/workchains/test_calcfunctions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Tests for calcfunctions in aiida-aimall workchains"""
# pylint:disable=no-member
import os

import pytest
from aiida.orm import Dict, Int, SinglefileData, Str, StructureData
from rdkit import Chem
Expand All @@ -8,6 +10,34 @@
from aiida_aimall.workchains import calcfunctions as cf


def test_get_molecule_str_from_smiles():
"""Test get_molecule_str_from_smiles"""
with pytest.raises(ValueError):
_ = cf.get_molecule_str_from_smiles(Str("[NH4]")) is None
methane_Dict = cf.get_molecule_str_from_smiles(Str("C"))

assert isinstance(methane_Dict, Dict)
assert "xyz" in methane_Dict
assert "charge" in methane_Dict
assert "multiplicity" in methane_Dict
assert methane_Dict["charge"] == 0
assert methane_Dict["multiplicity"] == 1


def test_xyzfile_to_StructureData(filepath_tests):
"""Test xyzfile_to_StructureData"""
input_file = SinglefileData(
os.path.join(
filepath_tests,
"workchains/inputs",
"ch4.xyz",
)
)

struct = cf.xyzfile_to_StructureData(input_file)
assert isinstance(struct, StructureData)


def test_generate_structure_data():
"""Test generate_structure_data function"""
test_Str = Dict(
Expand Down Expand Up @@ -114,6 +144,63 @@ def test_parameters_with_cm():
assert out_dict["multiplicity"] == 1


def test_get_wfxname_from_gaussianinputs():
"""Test get_wfxname_from_gaussianinputs"""
gaussian_sp = Dict(
{
"link0_parameters": {
"%chk": "aiida.chk",
"%mem": "3200MB", # Currently set to use 8000 MB in .sh files
"%nprocshared": 4,
},
"functional": "wb97xd",
"basis_set": "aug-cc-pvtz",
"charge": 0,
"multiplicity": 1,
"route_parameters": {"nosymmetry": None, "Output": "WFX"},
"input_parameters": {"output.wfx": None},
}
)
wfxname = cf.get_wfxname_from_gaussianinputs(gaussian_sp)
assert isinstance(wfxname, Str)
assert wfxname.value == "output.wfx"
gaussian_optfreq = Dict(
{
"link0_parameters": {
"%chk": "aiida.chk",
"%mem": "3200MB", # Currently set to use 8000 MB in .sh files
"%nprocshared": 4,
},
"functional": "wb97xd",
"basis_set": "aug-cc-pvtz",
"charge": 0,
"multiplicity": 1,
"route_parameters": {"opt": None, "freq": None, "Output": "WFX"},
"input_parameters": {"output.wfx": None, "output2.wfx": None},
}
)
wfxname = cf.get_wfxname_from_gaussianinputs(gaussian_optfreq)
assert isinstance(wfxname, Str)
assert wfxname.value == "output.wfx"
gaussian_nowfx = Dict(
{
"link0_parameters": {
"%chk": "aiida.chk",
"%mem": "3200MB", # Currently set to use 8000 MB in .sh files
"%nprocshared": 4,
},
"functional": "wb97xd",
"basis_set": "aug-cc-pvtz",
"charge": 0,
"multiplicity": 1,
"route_parameters": {"opt": None, "freq": None},
}
)
wfxname = cf.get_wfxname_from_gaussianinputs(gaussian_nowfx)
assert isinstance(wfxname, Str)
assert wfxname.value == ""


def test_validate_shell_code():
"""Test validate_shell_code"""
str_node = Str("aimall")
Expand All @@ -127,6 +214,20 @@ def test_validate_shell_code():
)


def test_validate_parser():
"""Test validate_file_ext - provided file extension should be wfx, wfn or fchk"""
# these should all return None, so check for not None
base_node = Str("aimall.base")
assert not cf.validate_parser(base_node, "foo")
group_node = Str("aimall.group")
assert not cf.validate_parser(group_node, "foo")
wrong_node = Str("wfn")
assert (
cf.validate_parser(wrong_node, "foo")
== "the `aim_parser` input must be either aimall.base or aimall.group"
)


def test_validate_file_ext():
"""Test validate_file_ext - provided file extension should be wfx, wfn or fchk"""
# these should all return None, so check for not None
Expand Down Expand Up @@ -176,6 +277,13 @@ def test_generate_rotated_structure_aiida(generate_workchain_folderdata):
assert abs(rot_dict["geom"][1][2]) < 0.0001


def test_remove_numcharss_from_strlist():
"""Test remove_numcharss_from_strlist"""
out_list = cf.remove_numcharss_from_strlist(["O1", "O2"])
assert isinstance(out_list, list)
assert out_list == ["O", "O"]


def test_dict_to_structure():
"""Test dict_to_structure"""
str_dict = Dict(
Expand Down

0 comments on commit 94ff837

Please sign in to comment.