def test_subgroup_supergroup(self): with warnings.catch_warnings() as w: warnings.simplefilter("ignore") self.assertTrue(SpaceGroup("Pma2").is_subgroup(SpaceGroup("Pccm"))) self.assertFalse( SpaceGroup.from_int_number(229).is_subgroup( SpaceGroup.from_int_number(230)))
def test_string(self): sg = SpaceGroup("R-3c") self.assertEqual(sg.to_latex_string(), r"R$\overline{3}$cH") sg = SpaceGroup("P6/mmm") self.assertEqual(sg.to_latex_string(), "P6/mmm") sg = SpaceGroup("P4_1") self.assertEqual(sg.to_unicode_string(), "P4₁")
def space_group_num(row): try: if len(row)>2 and row[-1] in ['H', 'R']: # remove conventions return SpaceGroup(row[:-1]).int_number, SpaceGroup(row[:-1]).crystal_system else: return SpaceGroup(row).int_number, SpaceGroup(row).crystal_system except ValueError: # miscellaneous/incorrect space-group. pymatgen wasn't able to identify these return None, None
def symmetry_relation(initial_point_group, final_point_group): if initial_point_group in ["3m", "-3m"]: initial_point_group += "1" if final_point_group in ["3m", "-3m"]: final_point_group += "1" initial = SpaceGroup(f"P{initial_point_group}") final = SpaceGroup(f"P{final_point_group}") if initial == final: return SymmRelation.same elif final.is_subgroup(initial): return SymmRelation.subgroup elif final.is_supergroup(initial): return SymmRelation.supergroup else: return SymmRelation.another
def test_point_group_is_set(self): for i in range(1, 231): sg = SpaceGroup.from_int_number(i) self.assertTrue(hasattr(sg, "point_group")) for symbol in _get_symm_data("space_group_encoding"): sg = SpaceGroup(symbol) self.assertTrue(hasattr(sg, "point_group"))
def __init__(self, input_spins = None, npoints=None, space_group = None, angle_range = None): """ Set of unit vector representing the orientation of spin magnetic moments. :param npoints: number of spin vectors [int] :param space_group: space group of material system [int] :param angle_range: angular range of vectors to compute [list or ndarray] ([[phi_min, phi_max], [theta_min, theta_max]]) """ def generate_semi_spin_axes_h(npoints, thet_min, thet_max, phi_min, phi_max): u = np.arange(0,1.0,1/int(np.sqrt(npoints))) thet = (thet_max - thet_min)*(u + thet_min) phi = arccos((cos(phi_max) - cos(phi_min))*u + cos(phi_min)) thetas, phis = np.meshgrid(thet, phi, sparse=False, indexing='xy') x, y, z = cos(thetas) * sin(phis), sin(thetas) * sin(phis), cos(phis) return np.array([x.flatten(),y.flatten(),z.flatten()]), np.array([thetas, phis]) if npoints: assert type(npoints) is int ##change to isinstance self._npoints = npoints if space_group: try: i = int(space_group) sg_obj = SpaceGroup.from_int_number(i) except ValueError: sg_obj = SpaceGroup(space_group) self._crystal_type = sg_obj.crystal_system if self._crystal_type is "triclinic": self._angle_range = np.array([[0, np.pi],[0, 2*np.pi]]) elif self._crystal_type is "monoclinic": self._angle_range = np.array([[0, np.pi],[0, 2*np.pi]]) elif self._crystal_type is "orthorhombic": self._angle_range = np.array([[0, np.pi],[0, np.pi]]) elif self._crystal_type is "tetragonal": self._angle_range = np.array([[0, np.pi],[0, np.pi/2]]) elif self._crystal_type is "trigonal": self._angle_range = np.array([[0, np.pi],[0, 2*np.pi]]) elif self._crystal_type is "hexagonal": self._angle_range = np.array([[0, np.pi],[0, 2*np.pi/3]]) else: self._angle_range = np.array([[0, np.pi/2],[0, np.pi/2]]) else: self._angle_range = np.array([[0, np.pi],[0, 2*np.pi]]) thet_min = self._angle_range[1][0] thet_max = self._angle_range[1][1] phi_min = self._angle_range[0][0] phi_max = self._angle_range[0][1] self._spin_axes, angle_list = generate_semi_spin_axes_h(npoints, thet_min, thet_max, phi_min, phi_max) self._spher_coords = [angle_list[0], angle_list[1], np.ones(npoints)] elif input_spins: ## Add assertions self._spin_axes = np.array(input_spins) self._spher_coords = None
def symmetry_relation(initial_point_group, final_point_group): """ Check the point group symmetry relation using the space group relation implemented in pymatgen. """ if initial_point_group in ["3m", "-3m"]: initial_point_group += "1" if final_point_group in ["3m", "-3m"]: final_point_group += "1" initial = SpaceGroup(f"P{initial_point_group}") final = SpaceGroup(f"P{final_point_group}") if initial == final: return SymmRelation.same elif final.is_subgroup(initial): return SymmRelation.subgroup elif final.is_supergroup(initial): return SymmRelation.supergroup else: return SymmRelation.another
def spacegroup_sunburst( data: Sequence[int | str] | pd.Series, show_counts: Literal["value", "percent", False] = False, **kwargs: Any, ) -> Figure: """Generate a sunburst plot with crystal systems as the inner ring for a list of international space group numbers. Hint: To hide very small labels, set a uniformtext minsize and mode='hide'. fig.update_layout(uniformtext=dict(minsize=9, mode="hide")) Args: data (list[int] | pd.Series): A sequence (list, tuple, pd.Series) of space group strings or numbers (from 1 - 230) or pymatgen structures. show_counts ("value" | "percent" | False): Whether to display values below each labels on the sunburst. Returns: Figure: The Plotly figure. """ if isinstance(next(iter(data)), Structure): # if 1st sequence item is structure, assume all are data = cast(Sequence[Structure], data) series = pd.Series( struct.get_space_group_info()[1] for struct in data # type: ignore ) else: series = pd.Series(data) df = pd.DataFrame(series.value_counts().reset_index()) df.columns = ["spacegroup", "count"] try: df["crystal_sys"] = [get_crystal_sys(x) for x in df.spacegroup] except ValueError: # column must be space group strings df["crystal_sys"] = [SpaceGroup(x).crystal_system for x in df.spacegroup] if "color_discrete_sequence" not in kwargs: kwargs["color_discrete_sequence"] = px.colors.qualitative.G10 fig = px.sunburst(df, path=["crystal_sys", "spacegroup"], values="count", **kwargs) if show_counts == "percent": fig.data[0].textinfo = "label+percent entry" elif show_counts == "value": fig.data[0].textinfo = "label+value" elif show_counts is not False: raise ValueError(f"Invalid {show_counts=}") fig.update_layout( margin=dict(l=10, r=10, b=10, pad=10), paper_bgcolor="rgba(0, 0, 0, 0)", ) return fig
def test_renamed_e_symbols(self): sg = SpaceGroup.from_int_number(64) assert sg.symbol == "Cmce" for sym, num in ( ("Aem2", 39), ("Aea2", 41), ("Cmce", 64), ("Cmme", 67), ("Ccce", 68), ): assert SpaceGroup(sym).int_number == num
def test_is_compatible(self): cubic = Lattice.cubic(1) hexagonal = Lattice.hexagonal(1, 2) rhom = Lattice.rhombohedral(3, 80) tet = Lattice.tetragonal(1, 2) ortho = Lattice.orthorhombic(1, 2, 3) sg = SpaceGroup("Fm-3m") self.assertTrue(sg.is_compatible(cubic)) self.assertFalse(sg.is_compatible(hexagonal)) sg = SpaceGroup("R-3mH") self.assertFalse(sg.is_compatible(cubic)) self.assertTrue(sg.is_compatible(hexagonal)) sg = SpaceGroup("R-3mR") self.assertTrue(sg.is_compatible(cubic)) self.assertTrue(sg.is_compatible(rhom)) self.assertFalse(sg.is_compatible(hexagonal)) sg = SpaceGroup("Pnma") self.assertTrue(sg.is_compatible(cubic)) self.assertTrue(sg.is_compatible(tet)) self.assertTrue(sg.is_compatible(ortho)) self.assertFalse(sg.is_compatible(rhom)) self.assertFalse(sg.is_compatible(hexagonal)) sg = SpaceGroup("P12/c1") self.assertTrue(sg.is_compatible(cubic)) self.assertTrue(sg.is_compatible(tet)) self.assertTrue(sg.is_compatible(ortho)) self.assertFalse(sg.is_compatible(rhom)) self.assertFalse(sg.is_compatible(hexagonal)) sg = SpaceGroup("P-1") self.assertTrue(sg.is_compatible(cubic)) self.assertTrue(sg.is_compatible(tet)) self.assertTrue(sg.is_compatible(ortho)) self.assertTrue(sg.is_compatible(rhom)) self.assertTrue(sg.is_compatible(hexagonal))
def _get_space_group_object(spg, mode): from pymatgen.symmetry.groups import SpaceGroup if spg and mode != 'bradcrack': logging.error("ERROR: Specifying symmetry only supported using " "Bradley and Cracknell path.") sys.exit() elif spg: try: if isinstance(spg, int): spg = SpaceGroup.from_int_number(spg) else: spg = SpaceGroup(spg) logging.error("WARNING: Forcing space group not recommended, the " "path is likely\nincorrect. Use at your own risk.\n") except ValueError: logging.error("ERROR: Space group not recognised.") sys.exit() return spg
def test_equivalence_to_spacegroup(self): # first 230 magnetic space groups have same symmetry operations # as normal space groups, so should give same orbits labels = ["Fm-3m", "Pnma", "P2/c", "P-1"] points = [[0, 0, 0], [0.5, 0, 0], [0.11, 0.22, 0.33]] for label in labels: sg = SpaceGroup(label) msg = MagneticSpaceGroup(label) self.assertEqual(sg.crystal_system, msg.crystal_system) for p in points: pp_sg = np.array(sg.get_orbit(p)) pp_msg = np.array(msg.get_orbit(p, 0)[0]) # discarding magnetic moment information pp_sg = pp_sg[np.lexsort(np.transpose(pp_sg)[::-1])] # sorting arrays so we can compare them pp_msg = pp_msg[np.lexsort(np.transpose(pp_msg)[::-1])] self.assertTrue(np.allclose(pp_sg, pp_msg))
def get_symmop(data): symops = [] for symmetry_label in [ "_symmetry_equiv_pos_as_xyz", "_symmetry_equiv_pos_as_xyz_", "_space_group_symop_operation_xyz", "_space_group_symop_operation_xyz_" ]: if data.get(symmetry_label): xyz = data.get(symmetry_label) if isinstance(xyz, str): msg = "A 1-line symmetry op P1 CIF is detected!" warnings.warn(msg) xyz = [xyz] try: symops = [SymmOp.from_xyz_string(s) for s in xyz] break except ValueError: continue if not symops: # Try to parse symbol 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_" ]: sg = data.get(symmetry_label) if sg: sg = sub_spgrp(sg) try: spg = space_groups.get(sg) if spg: symops = SpaceGroup(spg).symmetry_ops msg = "No _symmetry_equiv_pos_as_xyz type key found. " \ "Spacegroup from %s used." % symmetry_label warnings.warn(msg) break except ValueError: # Ignore any errors pass try: for d in _get_cod_data(): if sg == re.sub(r"\s+", "", d["hermann_mauguin"]): xyz = d["symops"] symops = [SymmOp.from_xyz_string(s) for s in xyz] msg = "No _symmetry_equiv_pos_as_xyz type key found. " \ "Spacegroup from %s used." % symmetry_label warnings.warn(msg) break except Exception: continue if symops: break if not symops: # 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.get(symmetry_label): try: i = int(braket2float(data.get(symmetry_label))) symops = SpaceGroup.from_int_number(i).symmetry_ops break except ValueError: continue if not symops: msg = "No _symmetry_equiv_pos_as_xyz type key found. " \ "Defaulting to P1." warnings.warn(msg) symops = [SymmOp.from_xyz_string(s) for s in ['x', 'y', 'z']] return symops
def test_attr(self): sg = SpaceGroup("Fm-3m") self.assertEqual(sg.full_symbol, "F4/m-32/m") self.assertEqual(sg.point_group, "m-3m")
def test_abbrev_symbols(self): sg = SpaceGroup("P2/c") self.assertEqual(sg.int_number, 13) sg = SpaceGroup("R-3mH") self.assertEqual(sg.int_number, 166)
def spacegroup_hist( data: Sequence[int | str] | pd.Series, show_counts: bool = True, xticks: Literal["all", "crys_sys_edges"] | int = 20, include_missing: bool = False, ax: Axes = None, **kwargs: Any, ) -> Axes: """Plot a histogram of spacegroups shaded by crystal system. Args: data (list[int | str] | pd.Series): A sequence (list, tuple, pd.Series) of space group strings or numbers (from 1 - 230) or pymatgen structures. show_counts (bool, optional): Whether to count the number of items in each crystal system. Defaults to True. xticks ('all' | 'crys_sys_edges' | int, optional): Where to add x-ticks. An integer will add ticks below that number of tallest bars. Defaults to 20. 'all' will show below all bars, 'crys_sys_edges' only at the edge from one crystal system to another. include_missing (bool, optional): Whether to include a 0-height bar for missing space groups missing from the data. Currently only implemented for numbers, not symbols. Defaults to False. ax (Axes, optional): matplotlib Axes on which to plot. Defaults to None. kwargs: Keywords passed to pd.Series.plot.bar(). Returns: ax: The plot's matplotlib Axes. """ if ax is None: ax = plt.gca() if isinstance(next(iter(data)), Structure): # if 1st sequence item is structure, assume all are series = pd.Series(struct.get_space_group_info()[1] for struct in data # type: ignore ) else: series = pd.Series(data) df = pd.DataFrame(series.value_counts(sort=False)) df.columns = ["counts"] crys_colors = { "triclinic": "red", "monoclinic": "teal", "orthorhombic": "blue", "tetragonal": "green", "trigonal": "orange", "hexagonal": "purple", "cubic": "yellow", } if df.index.is_numeric(): # assume index is space group numbers if include_missing: df = df.reindex(range(1, 231), fill_value=0) else: df = df.sort_index() df["crystal_sys"] = [get_crystal_sys(x) for x in df.index] ax.set(xlim=(0, 230)) xlabel = "International Spacegroup Number" else: # assume index is space group symbols # TODO: figure how to implement include_missing for space group symbols # if include_missing: # idx = [SpaceGroup.from_int_number(x).symbol for x in range(1, 231)] # df = df.reindex(idx, fill_value=0) df["crystal_sys"] = [SpaceGroup(x).crystal_system for x in df.index] # sort df by crystal system going from smallest to largest spacegroup numbers # e.g. triclinic (1-2) comes first, cubic (195-230) last sys_order = dict(zip(crys_colors, range(len(crys_colors)))) df = df.loc[df.crystal_sys.map(sys_order).sort_values().index] xlabel = "International Spacegroup Symbol" ax.set(xlabel=xlabel, ylabel="Count") kwargs["width"] = kwargs.get("width", 0.9) # set default bar width # make plot df.counts.plot.bar(figsize=[16, 4], ax=ax, **kwargs) # https://matplotlib.org/3.1.1/gallery/lines_bars_and_markers/fill_between_demo trans = transforms.blended_transform_factory(ax.transData, ax.transAxes) # count rows per crystal system crys_sys_counts = df.groupby("crystal_sys").sum("counts") # sort by key order in dict crys_colors crys_sys_counts = crys_sys_counts.loc[[ x for x in crys_colors if x in crys_sys_counts.index ]] crys_sys_counts["width"] = df.value_counts("crystal_sys") ax.set_title("Totals per crystal system", fontdict={"fontsize": 18}, pad=30) crys_sys_counts["color"] = pd.Series(crys_colors) x0 = 0 for cryst_sys, count, width, color in crys_sys_counts.itertuples(): x1 = x0 + width for patch in ax.patches[0 if x0 == 1 else x0:x1 + 1]: patch.set_facecolor(color) text_kwds = dict(transform=trans, horizontalalignment="center") ax.text( *[(x0 + x1) / 2, 0.95], cryst_sys, rotation=90, verticalalignment="top", fontdict={"fontsize": 14}, **text_kwds, ) if show_counts: ax.text( *[(x0 + x1) / 2, 1.02], f"{count:,} ({count/len(data):.0%})", fontdict={"fontsize": 12}, **text_kwds, ) ax.fill_between( [x0 - 0.5, x1 - 0.5], *[0, 1], facecolor=color, alpha=0.1, transform=trans, edgecolor="black", ) x0 += width ax.yaxis.grid(True) ax.xaxis.grid(False) if xticks == "crys_sys_edges" or isinstance(xticks, int): if isinstance(xticks, int): # get x_locs of n=xticks tallest bars x_indices = df.reset_index().sort_values("counts").tail( xticks).index else: # add x_locs of n=xticks tallest bars x_indices = crys_sys_counts.width.cumsum() majorLocator = FixedLocator(x_indices) ax.xaxis.set_major_locator(majorLocator) plt.xticks(rotation=90) return ax
def test_other_settings(self): sg = SpaceGroup("Pbnm") self.assertEqual(sg.int_number, 62) self.assertEqual(sg.order, 8) self.assertRaises(ValueError, SpaceGroup, "hello")
def test_symmops(self): sg = SpaceGroup("Pnma") op = SymmOp.from_rotation_and_translation( [[1, 0, 0], [0, -1, 0], [0, 0, -1]], [0.5, 0.5, 0.5]) self.assertIn(op, sg.symmetry_ops)
def test_get_orbit(self): sg = SpaceGroup("Fm-3m") p = np.random.randint(0, 100 + 1, size=(3, )) / 100 self.assertLessEqual(len(sg.get_orbit(p)), sg.order)
def test_get_orbit(self): sg = SpaceGroup("Fm-3m") p = np.random.random_integers(0, 100, size=(3, )) p /= 100 self.assertLessEqual(len(sg.get_orbit(p)), sg.order)
def get_symops(self, data): """ In order to generate symmetry equivalent positions, the symmetry operations are parsed. If the symops are not present, the space group symbol is parsed, and symops are generated. """ symops = [] for symmetry_label in [ "_symmetry_equiv_pos_as_xyz", "_symmetry_equiv_pos_as_xyz_", "_space_group_symop_operation_xyz", "_space_group_symop_operation_xyz_" ]: if data.data.get(symmetry_label): try: symops = [ SymmOp.from_xyz_string(s) for s in data.data.get(symmetry_label) ] break except ValueError: continue if not symops: # Try to parse symbol 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): try: spg = space_groups.get( sub_spgrp(data.data.get(symmetry_label))) if spg: symops = SpaceGroup(spg).symmetry_ops break except ValueError: continue if not symops: # 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): try: symops = SpaceGroup.from_int_number( str2float( data.data.get(symmetry_label))).symmetry_ops break except ValueError: continue if not symops: warnings.warn("No _symmetry_equiv_pos_as_xyz type key found. " "Defaulting to P1.") symops = [SymmOp.from_xyz_string(s) for s in ['x', 'y', 'z']] return symops
def test_full_symbols(self): sg = SpaceGroup("P2/m2/m2/m") self.assertEqual(sg.symbol, "Pmmm")
from collections import Counter import tqdm x1 = Xdatcar('1/XDATCAR') x2 = Xdatcar('2/XDATCAR') x3 = Xdatcar('3/XDATCAR') x4 = Xdatcar('4/XDATCAR') x5 = Xdatcar('5/XDATCAR') structures = x1.structures + x2.structures + x3.structures + x4.structures + x5.structures all_na_structure = Poscar.from_file('na_sn_all_na_ext.POSCAR.vasp').structure vertex_species = 'Se' centre_species = 'Na' sg = SpaceGroup('I41/acd:2') from pymatgen import Structure, Lattice lattice = all_na_structure.lattice na1 = Structure.from_spacegroup(sg='I41/acd:2', lattice=lattice, species=['Na'], coords=[[0.25, 0.0, 0.125]]) na2 = Structure.from_spacegroup(sg='I41/acd:2', lattice=lattice, species=['Na'], coords=[[0.00, 0.0, 0.125]]) na3 = Structure.from_spacegroup(sg='I41/acd:2', lattice=lattice, species=['Na'], coords=[[0.0, 0.25, 0.0]]) na4 = Structure.from_spacegroup(sg='I41/acd:2', lattice=lattice, species=['Na'], coords=[[0.0, 0.0, 0.0]]) na5 = Structure.from_spacegroup(sg='I41/acd:2', lattice=lattice, species=['Na'], coords=[[0.75, 0.25, 0.0]]) na6 = Structure.from_spacegroup(sg='I41/acd:2', lattice=lattice, species=['Na'], coords=[[0.5, 0.75, 0.625]]) i2 = Structure.from_spacegroup(sg='I41/acd:2', lattice=lattice, species=['Na'], coords=[[0.666, 0.1376, 0.05]]) na_structures = {'Na1': na1, 'Na2': na2, 'Na3': na3, 'Na4': na4, 'Na5': na5, 'Na6': na6,
def test_subgroup_supergroup(self): self.assertTrue(SpaceGroup('Pma2').is_subgroup(SpaceGroup('Pccm'))) self.assertFalse( SpaceGroup.from_int_number(229).is_subgroup( SpaceGroup.from_int_number(230)))
def test_order_symm_ops(self): for name in SpaceGroup.SG_SYMBOLS: sg = SpaceGroup(name) self.assertEqual(len(sg.symmetry_ops), sg.order)
def get_symops(self, data): """ In order to generate symmetry equivalent positions, the symmetry operations are parsed. If the symops are not present, the space group symbol is parsed, and symops are generated. """ symops = [] for symmetry_label in [ "_symmetry_equiv_pos_as_xyz", "_symmetry_equiv_pos_as_xyz_", "_space_group_symop_operation_xyz", "_space_group_symop_operation_xyz_" ]: if data.data.get(symmetry_label): xyz = data.data.get(symmetry_label) if isinstance(xyz, six.string_types): warnings.warn("A 1-line symmetry op P1 CIF is detected!") xyz = [xyz] try: symops = [SymmOp.from_xyz_string(s) for s in xyz] break except ValueError: continue if not symops: # Try to parse symbol 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_" ]: sg = data.data.get(symmetry_label) if sg: sg = sub_spgrp(sg) try: spg = space_groups.get(sg) if spg: symops = SpaceGroup(spg).symmetry_ops warnings.warn( "No _symmetry_equiv_pos_as_xyz type key found. " "Spacegroup from %s used." % symmetry_label) break except ValueError: # Ignore any errors pass try: for d in _get_cod_data(): if sg == re.sub(r"\s+", "", d["hermann_mauguin"]): xyz = d["symops"] symops = [ SymmOp.from_xyz_string(s) for s in xyz ] warnings.warn( "No _symmetry_equiv_pos_as_xyz type key found. " "Spacegroup from %s used." % symmetry_label) break except Exception as ex: continue if symops: break if not symops: # 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): try: i = int(str2float(data.data.get(symmetry_label))) symops = SpaceGroup.from_int_number(i).symmetry_ops break except ValueError: continue if not symops: warnings.warn("No _symmetry_equiv_pos_as_xyz type key found. " "Defaulting to P1.") symops = [SymmOp.from_xyz_string(s) for s in ['x', 'y', 'z']] return symops
def spacegroup(self): sg_symbol = sg_symbol_from_int_number(self.spacegroup_number) return SpaceGroup(sg_symbol)
def test_crystal_system(self): sg = SpaceGroup("R-3c") self.assertEqual(sg.crystal_system, "trigonal") sg = SpaceGroup("R-3cH") self.assertEqual(sg.crystal_system, "trigonal")