13
13
from io import StringIO
14
14
from itertools import groupby
15
15
from pathlib import Path
16
+ from typing import Literal
16
17
17
18
import numpy as np
18
19
from monty .io import zopen
@@ -885,8 +886,8 @@ def _parse_symbol(self, sym):
885
886
886
887
return parsed_sym
887
888
888
- def _get_structure (self , data , primitive , symmetrized ):
889
- """Generate structure from part of the cif ."""
889
+ def _get_structure (self , data , primitive , symmetrized ) -> Structure | None :
890
+ """Generate structure from part of the CIF ."""
890
891
891
892
def get_num_implicit_hydrogens (sym ):
892
893
num_h = {"Wat" : 2 , "wat" : 2 , "O-H" : 1 }
@@ -907,26 +908,23 @@ def get_num_implicit_hydrogens(sym):
907
908
908
909
oxi_states = self .parse_oxi_states (data )
909
910
910
- coord_to_species = {}
911
+ coord_to_species = {} # type: ignore
911
912
coord_to_magmoms = {}
912
913
labels = {}
913
914
914
915
def get_matching_coord (coord ):
915
916
keys = list (coord_to_species )
916
917
coords = np .array (keys )
917
918
for op in self .symmetry_operations :
918
- c = op .operate (coord )
919
- inds = find_in_coord_list_pbc (coords , c , atol = self ._site_tolerance )
920
- # can't use if inds, because python is dumb and np.array([0]) evaluates
921
- # to False
922
- if len (inds ) > 0 :
923
- return keys [inds [0 ]]
919
+ frac_coord = op .operate (coord )
920
+ indices = find_in_coord_list_pbc (coords , frac_coord , atol = self ._site_tolerance )
921
+ if len (indices ) > 0 :
922
+ return keys [indices [0 ]]
924
923
return False
925
924
926
925
for idx , label in enumerate (data ["_atom_site_label" ]):
927
926
try :
928
- # If site type symbol exists, use it. Otherwise, we use the
929
- # label.
927
+ # If site type symbol exists, use it. Otherwise, we use the label.
930
928
symbol = self ._parse_symbol (data ["_atom_site_type_symbol" ][idx ])
931
929
num_h = get_num_implicit_hydrogens (data ["_atom_site_type_symbol" ][idx ])
932
930
except KeyError :
@@ -946,7 +944,7 @@ def get_matching_coord(coord):
946
944
except Exception :
947
945
el = DummySpecies (symbol , o_s )
948
946
else :
949
- el = get_el_sp (symbol )
947
+ el = get_el_sp (symbol ) # type: ignore
950
948
951
949
x = str2float (data ["_atom_site_fract_x" ][idx ])
952
950
y = str2float (data ["_atom_site_fract_y" ][idx ])
@@ -963,7 +961,7 @@ def get_matching_coord(coord):
963
961
match = get_matching_coord (coord )
964
962
comp_d = {el : occu }
965
963
if num_h > 0 :
966
- comp_d ["H" ] = num_h
964
+ comp_d ["H" ] = num_h # type: ignore
967
965
self .warnings .append (
968
966
"Structure has implicit hydrogens defined, "
969
967
"parsed structure unlikely to be suitable for use "
@@ -1067,12 +1065,12 @@ def get_matching_coord(coord):
1067
1065
site_properties ["magmom" ] = all_magmoms
1068
1066
1069
1067
if len (site_properties ) == 0 :
1070
- site_properties = None
1068
+ site_properties = None # type: ignore
1071
1069
1072
1070
if any (all_labels ):
1073
1071
assert len (all_labels ) == len (all_species )
1074
1072
else :
1075
- all_labels = None
1073
+ all_labels = None # type: ignore
1076
1074
1077
1075
struct = Structure (lattice , all_species , all_coords , site_properties = site_properties , labels = all_labels )
1078
1076
@@ -1099,10 +1097,10 @@ def get_matching_coord(coord):
1099
1097
return struct
1100
1098
return None
1101
1099
1102
- def get_structures (self , primitive = True , symmetrized = False ):
1103
- "" "
1104
- Return list of structures in CIF file. primitive boolean sets whether a
1105
- conventional cell structure or primitive cell structure is returned .
1100
+ def get_structures (
1101
+ self , primitive : bool = True , symmetrized : bool = False , on_error : Literal [ "ignore" , "warn" , "raise" ] = "warn "
1102
+ ) -> list [ Structure ]:
1103
+ """Return list of structures in CIF file .
1106
1104
1107
1105
Args:
1108
1106
primitive (bool): Set to False to return conventional unit cells.
@@ -1116,9 +1114,11 @@ def get_structures(self, primitive=True, symmetrized=False):
1116
1114
currently Wyckoff labels and space group labels or numbers are
1117
1115
not included in the generated SymmetrizedStructure, these will be
1118
1116
notated as "Not Parsed" or -1 respectively.
1117
+ on_error ('ignore' | 'warn' | 'raise'): What to do in case of KeyError or ValueError
1118
+ while parsing CIF file. Defaults to 'warn'.
1119
1119
1120
1120
Returns:
1121
- List of Structures .
1121
+ list[Structure]: All structures in CIF file .
1122
1122
"""
1123
1123
if primitive and symmetrized :
1124
1124
raise ValueError (
@@ -1127,24 +1127,28 @@ def get_structures(self, primitive=True, symmetrized=False):
1127
1127
)
1128
1128
1129
1129
structures = []
1130
- for i , d in enumerate (self ._cif .data .values ()):
1130
+ for idx , dct in enumerate (self ._cif .data .values ()):
1131
1131
try :
1132
- struct = self ._get_structure (d , primitive , symmetrized )
1132
+ struct = self ._get_structure (dct , primitive , symmetrized )
1133
1133
if struct :
1134
1134
structures .append (struct )
1135
1135
except (KeyError , ValueError ) as exc :
1136
- # Warn the user (Errors should never pass silently)
1137
1136
# A user reported a problem with cif files produced by Avogadro
1138
1137
# in which the atomic coordinates are in Cartesian coords.
1139
- self .warnings .append (str (exc ))
1140
- warnings .warn (f"No structure parsed for { i + 1 } structure in CIF. Section of CIF file below." )
1141
- warnings .warn (str (d ))
1142
- warnings .warn (f"Error is { exc } ." )
1138
+ msg = f"No structure parsed for section { idx + 1 } in CIF.\n { exc } "
1139
+ if on_error == "raise" :
1140
+ raise ValueError (msg ) from exc
1141
+ if on_error == "warn" :
1142
+ warnings .warn (msg )
1143
+ self .warnings .append (msg )
1144
+ # continue silently if on_error == "ignore"
1143
1145
1144
- if self .warnings :
1146
+ # if on_error == "raise" we don't get to here so no need to check
1147
+ if self .warnings and on_error == "warn" :
1145
1148
warnings .warn ("Issues encountered while parsing CIF: " + "\n " .join (self .warnings ))
1149
+
1146
1150
if len (structures ) == 0 :
1147
- raise ValueError ("Invalid cif file with no structures!" )
1151
+ raise ValueError ("Invalid CIF file with no structures!" )
1148
1152
return structures
1149
1153
1150
1154
def get_bibtex_string (self ):
0 commit comments