Skip to content

Mark schema fields with None default as Optional to pass pydantic v2 validation #651

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 6, 2024
Merged
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ ignore = [
"ANN102",
"ANN401",
"BLE001",
"C408", # Unnecessary (dict/list/tuple) call - remove call
"C901", # function too complex
"DTZ", # datetime-tz-now
"EM", # exception message must not use f-string literal
Expand Down
22 changes: 14 additions & 8 deletions src/atomate2/common/schemas/cclib.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,28 @@ class TaskDocument(MoleculeMetadata, extra="allow"): # type: ignore[call-arg]
For the list of supported packages, see https://cclib.github.io
"""

molecule: Molecule = Field(None, description="Final output molecule from the task")
energy: float = Field(None, description="Final total energy")
dir_name: str = Field(None, description="Directory where the output is parsed")
logfile: str = Field(
molecule: Optional[Molecule] = Field(
None, description="Final output molecule from the task"
)
energy: Optional[float] = Field(None, description="Final total energy")
dir_name: Optional[str] = Field(
None, description="Directory where the output is parsed"
)
logfile: Optional[str] = Field(
None, description="Path to the log file used in the post-processing analysis"
)
attributes: dict = Field(
attributes: Optional[dict] = Field(
None, description="Computed properties and calculation outputs"
)
metadata: dict = Field(
metadata: Optional[dict] = Field(
None,
description="Calculation metadata, including input parameters and runtime "
"statistics",
)
task_label: str = Field(None, description="A description of the task")
tags: list[str] = Field(None, description="Optional tags for this task document")
task_label: Optional[str] = Field(None, description="A description of the task")
tags: Optional[list[str]] = Field(
None, description="Optional tags for this task document"
)
last_updated: str = Field(
default_factory=datetime_str,
description="Timestamp for this task document was last updated",
Expand Down
45 changes: 22 additions & 23 deletions src/atomate2/common/schemas/defects.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,52 +22,52 @@ class FormationEnergyDiagramDocument(BaseModel):
will not necessarily have all the entries in the phase diagram computed.
"""

bulk_entry: ComputedStructureEntry = Field(
bulk_entry: Optional[ComputedStructureEntry] = Field(
None,
description="The ComputedEntry representing the bulk structure.",
)

defect_entries: list[DefectEntry] = Field(
defect_entries: Optional[list[DefectEntry]] = Field(
None,
description="The defect entries for the formation energy diagram.",
)

pd_entries: list[ComputedEntry] = Field(
pd_entries: Optional[list[ComputedEntry]] = Field(
None,
description="The entries used to construct the phase diagram.",
)

vbm: float = Field(
vbm: Optional[float] = Field(
None,
description="The VBM of the pristine supercell calculation.",
)

band_gap: float = Field(
band_gap: Optional[float] = Field(
None,
description="The band gap of the pristine supercell calculation.",
)

inc_inf_values: bool = Field(
inc_inf_values: Optional[bool] = Field(
None,
description="Whether or not to include infinite values in the diagram.",
)

defect: Defect = Field(
defect: Optional[Defect] = Field(
None,
description="The defect for which the diagram is being calculated.",
)

bulk_sc_dir: str = Field(
bulk_sc_dir: Optional[str] = Field(
None,
description="The directory name of the pristine supercell calculation.",
)

defect_sc_dirs: dict[int, str] = Field(
defect_sc_dirs: Optional[dict[int, str]] = Field(
None,
description="The directory names of the charged defect calculations.",
)

dielectric: Union[float, list[list[float]]] = Field(
dielectric: Optional[Union[float, list[list[float]]]] = Field(
None,
description="The dielectric constant or tensor, can be used to compute "
"finite-size corrections.",
Expand Down Expand Up @@ -125,42 +125,41 @@ def as_formation_energy_diagram(
class CCDDocument(BaseModel):
"""Configuration-coordinate definition of configuration-coordinate diagram."""

q1: int = Field(None, description="Charge state 1.")
q2: int = Field(None, description="Charge state 2.")
structure1: Structure = Field(
q1: Optional[int] = Field(None, description="Charge state 1.")
q2: Optional[int] = Field(None, description="Charge state 2.")
structure1: Optional[Structure] = Field(
None,
description="The structure of defect (supercell) in charge state (q2).",
)
structure2: Structure = Field(
structure2: Optional[Structure] = Field(
None,
description="The structure of defect (supercell) in charge state (q2).",
)

distortions1: list[float] = Field(
distortions1: Optional[list[float]] = Field(
None,
description="The distortions of the defect (supercell) in charge state (q1).",
)
distortions2: list[float] = Field(
distortions2: Optional[list[float]] = Field(
None,
description="The distortions of the defect (supercell) in charge state (q2).",
)

energies1: list[float] = Field(
energies1: Optional[list[float]] = Field(
None,
description="The energies of the defect (supercell) in charge state (q1).",
)
energies2: list[float] = Field(
energies2: Optional[list[float]] = Field(
None,
description="The energies of the defect (supercell) in charge state (q2).",
)

static_dirs1: list[str] = Field(
static_dirs1: Optional[list[str]] = Field(
None,
description="Directories of distorted calculations for the defect (supercell) "
"in charge state (q1).",
)

static_dirs2: list[str] = Field(
static_dirs2: Optional[list[str]] = Field(
None,
description="Directories of distorted calculations for the defect (supercell) "
"in charge state (q2).",
Expand All @@ -178,13 +177,13 @@ class CCDDocument(BaseModel):
"charge state (q2).",
)

relaxed_index1: int = Field(
relaxed_index1: Optional[int] = Field(
None,
description="The index of the static calculation in that corresponds to the "
"relaxed charge state (q1).",
)

relaxed_index2: int = Field(
relaxed_index2: Optional[int] = Field(
None,
description="The index of the static calculation in that corresponds to the "
"relaxed charge state (q2).",
Expand Down
75 changes: 44 additions & 31 deletions src/atomate2/common/schemas/elastic.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Schemas for elastic tensor fitting and related properties."""

from copy import deepcopy
from typing import Optional

Expand All @@ -24,51 +23,61 @@
class DerivedProperties(BaseModel):
"""Properties derived from an elastic tensor."""

k_voigt: float = Field(None, description="Voigt average of the bulk modulus.")
k_reuss: float = Field(None, description="Reuss average of the bulk modulus.")
k_vrh: float = Field(
k_voigt: Optional[float] = Field(
None, description="Voigt average of the bulk modulus."
)
k_reuss: Optional[float] = Field(
None, description="Reuss average of the bulk modulus."
)
k_vrh: Optional[float] = Field(
None, description="Voigt-Reuss-Hill average of the bulk modulus."
)
g_voigt: float = Field(None, description="Voigt average of the shear modulus.")
g_reuss: float = Field(None, description="Reuss average of the shear modulus.")
g_vrh: float = Field(
g_voigt: Optional[float] = Field(
None, description="Voigt average of the shear modulus."
)
g_reuss: Optional[float] = Field(
None, description="Reuss average of the shear modulus."
)
g_vrh: Optional[float] = Field(
None, description="Voigt-Reuss-Hill average of the shear modulus."
)
universal_anisotropy: float = Field(
universal_anisotropy: Optional[float] = Field(
None, description="Universal elastic anisotropy."
)
homogeneous_poisson: float = Field(None, description="Homogeneous poisson ratio.")
y_mod: float = Field(
homogeneous_poisson: Optional[float] = Field(
None, description="Homogeneous poisson ratio."
)
y_mod: Optional[float] = Field(
None,
description="Young's modulus (SI units) from the Voight-Reuss-Hill averages of "
"the bulk and shear moduli.",
)
trans_v: float = Field(
trans_v: Optional[float] = Field(
None,
description="Transverse sound velocity (SI units) obtained from the "
"Voigt-Reuss-Hill average bulk modulus.",
)
long_v: float = Field(
long_v: Optional[float] = Field(
None,
description="Longitudinal sound velocity (SI units) obtained from the "
"Voigt-Reuss-Hill average bulk modulus.",
)
snyder_ac: float = Field(
snyder_ac: Optional[float] = Field(
None, description="Synder's acoustic sound velocity (SI units)."
)
snyder_opt: float = Field(
snyder_opt: Optional[float] = Field(
None, description="Synder's optical sound velocity (SI units)."
)
snyder_total: float = Field(
snyder_total: Optional[float] = Field(
None, description="Synder's total sound velocity (SI units)."
)
clark_thermalcond: Optional[float] = Field(
None, description="Clarke's thermal conductivity (SI units)."
)
cahill_thermalcond: float = Field(
cahill_thermalcond: Optional[float] = Field(
None, description="Cahill's thermal conductivity (SI units)."
)
debye_temperature: float = Field(
debye_temperature: Optional[float] = Field(
None,
description="Debye temperature from longitudinal and transverse sound "
"velocities (SI units).",
Expand All @@ -78,53 +87,57 @@ class DerivedProperties(BaseModel):
class FittingData(BaseModel):
"""Data used to fit elastic tensors."""

cauchy_stresses: list[Matrix3D] = Field(
cauchy_stresses: Optional[list[Matrix3D]] = Field(
None, description="The Cauchy stresses used to fit the elastic tensor."
)
strains: list[Matrix3D] = Field(
strains: Optional[list[Matrix3D]] = Field(
None, description="The strains used to fit the elastic tensor."
)
pk_stresses: list[Matrix3D] = Field(
pk_stresses: Optional[list[Matrix3D]] = Field(
None, description="The Piola-Kirchoff stresses used to fit the elastic tensor."
)
deformations: list[Matrix3D] = Field(
deformations: Optional[list[Matrix3D]] = Field(
None, description="The deformations corresponding to each strain state."
)
uuids: list[str] = Field(None, description="The uuids of the deformation jobs.")
job_dirs: list[Optional[str]] = Field(
uuids: Optional[list[str]] = Field(
None, description="The uuids of the deformation jobs."
)
job_dirs: Optional[list[Optional[str]]] = Field(
None, description="The directories where the deformation jobs were run."
)


class ElasticTensorDocument(BaseModel):
"""Raw and standardized elastic tensors."""

raw: MatrixVoigt = Field(None, description="Raw elastic tensor.")
ieee_format: MatrixVoigt = Field(None, description="Elastic tensor in IEEE format.")
raw: Optional[MatrixVoigt] = Field(None, description="Raw elastic tensor.")
ieee_format: Optional[MatrixVoigt] = Field(
None, description="Elastic tensor in IEEE format."
)


class ElasticDocument(StructureMetadata):
"""Document containing elastic tensor information and related properties."""

structure: Structure = Field(
structure: Optional[Structure] = Field(
None, description="The structure for which the elastic data is calculated."
)
elastic_tensor: ElasticTensorDocument = Field(
elastic_tensor: Optional[ElasticTensorDocument] = Field(
None, description="Fitted elastic tensor."
)
eq_stress: Optional[Matrix3D] = Field(
None, description="The equilibrium stress of the structure."
)
derived_properties: DerivedProperties = Field(
derived_properties: Optional[DerivedProperties] = Field(
None, description="Properties derived from the elastic tensor."
)
fitting_data: FittingData = Field(
fitting_data: Optional[FittingData] = Field(
None, description="Data used to fit the elastic tensor."
)
fitting_method: str = Field(
fitting_method: Optional[str] = Field(
None, description="Method used to fit the elastic tensor."
)
order: int = Field(
order: Optional[int] = Field(
None, description="Order of the expansion of the elastic tensor."
)

Expand Down
Loading