tklib.tkcrystal.tkpymatgen のソースコード

"""
Pymatgenライブラリをラップし、構造解析や描画機能を提供するモジュールです。

このモジュールは、結晶構造データの読み込み、解析、視覚化のためのユーティリティクラスと関数を含みます。
VASPの出力ファイルからの構造情報の抽出や、Matplotlibを用いた構造描画をサポートします。

関連リンク: :doc:`tkpymatgen_usage`
"""

import time
import numpy as np
from numpy import sin, cos
from xml.etree import ElementTree as ET
import matplotlib
import matplotlib.pyplot as plt
import re # 're'モジュールがコード内で使用されていますが、importされていません。既存のロジックは変更しないため、このまま記述します。

from pymatgen.io.cif import CifParser, CifWriter
from pymatgen.core.structure import Structure
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
from pymatgen.core import Element
from pymatgen.core import Composition

from pymatgen.io.vasp.outputs import Vasprun
from pymatgen.io.vasp.inputs import Poscar

from tabulate import tabulate


from tklib.tkobject import tkObject
from tklib.tkutils import get_ext, pint, pfloat
from tklib.tksci.tksci import pi
from tklib.tkwrapper.tktqdm import tqdm


# URL: https://github.com/materialsproject/pymatgen/blob/v2023.5.10/pymatgen/analysis/diffraction/xrd.py
# 'CuKa', 'CuKa2', 'CuKa1', 'CuKb1', 'MoKa', 'MoKa2', 'MoKa1', 'MoKb1',
# 'CrKa', 'CrKa2', 'CrKa1', 'CrKb1', 'FeKa', 'FeKa2', 'FeKa1', 'FeKb1', 'CoKa', 'CoKa2', 'CoKa1', 'CoKb1',
# 'AgKa', 'AgKa2', 'AgKa1', 'AgKb1'
"""
WAVELENGTHS = {
    "CuKa": 1.54184,
    "CuKa2": 1.54439,
    "CuKa1": 1.54056,
    "CuKb1": 1.39222,
    "MoKa": 0.71073,
    "MoKa2": 0.71359,
    "MoKa1": 0.70930,
    "MoKb1": 0.63229,
    "CrKa": 2.29100,
    "CrKa2": 2.29361,
    "CrKa1": 2.28970,
    "CrKb1": 2.08487,
    "FeKa": 1.93735,
    "FeKa2": 1.93998,
    "FeKa1": 1.93604,
    "FeKb1": 1.75661,
    "CoKa": 1.79026,
    "CoKa2": 1.79285,
    "CoKa1": 1.78896,
    "CoKb1": 1.63079,
    "AgKa": 0.560885,
    "AgKa2": 0.563813,
    "AgKa1": 0.559421,
    "AgKb1": 0.497082,
}
"""

