From 591cbae0e9df2e1681811456ae451d58cf2adb67 Mon Sep 17 00:00:00 2001 From: "Lori A. Burns" Date: Wed, 16 Aug 2023 15:49:57 -0400 Subject: [PATCH 1/3] syntax updates for pydantic2 --- psi4/driver/driver_cbs.py | 10 +++----- psi4/driver/driver_findif.py | 13 ++++------ psi4/driver/driver_nbody.py | 49 +++++++++++++++++++----------------- psi4/driver/task_base.py | 25 ++++++++---------- 4 files changed, 45 insertions(+), 52 deletions(-) diff --git a/psi4/driver/driver_cbs.py b/psi4/driver/driver_cbs.py index 3fbaa2c012d..4e17e075bb7 100644 --- a/psi4/driver/driver_cbs.py +++ b/psi4/driver/driver_cbs.py @@ -149,12 +149,7 @@ from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Union import numpy as np - -try: - from pydantic.v1 import Field, validator -except ImportError: - from pydantic import Field, validator - +from pydantic import Field, field_validator from qcelemental.models import AtomicResult, DriverEnum from psi4 import core @@ -1538,7 +1533,8 @@ class CompositeComputer(BaseComputer): # One-to-One list of QCSchema corresponding to `task_list`. results_list: List[Any] = [] - @validator('molecule') + @field_validator('molecule') + @classmethod def set_molecule(cls, mol): mol.update_geometry() mol.fix_com(True) diff --git a/psi4/driver/driver_findif.py b/psi4/driver/driver_findif.py index f36018c0579..d575462bfff 100644 --- a/psi4/driver/driver_findif.py +++ b/psi4/driver/driver_findif.py @@ -143,12 +143,7 @@ from typing import TYPE_CHECKING, Any, Callable, Dict, Iterator, List, Optional, Tuple, Union import numpy as np - -try: - from pydantic.v1 import Field, validator -except ImportError: - from pydantic import Field, validator - +from pydantic import Field, field_validator from qcelemental.models import AtomicResult, DriverEnum from psi4 import core @@ -1153,7 +1148,8 @@ class FiniteDifferenceComputer(BaseComputer): computer: BaseComputer = AtomicComputer method: str - @validator('driver') + @field_validator('driver') + @classmethod def set_driver(cls, driver): egh = ['energy', 'gradient', 'hessian'] if driver not in egh: @@ -1161,7 +1157,8 @@ def set_driver(cls, driver): return driver - @validator('molecule') + @field_validator('molecule') + @classmethod def set_molecule(cls, mol): mol.update_geometry() mol.fix_com(True) diff --git a/psi4/driver/driver_nbody.py b/psi4/driver/driver_nbody.py index 7e32efa1b0b..15b2bf9ca15 100644 --- a/psi4/driver/driver_nbody.py +++ b/psi4/driver/driver_nbody.py @@ -150,10 +150,7 @@ from enum import Enum from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Sequence, Set, Tuple, Union -try: - from pydantic.v1 import Field, validator -except ImportError: - from pydantic import Field, validator +from pydantic import Field, FieldValidationInfo, field_validator import logging @@ -856,62 +853,68 @@ class ManyBodyComputer(BaseComputer): keywords: Dict[str, Any] = Field({}, description="The computation keywords/options.") bsse_type: List[BsseEnum] = Field([BsseEnum.cp], description="Requested BSSE treatments. First in list determines which interaction or total energy/gradient/Hessian returned.") - nfragments: int = Field(-1, description="Number of distinct fragments comprising full molecular supersystem.") # formerly max_frag - max_nbody: int = Field(-1, description="Maximum number of bodies to include in the many-body treatment. Possible: max_nbody <= nfragments. Default: max_nbody = nfragments.") + nfragments: int = Field(-1, validate_default=True, description="Number of distinct fragments comprising full molecular supersystem.") # formerly max_frag + max_nbody: int = Field(-1, validate_default=True, description="Maximum number of bodies to include in the many-body treatment. Possible: max_nbody <= nfragments. Default: max_nbody = nfragments.") nbodies_per_mc_level: List[List[Union[int, Literal["supersystem"]]]] = Field([], description="Distribution of active n-body levels among model chemistry levels. All bodies in range [1, self.max_nbody] must be present exactly once. Number of items in outer list is how many different modelchems. Each inner list specifies what n-bodies to be run at the corresponding modelchem (e.g., `[[1, 2]]` has max_nbody=2 and 1-body and 2-body contributions computed at the same level of theory; `[[1], [2]]` has max_nbody=2 and 1-body and 2-body contributions computed at different levels of theory. An entry 'supersystem' means all higher order n-body effects up to the number of fragments. The n-body levels are effectively sorted in the outer list, and any 'supersystem' element is at the end.") # formerly nbody_list embedding_charges: Dict[int, List[float]] = Field({}, description="Atom-centered point charges to be used on molecule fragments whose basis sets are not included in the computation. Keys: 1-based index of fragment. Values: list of atom charges for that fragment.") - return_total_data: Optional[bool] = Field(None, description="When True, returns the total data (energy/gradient/Hessian) of the system, otherwise returns interaction data. Default is False for energies, True for gradients and Hessians. Note that the calculation of total counterpoise corrected energies implies the calculation of the energies of monomers in the monomer basis, hence specifying ``return_total_data = True`` may carry out more computations than ``return_total_data = False``.") + return_total_data: Optional[bool] = Field(None, validate_default=True, description="When True, returns the total data (energy/gradient/Hessian) of the system, otherwise returns interaction data. Default is False for energies, True for gradients and Hessians. Note that the calculation of total counterpoise corrected energies implies the calculation of the energies of monomers in the monomer basis, hence specifying ``return_total_data = True`` may carry out more computations than ``return_total_data = False``.") quiet: bool = Field(False, description="Whether to print/log formatted n-body energy analysis. Presently used by multi to suppress output. Candidate for removal from class once in-class/out-of-class functions sorted.") task_list: Dict[str, SubTaskComputers] = {} # Note that validation of user fields happens through typing and validator functions, so no class __init__ needed. - @validator("bsse_type", pre=True) + @field_validator("bsse_type", mode="before") + @classmethod def set_bsse_type(cls, v): if not isinstance(v, list): v = [v] # emulate ordered set return list(dict.fromkeys([bt.lower() for bt in v])) - @validator('molecule') + @field_validator('molecule') + @classmethod def set_molecule(cls, mol): mol.update_geometry() mol.fix_com(True) mol.fix_orientation(True) return mol - @validator("nfragments", always=True) - def set_nfragments(cls, v, values): - return values["molecule"].nfragments() + @field_validator("nfragments") + @classmethod + def set_nfragments(cls, v: int, info: FieldValidationInfo) -> int: + return info.data["molecule"].nfragments() - @validator("max_nbody", always=True) - def set_max_nbody(cls, v, values): + @field_validator("max_nbody") + @classmethod + def set_max_nbody(cls, v: int, info: FieldValidationInfo) -> int: if v == -1: - return values["nfragments"] + return info.data["nfragments"] else: - return min(v, values["nfragments"]) + return min(v, info.data["nfragments"]) - @validator("embedding_charges") - def set_embedding_charges(cls, v, values): - if len(v) != values["nfragments"]: + @field_validator("embedding_charges") + @classmethod + def set_embedding_charges(cls, v: Dict[int, List[float]], info: FieldValidationInfo) -> Dict[int, List[float]]: + if len(v) != info.data["nfragments"]: raise ValueError("embedding_charges dict should have entries for each 1-indexed fragment.") return v - @validator("return_total_data", always=True) - def set_return_total_data(cls, v, values): + @field_validator("return_total_data") + @classmethod + def set_return_total_data(cls, v: Optional[bool], info: FieldValidationInfo) -> bool: if v is not None: rtd = v - elif values["driver"] in ["gradient", "hessian"]: + elif info.data["driver"] in ["gradient", "hessian"]: rtd = True else: rtd = False - if values.get("embedding_charges", False) and rtd is False: + if info.data.get("embedding_charges", False) and rtd is False: raise ValueError("Cannot return interaction data when using embedding scheme.") return rtd diff --git a/psi4/driver/task_base.py b/psi4/driver/task_base.py index d79c39bc226..3495b4789c9 100644 --- a/psi4/driver/task_base.py +++ b/psi4/driver/task_base.py @@ -37,11 +37,7 @@ import logging from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Union -try: - from pydantic.v1 import Field, validator -except ImportError: - from pydantic import Field, validator - +from pydantic import ConfigDict, Field, field_validator import qcelemental as qcel from qcelemental.models import AtomicInput, AtomicResult, DriverEnum @@ -71,9 +67,10 @@ def compute(self): def plan(self): pass - class Config(qcel.models.ProtoModel.Config): - extra = "allow" - allow_mutation = True + model_config = ConfigDict( + extra="allow", + frozen=False, + ) class AtomicComputer(BaseComputer): @@ -89,18 +86,18 @@ class AtomicComputer(BaseComputer): result: Any = Field(default_factory=dict, description=":py:class:`~qcelemental.models.AtomicResult` return.") result_id: Optional[str] = Field(None, description="The optional ID for the computation.") - class Config(qcel.models.ProtoModel.Config): - pass - - @validator("basis") + @field_validator("basis") + @classmethod def set_basis(cls, basis): return basis.lower() - @validator("method") + @field_validator("method") + @classmethod def set_method(cls, method): return method.lower() - @validator("keywords") + @field_validator("keywords") + @classmethod def set_keywords(cls, keywords): return copy.deepcopy(keywords) From 773a6ab70f90e0c807bd3fce98baa96aa79cb786 Mon Sep 17 00:00:00 2001 From: "Lori A. Burns" Date: Fri, 18 Aug 2023 00:43:31 -0400 Subject: [PATCH 2/3] pydantic v2 api all tests run --- psi4/driver/driver_findif.py | 25 ++++++++++++++++++++----- psi4/driver/driver_nbody.py | 9 +++++---- psi4/driver/task_base.py | 21 +++++++++++++++++++++ psi4/driver/task_planner.py | 8 ++++---- tests/pytests/test_qcfractal.py | 19 +++++++++++-------- 5 files changed, 61 insertions(+), 21 deletions(-) diff --git a/psi4/driver/driver_findif.py b/psi4/driver/driver_findif.py index d575462bfff..45237e40e90 100644 --- a/psi4/driver/driver_findif.py +++ b/psi4/driver/driver_findif.py @@ -151,13 +151,23 @@ from . import p4util, qcdb from .constants import constants, nppp10, pp from .p4util.exceptions import ValidationError -from .task_base import AtomicComputer, BaseComputer, EnergyGradientHessianWfnReturn +from .task_base import AtomicComputer, BaseComputer, ComputerEnum, EnergyGradientHessianWfnReturn +from .driver_cbs import CompositeComputer + if TYPE_CHECKING: import qcportal logger = logging.getLogger(__name__) +FDTaskComputers = Union[AtomicComputer, CompositeComputer] + + +class FDComputerEnum(ComputerEnum): + atomic = "atomic" + composite = "composite" + + # CONVENTIONS: # n_ at the start of a variable name is short for "number of." # _pi at the end of a variable name is short for "per irrep." @@ -1143,9 +1153,14 @@ class FiniteDifferenceComputer(BaseComputer): molecule: Any driver: DriverEnum metameta: Dict[str, Any] = {} - task_list: Dict[str, BaseComputer] = {} + task_list: Dict[str, FDTaskComputers] = {} findifrec: Dict[str, Any] = {} - computer: BaseComputer = AtomicComputer + # Field `computer` "holds" a computer class: AtomicComputer or CompositeComputer, *not* an instance of the class. + # While pydantic v1 was ok with the class, pydantic v2 hates it, both at point of validation (it demands an + # instance of stated class, not the class itself; avoidable by `computer: Any = AtomicComputer`) and at point of + # serialization (it refuses to serialize the class/mappingproxy; avoidable by `plan.model_dump(...)` or + # `plan.dict(exclude=["computer", "task_list"])`, esp. in driver.py. Enum plus func avoids both objections. + computer: FDComputerEnum = FDComputerEnum.atomic method: str @field_validator('driver') @@ -1254,7 +1269,7 @@ def __init__(self, **data): passalong = {k: v for k, v in data.items() if k not in packet} passalong.pop('ptype', None) - self.task_list["reference"] = self.computer(**packet, **passalong) + self.task_list["reference"] = self.computer.computer()(**packet, **passalong) parent_group = self.molecule.point_group() for label, displacement in self.findifrec["displacements"].items(): @@ -1286,7 +1301,7 @@ def __init__(self, **data): if 'cbs_metadata' in data: packet['cbs_metadata'] = data['cbs_metadata'] - self.task_list[label] = self.computer(**packet, **passalong) + self.task_list[label] = self.computer.computer()(**packet, **passalong) # for n, displacement in enumerate(findif_meta_dict["displacements"].values(), start=2): diff --git a/psi4/driver/driver_nbody.py b/psi4/driver/driver_nbody.py index 15b2bf9ca15..fb0fdc8bd67 100644 --- a/psi4/driver/driver_nbody.py +++ b/psi4/driver/driver_nbody.py @@ -173,7 +173,8 @@ FragBasIndex = Tuple[Tuple[int], Tuple[int]] -SubTaskComputers = Union[AtomicComputer, CompositeComputer, FiniteDifferenceComputer] +MBETaskComputers = Union[AtomicComputer, CompositeComputer, FiniteDifferenceComputer] + def nbody(): """ @@ -863,7 +864,7 @@ class ManyBodyComputer(BaseComputer): return_total_data: Optional[bool] = Field(None, validate_default=True, description="When True, returns the total data (energy/gradient/Hessian) of the system, otherwise returns interaction data. Default is False for energies, True for gradients and Hessians. Note that the calculation of total counterpoise corrected energies implies the calculation of the energies of monomers in the monomer basis, hence specifying ``return_total_data = True`` may carry out more computations than ``return_total_data = False``.") quiet: bool = Field(False, description="Whether to print/log formatted n-body energy analysis. Presently used by multi to suppress output. Candidate for removal from class once in-class/out-of-class functions sorted.") - task_list: Dict[str, SubTaskComputers] = {} + task_list: Dict[str, MBETaskComputers] = {} # Note that validation of user fields happens through typing and validator functions, so no class __init__ needed. @@ -921,7 +922,7 @@ def set_return_total_data(cls, v: Optional[bool], info: FieldValidationInfo) -> def build_tasks( self, - mb_computer: SubTaskComputers, + mb_computer: MBETaskComputers, mc_level_idx: int, **kwargs: Dict[str, Any], ) -> int: @@ -1024,7 +1025,7 @@ def compute(self, client: Optional["qcportal.FractalClient"] = None): def prepare_results( self, - results: Optional[Dict[str, SubTaskComputers]] = None, + results: Optional[Dict[str, MBETaskComputers]] = None, client: Optional["qcportal.FractalClient"] = None, ) -> Dict[str, Any]: """Process the results from all n-body component molecular systems and model chemistry levels into final quantities. diff --git a/psi4/driver/task_base.py b/psi4/driver/task_base.py index 3495b4789c9..e0bc245a138 100644 --- a/psi4/driver/task_base.py +++ b/psi4/driver/task_base.py @@ -29,11 +29,13 @@ __all__ = [ "AtomicComputer", "BaseComputer", + "ComputerEnum", "EnergyGradientHessianWfnReturn", ] import abc import copy +from enum import Enum import logging from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Union @@ -277,3 +279,22 @@ def _drink_filter(stdout: str) -> str: stdout = stdout.replace("\n*** Psi4 exiting successfully. Buy a developer a beer!", "") stdout = stdout.replace("\n*** Psi4 encountered an error. Buy a developer more coffee!", "") return stdout + + +class ComputerEnum(str, Enum): + """Allowed driver compute layers.""" + + def computer(self) -> BaseComputer: + """Return class specified by enum.""" + + if self == "atomic": + return AtomicComputer + elif self == "composite": + from .driver_cbs import CompositeComputer + return CompositeComputer + elif self == "finitedifference": + from .driver_findif import FiniteDifferenceComputer + return FiniteDifferenceComputer + elif self == "manybody": + from .driver_nbody import ManyBodyComputer + return ManyBodyComputer diff --git a/psi4/driver/task_planner.py b/psi4/driver/task_planner.py index c1a2560236e..e92e98c0502 100644 --- a/psi4/driver/task_planner.py +++ b/psi4/driver/task_planner.py @@ -227,7 +227,7 @@ def task_planner(driver: DriverEnum, method: str, molecule: core.Molecule, **kwa **packet, mc_level_idx=mc_level_idx, findif_mode=dermode, - computer=CompositeComputer, + computer="composite", **cbsmeta, **current_findif_kwargs, **kwargs) @@ -272,7 +272,7 @@ def task_planner(driver: DriverEnum, method: str, molecule: core.Molecule, **kwa f'PLANNING FD(CBS): dermode={dermode} packet={packet} findif_kw={current_findif_kwargs} kw={kwargs}') plan = FiniteDifferenceComputer(**packet, findif_mode=dermode, - computer=CompositeComputer, + computer="composite", **current_findif_kwargs, **kwargs) return plan @@ -283,12 +283,12 @@ def task_planner(driver: DriverEnum, method: str, molecule: core.Molecule, **kwa convcrit = negotiate_convergence_criterion(dermode, method, return_optstash=False) if dermode[0] == dermode[1]: # analytic - logger.info(f'PLANNING Atomic: keywords={keywords}') + logger.info(f'PLANNING Atomic: {packet=} {keywords=} {kwargs=}') return AtomicComputer(**packet, **kwargs) else: keywords.update(convcrit) logger.info( - f'PLANNING FD: dermode={dermode} keywords={keywords} findif_kw={current_findif_kwargs} kw={kwargs}') + f'PLANNING FD: findif_mode={dermode} {packet=} {keywords=} {current_findif_kwargs=} {kwargs=}') return FiniteDifferenceComputer(**packet, findif_mode=dermode, **current_findif_kwargs, diff --git a/tests/pytests/test_qcfractal.py b/tests/pytests/test_qcfractal.py index 14bd41df0a3..f2a25a4868e 100644 --- a/tests/pytests/test_qcfractal.py +++ b/tests/pytests/test_qcfractal.py @@ -2,23 +2,26 @@ import pytest from utils import * -from addons import uusing +from addons import using import psi4 pytestmark = [pytest.mark.psi, pytest.mark.api] -@uusing("qcfractal") -@uusing("qcportal") @pytest.mark.cbs +@pytest.mark.nbody @pytest.mark.smoke @pytest.mark.quick +@pytest.mark.parametrize("dertype", [ + pytest.param(1, id="analytic"), + pytest.param(0, id="findif", marks=pytest.mark.findif), +]) @pytest.mark.parametrize("distributed", [ pytest.param(False, id="internal"), - pytest.param(True, id="snowflake"), + pytest.param(True, id="snowflake", marks=[*using("qcfractal"), *using("qcportal")]), ]) -def test_qcf_cbs_mbe(distributed, snowflake): +def test_qcf_cbs_mbe(distributed, snowflake, dertype): import psi4 dimer = psi4.geometry(""" @@ -38,16 +41,16 @@ def test_qcf_cbs_mbe(distributed, snowflake): if distributed: client = snowflake.client() - plan = psi4.gradient("HF/cc-pV[D,T]Z", bsse_type="CP", return_plan=True, return_total_data=True) + plan = psi4.gradient("HF/cc-pV[D,T]Z", bsse_type="CP", return_plan=True, return_total_data=True, dertype=dertype) plan.compute(client) snowflake.await_results() grad = plan.get_psi_results(client) else: - grad = psi4.gradient("HF/cc-pV[D,T]Z", bsse_type="CP", return_total_data=True) + grad = psi4.gradient("HF/cc-pV[D,T]Z", bsse_type="CP", return_total_data=True, dertype=dertype) assert compare_values(ref_ene, psi4.variable("CURRENT ENERGY")) - assert compare_values(ref_grad, grad, atol=1.e-7) + assert compare_values(ref_grad, grad, atol=1.e-7) # checks one sig fig if distributed: # `get_results` is a closer-to-internals alternative to `get_psi_results`. From 22143c1951cce2d0ca914b8930cdbcb17dab5194 Mon Sep 17 00:00:00 2001 From: "Lori A. Burns" Date: Fri, 18 Aug 2023 14:22:08 -0400 Subject: [PATCH 3/3] dict to model_dump and json to model_dump_json --- psi4/driver/driver.py | 12 ++++----- psi4/driver/driver_cbs.py | 6 ++--- psi4/driver/driver_findif.py | 4 +-- psi4/driver/driver_nbody.py | 4 +-- psi4/driver/qcdb/cfour.py | 2 +- psi4/driver/qcdb/molecule.py | 6 ++--- psi4/driver/schema_wrapper.py | 10 ++++---- psi4/driver/task_base.py | 6 ++--- tests/json/schema-1-energy/input.py | 4 +-- tests/json/schema-1-properties/input.py | 2 +- tests/json/schema-1-response/input.py | 2 +- tests/pytests/test_addons.py | 4 +-- tests/pytests/test_addons_qcschema.py | 34 ++++++++++++------------- tests/pytests/test_psi4_qcschema.py | 2 +- tests/pytests/test_qcng_dftd3_mp2d.py | 8 +++--- tests/pytests/test_qcschema.py | 2 +- 16 files changed, 54 insertions(+), 54 deletions(-) diff --git a/psi4/driver/driver.py b/psi4/driver/driver.py index d9289bdf655..f79c9c9c70a 100644 --- a/psi4/driver/driver.py +++ b/psi4/driver/driver.py @@ -446,7 +446,7 @@ def energy(name, **kwargs): # Are we planning? plan = task_planner.task_planner("energy", lowername, molecule, **kwargs) logger.debug('ENERGY PLAN') - logger.debug(pp.pformat(plan.dict())) + logger.debug(pp.pformat(plan.model_dump())) if kwargs.get("return_plan", False): # Plan-only requested @@ -595,7 +595,7 @@ def gradient(name, **kwargs): # Are we planning? plan = task_planner.task_planner("gradient", lowername, molecule, **kwargs) logger.debug('GRADIENT PLAN') - logger.debug(pp.pformat(plan.dict())) + logger.debug(pp.pformat(plan.model_dump())) if kwargs.get("return_plan", False): # Plan-only requested @@ -754,7 +754,7 @@ def properties(*args, **kwargs): # Are we planning? plan = task_planner.task_planner("properties", lowername, molecule, **kwargs) logger.debug('PROPERTIES PLAN') - logger.debug(pp.pformat(plan.dict())) + logger.debug(pp.pformat(plan.model_dump())) if kwargs.get("return_plan", False): # Plan-only requested @@ -1414,7 +1414,7 @@ def hessian(name, **kwargs): # Are we planning? plan = task_planner.task_planner("hessian", lowername, molecule, **kwargs) logger.debug('HESSIAN PLAN') - logger.debug(pp.pformat(plan.dict())) + logger.debug(pp.pformat(plan.model_dump())) if kwargs.get("return_plan", False): # Plan-only requested @@ -1690,7 +1690,7 @@ def vibanal_wfn( dipder=dipder, project_trans=project_trans, project_rot=project_rot) - vibrec.update({k: qca.json() for k, qca in vibinfo.items()}) + vibrec.update({k: qca.model_dump_json() for k, qca in vibinfo.items()}) core.print_out(vibtext) core.print_out(qcdb.vib.print_vibs(vibinfo, shortlong=True, normco='x', atom_lbl=symbols)) @@ -1711,7 +1711,7 @@ def vibanal_wfn( rotor_type=mol.rotor_type(), rot_const=np.asarray(mol.rotational_constants()), E0=core.variable('CURRENT ENERGY')) # someday, wfn.energy() - vibrec.update({k: qca.json() for k, qca in therminfo.items()}) + vibrec.update({k: qca.model_dump_json() for k, qca in therminfo.items()}) core.set_variable("ZPVE", therminfo['ZPE_corr'].data) # P::e THERMO core.set_variable("THERMAL ENERGY CORRECTION", therminfo['E_corr'].data) # P::e THERMO diff --git a/psi4/driver/driver_cbs.py b/psi4/driver/driver_cbs.py index 4e17e075bb7..bed60963a53 100644 --- a/psi4/driver/driver_cbs.py +++ b/psi4/driver/driver_cbs.py @@ -1589,7 +1589,7 @@ def __init__(self, **data): }) self.task_list.append(task) - # logger.debug("TASK\n" + pp.pformat(task.dict())) + # logger.debug("TASK\n" + pp.pformat(task.model_dump())) def build_tasks(self, obj, **kwargs): # permanently a dummy function @@ -1747,7 +1747,7 @@ def get_results(self, client: Optional["qcportal.FractalClient"] = None) -> Atom 'success': True, }) - logger.debug('CBS QCSchema:\n' + pp.pformat(cbs_model.dict())) + logger.debug('CBS QCSchema:\n' + pp.pformat(cbs_model.model_dump())) return cbs_model @@ -1796,7 +1796,7 @@ def get_psi_results( def _cbs_schema_to_wfn(cbs_model): """Helper function to produce Wavefunction from a Composite-flavored AtomicResult.""" - mol = core.Molecule.from_schema(cbs_model.molecule.dict()) + mol = core.Molecule.from_schema(cbs_model.molecule.model_dump()) basis = core.BasisSet.build(mol, "ORBITAL", 'def2-svp', quiet=True) wfn = core.Wavefunction(mol, basis) if hasattr(cbs_model.provenance, "module"): diff --git a/psi4/driver/driver_findif.py b/psi4/driver/driver_findif.py index 45237e40e90..77a36c18072 100644 --- a/psi4/driver/driver_findif.py +++ b/psi4/driver/driver_findif.py @@ -1473,7 +1473,7 @@ def get_results(self, client: Optional["qcportal.FractalClient"] = None) -> Atom 'success': True, }) - logger.debug('\nFINDIF QCSchema:\n' + pp.pformat(findif_model.dict())) + logger.debug('\nFINDIF QCSchema:\n' + pp.pformat(findif_model.model_dump())) return findif_model @@ -1523,7 +1523,7 @@ def _findif_schema_to_wfn(findif_model: AtomicResult) -> core.Wavefunction: """Helper function to produce Wavefunction and Psi4 files from a FiniteDifference-flavored AtomicResult.""" # new skeleton wavefunction w/mol, highest-SCF basis (just to choose one), & not energy - mol = core.Molecule.from_schema(findif_model.molecule.dict(), nonphysical=True) + mol = core.Molecule.from_schema(findif_model.molecule.model_dump(), nonphysical=True) sbasis = "def2-svp" if (findif_model.model.basis == "(auto)") else findif_model.model.basis basis = core.BasisSet.build(mol, "ORBITAL", sbasis, quiet=True) wfn = core.Wavefunction(mol, basis) diff --git a/psi4/driver/driver_nbody.py b/psi4/driver/driver_nbody.py index fb0fdc8bd67..b1c1b2eb539 100644 --- a/psi4/driver/driver_nbody.py +++ b/psi4/driver/driver_nbody.py @@ -1399,7 +1399,7 @@ def get_results(self, client: Optional["qcportal.FractalClient"] = None) -> Atom properties["return_gradient"] = ret_gradient properties["return_hessian"] = ret_ptype - component_results = self.dict()['task_list'] + component_results = self.model_dump()['task_list'] for k, val in component_results.items(): val['molecule'] = val['molecule'].to_schema(dtype=2) @@ -1421,7 +1421,7 @@ def get_results(self, client: Optional["qcportal.FractalClient"] = None) -> Atom 'success': True, }) - logger.debug('\nNBODY QCSchema:\n' + pp.pformat(nbody_model.dict())) + logger.debug('\nNBODY QCSchema:\n' + pp.pformat(nbody_model.model_dump())) return nbody_model diff --git a/psi4/driver/qcdb/cfour.py b/psi4/driver/qcdb/cfour.py index 0df1a502ac8..f240085b73b 100644 --- a/psi4/driver/qcdb/cfour.py +++ b/psi4/driver/qcdb/cfour.py @@ -61,7 +61,7 @@ def harvest_output(outtext): if "Final ZMATnew file" in outpass: continue psivar, qcskcoord, c4grad, version, module, error = qcng.programs.cfour.harvester.harvest_outfile_pass(outpass) - c4coord = Molecule.from_schema(qcskcoord.dict()) + c4coord = Molecule.from_schema(qcskcoord.model_dump()) pass_psivar.append(psivar) pass_coord.append(c4coord) diff --git a/psi4/driver/qcdb/molecule.py b/psi4/driver/qcdb/molecule.py index f526eb4fc5c..b3315df6086 100644 --- a/psi4/driver/qcdb/molecule.py +++ b/psi4/driver/qcdb/molecule.py @@ -1313,7 +1313,7 @@ def run_dftd3(self, func: Optional[str] = None, dashlvl: Optional[str] = None, d if dashparam: resinp['keywords']['params_tweaks'] = dashparam jobrec = qcng.compute(resinp, 'dftd3', raise_error=True) - jobrec = jobrec.dict() + jobrec = jobrec.model_dump() # hack as not checking type GRAD for k, qca in jobrec['extras']['qcvars'].items(): @@ -1403,7 +1403,7 @@ def run_dftd4(self, func: Optional[str] = None, dashlvl: Optional[str] = None, d resinp['keywords']['params_tweaks'] = dashparam jobrec = qcng.compute(resinp, 'dftd4', raise_error=True) - jobrec = jobrec.dict() + jobrec = jobrec.model_dump() # hack as not checking type GRAD for k, qca in jobrec['extras']['qcvars'].items(): @@ -1487,7 +1487,7 @@ def run_gcp(self, func: Optional[str] = None, dertype: Union[int, str, None] = N except qcng.exceptions.ResourceError: jobrec = qcng.compute(resinp, 'gcp', raise_error=True) - jobrec = jobrec.dict() + jobrec = jobrec.model_dump() # hack (instead of checking dertype GRAD) to collect `(nat, 3)` ndarray of gradient if present for variable_name, qcv in jobrec['extras']['qcvars'].items(): diff --git a/psi4/driver/schema_wrapper.py b/psi4/driver/schema_wrapper.py index 1a497065838..99dc4f215ea 100644 --- a/psi4/driver/schema_wrapper.py +++ b/psi4/driver/schema_wrapper.py @@ -257,7 +257,7 @@ def _convert_basis(basis): centers.append(qcel.models.basis.BasisCenter(electron_shells=center_shells)) # Take unique to prevent duplicate data, doesn't matter too much - hashes = [hash(json.dumps(centers[x].dict(), sort_keys=True)) for x in range(len(centers))] + hashes = [hash(json.dumps(centers[x].model_dump(), sort_keys=True)) for x in range(len(centers))] uniques = {k: v for k, v in zip(hashes, centers)} name_map = {} @@ -451,19 +451,19 @@ def run_qcschema( # Echo the infile on the outfile core.print_out("\n ==> Input QCSchema <==\n") core.print_out("\n--------------------------------------------------------------------------\n") - core.print_out(pp.pformat(json.loads(input_model.json()))) + core.print_out(pp.pformat(json.loads(input_model.model_dump_json()))) core.print_out("\n--------------------------------------------------------------------------\n") keep_wfn = input_model.protocols.wavefunction != 'none' # qcschema should be copied - ret_data = run_json_qcschema(input_model.dict(), clean, False, keep_wfn=keep_wfn) + ret_data = run_json_qcschema(input_model.model_dump(), clean, False, keep_wfn=keep_wfn) ret_data["provenance"].update({ "creator": "Psi4", "version": __version__, "routine": "psi4.schema_runner.run_qcschema" }) - ret_data["native_files"]["input"] = json.dumps(json.loads(input_model.json()), indent=1) + ret_data["native_files"]["input"] = json.dumps(json.loads(input_model.model_dump_json()), indent=1) exit_printing(start_time=start_time, success=True) @@ -472,7 +472,7 @@ def run_qcschema( except Exception as exc: if not isinstance(input_data, dict): - input_data = input_data.dict() + input_data = input_data.model_dump() input_data = input_data.copy() input_data["stdout"] = _read_output(outfile) diff --git a/psi4/driver/task_base.py b/psi4/driver/task_base.py index e0bc245a138..75d74d807b6 100644 --- a/psi4/driver/task_base.py +++ b/psi4/driver/task_base.py @@ -216,12 +216,12 @@ def compute(self, client: Optional["qcportal.client.FractalClient"] = None): ) # ... END - #pp.pprint(self.result.dict()) + #pp.pprint(self.result.model_dump()) #print("... JSON returns >>>") core.set_output_file(gof, True) core.reopen_outfile() - logger.debug(pp.pformat(self.result.dict())) - core.print_out(_drink_filter(self.result.dict()["stdout"])) + logger.debug(pp.pformat(self.result.model_dump())) + core.print_out(_drink_filter(self.result.model_dump()["stdout"])) self.computed = True def get_results(self, client: Optional["qcportal.FractalClient"] = None) -> AtomicResult: diff --git a/tests/json/schema-1-energy/input.py b/tests/json/schema-1-energy/input.py index c7db4409736..ead2b680c58 100644 --- a/tests/json/schema-1-energy/input.py +++ b/tests/json/schema-1-energy/input.py @@ -126,9 +126,9 @@ json_data["extras"] = {"current_qcvars_only": True} json_ret = psi4.schema_wrapper.run_qcschema(json_data) -#print(json.dumps(json_ret.json(), indent=2)) +#print(json.dumps(json_ret.model_dump_json(), indent=2)) #import pprint -#pprint.pprint(json_ret.dict(), width=200) +#pprint.pprint(json_ret.model_dump(), width=200) psi4.compare_integers(True, json_ret.success, "JSON Success") #TEST psi4.compare_values(expected_return_result, json_ret.return_result, 5, "Return Value") #TEST diff --git a/tests/json/schema-1-properties/input.py b/tests/json/schema-1-properties/input.py index 235b25eef0a..8fc0724f32c 100644 --- a/tests/json/schema-1-properties/input.py +++ b/tests/json/schema-1-properties/input.py @@ -145,7 +145,7 @@ expected_return_result["wiberg_lowdin_indices"] = np.array(expected_return_result["wiberg_lowdin_indices"]).reshape((3, 3)) expected_return_result["mayer_indices"] = np.array(expected_return_result["mayer_indices"]).reshape((3, 3)) -json_ret = psi4.schema_wrapper.run_qcschema(json_data).dict() +json_ret = psi4.schema_wrapper.run_qcschema(json_data).model_dump() # formerly .dict(), but both still work # can't write msgpack arrays to json diff --git a/tests/json/schema-1-response/input.py b/tests/json/schema-1-response/input.py index 400adb86ab3..af9edfc3f5f 100644 --- a/tests/json/schema-1-response/input.py +++ b/tests/json/schema-1-response/input.py @@ -298,7 +298,7 @@ expected_response = {k: (np.asarray(v) if isinstance(v, list) else v) for k, v in expected_response.items()} -json_ret = psi4.schema_wrapper.run_qcschema(json_data).dict() +json_ret = psi4.schema_wrapper.run_qcschema(json_data).dict() # .model_dump() now, but .dict() still works psi4.compare_integers(True, json_ret["success"], "JSON Success") #TEST psi4.compare_strings("qcschema_output", json_ret["schema_name"], "Schema Name") #TEST diff --git a/tests/pytests/test_addons.py b/tests/pytests/test_addons.py index 8b0080a0dc9..ca2e8e7d06c 100644 --- a/tests/pytests/test_addons.py +++ b/tests/pytests/test_addons.py @@ -262,7 +262,7 @@ def test_mp2d(): 'keywords': {}, } jrec = qcng.compute(resinp, 'mp2d', raise_error=True) - jrec = jrec.dict() + jrec = jrec.dict() # .model_dump() preferred assert psi4.compare_values(expected, jrec['extras']['qcvars']['CURRENT ENERGY'], 7, 'E') assert psi4.compare_values(expected, jrec['extras']['qcvars']['DISPERSION CORRECTION ENERGY'], 7, 'disp E') @@ -878,7 +878,7 @@ def test_run_qcschema(): } json_ret = psi4.json_wrapper.run_qcschema(json_input) - print(json_ret.dict()) + print(json_ret.model_dump()) assert psi4.compare(True, json_ret.success, "Success") assert psi4.compare_values(-5.474227786274896, json_ret.properties.return_energy, 4, "SCF ENERGY") diff --git a/tests/pytests/test_addons_qcschema.py b/tests/pytests/test_addons_qcschema.py index f09fb1a1e04..0e4b679bd3c 100644 --- a/tests/pytests/test_addons_qcschema.py +++ b/tests/pytests/test_addons_qcschema.py @@ -17,7 +17,7 @@ # assert 0 # * switch to json running # atres = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) -# pprint.pprint(atres.dict()) +# pprint.pprint(atres.model_dump()) pytestmark = [pytest.mark.psi, pytest.mark.api, pytest.mark.quick, pytest.mark.smoke] @@ -114,7 +114,7 @@ def test_ipi_broker1(): ## assert 0 ## ## atres = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) -## pprint.pprint(atres.dict()) +## pprint.pprint(atres.model_dump()) # # # assert psi4.compare_values(refnuc, water.nuclear_repulsion_energy(), 3, "Nuclear repulsion energy") @@ -140,7 +140,7 @@ def test_ipi_broker1(): ## assert 0 ## ## atres = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) -## pprint.pprint(atres.dict()) +## pprint.pprint(atres.model_dump()) # # # assert psi4.compare_values(refnuc, water_mirror.nuclear_repulsion_energy(), 3, "Nuclear repulsion energy") @@ -172,7 +172,7 @@ def test_ipi_broker1(): ## assert 0 ## ## atres = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) -## pprint.pprint(atres.dict()) +## pprint.pprint(atres.model_dump()) # # # assert psi4.compare_values( 8.801465529972, psi4.variable("NUCLEAR REPULSION ENERGY"), 6, 'NRE') @@ -274,7 +274,7 @@ def test_libefp(): ## atres = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) -## pprint.pprint(atres.dict()) +## pprint.pprint(atres.model_dump()) # # # assert psi4.compare_values( 9.1793879214, qmefp.nuclear_repulsion_energy(), 6, 'QM NRE') @@ -342,7 +342,7 @@ def test_pcmsolver(): jatin = """{"id": null, "schema_name": "qcschema_input", "schema_version": 1, "molecule": {"schema_name": "qcschema_molecule", "schema_version": 2, "validated": true, "symbols": ["N", "H", "H", "H"], "geometry": [-1e-10, -0.1040380466, 0.0, -0.9015844116, 0.4818470201, -1.5615900098, -0.9015844116, 0.4818470201, 1.5615900098, 1.8031688251, 0.4818470204, 0.0], "name": "H3N", "molecular_charge": 0.0, "molecular_multiplicity": 1, "masses": [14.00307400443, 1.00782503223, 1.00782503223, 1.00782503223], "real": [true, true, true, true], "atom_labels": ["", "", "", ""], "atomic_numbers": [7, 1, 1, 1], "mass_numbers": [14, 1, 1, 1], "fragments": [[0, 1, 2, 3]], "fragment_charges": [0.0], "fragment_multiplicities": [1], "fix_com": false, "fix_orientation": false, "fix_symmetry": "c1", "provenance": {"creator": "QCElemental", "version": "v0.17.0+7.gf55d5ac.dirty", "routine": "qcelemental.molparse.from_string"}}, "driver": "energy", "model": {"method": "scf", "basis": "STO-3G"}, "keywords": {"pcm": 1, "pcm__input": "\\n Units = Angstrom\\n Medium {\\n SolverType = IEFPCM\\n Solvent = Water\\n }\\n \\n Cavity {\\n RadiiSet = UFF\\n Type = GePol\\n Scaling = False\\n Area = 0.3\\n Mode = Implicit\\n }\\n ", "pcm_scf_type": "TOTAL", "scf_type": "PK"}, "protocols": {}, "extras": {"wfn_qcvars_only": true}, "provenance": {"creator": "Psi4", "version": "1.4a2.dev1089", "routine": "psi4.driver.p4util.procutil"}}""" atres1 = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) - pprint.pprint(atres1.dict()) + pprint.pprint(atres1.model_dump()) assert psi4.compare_values(nucenergy, atres1.properties.nuclear_repulsion_energy, 10, "Nuclear repulsion energy (PCM, total algorithm)") assert psi4.compare_values(totalenergy, atres1.return_result, 10, "Total energy (PCM, total algorithm)") @@ -352,7 +352,7 @@ def test_pcmsolver(): jatin = """{"id": null, "schema_name": "qcschema_input", "schema_version": 1, "molecule": {"schema_name": "qcschema_molecule", "schema_version": 2, "validated": true, "symbols": ["N", "H", "H", "H"], "geometry": [-1e-10, -0.1040380466, 0.0, -0.9015844116, 0.4818470201, -1.5615900098, -0.9015844116, 0.4818470201, 1.5615900098, 1.8031688251, 0.4818470204, 0.0], "name": "H3N", "molecular_charge": 0.0, "molecular_multiplicity": 1, "masses": [14.00307400443, 1.00782503223, 1.00782503223, 1.00782503223], "real": [true, true, true, true], "atom_labels": ["", "", "", ""], "atomic_numbers": [7, 1, 1, 1], "mass_numbers": [14, 1, 1, 1], "fragments": [[0, 1, 2, 3]], "fragment_charges": [0.0], "fragment_multiplicities": [1], "fix_com": false, "fix_orientation": false, "fix_symmetry": "c1", "provenance": {"creator": "QCElemental", "version": "v0.17.0+7.gf55d5ac.dirty", "routine": "qcelemental.molparse.from_string"}}, "driver": "energy", "model": {"method": "scf", "basis": "STO-3G"}, "keywords": {"pcm": 1, "pcm__input": "\\n Units = Angstrom\\n Medium {\\n SolverType = IEFPCM\\n Solvent = Water\\n }\\n \\n Cavity {\\n RadiiSet = UFF\\n Type = GePol\\n Scaling = False\\n Area = 0.3\\n Mode = Implicit\\n }\\n ", "pcm_scf_type": "SEPARATE", "scf_type": "PK"}, "protocols": {}, "extras": {"wfn_qcvars_only": true}, "provenance": {"creator": "Psi4", "version": "1.4a2.dev1089", "routine": "psi4.driver.p4util.procutil"}}""" atres2 = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) - pprint.pprint(atres2.dict()) + pprint.pprint(atres2.model_dump()) assert psi4.compare_values(totalenergy, atres2.return_result, 10, "Total energy (PCM, separate algorithm)") assert psi4.compare_values(polenergy, atres2.extras["qcvars"]["PCM POLARIZATION ENERGY"], 6, "Polarization energy (PCM, separate algorithm)") @@ -360,7 +360,7 @@ def test_pcmsolver(): jatin = """{"id": null, "schema_name": "qcschema_input", "schema_version": 1, "molecule": {"schema_name": "qcschema_molecule", "schema_version": 2, "validated": true, "symbols": ["N", "H", "H", "H"], "geometry": [-1e-10, -0.1040380466, 0.0, -0.9015844116, 0.4818470201, -1.5615900098, -0.9015844116, 0.4818470201, 1.5615900098, 1.8031688251, 0.4818470204, 0.0], "name": "H3N", "molecular_charge": 0.0, "molecular_multiplicity": 1, "masses": [14.00307400443, 1.00782503223, 1.00782503223, 1.00782503223], "real": [true, true, true, true], "atom_labels": ["", "", "", ""], "atomic_numbers": [7, 1, 1, 1], "mass_numbers": [14, 1, 1, 1], "fragments": [[0, 1, 2, 3]], "fragment_charges": [0.0], "fragment_multiplicities": [1], "fix_com": false, "fix_orientation": false, "fix_symmetry": "c1", "provenance": {"creator": "QCElemental", "version": "v0.17.0+7.gf55d5ac.dirty", "routine": "qcelemental.molparse.from_string"}}, "driver": "energy", "model": {"method": "scf", "basis": "STO-3G"}, "keywords": {"pcm": 1, "pcm__input": "\\n Units = Angstrom\\n Medium {\\n SolverType = IEFPCM\\n Solvent = Water\\n }\\n \\n Cavity {\\n RadiiSet = UFF\\n Type = GePol\\n Scaling = False\\n Area = 0.3\\n Mode = Implicit\\n }\\n ", "pcm_scf_type": "TOTAL", "scf_type": "PK", "reference": "uhf"}, "protocols": {}, "extras": {"wfn_qcvars_only": true}, "provenance": {"creator": "Psi4", "version": "1.4a2.dev1089", "routine": "psi4.driver.p4util.procutil"}}""" atres3 = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) - pprint.pprint(atres3.dict()) + pprint.pprint(atres3.model_dump()) assert psi4.compare_values(totalenergy, atres3.return_result, 10, "Total energy (PCM, separate algorithm)") assert psi4.compare_values(polenergy, atres3.extras["qcvars"]["PCM POLARIZATION ENERGY"], 6, "Polarization energy (PCM, separate algorithm)") @@ -368,7 +368,7 @@ def test_pcmsolver(): jatin = """{"id": null, "schema_name": "qcschema_input", "schema_version": 1, "molecule": {"schema_name": "qcschema_molecule", "schema_version": 2, "validated": true, "symbols": ["N", "H", "H", "H"], "geometry": [-1e-10, -0.1040380466, 0.0, -0.9015844116, 0.4818470201, -1.5615900098, -0.9015844116, 0.4818470201, 1.5615900098, 1.8031688251, 0.4818470204, 0.0], "name": "H3N", "molecular_charge": 0.0, "molecular_multiplicity": 1, "masses": [14.00307400443, 1.00782503223, 1.00782503223, 1.00782503223], "real": [true, true, true, true], "atom_labels": ["", "", "", ""], "atomic_numbers": [7, 1, 1, 1], "mass_numbers": [14, 1, 1, 1], "fragments": [[0, 1, 2, 3]], "fragment_charges": [0.0], "fragment_multiplicities": [1], "fix_com": false, "fix_orientation": false, "fix_symmetry": "c1", "provenance": {"creator": "QCElemental", "version": "v0.17.0+7.gf55d5ac.dirty", "routine": "qcelemental.molparse.from_string"}}, "driver": "energy", "model": {"method": "scf", "basis": "STO-3G"}, "keywords": {"pcm": 1, "pcm__input": "\\n Units = Angstrom\\n Medium {\\n SolverType = IEFPCM\\n Solvent = Water\\n }\\n \\n Cavity {\\n RadiiSet = UFF\\n Type = GePol\\n Scaling = False\\n Area = 0.3\\n Mode = Implicit\\n }\\n ", "pcm_scf_type": "TOTAL", "scf_type": "PK", "reference": "rohf"}, "protocols": {}, "extras": {"wfn_qcvars_only": true}, "provenance": {"creator": "Psi4", "version": "1.4a2.dev1089", "routine": "psi4.driver.p4util.procutil"}}""" atres4 = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) - pprint.pprint(atres4.dict()) + pprint.pprint(atres4.model_dump()) assert psi4.compare_values(totalenergy, atres4.return_result, 10, "Total energy (PCM, separate algorithm)") assert psi4.compare_values(polenergy, atres4.extras["qcvars"]["PCM POLARIZATION ENERGY"], 6, "Polarization energy (PCM, separate algorithm)") @@ -433,7 +433,7 @@ def test_json(): } json_ret = psi4.schema_wrapper.run_qcschema(json_input) - json_ret = json_ret.dict() + json_ret = json_ret.model_dump() pprint.pprint(json_ret) assert psi4.compare_integers(True, json_ret["success"], "Success") @@ -475,7 +475,7 @@ def test_json(): ## assert 0 ## ## atres = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) -## pprint.pprint(atres.dict()) +## pprint.pprint(atres.model_dump()) # # # assert psi4.compare_values(-76.062748460117, psi4.variable('scf total energy'), 6, 'SCF') @@ -506,7 +506,7 @@ def test_v2rdm_casscf(): jatin = """{"id": null, "schema_name": "qcschema_input", "schema_version": 1, "molecule": {"schema_name": "qcschema_molecule", "schema_version": 2, "validated": true, "symbols": ["N", "N"], "geometry": [0.0, 0.0, -0.4724315332214108, 0.0, 0.0, 0.4724315332214108], "name": "N2", "molecular_charge": 0.0, "molecular_multiplicity": 1, "masses": [14.00307400443, 14.00307400443], "real": [true, true], "atom_labels": ["", ""], "atomic_numbers": [7, 7], "mass_numbers": [14, 14], "fragments": [[0, 1]], "fragment_charges": [0.0], "fragment_multiplicities": [1], "fix_com": false, "fix_orientation": false, "provenance": {"creator": "QCElemental", "version": "v0.17.0+7.gf55d5ac.dirty", "routine": "qcelemental.molparse.from_string"}}, "driver": "energy", "model": {"method": "v2rdm-casscf", "basis": "CC-PVDZ"}, "keywords": {"active": [1, 0, 1, 1, 0, 1, 1, 1], "cholesky_tolerance": 1e-12, "d_convergence": 1e-10, "maxiter": 500, "restricted_docc": [2, 0, 0, 0, 0, 2, 0, 0], "scf_type": "CD", "v2rdm_casscf__r_convergence": 1e-5, "v2rdm_casscf__e_convergence": 1e-6, "v2rdm_casscf__maxiter": 20000}, "protocols": {}, "extras": {"wfn_qcvars_only": true}, "provenance": {"creator": "Psi4", "version": "1.4a2.dev1089", "routine": "psi4.driver.p4util.procutil"}}""" atres = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) - pprint.pprint(atres.dict()) + pprint.pprint(atres.model_dump()) assert psi4.compare_values(-103.04337420425350, atres.extras["qcvars"]["SCF TOTAL ENERGY"], 8, "SCF total energy") assert psi4.compare_values(-103.086205379481, atres.return_result, 5, "v2RDM-CASSCF total energy") @@ -549,14 +549,14 @@ def test_v2rdm_casscf(): ## assert 0 ## ## atres = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) -## pprint.pprint(atres.dict()) +## pprint.pprint(atres.model_dump()) # ## atin = psi4.driver.p4util.state_to_atomicinput(driver="energy", method="ccsd", molecule=ethene_ethyne) ## print(f' jatin = """{atin.serialize("json")}"""') ## assert 0 ## ## atres = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) -## pprint.pprint(atres.dict()) +## pprint.pprint(atres.model_dump()) # # # assert psi4.compare_values(en_gpu_dfcc, en_dfcc, 8, "CCSD total energy") @@ -653,7 +653,7 @@ def test_dkh(): ## assert 0 ## ## atres = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) -## pprint.pprint(atres.dict()) +## pprint.pprint(atres.model_dump()) # # # scf = psi4.energy('scf') @@ -674,7 +674,7 @@ def test_snsmp2(): jatin = """{"id": null, "schema_name": "qcschema_input", "schema_version": 1, "molecule": {"schema_name": "qcschema_molecule", "schema_version": 2, "validated": true, "symbols": ["He", "He"], "geometry": [-1.8897261254578286, -2.892808813508824e-17, 0.0, 1.8897261254578286, 2.892808813508824e-17, 0.0], "name": "He2", "molecular_charge": 0.0, "molecular_multiplicity": 1, "masses": [4.00260325413, 4.00260325413], "real": [true, true], "atom_labels": ["", ""], "atomic_numbers": [2, 2], "mass_numbers": [4, 4], "fragments": [[0], [1]], "fragment_charges": [0.0, 0.0], "fragment_multiplicities": [1, 1], "fix_com": false, "fix_orientation": false, "provenance": {"creator": "QCElemental", "version": "v0.17.0+7.gf55d5ac.dirty", "routine": "qcelemental.molparse.from_string"}}, "driver": "energy", "model": {"method": "sns-mp2", "basis": "(auto)"}, "keywords": {}, "protocols": {}, "extras": {"wfn_qcvars_only": true}, "provenance": {"creator": "Psi4", "version": "1.4a2.dev1089", "routine": "psi4.driver.p4util.procutil"}}""" atres = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) - pprint.pprint(atres.dict()) + pprint.pprint(atres.model_dump()) assert psi4.compare_values(0.00176708227, atres.return_result, 5, "SNS-MP2 IE [Eh]") @@ -797,7 +797,7 @@ def test_cppe(): ## assert 0 ## ## atres = psi4.schema_wrapper.run_qcschema(json.loads(jatin)) -## pprint.pprint(atres.dict()) +## pprint.pprint(atres.model_dump()) # # # ene = psi4.energy("cct3") diff --git a/tests/pytests/test_psi4_qcschema.py b/tests/pytests/test_psi4_qcschema.py index f5a845683a7..4eb3ad3a04b 100644 --- a/tests/pytests/test_psi4_qcschema.py +++ b/tests/pytests/test_psi4_qcschema.py @@ -16,7 +16,7 @@ # assert 0 # * switch to json running # atres = psi4.schema_wrapper.run_qcschema(jatin) -# pprint.pprint(atres.dict()) +# pprint.pprint(atres.model_dump()) @pytest.fixture diff --git a/tests/pytests/test_qcng_dftd3_mp2d.py b/tests/pytests/test_qcng_dftd3_mp2d.py index b50ca881485..6f45cf688f2 100644 --- a/tests/pytests/test_qcng_dftd3_mp2d.py +++ b/tests/pytests/test_qcng_dftd3_mp2d.py @@ -288,7 +288,7 @@ def test_3(): }, } res = qcng.compute(resinp, 'dftd3', raise_error=True) - res = res.dict() + res = res.model_dump() #res = dftd3.run_dftd3_from_arrays(molrec=sys, name_hint='b3lyp', level_hint='d3bj') assert compare('B3LYP-D3(BJ)', _compute_key(res['extras']['local_keywords']), 'key') @@ -390,7 +390,7 @@ def test_mp2d__run_mp2d__2body(inp, subjects, request): 'keywords': {}, } jrec = qcng.compute(resinp, 'mp2d', raise_error=True) - jrec = jrec.dict() + jrec = jrec.model_dump() #assert len(jrec['extras']['qcvars']) == 8 @@ -453,7 +453,7 @@ def test_dftd3__run_dftd3__2body(inp, program, subjects, request): 'keywords': keywords, } jrec = qcng.compute(resinp, program, raise_error=True) - jrec = jrec.dict() + jrec = jrec.model_dump() assert len(jrec['extras']['qcvars']) == (8 if program == "dftd3" else 6) @@ -510,7 +510,7 @@ def test_dftd3__run_dftd3__3body(inp, subjects, request): 'keywords': {}, } jrec = qcng.compute(resinp, 'dftd3', raise_error=True) - jrec = jrec.dict() + jrec = jrec.model_dump() assert len(jrec['extras']['qcvars']) == 8 diff --git a/tests/pytests/test_qcschema.py b/tests/pytests/test_qcschema.py index f2cd0867bb9..df69d682ef7 100644 --- a/tests/pytests/test_qcschema.py +++ b/tests/pytests/test_qcschema.py @@ -146,7 +146,7 @@ def test_qcschema_wavefunction_scf_orbitals(result_data_fixture): wfn = ret.wavefunction expected_keys = {'basis', 'restricted', 'scf_orbitals_a', 'scf_eigenvalues_a', 'orbitals_a', 'eigenvalues_a'} - assert wfn.dict().keys() == expected_keys + assert wfn.model_dump().keys() == expected_keys def test_qcschema_wavefunction_scf_occupations_gs(result_data_fixture): result_data_fixture["protocols"] = {"wavefunction": "all"}