-
Notifications
You must be signed in to change notification settings - Fork 70
/
common_models.py
145 lines (114 loc) · 5.43 KB
/
common_models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
from enum import Enum
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
import numpy as np
try:
from pydantic.v1 import Field
except ImportError: # Will also trap ModuleNotFoundError
from pydantic import Field
from .basemodels import ProtoModel, qcschema_draft
from .basis import BasisSet
if TYPE_CHECKING:
try:
from pydantic.v1.typing import ReprArgs
except ImportError: # Will also trap ModuleNotFoundError
from pydantic.typing import ReprArgs
# Encoders, to be deprecated
ndarray_encoder = {np.ndarray: lambda v: v.flatten().tolist()}
class Provenance(ProtoModel):
"""Provenance information."""
creator: str = Field(..., description="The name of the program, library, or person who created the object.")
version: str = Field(
"",
description="The version of the creator, blank otherwise. This should be sortable by the very broad `PEP 440 <https://www.python.org/dev/peps/pep-0440/>`_.",
)
routine: str = Field("", description="The name of the routine or function within the creator, blank otherwise.")
class Config(ProtoModel.Config):
canonical_repr = True
extra: str = "allow"
def schema_extra(schema, model):
schema["$schema"] = qcschema_draft
class Model(ProtoModel):
"""The computational molecular sciences model to run."""
method: str = Field( # type: ignore
...,
description="The quantum chemistry method to evaluate (e.g., B3LYP, PBE, ...). "
"For MM, name of the force field.",
)
basis: Optional[Union[str, BasisSet]] = Field( # type: ignore
None,
description="The quantum chemistry basis set to evaluate (e.g., 6-31g, cc-pVDZ, ...). Can be ``None`` for "
"methods without basis sets. For molecular mechanics, name of the atom-typer.",
)
# basis_spec: BasisSpec = None # This should be exclusive with basis, but for now will be omitted
class Config(ProtoModel.Config):
canonical_repr = True
extra: str = "allow"
class DriverEnum(str, Enum):
"""Allowed computation driver values."""
energy = "energy"
gradient = "gradient"
hessian = "hessian"
properties = "properties"
def derivative_int(self):
egh = ["energy", "gradient", "hessian", "third", "fourth", "fifth"]
if self == "properties":
return 0
else:
return egh.index(self)
class ComputeError(ProtoModel):
"""Complete description of the error from an unsuccessful program execution."""
error_type: str = Field( # type: ignore
..., # Error enumeration not yet strict
description="The type of error which was thrown. Restrict this field to short classifiers e.g. 'input_error'. Suggested classifiers: https://github.com/MolSSI/QCEngine/blob/master/qcengine/exceptions.py",
)
error_message: str = Field( # type: ignore
...,
description="Text associated with the thrown error. This is often the backtrace, but it can contain additional "
"information as well.",
)
extras: Optional[Dict[str, Any]] = Field( # type: ignore
None,
description="Additional information to bundle with the error.",
)
class Config:
repr_style = ["error_type", "error_message"]
def __repr_args__(self) -> "ReprArgs":
return [("error_type", self.error_type), ("error_message", self.error_message)]
class FailedOperation(ProtoModel):
"""Record indicating that a given operation (program, procedure, etc.) has failed and containing the reason and input data which generated the failure."""
id: str = Field( # type: ignore
None,
description="A unique identifier which links this FailedOperation, often of the same Id of the operation "
"should it have been successful. This will often be set programmatically by a database such as "
"Fractal.",
)
input_data: Any = Field( # type: ignore
None,
description="The input data which was passed in that generated this failure. This should be the complete "
"input which when attempted to be run, caused the operation to fail.",
)
success: bool = Field( # type: ignore
False,
description="A boolean indicator that the operation failed consistent with the model of successful operations. "
"Should always be False. Allows programmatic assessment of all operations regardless of if they failed or "
"succeeded",
)
error: ComputeError = Field( # type: ignore
...,
description="A container which has details of the error that failed this operation. See the "
":class:`ComputeError` for more details.",
)
extras: Optional[Dict[str, Any]] = Field( # type: ignore
None,
description="Additional information to bundle with the failed operation. Details which pertain specifically "
"to a thrown error should be contained in the `error` field. See :class:`ComputeError` for details.",
)
def __repr_args__(self) -> "ReprArgs":
return [("error", self.error)]
qcschema_input_default = "qcschema_input"
qcschema_output_default = "qcschema_output"
qcschema_optimization_input_default = "qcschema_optimization_input"
qcschema_optimization_output_default = "qcschema_optimization_output"
qcschema_torsion_drive_input_default = "qcschema_torsion_drive_input"
qcschema_torsion_drive_output_default = "qcschema_torsion_drive_output"
qcschema_molecule_default = "qcschema_molecule"