def braket2float(s): try: return float(s) except ValueError: if isinstance(s, str): return str2float(s) raise TypeError('cannot parse {} into float'.format(s))
def get_symme(self): for d in self._cif.data.values(): data = d # Try to parse International number for symmetry_label in [ "_space_group_IT_number", "_space_group_IT_number_", "_symmetry_Int_Tables_number", "_symmetry_Int_Tables_number_" ]: if data.data.get(symmetry_label): symm_number = int(str2float(data.data.get(symmetry_label))) break for symmetry_label in [ "_symmetry_space_group_name_H-M", "_symmetry_space_group_name_H_M", "_symmetry_space_group_name_H-M_", "_symmetry_space_group_name_H_M_", "_space_group_name_Hall", "_space_group_name_Hall_", "_space_group_name_H-M_alt", "_space_group_name_H-M_alt_", "_symmetry_space_group_name_hall", "_symmetry_space_group_name_hall_", "_symmetry_space_group_name_h-m", "_symmetry_space_group_name_h-m_" ]: if data.data.get(symmetry_label): sg = data.data.get(symmetry_label) break return symm_number, sg
def _get_structure(self, data, primitive): """ Generate structure from part of the cif. """ def get_num_implicit_hydrogens(sym): num_h = {"Wat": 2, "wat": 2, "O-H": 1} return num_h.get(sym[:3], 0) lattice = self.get_lattice(data) # if magCIF, get magnetic symmetry moments and magmoms # else standard CIF, and use empty magmom dict if self.feature_flags["magcif_incommensurate"]: raise NotImplementedError( "Incommensurate structures not currently supported.") elif self.feature_flags["magcif"]: self.symmetry_operations = self.get_magsymops(data) magmoms = self.parse_magmoms(data, lattice=lattice) else: self.symmetry_operations = self.get_symops(data) magmoms = {} oxi_states = self.parse_oxi_states(data) coord_to_species = OrderedDict() coord_to_magmoms = OrderedDict() def get_matching_coord(coord): keys = list(coord_to_species.keys()) coords = np.array(keys) for op in self.symmetry_operations: c = op.operate(coord) inds = find_in_coord_list_pbc(coords, c, atol=self._site_tolerance) # cant use if inds, because python is dumb and np.array([0]) evaluates # to False if len(inds): return keys[inds[0]] return False label_el_dict = {} for i in range(len(data["_atom_site_label"])): try: # If site type symbol exists, use it. Otherwise, we use the # label. symbol = self._parse_symbol(data["_atom_site_type_symbol"][i]) label = data["_atom_site_label"][i] num_h = get_num_implicit_hydrogens( data["_atom_site_type_symbol"][i]) except KeyError: symbol = self._parse_symbol(data["_atom_site_label"][i]) label = data["_atom_site_label"][i] num_h = get_num_implicit_hydrogens(data["_atom_site_label"][i]) if not symbol: continue if oxi_states is not None: o_s = oxi_states.get(symbol, 0) # use _atom_site_type_symbol if possible for oxidation state if "_atom_site_type_symbol" in data.data.keys(): oxi_symbol = data["_atom_site_type_symbol"][i] o_s = oxi_states.get(oxi_symbol, o_s) try: el = Specie(symbol, o_s) except: el = DummySpecie(symbol, o_s) else: el = get_el_sp(symbol) x = str2float(data["_atom_site_fract_x"][i]) y = str2float(data["_atom_site_fract_y"][i]) z = str2float(data["_atom_site_fract_z"][i]) magmom = magmoms.get(data["_atom_site_label"][i], np.array([0, 0, 0])) try: occu = str2float(data["_atom_site_occupancy"][i]) except (KeyError, ValueError): occu = 1 if occu > 0: coord = (x, y, z) match = get_matching_coord(coord) comp_d = {el: occu} if num_h > 0: comp_d["H"] = num_h comp = Composition(comp_d) if not match: coord_to_species[coord] = comp coord_to_magmoms[coord] = magmom else: coord_to_species[match] += comp # disordered magnetic not currently supported coord_to_magmoms[match] = None label_el_dict[coord] = label sum_occu = [ sum(c.values()) for c in coord_to_species.values() if not set(c.elements) == {Element("O"), Element("H")} ] if any([o > 1 for o in sum_occu]): msg = "Some occupancies (%s) sum to > 1! If they are within " \ "the tolerance, they will be rescaled." % str(sum_occu) warnings.warn(msg) self.errors.append(msg) allspecies = [] allcoords = [] allmagmoms = [] allhydrogens = [] alllabels = [] # check to see if magCIF file is disordered if self.feature_flags["magcif"]: for k, v in coord_to_magmoms.items(): if v is None: # Proposed solution to this is to instead store magnetic # moments as Specie 'spin' property, instead of site # property, but this introduces ambiguities for end user # (such as unintended use of `spin` and Specie will have # fictious oxidation state). raise NotImplementedError( 'Disordered magnetic structures not currently supported.' ) if coord_to_species.items(): for comp, group in groupby(sorted(list(coord_to_species.items()), key=lambda x: x[1]), key=lambda x: x[1]): tmp_coords = [site[0] for site in group] #print(tmp_coords) labels = [] for i in tmp_coords: labels.append(label_el_dict[i]) #print(labels) tmp_magmom = [ coord_to_magmoms[tmp_coord] for tmp_coord in tmp_coords ] if self.feature_flags["magcif"]: coords, magmoms, coords_num = self._unique_coords( tmp_coords, magmoms_in=tmp_magmom, lattice=lattice) else: coords, magmoms, coords_num = self._unique_coords( tmp_coords) if set(comp.elements) == {Element("O"), Element("H")}: # O with implicit hydrogens im_h = comp["H"] species = Composition({"O": comp["O"]}) else: im_h = 0 species = comp allhydrogens.extend(len(coords) * [im_h]) allcoords.extend(coords) allspecies.extend(len(coords) * [species]) allmagmoms.extend(magmoms) for i in range(len(coords_num)): alllabels.extend(coords_num[i] * [labels[i]]) # rescale occupancies if necessary for i, species in enumerate(allspecies): totaloccu = sum(species.values()) if 1 < totaloccu <= self._occupancy_tolerance: allspecies[i] = species / totaloccu if allspecies and len(allspecies) == len(allcoords) \ and len(allspecies) == len(allmagmoms): site_properties = dict() if any(allhydrogens): assert len(allhydrogens) == len(allcoords) site_properties["implicit_hydrogens"] = allhydrogens if self.feature_flags["magcif"]: site_properties["magmom"] = allmagmoms if len(site_properties) == 0: site_properties = None struct = Structure(lattice, allspecies, allcoords, site_properties=site_properties) #struct = struct.get_sorted_structure() if primitive and self.feature_flags['magcif']: struct = struct.get_primitive_structure(use_site_props=True) elif primitive: struct = struct.get_primitive_structure() struct = struct.get_reduced_structure() struct.add_site_property("_atom_site_label", alllabels) return struct