@@ -520,7 +520,7 @@ def is_valid(self, tol: float = DISTANCE_TOLERANCE) -> bool:
520
520
return bool (np .min (all_dists ) > tol )
521
521
522
522
@abstractmethod
523
- def to (self , filename : str = "" , fmt : FileFormats = "" ) -> str | None :
523
+ def to (self , filename : PathLike = "" , fmt : FileFormats = "" ) -> str | None :
524
524
"""Generate string representations (cif, json, poscar, ....) of SiteCollections (e.g.,
525
525
molecules / structures). Should return str or None if written to a file.
526
526
"""
@@ -564,6 +564,7 @@ def add_site_property(self, property_name: str, values: Sequence | NDArray) -> S
564
564
"""
565
565
if len (values ) != len (self ):
566
566
raise ValueError (f"{ len (values )= } must equal sites in structure={ len (self )} " )
567
+
567
568
for site , val in zip (self , values , strict = True ):
568
569
site .properties [property_name ] = val
569
570
@@ -2964,7 +2965,11 @@ def to(self, filename: PathLike = "", fmt: FileFormats = "", **kwargs) -> str:
2964
2965
writer = Cssr (self )
2965
2966
2966
2967
elif fmt == "json" or fnmatch (filename .lower (), "*.json*" ):
2967
- json_str = json .dumps (self .as_dict (), ** kwargs ) if kwargs else orjson .dumps (self .as_dict ()).decode ()
2968
+ json_str = (
2969
+ json .dumps (self .as_dict (), ** kwargs )
2970
+ if kwargs
2971
+ else orjson .dumps (self .as_dict (), option = orjson .OPT_SERIALIZE_NUMPY ).decode ()
2972
+ )
2968
2973
2969
2974
if filename :
2970
2975
with zopen (filename , mode = "wt" , encoding = "utf-8" ) as file :
@@ -3989,11 +3994,11 @@ def get_centered_molecule(self) -> Self:
3989
3994
properties = self .properties ,
3990
3995
)
3991
3996
3992
- def to (self , filename : str = "" , fmt : str = "" ) -> str | None :
3997
+ def to (self , filename : PathLike = "" , fmt : str = "" ) -> str | None :
3993
3998
"""Outputs the molecule to a file or string.
3994
3999
3995
4000
Args:
3996
- filename (str ): If provided, output will be written to a file. If
4001
+ filename (PathLike ): If provided, output will be written to a file. If
3997
4002
fmt is not specified, the format is determined from the
3998
4003
filename. Defaults is None, i.e. string output.
3999
4004
fmt (str): Format to output to. Defaults to JSON unless filename
@@ -4006,22 +4011,28 @@ def to(self, filename: str = "", fmt: str = "") -> str | None:
4006
4011
str: String representation of molecule in given format. If a filename
4007
4012
is provided, the same string is written to the file.
4008
4013
"""
4014
+ filename = str (filename )
4009
4015
fmt = fmt .lower ()
4016
+
4010
4017
writer : Any
4011
4018
if fmt == "xyz" or fnmatch (filename .lower (), "*.xyz*" ):
4012
4019
from pymatgen .io .xyz import XYZ
4013
4020
4014
4021
writer = XYZ (self )
4022
+
4015
4023
elif any (fmt == ext or fnmatch (filename .lower (), f"*.{ ext } *" ) for ext in ("gjf" , "g03" , "g09" , "com" , "inp" )):
4016
4024
from pymatgen .io .gaussian import GaussianInput
4017
4025
4018
4026
writer = GaussianInput (self )
4027
+
4019
4028
elif fmt == "json" or fnmatch (filename , "*.json*" ) or fnmatch (filename , "*.mson*" ):
4020
- json_str = orjson .dumps (self .as_dict ()).decode ()
4029
+ json_str = orjson .dumps (self .as_dict (), option = orjson .OPT_SERIALIZE_NUMPY ).decode ()
4030
+
4021
4031
if filename :
4022
4032
with zopen (filename , mode = "wt" , encoding = "utf-8" ) as file :
4023
4033
file .write (json_str ) # type:ignore[arg-type]
4024
4034
return json_str
4035
+
4025
4036
elif fmt in {"yaml" , "yml" } or fnmatch (filename , "*.yaml*" ) or fnmatch (filename , "*.yml*" ):
4026
4037
yaml = YAML ()
4027
4038
str_io = io .StringIO ()
@@ -4031,6 +4042,7 @@ def to(self, filename: str = "", fmt: str = "") -> str | None:
4031
4042
with zopen (filename , mode = "wt" , encoding = "utf-8" ) as file :
4032
4043
file .write (yaml_str ) # type:ignore[arg-type]
4033
4044
return yaml_str
4045
+
4034
4046
else :
4035
4047
from pymatgen .io .babel import BabelMolAdaptor
4036
4048
@@ -4042,6 +4054,7 @@ def to(self, filename: str = "", fmt: str = "") -> str | None:
4042
4054
4043
4055
if filename :
4044
4056
writer .write_file (filename )
4057
+
4045
4058
return str (writer )
4046
4059
4047
4060
@classmethod
@@ -4109,28 +4122,35 @@ def from_file(cls, filename: PathLike) -> IMolecule | Molecule: # type:ignore[o
4109
4122
Molecule
4110
4123
"""
4111
4124
filename = str (filename )
4125
+ fname = filename .lower ()
4112
4126
4113
4127
with zopen (filename , mode = "rt" , encoding = "utf-8" ) as file :
4114
- contents : str = file .read () # type:ignore[assignment]
4115
- fname = filename . lower ()
4128
+ contents : str = cast ( "str" , file .read ())
4129
+
4116
4130
if fnmatch (fname , "*.xyz*" ):
4117
4131
return cls .from_str (contents , fmt = "xyz" )
4132
+
4118
4133
if any (fnmatch (fname .lower (), f"*.{ r } *" ) for r in ("gjf" , "g03" , "g09" , "com" , "inp" )):
4119
4134
return cls .from_str (contents , fmt = "g09" )
4135
+
4120
4136
if any (fnmatch (fname .lower (), f"*.{ r } *" ) for r in ("out" , "lis" , "log" )):
4121
4137
from pymatgen .io .gaussian import GaussianOutput
4122
4138
4123
4139
return GaussianOutput (filename ).final_structure
4140
+
4124
4141
if fnmatch (fname , "*.json*" ) or fnmatch (fname , "*.mson*" ):
4125
4142
return cls .from_str (contents , fmt = "json" )
4143
+
4126
4144
if fnmatch (fname , "*.yaml*" ) or fnmatch (filename , "*.yml*" ):
4127
4145
return cls .from_str (contents , fmt = "yaml" )
4128
- from pymatgen .io .babel import BabelMolAdaptor
4129
4146
4130
4147
if match := re .search (r"\.(pdb|mol|mdl|sdf|sd|ml2|sy2|mol2|cml|mrv)" , filename .lower ()):
4148
+ from pymatgen .io .babel import BabelMolAdaptor
4149
+
4131
4150
new = BabelMolAdaptor .from_file (filename , match [1 ]).pymatgen_mol
4132
4151
new .__class__ = cls
4133
4152
return new
4153
+
4134
4154
raise ValueError ("Cannot determine file type." )
4135
4155
4136
4156
0 commit comments