515122/05/23 3.2.4 Added Symmetry.wyckoff_label(), Symmetry.spacegroup_dict
525206/05/24 3.3.0 Symmetry.from_cif now loads operations from find_spacegroup if not already loaded
535306/04/25 3.3.1 scale parameter of superlattice improved
54+ 15/09/25 3.3.2 Atoms.type changed to always be array type
5455
5556@author: DGPorter
5657"""
@@ -1088,6 +1089,7 @@ class Atoms:
10881089 "_atom_site_fract_y" ,
10891090 "_atom_site_fract_z" ,
10901091 ]
1092+ _type_str_fmt = '<U8'
10911093
10921094 def __init__ (self , u = [0 ], v = [0 ], w = [0 ], type = None ,
10931095 label = None , occupancy = None , uiso = None , mxmymz = None ):
@@ -1100,9 +1102,9 @@ def __init__(self, u=[0], v=[0], w=[0], type=None,
11001102 # ---Defaults---
11011103 # type
11021104 if type is None :
1103- self .type = np .asarray ([self ._default_atom ] * Natoms )
1105+ self .type = np .asarray ([self ._default_atom ] * Natoms , dtype = self . _type_str_fmt )
11041106 else :
1105- self .type = np .asarray (type , dtype = str ).reshape (- 1 )
1107+ self .type = np .asarray (type , dtype = self . _type_str_fmt ).reshape (- 1 )
11061108 # label
11071109 if label is None :
11081110 self .label = self .type .copy ()
@@ -1136,7 +1138,7 @@ def __call__(self, u=[0], v=[0], w=[0], type=None,
11361138
11371139 def __getitem__ (self , idx ):
11381140 if isinstance (idx , str ):
1139- idx = self .label .index (idx )
1141+ idx = list ( self .label ) .index (idx )
11401142 return self .atom (idx )
11411143
11421144 def fromcif (self , cifvals ):
@@ -1221,8 +1223,8 @@ def fromcif(self, cifvals):
12211223 self .u = u
12221224 self .v = v
12231225 self .w = w
1224- self .type = element
1225- self .label = label
1226+ self .type = np . array ( element , dtype = self . _type_str_fmt )
1227+ self .label = np . array ( label , dtype = self . _type_str_fmt )
12261228 self .occupancy = occ
12271229 self .uiso = uiso
12281230 self .mx = mx
@@ -1276,19 +1278,21 @@ def atom(self, idx):
12761278 return atoms [0 ]
12771279 return atoms
12781280
1279- def changeatom (self , idx = None , u = None , v = None , w = None , type = None ,
1281+ def changeatom (self , idx , u = None , v = None , w = None , type = None ,
12801282 label = None , occupancy = None , uiso = None , mxmymz = None ):
12811283 """
1282- Change an atoms properties
1283- :param idx:
1284- :param u:
1285- :param v:
1286- :param w:
1287- :param type:
1288- :param label:
1289- :param occupancy:
1290- :param uiso:
1291- :param mxmymz:
1284+ Change an atom site's properties.
1285+ If properties are given as None, they are not changed.
1286+
1287+ :param idx: atom array index
1288+ :param u: atomic position u in relative coordinates along basis vector a
1289+ :param v: atomic position u in relative coordinates along basis vector b
1290+ :param w: atomic position u in relative coordinates along basis vector c
1291+ :param type: atomic element type
1292+ :param label: atomic site label
1293+ :param occupancy: atom site occupancy
1294+ :param uiso: atom site isotropic thermal parameter
1295+ :param mxmymz: atom site magnetic vector (mx, my, mz)
12921296 :return: None
12931297 """
12941298
@@ -1307,7 +1311,7 @@ def changeatom(self, idx=None, u=None, v=None, w=None, type=None,
13071311 if label is not None :
13081312 old_labels = list (self .label )
13091313 old_labels [idx ] = label
1310- self .label = np .array (old_labels )
1314+ self .label = np .array (old_labels , dtype = self . _type_str_fmt )
13111315
13121316 if occupancy is not None :
13131317 self .occupancy [idx ] = occupancy
@@ -1433,11 +1437,11 @@ def remove_duplicates(self, min_distance=0.01, all_types=False):
14331437 """
14341438
14351439 uvw = self .uvw ()
1436- type = self .type
1440+ atom_type = self .type
14371441 rem_atom_idx = []
1438- for n in range (0 , len (type ) - 1 ):
1442+ for n in range (0 , len (atom_type ) - 1 ):
14391443 match_position = fg .mag (uvw [n , :] - uvw [n + 1 :, :]) < min_distance
1440- match_type = type [n ] == type [n + 1 :]
1444+ match_type = atom_type [n ] == atom_type [n + 1 :]
14411445 if all_types :
14421446 rem_atom_idx += list (1 + n + np .where (match_position )[0 ])
14431447 else :
@@ -1588,6 +1592,10 @@ def mass_fraction(self):
15881592
15891593 return weights / total_weight
15901594
1595+ def scattering_factor_coefficients (self , table = 'itc' ):
1596+ """Return scattering factor coefficients for the elements"""
1597+ return fc .scattering_factor_coefficients (* self .type , table = table )
1598+
15911599 def info (self , idx = None , type = None ):
15921600 """
15931601 Prints properties of all atoms
0 commit comments