From a86f3a4ac572c37451dcda17a9255acc0a3730fd Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Mon, 17 Jan 2022 16:37:56 +0100 Subject: [PATCH 1/6] TST: Add dedicated `pre-release` and `slow` tests --- .github/workflows/pythonpackage.yml | 36 +++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index b79844d..b6f069a 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -12,13 +12,21 @@ on: jobs: build: - name: Python ${{ matrix.version }} on ${{ matrix.os }} + name: ${{ matrix.os }} (py ${{ matrix.version }}${{ matrix.special }}) runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] version: ["3.7", "3.8", "3.9", "3.10"] + special: [""] + include: + - os: ubuntu-latest + special: '; pre-release' + version: '3.10' + - os: ubuntu-latest + special: '; slow' + version: '3.10' env: CP2K_DATA_DIR: "/usr/share/cp2k" @@ -31,7 +39,7 @@ jobs: - uses: actions/checkout@v2 - name: Install CP2K - if: matrix.os == 'ubuntu-latest' + if: matrix.special == '; slow' run: | sudo apt-get update sudo apt install cp2k @@ -42,7 +50,19 @@ jobs: python-version: ${{ matrix.version }} - name: Install dependencies - run: pip install -e .[test] + run: | + case "${{ matrix.special }}" in + "; pre-release") + pip install --pre -e .[test] --upgrade --force-reinstall + pip install git+https://github.com/nlesc-nano/CAT@master --upgrade + pip install git+https://github.com/nlesc-nano/auto-FOX@master --upgrade + pip install git+https://github.com/SCM-NV/qmflows@master --upgrade + pip install git+https://github.com/SCM-NV/PLAMS@master --upgrade + ;; + *) + pip install -e .[test] + ;; + esac - name: Info Python run: | @@ -53,11 +73,17 @@ jobs: run: pip list - name: Info CP2K - if: matrix.os == 'ubuntu-latest' + if: matrix.special == '; slow' run: cp2k.popt --version - name: Run tests - run: pytest -m "not slow" + run: | + case "${{ matrix.special }}" in + "; slow") + pytest -m "slow" ;; + *) + pytest -m "not slow" ;; + esac - name: Run codecov uses: codecov/codecov-action@v2 From 13d681ab5a188e84952a37d752e696c4621584ca Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Mon, 17 Jan 2022 16:39:07 +0100 Subject: [PATCH 2/6] TST: Use python 3.10 for the linting tests --- .github/workflows/pythonpackage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index b6f069a..37d1db6 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -96,10 +96,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up Python 3.9 on ubuntu-latest + - name: Set up Python 3.10 on ubuntu-latest uses: actions/setup-python@v2 with: - python-version: 3.9 + python-version: "3.10" - name: Install linters run: pip install "flake8>=3.8.0" From 591770095bdff382a68cf1fa3508c841f0aa4383 Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Mon, 17 Jan 2022 16:39:37 +0100 Subject: [PATCH 3/6] TST: Add more BDE tests --- tests/test_bde_workflow.py | 111 ++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 46 deletions(-) diff --git a/tests/test_bde_workflow.py b/tests/test_bde_workflow.py index b9991c6..c06570b 100644 --- a/tests/test_bde_workflow.py +++ b/tests/test_bde_workflow.py @@ -13,7 +13,7 @@ import pandas as pd from assertionlib import assertion from nanoutils import UniqueLoader -from scm.plams import readpdb, Settings +from scm.plams import readpdb, Settings, Cp2kJob from CAT.base import validate_input from CAT.settings_dataframe import SettingsDataFrame @@ -21,51 +21,60 @@ from nanoCAT.bde import init_bde PATH = Path("tests") / "test_files" +BASE_SETTINGS = Settings(yaml.load(textwrap.dedent(""" + path: tests/test_files + input_cores: + - Br5ClCs8Pb.xyz + input_ligands: + - CO + optional: + database: + read: False + write: False + qd: + dissociate: + core_atom: null + core_index: null + lig_count: 1 + + keep_files: True + xyn_pre_opt: False + job1: Cp2kJob + s1: + input: + motion: + geo_opt: + type: minimization + optimizer: bfgs + max_iter: 10 + max_force: 1e-03 + force_eval: + dft: + basis_set_file_name: BASIS_MOLOPT + potential_file_name: GTH_POTENTIALS + xc: + xc_functional pbe: {} + scf: + eps_scf: 1e-05 + max_scf: 20 + subsys: + cell: + abc: 8.00 8.00 8.00 + periodic: None + kind H: + basis_set: DZVP-MOLOPT-SR-GTH + potential: GTH-PBE + kind Cl: + basis_set: DZVP-MOLOPT-SR-GTH + potential: GTH-PBE + job2: null + s2: null +""").strip(), Loader=UniqueLoader)) def construct_df() -> SettingsDataFrame: # Construct the settings - settings = Settings(yaml.load(textwrap.dedent(""" - path: tests/test_files - input_cores: - - Br5ClCs8Pb.xyz - input_ligands: - - CO - optional: - database: - read: False - write: False - qd: - dissociate: - core_atom: null - core_index: null - core_core_dist: 2.0 - lig_count: 1 - - keep_files: True - xyn_pre_opt: False - job1: Cp2kJob - s1: - input: - FORCE_EVAL: - DFT: - BASIS_SET_FILE_NAME: BASIS_MOLOPT - POTENTIAL_FILE_NAME: GTH_POTENTIALS - XC: - XC_FUNCTIONAL pbe: {} - SUBSYS: - CELL: - ABC: 7.00 7.00 7.00 - PERIODIC: None - KIND H: - BASIS_SET: DZVP-MOLOPT-SR-GTH-q1 - POTENTIAL: GTH-PBE-q1 - KIND Cl: - BASIS_SET: DZVP-MOLOPT-SR-GTH-q7 - POTENTIAL: GTH-PBE-q7 - job2: null - s2: null - """).strip(), Loader=UniqueLoader)) + settings = BASE_SETTINGS.copy() validate_input(settings) settings.optional.database.db = None settings.optional.qd.dissociate.xyn_opt = False @@ -89,9 +98,14 @@ def construct_df() -> SettingsDataFrame: @pytest.mark.skipif(find_executable("cp2k.popt") is None, reason="requires CP2K") +@pytest.mark.slow class TestBDEWorkflow: PARAMS = dict( - core_index=("core_index", [3]), + core_index={"core_index": [3]}, + core_atom={"core_atom": "H", "lig_core_dist": 2.0}, + freq={"core_index": [3], "job2": Cp2kJob, + "s2": BASE_SETTINGS.optional.qd.dissociate.s1.copy()}, + qd_opt={"core_index": [3], "qd_opt": True}, ) @pytest.fixture(scope="function", autouse=True) @@ -101,12 +115,17 @@ def clear_db(self) -> Generator[None, None, None]: shutil.rmtree(PATH / "database", ignore_errors=True) shutil.rmtree(PATH / "qd" / "bde", ignore_errors=True) - @pytest.mark.parametrize("key,value", PARAMS.values(), ids=PARAMS.keys()) - def test_core_index(self, key: str, value: Any, clear_db: None) -> None: + @pytest.mark.parametrize("kwargs", PARAMS.values(), ids=PARAMS) + def test_pass(self, kwargs: dict[str, Any], clear_db: None) -> None: qd_df = construct_df() - qd_df.settings.optional.qd.dissociate[key] = value + qd_df.settings.optional.qd.dissociate.update(kwargs) init_bde(qd_df) bde = qd_df["BDE dE", "0"].iloc[0] assertion.len_eq(qd_df["BDE dE"].columns, 1) assertion.assert_(np.isfinite, bde) + + if "job2" in kwargs: + bde_gibbs = qd_df["BDE dG", "0"].iloc[0] + assertion.len_eq(qd_df["BDE dG"].columns, 1) + assertion.assert_(np.isfinite, bde_gibbs) From 0ffc65269678e631edc1de5b45d10dc2696874be Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Thu, 20 Jan 2022 17:39:12 +0100 Subject: [PATCH 4/6] BUG: Do not use AMS-style frequency input settings for CP2K --- nanoCAT/bde/bde_workflow.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/nanoCAT/bde/bde_workflow.py b/nanoCAT/bde/bde_workflow.py index 616fb4c..f00f2c2 100644 --- a/nanoCAT/bde/bde_workflow.py +++ b/nanoCAT/bde/bde_workflow.py @@ -270,7 +270,8 @@ def get_bde_ddG(tot: Molecule, lig: Molecule, core: Iterable[Molecule], return np.full(len_core, np.nan) # Optimize XYn - s.input.ams.Constraints.Atom = lig.properties.indices + if job is AMSJob: + s.input.ams.Constraints.Atom = lig.properties.indices lig.job_freq(job, s, name='G_XYn_freq') # Extract energies @@ -282,7 +283,8 @@ def get_bde_ddG(tot: Molecule, lig: Molecule, core: Iterable[Molecule], return np.full(len_core, np.nan) # Optimize the full quantum dot - s.input.ams.Constraints.Atom = tot.properties.indices + if job is AMSJob: + s.input.ams.Constraints.Atom = tot.properties.indices tot.job_freq(job, s, name='G_QD_freq') # Extract energies @@ -295,7 +297,8 @@ def get_bde_ddG(tot: Molecule, lig: Molecule, core: Iterable[Molecule], # Optimize the quantum dot(s) - XYn for mol in core: - s.input.ams.Constraints.Atom = mol.properties.indices + if job is AMSJob: + s.input.ams.Constraints.Atom = mol.properties.indices mol.job_freq(job, s, name='G_QD-XYn_freq') # Extract energies From 470bea84f1bf70596866c099d0287365b2a0a2d8 Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Thu, 20 Jan 2022 17:40:16 +0100 Subject: [PATCH 5/6] BLD bump the minimum CAT and qmflows versions --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index d383768..edee3bd 100644 --- a/setup.py +++ b/setup.py @@ -71,8 +71,8 @@ 'noodles>=0.3.3', 'more-itertools>=1.0', 'plams>=1.5.1', - 'qmflows>=0.11.0', - 'nlesc-CAT>=0.10.4', + 'qmflows>=0.11.1', + 'nlesc-CAT>=0.10.5', 'Auto-FOX>=0.10.0', 'rdkit-pypi>=2018.03.1', ], From c6c442510cc8ede535e020fa6337404d82a2a686 Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Fri, 21 Jan 2022 16:34:02 +0100 Subject: [PATCH 6/6] TST: Mark tests that require AMS as such --- tests/test_fast_sigma_recipe.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/test_fast_sigma_recipe.py b/tests/test_fast_sigma_recipe.py index aa55750..8c7556e 100644 --- a/tests/test_fast_sigma_recipe.py +++ b/tests/test_fast_sigma_recipe.py @@ -47,6 +47,11 @@ SANITIZE4_DF.index = pd.Index([None] * len(SANITIZE_DF.index), name=SANITIZE_DF.index.name) +def has_env_vars(*env_vars: str) -> bool: + """Check if the passed environment variables are available.""" + return set(env_vars).issubset(os.environ) + + def compare_df(df1: pd.DataFrame, df2: pd.DataFrame) -> None: """Compare the content of two dataframes.""" __tracebackhide__ = True @@ -64,10 +69,11 @@ def compare_df(df1: pd.DataFrame, df2: pd.DataFrame) -> None: np.testing.assert_array_equal(v1, v2, err_msg=k) +@pytest.mark.slow +@pytest.mark.skipif(not has_env_vars("AMSBIN", "AMSHOME", "AMSRESOURCES"), reason="Requires AMS") class TestFastSigma: """Tests for :func:`nanoCAT.recipes.run_fast_sigma`.""" - @pytest.mark.slow @pytest.mark.parametrize( "kwargs", [{}, {"return_df": True}, {"chunk_size": 1, "return_df": True}, {"processes": 1}], @@ -114,7 +120,6 @@ def test_raises( with pytest.raises(exc): run_fast_sigma(SMILES, solvents, **kwargs) - @pytest.mark.slow def test_warns(self, tmp_path: Path) -> None: """Test that whether appropiate warning is issued.""" with pytest.warns(RuntimeWarning) as record: