Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,11 @@ jobs:
# pytest: ""

# DOWNLOAD problem Mar 2026
#- conda-env: mace
# python-version: "3.10"
# label: MACE
# runs-on: ubuntu-latest
# pytest: ""
- conda-env: mace
python-version: "3.13"
label: MACE
runs-on: ubuntu-latest
pytest: ""

- conda-env: aimnet2
python-version: 3.11
Expand Down Expand Up @@ -205,7 +205,7 @@ jobs:
run: |
# conda remove qcelemental --force
# python -m pip install 'git+https://github.com/MolSSI/QCElemental.git@next2026' --no-deps
conda install "conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3"
conda install "conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc4"

# note: conda remove --force, not mamba remove --force b/c https://github.com/mamba-org/mamba/issues/412
# alt. is micromamba but not yet ready for setup-miniconda https://github.com/conda-incubator/setup-miniconda/issues/75
Expand Down Expand Up @@ -254,7 +254,7 @@ jobs:
python -c "import qcelemental as q;print(q.__file__, q.__version__)"
python -c "import qcengine as q;print(q.__file__, q.__version__)"
git describe
git log --oneline
# git log --oneline

- name: Special Config - Windows Psi4
if: "(((matrix.cfg.label == 'optimization-dispersion') || (matrix.cfg.label == 'Psi4-1.8')) && (matrix.cfg.runs-on == 'windows-latest'))"
Expand Down Expand Up @@ -286,12 +286,12 @@ jobs:
- name: PyTest
run: |
# export MKL_CBWR=AVX
pytest -rws -v ${{ matrix.cfg.pytest }} --cov=qcengine --color=yes --cov-report=xml qcengine/
pytest -rws -v ${{ matrix.cfg.pytest }} --cov=qcengine --durations=20 --durations-min=40 --strict-markers --color=yes --cov-report=xml qcengine/

- name: PyTest - Task_Config
run: |
rm -f qcengine.yaml
pytest -rws -v -k "test_config" --cov=qcengine --color=yes --cov-report=xml qcengine/
pytest -rws -v -k "test_config" --cov=qcengine --strict-markers --color=yes --cov-report=xml qcengine/

- name: CodeCov
uses: codecov/codecov-action@v4
Expand Down
4 changes: 3 additions & 1 deletion devtools/conda-envs/adcc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ channels:
dependencies:
- adcc>=0.15.7
- psi4>=1.8.1
- libint=2.9.0=*_4

# Core
- python
- py-cpuinfo
- psutil
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental>=0.50.0rc4
- qcmanybody>=0.7.0
- pydantic=2
- pydantic-settings
- msgpack-python
Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/aimnet2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ dependencies:
- pyyaml
- py-cpuinfo
- psutil
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental
- pydantic>=2.0.0
- pydantic-settings

Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/mace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ dependencies:
- pyyaml
- py-cpuinfo
- psutil
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental
- pydantic>=2.0.0
- pydantic-settings

Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/mrchem.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ dependencies:
- pyyaml
- py-cpuinfo
- psutil
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental
- pydantic=2
- pydantic-settings
- setuptools <82.0 # for berny
Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/nwchem-cf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ dependencies:
- pyyaml
- py-cpuinfo
- psutil
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental
- pydantic>=2.0.0
- networkx>=2.4.0
- qcmanybody
Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/nwchem.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ dependencies:
- pyyaml
- py-cpuinfo
- psutil
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental
- pydantic>=2.0.0
- networkx>=2.4.0
- pydantic-settings
Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/openmm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ dependencies:
- pyyaml
- py-cpuinfo
- psutil
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental
- pydantic >=2
- pydantic-settings
# - pint <0.22 # needed for a while see #416
Expand Down
5 changes: 3 additions & 2 deletions devtools/conda-envs/opt-disp-cf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ dependencies:
- rdkit
# - rdkit<=2025.03.4 # Windows+psi4 error with 03.5 # sometimes fine, sometimes flaky even w/exactly same packages in env
- mopac
- libint=2.9.0=*_4 # old (1.10=*_2) psi4 to release qcmb constraint to use new qcnb (0.7) with new qcel (rc4)

# Mixed Tests
- dftd3-python
Expand All @@ -15,7 +16,7 @@ dependencies:
- geometric=1.0
- optking
- pymdi
- qcmanybody
- qcmanybody>=0.7.0
- pyberny
- setuptools <82.0 # for berny

Expand All @@ -24,7 +25,7 @@ dependencies:
- pyyaml
- py-cpuinfo
- psutil
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental>=0.50.0rc4
- pydantic=2
- pydantic-settings
- msgpack-python
Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/opt-disp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ dependencies:
- pyyaml
- py-cpuinfo
- psutil
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental
- msgpack-python

# Testing
Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/psi-cf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ dependencies:
- numpy<2
- libgcc<14.3 # until psi4 package itself conveys this
- pydantic-settings
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental

# Core
- python
Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/psi-nightly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dependencies:
- pyyaml
- py-cpuinfo
- psutil
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental
- pydantic>=2.0.0
- pydantic-settings
- msgpack-python
Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/torchani.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ dependencies:
- pyyaml
- py-cpuinfo
- psutil
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental
- pydantic>=2
- pydantic-settings

Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/xtb.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ dependencies:
- pyyaml
- py-cpuinfo
- psutil
- conda-forge/label/qcelemental_dev::qcelemental=0.50.0rc3
- conda-forge/label/qcelemental_dev::qcelemental
- pydantic >=2
- pydantic-settings

Expand Down
28 changes: 28 additions & 0 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,34 @@ Changelog
.. - UNSOLVED (:issue:`397`) extras failed


.. _`sec:cl0500rc3`:

v0.50.0rc3 / 2026-04-02 (Prerelease)
------------------------------------

:docs:`v0.50.0rc3` for current. :docs:`v0.34.1` for QCSchema v1.

New Features
++++++++++++
- (:pr:`499`) Testing - Program names are now pytest markers, so `pytest -m openmm`
thoroughly collects all tests involving that program. Note that the nearly
retired harnesses for Grimme programs have markers "classic-dftd3" and "classic-gcp".

Enhancements
++++++++++++
- (:pr:`499`) QCElemental - Update encoding=json to mode=json in serialization
calls to match QCElemental v0.50.0rc4 changes.
- (:pr:`499`) DFTD3, DFTD4 - Allow running in QCSchema v2 mode for WIP upstream versions.
Note that QCEngine-added input extras appear in `AtomicResult.input_data.specification.extras`,
formerly `AtomicResult.extras`, even routing through older (pre-v1.3, v4.1) programs.
- (:pr:`499`) GCP, MP2D - Update model_copy and casting of energy for qcel rc3 and Pydantic v2.

Bug Fixes
+++++++++
- (:pr:`499`) Psi4 - Fix Psi4 detected but not registered error arising from parsing
of version and paths being obscured by QCSchema/Pydantic Warnings.


.. _`sec:cl0500rc2`:

v0.50.0rc2 / 2026-03-13 (Prerelease)
Expand Down
39 changes: 38 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ dependencies = [
"pyyaml",
"py-cpuinfo",
"psutil",
"qcelemental>=0.50.0rc3,<0.70.0",
"qcelemental>=0.50.0rc4,<0.70.0",
"pydantic >=2.11; python_version <'3.14'",
"pydantic >=2.12; python_version >='3.14'",
"pydantic-settings",
Expand Down Expand Up @@ -105,4 +105,41 @@ markers = [
"long",
"""slow: marks tests as slow (deselect with '-m "not slow"')""",
"smoke",
'addon: "tests require external non-required software"',

"adcc: tests using adcc software; skip if unavailable",
"aimnet2: tests using AIMNET2 software; skip if unavailable",
"berny: tests using pyberny software; skip if unavailable",
"cfour: tests using Cfour software; skip if unavailable",
"classic-dftd3: tests using DFTD3 executable software; skip if unavailable",
"classic-dftd3_321: tests using DFTD3 classic executable >=v3.2.1 software; skip if unavailable",
"s-dftd3: tests using modern simple-dftd3 software; skip if unavailable",
"dftd4: tests using DFTD4 software; skip if unavailable",
"dftd4_350: tests using DFTD4 >=3.5.0 software; skip if unavailable",
"gamess: tests using GAMESS-US software; skip if unavailable",
"mctc-gcp: tests using modern mctc-gcp software; skip if unavailable",
"classic-gcp: tests using GCP executable software; skip if unavailable",
"geometric: tests using geomeTRIC software; skip if unavailable",
"mace: tests using MACE software; skip if unavailable",
"mdi: tests using MDI software; skip if unavailable",
"molpro: tests using Molpro software; skip if unavailable",
"mopac: tests using Mopac software; skip if unavailable",
"mp2d: tests using MP2D software; skip if unavailable",
"mrchem: tests using MR-Chem software; skip if unavailable",
"nwchem: tests using NWChem Classic software; skip if unavailable",
"openmm: tests using OpenMM software; skip if unavailable",
"optking: tests using OptKing software; skip if unavailable",
"optking_v2: tests using OptKing QCSchema-v2-compatible software; skip if unavailable",
"psi4: tests using Psi4 software; skip if unavailable",
"qcdb: tests using QCDB software; skip if unavailable",
"qchem: tests using Q-Chem software; skip if unavailable",
"qcmanybody: tests using QCManyBody software; skip if unavailable",
"qcore: tests using Qcore (ret.) software; skip if unavailable",
"rdkit: tests using RDKIT software; skip if unavailable",
"terachem: tests using TeraChem software; skip if unavailable",
"terachem_pbs: tests using TeraChem through PBS software; skip if unavailable",
"torchani: tests using Torch-ANI software; skip if unavailable",
"torsiondrive: tests using TorsionDrive software; skip if unavailable",
"turbomole: tests using Turbomole software; skip if unavailable",
"xtb: tests using xTB software; skip if unavailable",
]
2 changes: 1 addition & 1 deletion qcengine/programs/adcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def compute(self, input_model: "AtomicInput", config: "TaskConfig") -> "AtomicRe
except Exception as e:
raise UnknownError(str(e))

input_data = input_model.model_dump(encoding="json")
input_data = input_model.model_dump(mode="json")
output_data = {"input_data": input_data, "extras": {}, "molecule": mol}
output_data["success"] = compute_success

Expand Down
2 changes: 1 addition & 1 deletion qcengine/programs/dftd3.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def parse_output(self, outfiles: Dict[str, str], input_model: "AtomicInput") ->
# jobrec["molecule"]["real"] = list(jobrec["molecule"]["real"])

retres = calcinfo[f"CURRENT {input_model.specification.driver.upper()}"]
if isinstance(retres, Decimal):
if isinstance(retres, (str, Decimal)):
retres = float(retres)
elif isinstance(retres, np.ndarray):
retres = retres.ravel().tolist()
Expand Down
80 changes: 60 additions & 20 deletions qcengine/programs/dftd_ng.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,20 +104,40 @@ def compute(self, input_model: AtomicInput, config: TaskConfig) -> AtomicResult:
level_hint = "d4"
input_data["specification"]["keywords"]["level_hint"] = level_hint

# dftd4 speaks qcsk.v1
input_model_v1 = qcelemental.models.v2.AtomicInput(**input_data).convert_v(1)
if parse_version(self.get_version()) < parse_version("4.1.0"):
# dftd4 speaks qcsk.v1
input_model_v1 = qcelemental.models.v2.AtomicInput(**input_data).convert_v(1)

# Run the Harness
output_v1 = run_qcschema(input_model_v1)
# Run the Harness
output_v1 = run_qcschema(input_model_v1)

# d4 qcschema interface stores error in Result model
if not output_v1.success:
return FailedOperation(input_data=input_data, error=output_v1.error.model_dump())
# d4 qcschema interface stores error in Result model
if not output_v1.success:
return FailedOperation(input_data=input_data, error=output_v1.error.model_dump())

output = output_v1.convert_v(2, external_input_data=input_model)
# Unclear whether external_input_data should be input_model (user input in v2) or input_data
# (user input + processing above with tweaks and hints). Former seems cleaner (and works)
# but places "extras.info" differently in pre-/post-1.3.0 routes, so using latter.
output = output_v1.convert_v(2, external_input_data=input_data)

if "info" in output.extras:
qcvkey = output.extras["info"]["fctldash"].upper()
else:
# dftd4 >4.1 speaks qcsk.v1 or qcsk.v2
input_model_v2 = qcelemental.models.v2.AtomicInput(**input_data)

# Run the Harness
output_v2 = run_qcschema(input_model_v2)

# d4 qcschema interface stores error in Result model
# TODO
if not output_v2.success:
# return FailedOperation(input_data=input_data, error=output_v2.error.model_dump())
return output_v2

output = output_v2

if "info" in output.input_data.specification.extras:
# formerly output.extras["info"]
qcvkey = output.input_data.specification.extras["info"]["fctldash"].upper()

calcinfo = {}
energy = output.properties.return_energy
Expand Down Expand Up @@ -279,20 +299,40 @@ def compute(self, input_model: AtomicInput, config: TaskConfig) -> AtomicResult:
input_data["specification"]["keywords"]["params_tweaks"] = {**planinfo["dashparams"], "s9": 0.0}
input_data["specification"]["keywords"]["level_hint"] = level_hint

# sdftd3 speaks qcsk.v1
input_model_v1 = qcelemental.models.v2.AtomicInput(**input_data).convert_v(1)
if parse_version(self.get_version()) < parse_version("1.3.0"):
# sdftd3 speaks qcsk.v1
input_model_v1 = qcelemental.models.v2.AtomicInput(**input_data).convert_v(1)

# Run the Harness
output_v1 = run_qcschema(input_model_v1)

# d3 qcschema interface stores error in Result model
if not output_v1.success:
return FailedOperation(input_data=input_data, error=output_v1.error.model_dump())

# Unclear whether external_input_data should be input_model (user input in v2) or input_data
# (user input + processing above with tweaks and hints). Former seems cleaner (and works)
# but places "extras.info" differently in pre-/post-1.3.0 routes, so using latter.
output = output_v1.convert_v(2, external_input_data=input_data)

else:
# sdftd3 >1.3.0??? speaks qcsk.v1 or qcsk.v2
input_model_v2 = qcelemental.models.v2.AtomicInput(**input_data)

# Run the Harness
output_v1 = run_qcschema(input_model_v1)
# Run the Harness
output_v2 = run_qcschema(input_model_v2)

# d3 qcschema interface stores error in Result model
if not output_v1.success:
return FailedOperation(input_data=input_data, error=output_v1.error.model_dump())
# d3 qcschema interface stores error in Result model
# TODO
if not output_v2.success:
# return FailedOperation(input_data=input_data, error=output_v2.error.model_dump())
return output_v2

output = output_v1.convert_v(2, external_input_data=input_model)
output = output_v2

if "info" in output.extras:
qcvkey = output.extras["info"]["fctldash"].upper()
if "info" in output.input_data.specification.extras:
# formerly output.extras["info"]
qcvkey = output.input_data.specification.extras["info"]["fctldash"].upper()

calcinfo = {}
energy = output.properties.return_energy
Expand Down
Loading
Loading