@@ -35,11 +35,11 @@ def to_pymatgen(self) -> Any:
35
35
@classmethod
36
36
def from_dict (cls , dct : dict [str , Any ]) -> Self :
37
37
"""MSONable-like function to create this object from a dict."""
38
- raise NotImplementedError
38
+ return cls ( ** dct )
39
39
40
40
def as_dict (self ) -> dict [str , Any ]:
41
41
"""MSONable-like function to create dict representation of this object."""
42
- raise NotImplementedError
42
+ return self . model_dump ()
43
43
44
44
45
45
class SiteProperties (Enum ):
@@ -183,35 +183,26 @@ def __str__(self):
183
183
return self .name
184
184
185
185
186
- class LightLattice ( tuple ):
186
+ class LatticeReplica ( EmmetReplica ):
187
187
"""Low memory representation of a Lattice as a tuple of a 3x3 matrix."""
188
188
189
- def __new__ (cls , matrix ):
190
- """Overset __new__ to define new tuple instance."""
191
- lattice_matrix = np .array (matrix )
192
- if lattice_matrix .shape != (3 , 3 ):
193
- raise ValueError ("Lattice matrix must be 3x3." )
194
- return super (LightLattice , cls ).__new__ (
195
- cls , tuple ([tuple (v ) for v in lattice_matrix .tolist ()])
196
- )
197
-
198
- def as_dict (self ) -> dict [str , list | str ]:
199
- """Define MSONable-like as_dict."""
200
- return {"@class" : self .__class__ , "@module" : self .__module__ , "matrix" : self }
189
+ matrix : Matrix3D = Field (
190
+ description = "The matrix represenation of the lattice, with a, b, and c as rows."
191
+ )
201
192
202
193
@classmethod
203
- def from_dict (cls , dct : dict ) -> Self :
204
- """Define MSONable-like from_dict ."""
205
- return cls (dct [ " matrix" ] )
194
+ def from_pymatgen (cls , pmg_obj : Lattice ) -> Self :
195
+ """Create a LatticeReplica from a pymatgen .Lattice ."""
196
+ return cls (matrix = pmg_obj . matrix )
206
197
207
- def copy (self ) -> Self :
208
- """Return a new copy of LightLattice ."""
209
- return LightLattice (self )
198
+ def to_pymatgen (self ) -> Lattice :
199
+ """Create a pymatgen .Lattice ."""
200
+ return Lattice (self . matrix )
210
201
211
202
@property
212
203
def volume (self ) -> float :
213
204
"""Get the volume enclosed by the direct lattice vectors."""
214
- return abs (np .linalg .det (self ))
205
+ return abs (np .linalg .det (self . matrix ))
215
206
216
207
217
208
class ElementReplica (EmmetReplica ):
@@ -294,20 +285,23 @@ def from_pymatgen(cls, pmg_obj: Element | PeriodicSite) -> Self:
294
285
element = ElementSymbol (
295
286
next (iter (pmg_obj .species .remove_charges ().as_dict ()))
296
287
),
297
- lattice = LightLattice (pmg_obj .lattice . matrix ),
288
+ lattice = LatticeReplica . from_pymatgen (pmg_obj .lattice ),
298
289
frac_coords = pmg_obj .frac_coords ,
299
290
cart_coords = pmg_obj .coords ,
300
291
)
301
292
302
- def to_pymatgen (self ) -> PeriodicSite :
303
- """Create a PeriodicSite from a ElementReplica."""
304
- return PeriodicSite (
305
- self .element .name ,
306
- self .frac_coords ,
307
- Lattice (self .lattice ),
308
- coords_are_cartesian = False ,
309
- properties = self .properties ,
310
- )
293
+ def to_pymatgen (self ) -> PeriodicSite | Element :
294
+ """Create an Element or PeriodicSite from a ElementReplica."""
295
+
296
+ if self .lattice and self .frac_coords :
297
+ return PeriodicSite (
298
+ self .element .name ,
299
+ self .frac_coords ,
300
+ Lattice (self .lattice ),
301
+ coords_are_cartesian = False ,
302
+ properties = self .properties ,
303
+ )
304
+ return Element (self .element .name )
311
305
312
306
@property
313
307
def species (self ) -> dict [str , int ]:
@@ -395,7 +389,7 @@ class StructureReplica(BaseModel):
395
389
396
390
Parameters
397
391
-----------
398
- lattice : LightLattice
392
+ lattice : LatticeReplica
399
393
A 3x3 tuple of the lattice vectors, with a, b, and c as subsequent rows.
400
394
species : list[ElementReplica]
401
395
A list of elements in the structure
@@ -408,7 +402,7 @@ class StructureReplica(BaseModel):
408
402
The total charge on the structure.
409
403
"""
410
404
411
- lattice : LightLattice = Field (description = "The lattice in 3x3 matrix form." )
405
+ lattice : LatticeReplica = Field (description = "The lattice in 3x3 matrix form." )
412
406
species : list [ElementReplica ] = Field (description = "The elements in the structure." )
413
407
frac_coords : ListMatrix3D = Field (
414
408
description = "The direct coordinates of the sites in the structure."
@@ -436,7 +430,7 @@ def __getitem__(self, idx: int | slice) -> ElementReplica | list[ElementReplica]
436
430
return self .sites [idx ]
437
431
raise IndexError ("Index must be an integer or slice!" )
438
432
439
- def __iter__ (self ) -> Iterator [ElementReplica ]:
433
+ def __iter__ (self ) -> Iterator [ElementReplica ]: # type: ignore[override]
440
434
"""Permit list-like iteration on the sites in StructureReplica."""
441
435
yield from self .sites
442
436
@@ -471,8 +465,8 @@ def from_pymatgen(cls, pmg_obj: Structure) -> Self:
471
465
"Currently, `StructureReplica` is intended to represent only ordered materials."
472
466
)
473
467
474
- lattice = LightLattice (pmg_obj .lattice . matrix )
475
- properties = [{} for _ in range (len (pmg_obj ))]
468
+ lattice = LatticeReplica . from_pymatgen (pmg_obj .lattice )
469
+ properties : list [ dict [ str , Any ]] = [{} for _ in range (len (pmg_obj ))]
476
470
for idx , site in enumerate (pmg_obj ):
477
471
for k in ("charge" , "magmom" , "velocities" , "selective_dynamics" ):
478
472
if (prop := site .properties .get (k )) is not None :
@@ -499,13 +493,13 @@ def from_pymatgen(cls, pmg_obj: Structure) -> Self:
499
493
def to_pymatgen (self ) -> Structure :
500
494
"""Convert to a pymatgen .Structure."""
501
495
return Structure .from_sites (
502
- [site .to_periodic_site () for site in self ], charge = self .charge
496
+ [site .to_pymatgen () for site in self ], charge = self .charge # type: ignore[misc]
503
497
)
504
498
505
499
@classmethod
506
500
def from_poscar (cls , poscar_path : str | Path ) -> Self :
507
501
"""Define convenience method to create a StructureReplica from a VASP POSCAR."""
508
- return cls .from_structure (Poscar .from_file (poscar_path ).structure )
502
+ return cls .from_pymatgen (Poscar .from_file (poscar_path ).structure )
509
503
510
504
def __str__ (self ):
511
505
"""Define format for printing a Structure."""
0 commit comments