11from __future__ import annotations
22
3+ import copy
34import json
45import logging
56from dataclasses import dataclass , asdict
1920
2021@dataclass
2122class CrystalStructure (JsonDataclass ):
22- lattice : Lattice
23- basis : CrystalBasis
23+ lattice : Optional [ Lattice ]
24+ basis : Optional [ CrystalBasis ]
2425 spacegroup : Optional [int ] = None
2526 chemical_composition : Optional [str ] = None
2627 wyckoff_symbols : Optional [list [str ]] = None
@@ -30,9 +31,22 @@ def __post_init__(self):
3031 if not self .phase_fraction is None :
3132 if not 0 <= self .phase_fraction <= 1 :
3233 raise ValueError (f'Phase fraction must be between 0 and 1. Got { self .phase_fraction } ' )
33- if not len (self .basis ) == 0 :
34+ if not self .lattice is None :
35+ for p in self .lattice .parameters :
36+ if p != p :
37+ raise ValueError (f'Lattice parameters { self .lattice .parameters } contain nan values' )
38+ if self .phase_fraction != self .phase_fraction :
39+ raise ValueError (f'Phase fraction { self .phase_fraction } is nan' )
40+
41+ if not self .basis is None :
3442 self .calculate_properties ()
3543
44+
45+
46+ @classmethod
47+ def make_empty (cls ):
48+ return CrystalStructure (lattice = None , basis = None )
49+
3650 @classmethod
3751 def from_cif (cls , cif_content : str ) -> CrystalStructure :
3852 pymatgen_structure = Structure .from_str (cif_content , fmt = 'cif' )
@@ -85,7 +99,7 @@ def get_view(self) -> str:
8599 # properties
86100
87101 def calculate_properties (self ):
88- if len ( self .basis ) == 0 :
102+ if self .basis is None :
89103 raise ValueError ('Base is empty! Cannot calculate properties of empty crystal. Aborting ...' )
90104
91105 pymatgen_structure = self .to_pymatgen ()
@@ -97,10 +111,14 @@ def calculate_properties(self):
97111 self .chemical_composition = pymatgen_structure .composition .formula
98112
99113 def get_standardized (self ) -> CrystalStructure :
100- struct = self .to_pymatgen () if len (self .basis ) > 0 else Structure (self .lattice , ["H" ], [[0 , 0 , 0 ]])
114+ if self .lattice is None :
115+ return copy .deepcopy (self )
116+
117+ struct = self .to_pymatgen () if not self .basis is None else Structure (self .lattice , ["H" ], [[0 , 0 , 0 ]])
101118 analzyer = SpacegroupAnalyzer (structure = struct )
102119 std_struct = analzyer .get_conventional_standard_structure ()
103- if len (self .basis ) == 0 :
120+
121+ if self .basis is None :
104122 return CrystalStructure (lattice = std_struct .lattice , basis = CrystalBasis .empty ())
105123 else :
106124 return CrystalStructure .from_pymatgen (pymatgen_structure = std_struct )
0 commit comments