[ドキュメント] def to_str(v): """ 与えられた数値vを分数または記号の文字列に変換します。 特定の浮動小数点値を'1/2', '-1/2'などの分数表現や'+', '-'記号に変換します。 0.0はNoneに、正の値は先頭の'+'が削除された文字列になります。 :param v: 変換する浮動小数点数。 :type v: float :returns: 変換された文字列、またはNone。 :rtype: str or None """ eps = 1.0e-6 if v == 0.0: return None if v == 1.0: return '+' if v == -1.0: return '-' if abs(v - 0.5) < eps: return '1/2' if abs(v + 0.5) < eps: return '-1/2' if abs(v - 0.25) < eps: return '1/4' if abs(v + 0.25) < eps: return '-1/4' if abs(v - 1.0/3.0) < eps: return '1/3' if abs(v + 1.0/3.0) < eps: return '-1/3' if abs(v - 2.0/3.0) < eps: return '2/3' if abs(v + 2.0/3.0) < eps: return '-2/3' if abs(v - 1.0/6.0) < eps: return '1/6' if abs(v + 1.0/6.0) < eps: return '-1/6' if abs(v - 5.0/6.0) < eps: return '5/6' if abs(v + 5.0/6.0) < eps: return '-5/6' if v > 0.0: return re.sub(r'^\+', '', v) # reモジュールがimportされていません。 return v
[ドキュメント] def vector_to_str(v): """ 3要素のベクトルをx, y, z成分を含む文字列に変換します。 to_str関数を使用して各成分を変換し、非Noneの成分を結合して文字列を生成します。 先頭の'+'記号は削除されます。 :param v: 変換する3要素のベクトル。 :type v: list or tuple or numpy.ndarray :returns: 変換されたベクトル文字列。 :rtype: str """ sx = to_str(v[0]) sy = to_str(v[1]) sz = to_str(v[2]) s = '' if sx: s += sx + 'x' if sy: s += sy + 'y' if sz: s += sz + 'z' return re.sub(r'^\+', '', s) # reモジュールがimportされていません。
[ドキュメント] def matrix_to_str(m): """ 3x3行列を行列の各行をベクトル文字列に変換して返します。 :param m: 変換する3x3行列。 :type m: list of list or numpy.ndarray :returns: 各行のベクトル文字列(x, y, z)のタプル。 :rtype: tuple of str """ x = vector_to_str(m[0]) y = vector_to_str(m[1]) z = vector_to_str(m[2]) return x, y, z
[ドキュメント] def is_valid_vasprun(path): """ 指定されたパスのvasprun.xmlファイルが有効なXML形式であるかをチェックします。 ファイルをXMLとしてパースできるかどうかに基づいて真偽値を返します。 :param path: vasprun.xmlファイルのパス。 :type path: str :returns: ファイルが有効なXMLであればTrue、そうでなければFalse。 :rtype: bool """ try: tree = ET.parse(path) return True except ET.ParseError: return False
[ドキュメント] class tkPymatgenVASP(tkObject): """ VASPの出力ファイル(vasprun.xml, POSCAR)を扱うためのPymatgenラッパーを提供します。 このクラスは、VASP計算の結果から構造情報やその他のデータを読み込み、管理することを目的としています。 """ def __init__(self, **args): """ tkPymatgenVASPクラスの新しいインスタンスを初期化します。 :param args: 親クラスtkObjectに渡される可変長キーワード引数。 :type args: dict """ self.poscar = None self.vasprun = None self.structure = None def __del__(self): """ tkPymatgenVASPオブジェクトが破棄される際に実行されるデストラクタです。 現在の実装では何も行いません。 """ pass
[ドキュメント] def read_vasprun(self, infile = 'vasprun.xml', validate = False): """ 指定されたファイルからVASPのvasprun.xmlデータを読み込みます。 ファイルが'.xml'拡張子を持つ場合、PymatgenのVasprunオブジェクトとして読み込みます。 必要に応じてXMLの妥当性検証を行うこともできます。 :param infile: 読み込むvasprun.xmlファイルのパス。デフォルトは'vasprun.xml'です。 :type infile: str :param validate: XMLファイルの妥当性を検証するかどうかを示すフラグ。Trueの場合、無効なXMLは読み込みません。 :type validate: bool :returns: 読み込みに成功した場合、Vasprunオブジェクトを返します。それ以外の場合はNoneを返します。 :rtype: pymatgen.io.vasp.outputs.Vasprun or None """ ext = get_ext(infile).lower() if ext == '.xml': if validate and not is_valid_vasprun(infile): return None self.vasprun = Vasprun(infile) return self.vasprun return None
[ドキュメント] def read_structure(self, infile, vasprun = None): """ 指定されたファイルから結晶構造を読み込み、PymatgenのStructureオブジェクトとして設定します。 vasprun.xmlファイルまたはPOSCARファイルからの読み込みをサポートします。 vasprun.xmlを読み込んだ場合、最終構造を取得します。 :param infile: 読み込む構造ファイルのパス(例: 'vasprun.xml'または'POSCAR')。 :type infile: str :param vasprun: 既存のVasprunオブジェクト。指定された場合、そのfinal_structureを使用します。 Noneの場合、infileが'vasprun.xml'であれば新たにVasprunを読み込みます。 :type vasprun: pymatgen.io.vasp.outputs.Vasprun or None :returns: 読み込みに成功した場合、(PoscarオブジェクトまたはVasprunオブジェクト, Structureオブジェクト)のタプルを返します。 失敗した場合は(False, False)を返します。 :rtype: tuple of (pymatgen.io.vasp.inputs.Poscar or pymatgen.io.vasp.outputs.Vasprun or bool, pymatgen.core.structure.Structure or bool) """ if vasprun is None: if infile == 'vasprun.xml': self.vasprun = Vasprun(infile) if self.vasprun: self.structure = vasprun.final_structure # vasprunがNoneの可能性があり、この行でエラーとなる可能性があります。 return self.vasprun, self.structure else: return False, False # 上記のifブロックがTrueの場合、以下のコードは到達しません。 self.poscar = Poscar.from_file(infile, check_for_POTCAR = True) if not self.poscar: return False, False self.structure = self.poscar.structure return self.poscar, self.structure
#class tkSpaceGroupObject(tkCrystalObject):
[ドキュメント] class tkPymatgen(tkObject): """ Pymatgenの機能を用いて結晶構造の解析や操作を行うためのラッパークラスです。 構造データの読み込み、対称性の解析、情報の抽出、および描画機能を提供します。 """ def __init__(self, **args): """ tkPymatgenクラスの新しいインスタンスを初期化します。 :param args: 親クラスtkObjectに渡される可変長キーワード引数。 :type args: dict """ self.structure = None self.space_group_analyzer = None self.symmetrized_structure = None self.iSPG = None self.SPG_name = None def __del__(self): """ tkPymatgenオブジェクトが破棄される際に実行されるデストラクタです。 現在の実装では何も行いません。 """ pass #https://github.com/materialsproject/pymatgen/blob/v2023.10.4/pymatgen/symmetry/structure.py#L18-L151 def __str__(self, structure = None) -> str: """ 現在の構造、または指定された構造の詳細な文字列表現を返します。 PymatgenのSymmetrizedStructureの__str__メソッドに似た形式で、 組成、格子パラメータ、サイト情報などを整形して出力します。 :param structure: 情報を表示するPymatgenのStructureオブジェクト。 Noneの場合、自身が持つstructure属性を使用します。 :type structure: pymatgen.core.structure.Structure or None :returns: 構造の詳細情報を含む文字列。 :rtype: str """ if structure is None: structure = self.structure if structure is None: return self.ClassPath() outs = [ "SymmetrizedStructure", f"Full Formula ({structure.composition.formula})", f"Reduced Formula: {structure.composition.reduced_formula}", ] if getattr(structure, 'spacegroup', None): outs.append(f"Spacegroup: {structure.spacegroup.int_symbol} ({structure.spacegroup.int_number})") def to_str(x): return f"{x:>10.6f}" outs.append(f"abc : {' '.join(to_str(val) for val in structure.lattice.abc)}") outs.append(f"angles: {' '.join(to_str(val) for val in structure.lattice.angles)}") if structure._charge: outs.append(f"Overall Charge: {structure._charge:+}") if getattr(structure, 'equivalent_sites', None): outs.append(f"Sites ({len(structure.equivalent_sites)})") data = [] props = structure.site_properties keys = sorted(props) for idx, sites in enumerate(structure.equivalent_sites): site = sites[0] row = [str(idx), site.species_string] row.extend([to_str(j) for j in site.frac_coords]) row.append(structure.wyckoff_symbols[idx]) for k in keys: row.append(props[k][idx]) data.append(row) outs.append(tabulate(data, headers=["#", "SP", "a", "b", "c", "Wyckoff", *keys])) return "\n".join(outs)
[ドキュメント] def print_variables(self, obj): """ 指定されたオブジェクトのメンバ変数を標準出力に表示します。 :param obj: メンバ変数を出力するオブジェクト。 :type obj: object """ variables = self.get_member_variables(obj) print("variables:") for m in variables: print(f" variable: {m}")
[ドキュメント] def print_methods(self, obj): """ 指定されたオブジェクトのメンバ関数(メソッド)を標準出力に表示します。 :param obj: メンバ関数を出力するオブジェクト。 :type obj: object """ members = self.get_member_functions(obj)[0] print("methods:") for m in members: print(f" method: {m}")
[ドキュメント] def read(self, path, primitive = False): """ 指定されたファイルパスから結晶構造を読み込み、Structureオブジェクトとして設定します。 :param path: 読み込む構造ファイルのパス。 :type path: str :param primitive: Trueの場合、読み込まれた構造をプリミティブセルに変換します。 :type primitive: bool :returns: 読み込まれたPymatgenのStructureオブジェクト。 :rtype: pymatgen.core.structure.Structure """ self.path = path self.structure = Structure.from_file(path, primitive = primitive) return self.structure
[ドキュメント] def get_structure(self, structure = None): """ 現在のインスタンスに設定されているStructureオブジェクトを取得します。 もしsymmetrized_structureが設定されていればそれを優先し、そうでなければstructureを返します。 引数にstructureが指定された場合はそれをそのまま返します。 :param structure: 使用するPymatgenのStructureオブジェクト。指定しない場合はインスタンスの属性が使用されます。 :type structure: pymatgen.core.structure.Structure or None :returns: PymatgenのStructureオブジェクト。見つからない場合はNone。 :rtype: pymatgen.core.structure.Structure or None """ if structure is None: structure = self.get("symmetrized_structure", None) if structure is None: structure = self.get("structure", None) return structure
[ドキュメント] def to(self, path, structure = None, symprec = 1.0e-3, print_level = 0): """ 構造情報を指定されたファイルパスに保存します。 現在はCIF形式での symmetrized_structure の保存をサポートしています。 :param path: 構造を保存するファイルのパス。 :type path: str :param structure: 保存するPymatgenのStructureオブジェクト。Noneの場合、内部の構造が使用されます。 :type structure: pymatgen.core.structure.Structure or None :param symprec: 対称性解析に使用する許容誤差。symmetrized_structureのCifWriterに渡されます。 :type symprec: float :param print_level: 詳細な出力レベル。0より大きい場合、保存情報を表示します。 :type print_level: int :returns: 保存が成功した場合True、Structureオブジェクトが見つからない場合はNone。 :rtype: bool or None """ structure = self.get_structure(structure) if structure is None: print("\nError in tkpymatgen.to(): Can not get structure.") return None if print_level: print("") print(f"Save the symmetrized structure to [{path}]") # This does not save the symmetrized structure. So implement with tkCrytal # self.struct.to(filename = convCIFfile, fmt = "cif") writer = CifWriter(self.symmetrized_structure, symprec = symprec) writer.write_file(path) return True
[ドキュメント] def get_structure_inf(self): """ 現在のStructureオブジェクトから様々な情報を辞書形式で取得します。 格子パラメータ、体積、距離行列、組成、原子座標など、Structureオブジェクトの基本的な情報を集約します。 :returns: 構造の様々な情報を含む辞書。 :rtype: dict """ s = self.structure lattice_inf = s.lattice a, b, c, alpha, beta, gamma = lattice_inf.parameters volume = lattice_inf.volume aij = lattice_inf.matrix inf = { "dict": s.as_dict, "lattice_parameters": [*s.lattice.abc, *s.lattice.angles], # "lattice_vectors": s.lattice, "lattice_vectors": s.lattice.matrix, "gij" : s.distance_matrix, "total_charge": s.charge, "composition" : s.composition, "formula" : s.formula, "volume" : s.volume, "density" : s.density, "properties" : s.properties, "cart_coord" : s.cart_coords, "frac_coord" : s.frac_coords, #print("atomic num:", s.atomic_numbers) } return inf
#print("site_properties:", site_properties.sites) #print("species:", symmetrized_structure.species) #print("elements:", symmetrized_structure.elements) #print("types_of_species:", symmetrized_structure.types_of_species) #print("types_of_specie:", symmetrized_structure.types_of_specie)
[ドキュメント] def structure2inf(self, structure = None): """ 構造から格子情報とサイト情報を抽出しますが、この関数は途中で処理が終了し、辞書を返しません。 :param structure: 情報を抽出するPymatgenのStructureオブジェクト。Noneの場合、内部の構造が使用されます。 :type structure: pymatgen.core.structure.Structure or None """ structure = self.get_structure(structure) inf = { "latt": [latt.a, latt.b, latt.c, latt.alpha, latt.beta, latt.gamma], } inf["sites"] = [] for site in structure: element = site.specie xyz = site.frac_coords xyzc = site.coords inf["sites"].append({"atom_name": element, "xyz": xyz, "xyzc": xyzc})
# ここでinfを返すべきですが、コードはここで終了しています。
[ドキュメント] def structure2inf_flat(self, structure = None, symprec = 1.0e-4, coordinate = "fc", site_name = "as"): """ 構造からフラットな形式で情報を抽出し、辞書として返します。 空間群情報、格子定数、化学式、原子数、組成式、各原子の座標(分数または実空間)などを含みます。 原子の座標は、サイトIDまたは原子名と連番でアクセスできるように格納されます。 :param structure: 情報を抽出するPymatgenのStructureオブジェクト。Noneの場合、内部の構造が使用されます。 :type structure: pymatgen.core.structure.Structure or None :param symprec: 対称性解析に使用する許容誤差。 :type symprec: float :param coordinate: 出力する座標の形式。"f"で分数座標、"c"で実空間座標。両方含める場合は"fc"のように指定します。 :type coordinate: str :param site_name: サイト名の命名規則。"s"でサイトIDベース、"a"で原子名ベース。両方含める場合は"as"のように指定します。 :type site_name: str :returns: 構造のフラットな情報を含む辞書。 :rtype: dict """ structure = self.get_structure(structure) latt = structure.lattice iSPG, SPG_name, symmetrized_structure = self.symmetrize(structure, symprec) formula, reduced_formula = self.chemical_formula(structure) natoms = len(structure) composition = Composition(reduced_formula) formula_weight = pfloat(composition.weight) num_atoms_in_formula = composition.num_atoms Z = int(natoms / num_atoms_in_formula + 1.0e-5) inf = { "spg_name" : SPG_name, "ispg" : iSPG, "a" : latt.a, "b" : latt.b, "c" : latt.c, "alpha" : latt.alpha, "beta" : latt.beta, "gamma" : latt.gamma, "formula" : formula, "formula_weight" : formula_weight, "formula_unit" : reduced_formula, "natoms" : natoms, "natoms_in_formula": num_atoms_in_formula, "Z" : Z, } atomic_sites = structure.sites iatom_dict = {} for idx, site in enumerate(atomic_sites): name = site.specie.symbol xyz = site.frac_coords xyzc = site.coords if name in iatom_dict.keys(): iatom_dict[name] += 1 else: iatom_dict[name] = 1 iatom = iatom_dict[name] label = f"{name}_{iatom}" inf[f"atom_name{idx+1}"] = name if 'f' in coordinate and 's' in site_name: inf[f"xf_site_{idx+1}"] = xyz[0] inf[f"yf_site_{idx+1}"] = xyz[1] inf[f"zf_site_{idx+1}"] = xyz[2] if 'c' in coordinate and 's' in site_name: inf[f"xc_site_{idx+1}"] = xyzc[0] inf[f"yc_site_{idx+1}"] = xyzc[1] inf[f"zc_site_{idx+1}"] = xyzc[2] if 'f' in coordinate and 'a' in site_name: inf[f"xf_{label}"] = xyz[0] inf[f"yf_{label}"] = xyz[1] inf[f"zf_{label}"] = xyz[2] if 'c' in coordinate and 'a' in site_name: inf[f"xc_{label}"] = xyzc[0] inf[f"yc_{label}"] = xyzc[1] inf[f"zc_{label}"] = xyzc[2] return inf
[ドキュメント] def chemical_formula(self, structure = None): """ 構造から化学式と簡約化された化学式を取得します。 :param structure: 情報を抽出するPymatgenのStructureオブジェクト。Noneの場合、内部の構造が使用されます。 :type structure: pymatgen.core.structure.Structure or None :returns: (化学式, 簡約化された化学式)のタプル。構造がNoneの場合は(None, None)。 :rtype: tuple of (str or None, str or None) """ structure = self.get_structure(structure) if structure is None: return None, None formula = structure.formula reduced_formula = structure.composition.reduced_formula return formula, reduced_formula
[ドキュメント] def get_site_inf(self, site): """ 指定されたサイトから基本的な情報を辞書形式で取得します。 組成、種、座標などを含みます。 :param site: 情報を取得するPymatgenのSiteオブジェクト。 :type site: pymatgen.core.sites.Site :returns: サイトの基本的な情報を含む辞書。 :rtype: dict """ inf = { "composition": site.species_string, "species": site.species, # "specie": site.specie, "label": site.label, "x": site.a, "y": site.b, "z": site.c, } return inf
[ドキュメント] def get_sites(self, structure): """ 指定された構造のすべてのサイトのリストを取得します。 :param structure: サイトを取得するPymatgenのStructureオブジェクト。 :type structure: pymatgen.core.structure.Structure :returns: Structureに含まれるすべてのSiteオブジェクトのリスト。 :rtype: list of pymatgen.core.sites.Site """ sites = structure.sites return sites
[ドキュメント] def get_asymmetric_sites(self, structure): """ 指定された構造の非対称サイトのリストを取得します。 結晶学的に等価なサイトのグループから、代表となるサイトのみを抽出します。 :param structure: 非対称サイトを取得するPymatgenのStructureオブジェクト。 :type structure: pymatgen.core.structure.Structure :returns: 非対称Siteオブジェクトのリスト。 :rtype: list of pymatgen.core.sites.Site """ sites = self.get_sites(structure) asym_sites = [] for s in sites: ls = structure.find_equivalent_sites(s) if s is ls[0]: asym_sites.append(ls[0]) return asym_sites
[ドキュメント] def get_site_occ_inf(self, site): """ 指定されたサイトの占有情報(Composition情報)を辞書形式で取得します。 サイトの文字列表現、化学式、重さ、組成などを返します。 :param site: 情報を取得するPymatgenのSiteオブジェクト。 :type site: pymatgen.core.sites.Site :returns: サイトの占有情報を含む辞書。 :rtype: dict """ inf = { "site_name": site.__str__().replace(' ', ''), "alphabetical_formula": site.alphabetical_formula, "formula": site.formula, "reduced_formula": site.reduced_formula, "weight": site.weight, # "charge": site.charge, "element_composition": site.element_composition, "elements": site.elements, "fractional_composition": site.fractional_composition, } return inf
[ドキュメント] def get_species_and_occu(self, structure): """ 指定された構造のサイトに存在する元素とその占有率のリストを取得します。 :param structure: 情報を取得するPymatgenのStructureオブジェクト。 :type structure: pymatgen.core.structure.Structure :returns: 元素と占有率のリスト。 :rtype: list """ species_occ = structure.species_and_occu return species_occ
[ドキュメント] def get_composition_inf(self, composition): """ PymatgenのCompositionオブジェクトから詳細な情報を辞書形式で取得します。 組成、原子数、種数、分子量などを含みます。 :param composition: 情報を取得するPymatgenのCompositionオブジェクト。 :type composition: pymatgen.core.Composition :returns: Compositionオブジェクトの詳細情報を含む辞書。 :rtype: dict """ d = composition.to_data_dict comp = d['unit_cell_composition'] inf = { "dict": d, "site_name": composition.__str__().replace(' ', ''), "composition": comp, "unit_cell_composition": comp, "natoms": composition.num_atoms, "nspecies": len(comp), "weight": composition.weight, } return inf ''' comp = Composition(formula) print(f"{comp=}") print(f"{comp.as_dict()=}") print(comp.get_el_amt_dict()) print(comp.get_integer_formula_and_factor()) print(comp.reduced_formula) print(comp.reduced_composition) print(comp.weight) print(comp.num_atoms) print(comp.elements) print(comp.formula) print(comp.alphabetical_formula) print(comp.num_atoms) print(comp.chemical_system) print(comp.fractional_composition) '''
[ドキュメント] def get_ionic_radius(self, atom_name, charge = None, ncoordination = None): """ 指定された原子名、電荷、配位数に基づいてイオン半径を取得します。 PymatgenのElementオブジェクトからイオン半径のデータにアクセスします。 電荷が指定されない場合、一般的な酸化状態の最初のものが使用されます。 配位数が指定されない場合、指定された電荷に最も適合する半径が返されます。 :param atom_name: 原子名(例: "O", "Fe")。 :type atom_name: str :param charge: イオンの電荷。Noneの場合、一般的な酸化状態が使用されます。 :type charge: int or None :param ncoordination: 配位数。Noneの場合、配位数を考慮しない半径が返されます。 :type ncoordination: int or None :returns: 原子名、電荷、配位数に対応するイオン半径。見つからない場合は1.0またはNone。 :rtype: float or None """ element = Element(atom_name) if charge is None: charge = element.common_oxidation_states[0] ionic_radii = element.ionic_radii if ncoordination is None: r = ionic_radii.get(charge, 1.0) else: r = ionic_radii.get((charge, ncoordination), None) if r is None and charge in ionic_radii: r = ionic_radii.get(charge, 1.0) return r
[ドキュメント] def get_atom_inf(self, atom_name, charge = None, ncoordination = None): """ 指定された原子名から原子の基本情報(質量、原子番号、電荷、イオン半径、電子構造)を辞書形式で取得します。 :param atom_name: 原子名(例: "O", "Fe")。 :type atom_name: str :param charge: イオンの電荷。Noneの場合、一般的な酸化状態の最初のものが使用されます。 :type charge: int or None :param ncoordination: 配位数。Noneの場合、配位数を考慮しないイオン半径が取得されます。 :type ncoordination: int or None :returns: 原子情報を含む辞書。 :rtype: dict """ element = Element(atom_name) if charge is None: charge = element.common_oxidation_states[0] if charge is None: charge = 0 r = self.get_ionic_radius(atom_name, charge, ncoordination) electronic_structure = element.electronic_structure inf = { "name": atom_name, "M": element.atomic_mass, "Z": element.Z, "charge": charge, "r": r, "electronic_structure": electronic_structure, } return inf
[ドキュメント] def elements(self, structure = None): """ 指定された構造に含まれる元素のリストと、それぞれの原子量、原子番号、数を取得します。 :param structure: 情報を抽出するPymatgenのStructureオブジェクト。Noneの場合、内部の構造が使用されます。 :type structure: pymatgen.core.structure.Structure or None :returns: 各元素の原子名、原子量、原子番号、数を含む辞書のリスト。構造がNoneの場合はNone。 :rtype: list of dict or None """ formula, reduced_formula = self.chemical_formula(structure) if formula is None: return None composition = Composition(formula) c_dict = composition.as_dict() e_list = [] for i, atom_name in enumerate(c_dict.keys()): element = Element(atom_name) inf = element.data # print(inf) M = inf['Atomic mass'] Z = inf['Atomic no'] e_list.append({"atom_name": atom_name, "M": M, "Z": Z, "n": c_dict[atom_name]}) return e_list
[ドキュメント] def get_atom_color(self, atom_name, Z): """ 指定された原子名と原子番号に基づいて原子の描画色を決定します。 既知の原子(O, S, Se, Bi)には特定の色を割り当て、それ以外の原子には原子番号に基づく擬似ランダムな色を生成します。 :param atom_name: 原子名(例: "O", "Fe")。 :type atom_name: str :param Z: 原子番号。 :type Z: int :returns: 原子の色を表す文字列(例: "red")またはRGBタプル。 :rtype: str or tuple of float """ # colors = {} colors = {"O": "red", "S": "green", "Se": "darkyellow", "Bi": "blue"} if atom_name in colors: return colors[atom_name] # np.random.seed(Z) # r = np.random.rand() # g = np.random.rand() # b = np.random.rand() r = (Z % 9) / 8 g = (Z % 12) / 11 b = (Z % 15) / 14 total = r + g + b if total > 0.8: r *= 0.8 b *= 0.8 g *= 0.8 return (r, g, b)
[ドキュメント] def draw_box(self, axis, structure, origin, ax, ay, az, color = 'black', linewidth = 1.0): """ 3D軸上に単位セル(または指定された範囲)のボックスを描画します。 :param axis: Matplotlibの3D軸オブジェクト。 :type axis: matplotlib.axes._subplots.Axes3DSubplot :param structure: 基になるPymatgenのStructureオブジェクト。 :type structure: pymatgen.core.structure.Structure :param origin: ボックスの開始点となる原点座標。 :type origin: list or numpy.ndarray :param ax: x方向のベクトル。 :type ax: list or numpy.ndarray :param ay: y方向のベクトル。 :type ay: list or numpy.ndarray :param az: z方向のベクトル。 :type az: list or numpy.ndarray :param color: ボックスの線の色。 :type color: str :param linewidth: ボックスの線の太さ。 :type linewidth: float """ lattice = structure.lattice a000 = origin a100 = [origin[i] + ax[i] for i in range(3)] a101 = [origin[i] + ax[i] + az[i] for i in range(3)] a110 = [origin[i] + ax[i] + ay[i] for i in range(3)] a111 = [origin[i] + ax[i] + ay[i] + az[i] for i in range(3)] a010 = [origin[i] + ay[i] for i in range(3)] a011 = [origin[i] + ay[i] + az[i] for i in range(3)] a001 = [origin[i] + az[i] for i in range(3)] ls = [a000, a100, a110, a010, a000, a001, a101, a111, a011, a001] # ls = lattice.get_cartesian_coords([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0], [0, 0, 0], # [0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1], [0, 0, 1]]) for i in range(4): axis.plot([ls[i][0], ls[i+1][0]], [ls[i][1], ls[i+1][1]], [ls[i][2], ls[i+1][2]], color = 'blue', linewidth = 0.5) axis.plot([ls[i+5][0], ls[i+6][0]], [ls[i+5][1], ls[i+6][1]], [ls[i+5][2], ls[i+6][2]], color = 'blue', linewidth = 0.5) axis.plot([ls[i][0], ls[i+5][0]], [ls[i][1], ls[i+5][1]], [ls[i][2], ls[i+5][2]], color = 'blue', linewidth = 0.5)
[ドキュメント] def calculate_all_distances(self, structure, max_distance = 2.75): """ 構造内のすべての原子ペア間の距離を計算し、指定された最大距離以下のペアをリストアップします。 :param structure: 距離を計算するPymatgenのStructureオブジェクト。 :type structure: pymatgen.core.structure.Structure :param max_distance: 距離を記録する最大値(Å)。 :type max_distance: float :returns: [原子Iのインデックス, 原子Jのインデックス, 距離]のリスト。 :rtype: list of list """ natoms = len(structure) sites = structure.sites # print("natoms=", natoms) distances = [] for i in range(natoms): for j in range(i + 1, natoms): # distance = structure.get_distance(i, j) pos_i = sites[i].coords pos_j = sites[j].coords distance = np.linalg.norm(np.array(pos_i) - np.array(pos_j)) if distance <= max_distance: distances.append([i, j, distance]) return distances
[ドキュメント] def draw_atoms2(self, structure, draw_range, kr = 400.0): """ (未定義変数を含むため機能しない可能性あり) 指定された描画範囲内の原子をプロットし、新しいStructureオブジェクトとラベル辞書を返します。 各原子は原子名と原子番号に基づいて色とサイズ(半径)が決定されます。 :param structure: 描画するPymatgenのStructureオブジェクト。 :type structure: pymatgen.core.structure.Structure :param draw_range: [[xmin, xmax], [ymin, ymax], [zmin, zmax]]形式の描画範囲。 :type draw_range: list of list of float :param kr: 原子半径をスケーリングするための係数。 :type kr: float :returns: 描画された原子のみを含む新しいStructureオブジェクトと、原子名をキーとするラベル辞書。 :rtype: tuple of (pymatgen.core.structure.Structure, dict) """ xrange, yrange, zrange = draw_range structure_draw = Structure(lattice, [], []) # latticeが未定義 label_dict = {} for site in sites: # sitesが未定義 x, y, z = site.coords if x < xrange[0] or xrange[1] < x: continue if y < yrange[0] or yrange[1] < y: continue if z < zrange[0] or zrange[1] < z: continue atom_name = site.specie.symbol atom_inf = self.get_atom_inf(atom_name) # print("atom=", atom_name, atom_inf) r = kr * atom_inf["r"] color = self.get_atom_color(atom_name, atom_inf["Z"]) if atom_name not in label_dict.keys(): label_dict[atom_name] = 1 ax.scatter(x, y, z, label = atom_name, s = r, color = color) # axが未定義 # ax.text(x, y, z, atom_name, fontsize=12, ha='center') else: ax.scatter(x, y, z, s = r, color = color) structure_draw.append(atom_name, site.coords, coords_are_cartesian = True) return structure_draw, label_dict
[ドキュメント] def draw_atoms(self, ax, structure, draw_range, kr = 400.0, atom_alpha = 0.5, vector_r = 3.0, vector_length = 3.0, arrow_length_ratio = 0.3): """ 指定された3D軸上に構造の原子を描画します。 原子は色とサイズで表現され、`velocity`プロパティを持つ場合は速度ベクトルも描画されます。 :param ax: Matplotlibの3D軸オブジェクト。 :type ax: matplotlib.axes._subplots.Axes3DSubplot :param structure: 描画するPymatgenのStructureオブジェクト。 :type structure: pymatgen.core.structure.Structure :param draw_range: [[xmin, xmax], [ymin, ymax], [zmin, zmax]]形式の描画範囲。 :type draw_range: list of list of float :param kr: 原子半径をスケーリングするための係数。 :type kr: float :param atom_alpha: 原子の透明度(0.0-1.0)。 :type atom_alpha: float :param vector_r: 速度ベクトル線の太さ。 :type vector_r: float :param vector_length: 速度ベクトルの最大描画長さ。 :type vector_length: float :param arrow_length_ratio: 速度ベクトルの矢印部分の長さ比率。 :type arrow_length_ratio: float :returns: 描画された原子のみを含む新しいStructureオブジェクトと、描画情報を含む辞書。 :rtype: tuple of (pymatgen.core.structure.Structure, dict) """ lattice = structure.lattice structure_draw = Structure(lattice, [], []) eps = 0.1 xrange, yrange, zrange = draw_range sites = structure.sites draw_inf = {"atoms": {}} arrows_data_list = [] i = 0 for isite, site in enumerate(sites): x, y, z = site.coords if x < xrange[0] - eps or xrange[1] + eps < x: continue if y < yrange[0] - eps or yrange[1] + eps < y: continue if z < zrange[0] - eps or zrange[1] + eps < z: continue atom_name = site.specie.symbol atom_inf = self.get_atom_inf(atom_name) r = kr * atom_inf["r"] color = self.get_atom_color(atom_name, atom_inf["Z"]) structure_draw.append(atom_name, site.coords, coords_are_cartesian = True) structure_draw.sites[i].properties = site.properties.copy() i += 1 v = site.properties.get("velocity", None) if v: vx, vy, vz = v else: vx, vy, vz = None, None, None if atom_name not in draw_inf["atoms"].keys(): draw_inf["atoms"][atom_name] = \ {"isite": [], "r": r, "color": color, "x": [], "y": [], "z": [], "vx": [], "vy": [], "vz": []} draw_inf["atoms"][atom_name]["isite"].append(isite) draw_inf["atoms"][atom_name]["x"].append(x) draw_inf["atoms"][atom_name]["y"].append(y) draw_inf["atoms"][atom_name]["z"].append(z) draw_inf["atoms"][atom_name]["vx"].append(vx) draw_inf["atoms"][atom_name]["vy"].append(vy) draw_inf["atoms"][atom_name]["vz"].append(vz) l0_max = 0.0 for atom_name, d in draw_inf["atoms"].items(): vx, vy, vz = d["vx"], d["vy"], d["vz"] if vx[0] is None: continue for i in range(len(vx)): l0 = np.linalg.norm([vx[i], vy[i], vz[i]]) if l0_max < l0: l0_max = l0 if l0_max > 0.0: kv = vector_length / l0_max else: kv = None # print("vector_length=", vector_length, l0_max, kv) plot_data_list = [] for atom_name, d in draw_inf["atoms"].items(): x, y, z = d["x"], d["y"], d["z"] vx, vy, vz = d["vx"], d["vy"], d["vz"] color = d["color"] scatter = ax.scatter(x, y, z, label = atom_name, marker = 'o', s = d["r"], alpha = atom_alpha, facecolor = color, edgecolor = "w") #color = color) plot_data_list.append(scatter) if vx[0] is not None: for i in range(len(x)): l0 = np.linalg.norm([vx[i], vy[i], vz[i]]) length = l0 * kv # print(f" {atom_name} at ({x[i]:.4f}, {y[i]:.4f}, {z[i]:.4f}) dx=({vx[i]:10.4g}, {vy[i]:10.4g}, {vz[i]:10.4g}) |dx|={l0:10.4g} l={length:.4f}") # print("xyz=", i, x[i], y[i], z[i], vx[i], vy[i], vz[i], length) quiver = ax.quiver(x, y, z, vx[i], vy[i], vz[i], length = length, linewidth = vector_r, arrow_length_ratio = arrow_length_ratio, color = color, normalize = True) arrows_data_list.append(quiver) draw_inf["plot_data_list"] = plot_data_list draw_inf["arrows_data_list"] = arrows_data_list draw_inf["l0_max"] = l0_max draw_inf["kv"] = kv return structure_draw, draw_inf
[ドキュメント] def configure_axis_structure(self, ax, xrange, yrange, zrange, fontsize = 12, legend_fontsize = 12): """ 3Dプロットの軸を構造描画用に設定します。 軸ラベル、目盛り、背景、ボックスアスペクト比などを調整します。 :param ax: Matplotlibの3D軸オブジェクト。 :type ax: matplotlib.axes._subplots.Axes3DSubplot :param xrange: x軸の範囲 [xmin, xmax]。 :type xrange: list of float :param yrange: y軸の範囲 [ymin, ymax]。 :type yrange: list of float :param zrange: z軸の範囲 [zmin, zmax]。 :type zrange: list of float :param fontsize: 軸ラベルと目盛りのフォントサイズ。 :type fontsize: int :param legend_fontsize: 凡例のフォントサイズ (ただしこの関数では直接使用されません)。 :type legend_fontsize: int """ ax.tick_params(axis = 'both', which = 'major', labelsize = fontsize) ax.set_xlabel(f'$x$', fontsize = fontsize, labelpad = -5) ax.set_ylabel(f'$y$', fontsize = fontsize, labelpad = -5) ax.set_zlabel(f'$z$', fontsize = fontsize, labelpad = 0) # ax.set_xlabel(f'$a=${lattice.a:.4f} $\AA$', fontsize = fontsize, labelpad = -5) # ax.set_ylabel(f'$b=${lattice.b:.4f} $\AA$', fontsize = fontsize, labelpad = -5) # ax.set_zlabel(f'$c=${lattice.c:.4f} $\AA$', fontsize = fontsize, labelpad = 0) ax.grid(False) ax.xaxis.pane.fill = False ax.yaxis.pane.fill = False ax.zaxis.pane.fill = False ax.xaxis.pane.set_edgecolor('w') ax.yaxis.pane.set_edgecolor('w') ax.zaxis.pane.set_edgecolor('w') ax.xaxis.pane.set_alpha(0) ax.yaxis.pane.set_alpha(0) ax.zaxis.pane.set_alpha(0) # ax.w_xaxis.line.set_color('none') # ax.w_yaxis.line.set_color('none') # ax.w_zaxis.line.set_color('none') ax.set_xticks([]) ax.set_yticks([]) ax.set_zticks([]) ax.set_xticklabels([]) ax.set_yticklabels([]) ax.set_zticklabels([]) ax.set_xlim(xrange) ax.set_ylim(yrange) ax.set_zlim(zrange) ax.set_box_aspect([xrange[1] - xrange[0], yrange[1] - yrange[0], zrange[1] - zrange[0]])
[ドキュメント] def get_xyz_range(self, structure, draw_range): """ 描画範囲の相対座標を絶対座標に変換します。 `draw_range`がNoneの場合、単位セルの範囲を使用します。 :param structure: 基になるPymatgenのStructureオブジェクト。 :type structure: pymatgen.core.structure.Structure :param draw_range: x,y,z方向の描画範囲の相対座標 [[xmin_rel, xmax_rel], [ymin_rel, ymax_rel], [zmin_rel, zmax_rel]]。 :type draw_range: list of list of float :returns: x, y, z軸の絶対座標範囲のタプル。 :rtype: tuple of list of float """ if draw_range[0]: xrange = [draw_range[0][0] * structure.lattice.a, draw_range[0][1] * structure.lattice.a] else: xrange = [0, structure.lattice.a] if draw_range[1]: yrange = [draw_range[1][0] * structure.lattice.b, draw_range[1][1] * structure.lattice.b] else: yrange = [0, structure.lattice.b] if draw_range[2]: zrange = [draw_range[2][0] * structure.lattice.c, draw_range[2][1] * structure.lattice.c] else: zrange = [0, structure.lattice.c] return xrange, yrange, zrange
[ドキュメント] def draw_bonds(self, ax, structure, distances, bond_r, color = 'gray'): """ 指定された3D軸上に原子間の結合を描画します。 `distances`リストに基づいて結合を描画します。 :param ax: Matplotlibの3D軸オブジェクト。 :type ax: matplotlib.axes._subplots.Axes3DSubplot :param structure: 結合を描画するPymatgenのStructureオブジェクト。 :type structure: pymatgen.core.structure.Structure :param distances: 結合する原子ペアとその距離のリスト。[[i, j, d], ...]の形式。 :type distances: list of list :param bond_r: 結合線の太さ。 :type bond_r: float :param color: 結合線の色。 :type color: str :returns: 描画された結合線オブジェクトのリスト。 :rtype: list of matplotlib.lines.Line2D """ sites = structure.sites bonds_plot_list = [] for dis in distances: i, j, d = dis site_i = sites[i] site_j = sites[j] pos_i = site_i.coords pos_j = site_j.coords # print("i,j=", i, j, pos_i, pos_j) data, = ax.plot([pos_i[0], pos_j[0]], [pos_i[1], pos_j[1]], [pos_i[2], pos_j[2]], linestyle = '-', color = color, linewidth = bond_r) bonds_plot_list.append(data) return bonds_plot_list
[ドキュメント] def draw_structure(self, tkplt, ax, structure, draw_range = [[0.0, 1.0], [0.0, 1.0], [0.0, 1.0]], max_distance = 2.75, kr = 200.0, atom_alpha = 0.5, bond_r = 5.0, vector_r = 3.0, vector_length = 3.0, arrow_length_ratio = 0.3, displacement = 1.0, sleep = 0.01, time_step = 0.1, nstep = 100, animation = False, stop_callback = None, fontsize = 16, legend_fontsize = 16): """ 結晶構造を3Dプロットで描画します。 単位セルボックス、原子、結合を描画し、必要に応じて原子の動きのアニメーションも実行します。 :param tkplt: 描画に使用するmatplotlib.pyplotオブジェクト、またはそれをラップするtkpltオブジェクト。 :type tkplt: module or object :param ax: 描画するMatplotlibの3D軸オブジェクト。 :type ax: matplotlib.axes._subplots.Axes3DSubplot :param structure: 描画するPymatgenのStructureオブジェクト。 :type structure: pymatgen.core.structure.Structure :param draw_range: x,y,z方向の描画範囲の相対座標 [[xmin_rel, xmax_rel], [ymin_rel, ymax_rel], [zmin_rel, zmax_rel]]。 :type draw_range: list of list of float :param max_distance: 結合とみなす原子間の最大距離(Å)。 :type max_distance: float :param kr: 原子半径をスケーリングするための係数。 :type kr: float :param atom_alpha: 原子の透明度(0.0-1.0)。 :type atom_alpha: float :param bond_r: 結合線の太さ。 :type bond_r: float :param vector_r: 速度ベクトル線の太さ。 :type vector_r: float :param vector_length: 速度ベクトルの最大描画長さ。 :type vector_length: float :param arrow_length_ratio: 速度ベクトルの矢印部分の長さ比率。 :type arrow_length_ratio: float :param displacement: アニメーションにおける原子の変位スケール因子。 :type displacement: float :param sleep: アニメーションのフレーム間隔(秒)。 :type sleep: float :param time_step: アニメーションの仮想的な時間ステップ。 :type time_step: float :param nstep: アニメーションの総ステップ数。 :type nstep: int :param animation: Trueの場合、原子の動きをアニメーション表示します。 :type animation: bool :param stop_callback: アニメーションを停止させる条件をチェックするコールバック関数。Trueを返すとアニメーションが停止します。 :type stop_callback: callable or None :param fontsize: 軸ラベルなどのフォントサイズ。 :type fontsize: int :param legend_fontsize: 凡例のフォントサイズ。 :type legend_fontsize: int """ if type(tkplt).__module__ == 'matplotlib.pyplot': tkplt = None elif type(tkplt).__module__ == 'builtins': plt = tkplt else: plt = tkplt.plt lattice = structure.lattice aij = structure.lattice.matrix xrange, yrange, zrange = self.get_xyz_range(structure, draw_range) self.configure_axis_structure(ax, xrange, yrange, zrange) ax.plot([], [], label = f'$a=${lattice.a:.4f} $\AA$') ax.plot([], [], label = f'$b=${lattice.b:.4f} $\AA$') ax.plot([], [], label = f'$c=${lattice.c:.4f} $\AA$') xr0 = draw_range[0][0] yr0 = draw_range[1][0] zr0 = draw_range[2][0] self.draw_box(ax, structure, [xr0, yr0, zr0], [aij[0][0], aij[0][1], aij[0][2]], [aij[1][0], aij[1][1], aij[1][2]], [aij[2][0], aij[2][1], aij[2][2]], color = 'blue', linewidth = 0.5) print() print("Draw structure 0") structure_draw, draw_inf = self.draw_atoms(ax, structure, draw_range = [xrange, yrange, zrange], kr = kr, atom_alpha = atom_alpha, vector_r = vector_r, vector_length = vector_length, arrow_length_ratio = arrow_length_ratio, ) distances = self.calculate_all_distances(structure_draw, max_distance = max_distance) bonds_plot_list = self.draw_bonds(ax, structure_draw, distances, bond_r, color = 'gray') legend = ax.legend(fontsize = legend_fontsize) # legend.set_draggable(True) if tkplt: tkplt.draw() else: plt.pause(1.0e-5) # animation if not animation: return v = structure.sites[0].properties.get("velocity", None) if v is None: return nsites = len(structure.sites) kv = draw_inf["kv"] l0_max = draw_inf["l0_max"] plot_data_list = draw_inf["plot_data_list"] arrows_data_list = draw_inf["arrows_data_list"] print("Animation...") for istep in tqdm(range(1, nstep)): # print(f"Draw structure {istep}") for quiver in arrows_data_list: quiver.remove() phi = 2.0 * pi * time_step * istep cosphi = cos(phi) sinphi = sin(phi) arrows_data_list = [] positions = [None] * nsites for iatom, atom_name in enumerate(draw_inf["atoms"].keys()): d = draw_inf["atoms"][atom_name] isite_list = d["isite"] color = d["color"] x_list = d["x"] y_list = d["y"] z_list = d["z"] vx_list = d["vx"] vy_list = d["vy"] vz_list = d["vz"] x_new = [] y_new = [] z_new = [] for i in range(len(x_list)): isite = isite_list[i] x = x_list[i] y = y_list[i] z = z_list[i] vx = vx_list[i] vy = vy_list[i] vz = vz_list[i] x += kv * vx * displacement * sinphi y += kv * vy * displacement * sinphi z += kv * vz * displacement * sinphi x_new.append(x) y_new.append(y) z_new.append(z) # print("isite=", isite, nsites) positions[isite] = [x, y, z] l0 = np.linalg.norm([vx, vy, vz]) length = l0 * kv * cosphi quiver = ax.quiver(x, y, z, vx, vy, vz, length = length, linewidth = vector_r, arrow_length_ratio = arrow_length_ratio, color = color, normalize = True) arrows_data_list.append(quiver) scatter = plot_data_list[iatom] scatter._offsets3d = (x_new, y_new, z_new) for ibond, dis in enumerate(distances): bonds_plot_list[ibond].remove() i, j, d = dis pos_i = positions[i] pos_j = positions[j] data, = ax.plot([pos_i[0], pos_j[0]], [pos_i[1], pos_j[1]], [pos_i[2], pos_j[2]], linestyle = '-', color = 'gray', linewidth = bond_r) bonds_plot_list[ibond] = data if tkplt: tkplt.draw() else: plt.pause(1.0e-5) if stop_callback and stop_callback(): print() print("Animation temrinated by user") break time.sleep(sleep)
[ドキュメント] def symmetrize(self, structure, prec = 1.0e-3): """ 指定された構造の対称性解析を行い、空間群情報と対称化された構造を取得します。 結果はインスタンスの属性に保存されます。 :param structure: 対称性解析を行うPymatgenのStructureオブジェクト。 :type structure: pymatgen.core.structure.Structure :param prec: 対称性操作を決定するための許容誤差。 :type prec: float :returns: (空間群番号, 空間群シンボル, 対称化されたStructureオブジェクト)のタプル。 :rtype: tuple of (int, str, pymatgen.symmetry.structure.SymmetrizedStructure) """ self.space_group_analyzer = SpacegroupAnalyzer(structure, symprec = prec) self.iSPG = self.space_group_analyzer.get_space_group_number() self.SPG_name = self.space_group_analyzer.get_space_group_symbol() self.symmetrized_structure = self.space_group_analyzer.get_symmetrized_structure() return self.iSPG, self.SPG_name, self.symmetrized_structure
[ドキュメント] def get_symmetrized_structure(self, symprec = 1.0e-3): """ 現在のStructureオブジェクトから対称化された構造を取得します。 SpacegroupAnalyzerを用いて対称性解析を行い、対称化されたStructureオブジェクトを返します。 :param symprec: 対称性操作を決定するための許容誤差。 :type symprec: float :returns: 対称化されたPymatgenのSymmetrizedStructureオブジェクト。 :rtype: pymatgen.symmetry.structure.SymmetrizedStructure """ self.symmetry_analyzer = SpacegroupAnalyzer(self.structure, symprec = symprec) self.symmetrized_structure = self.symmetry_analyzer.get_symmetrized_structure() return self.symmetrized_structure
[ドキュメント] def get_spacegroup(self): """ 現在のStructureオブジェクトの空間群情報(シンボルと番号)を取得します。 :returns: (空間群シンボル, 空間群番号)のタプル。 :rtype: tuple of (str, int) """ # iSPG = space_group_analyzer.get_space_group_number() # SPG_name = space_group_analyzer.get_space_group_symbol() spg_name, spg_num = self.structure.get_space_group_info() return spg_name, spg_num
[ドキュメント] def get_symmetry_inf(self, symprec = 1.0e-3): """ 現在のStructureオブジェクトの対称性に関する詳細情報を辞書形式で取得します。 空間群データセット、シンボル、番号、Hall記号、対称操作、点群情報などを含みます。 :param symprec: 対称性操作を決定するための許容誤差。 :type symprec: float :returns: 対称性に関する詳細情報を含む辞書。 :rtype: dict """ self.symmetry_analyzer = SpacegroupAnalyzer(self.structure, symprec = symprec) sa = self.symmetry_analyzer inf = { "dataset": sa.get_symmetry_dataset(), "spg_name": sa.get_space_group_symbol(), "spg_num": sa.get_space_group_number(), "is_laue": sa.is_laue(), "hall": sa.get_hall(), "sym_op" : sa.get_symmetry_operations(cartesian = False), "pointgroup_name": sa.get_point_group_symbol(), "popintgroup_op" : sa.get_point_group_operations(), } return inf