Xenonpyによる記述子の作成

本記事の概要

本記事では、Xenonpyを用いた記述子の作成方法を紹介する。
Pythonの基礎は習得していることを前提に話を進めていく。
目次:

Xenonpyとは

XenonPyは、統計数理研究所ものづくりデータ科学研究センターのチーム (Chang Liu 特任助教、野口瑶 特任研究員、Stephen Wu 助教、山田寛尚 特任研究員、吉田亮 同センター長) が物質・材料研究機構と共同開発しているマテリアルズインフォマティクス (MI) のオープンソースプラットフォーム。XenonPyには、様々なマテリアルインフォマティクスのアプリケーションのためのツールが豊富に用意されている。記述子生成クラスでは、組成、構造から数種類の数値記述子を計算することができる。

以下、公式ドキュメント
xenonpy.readthedocs.io

早速、実装

Xenonpyのインストール方法は、以下のサイトを参考にしてください。
xenonpy.readthedocs.io

Xenonpyを使用するために、以下のrdkitをインストールしておく必要がある。

! conda install --yes -c rdkit rdkit #最初にinstallしてください。

ライブラリのインポート

import pandas as pd
import numpy as np
import os, sys,warnings
warnings.filterwarnings('ignore')

from pymatgen.io.cif import CifParser
from pymatgen.core.composition import Composition
from xenonpy.descriptor import Compositions,Structures

組成記述子の作成

与えられた化学組成に対して290種類の組成特性を計算することができるらしい。
全ての記述子を確認したい方は、以下のURLをご確認ください。
xenonpy.readthedocs.io

XenonpyのCompositionsクラスでは、辞書形式に変換された組成から記述子を計算することができる。
注意)Compositionsは、Xenonpyの記述子を計算するためのクラス、CompositionはPymatgenの組成を辞書形式に変換してくれるクラス。自分で組成を辞書形式にするのが面倒であるため、PymatgenのCompositionクラスを使用している。 そして、Compositionsクラスに”composition”という列名があるデータフレームを渡すと組成情報から組成記述子を作成することができる。

def comp_descriptors(comp_holder):    
    comp_holder = [Composition(x)  for x in comp_holder] #Change strings(compositions) into dictionary
    df = pd.DataFrame({'composition':comp_holder})
    cal_comp = Compositions() 
    descriptor_comp = cal_comp.transform(df) #Make descriptors 
    return descriptor_comp

comp_holder  = [
    'Li2O',
    'MgO',
    'LiCoO2',
    'MgCo2O4',
    'Fe'
]

df = comp_descriptors(comp_holder)
df

>(出力)
f:id:ataruto:20210401214412p:plain

構造記述子の作成

構造記述子は、RDF(radial distribution function) OFM (orbital field matrix)2) を使用している。
参考)Pham et al. Machine learning reveals orbital interaction in materials, Sci Technol Adv Mater. 18(1): 756-765, 2017.

私が作成したプログラムではcifファイルが入っているディレクトリで、以下の関数を実行する必要がある。 そのためcifファイルが入っているディレクトリへのパスを引数で渡している。

Xenonpyでは、cifではなくPOSCARを読み取り構造記述子を作成する。この変換のプログラムなどは作成するのが面倒なのでPymatgenを使用している。そして、POSCAR形式の情報をデータフレームに格納し、その列名を"structure"にしておくことで、Structureクラスが読み取ることができ、構造記述子を計算することができる。

def getciflist(path_to_cif):
    ls = os.listdir(path_to_cif)
    calclist = []
    for i in ls:
        if '.cif' in i:
            calclist.append(i.rstrip())
    return calclist

def str_descript(path_to_cif): #strはstructureの略
    cif_list = getciflist(path_to_cif)
    str_holder = []
    cif_holder = []
    for cif in tqdm(cif_list): #時間がかかる場合があるので、tqmdでprogressバーを表示している
        cif_p = CifParser(cif)#cifの読み込み
        str_holder.append(cif_p.get_structures())#cifをPOSCARに変換している。
    df = pd.DataFrame({'structure':str_holder})
    cal_str = Structures()
    descriptor_str = cal_str.transform(df)#Make descriptors
    return descriptor_str

cwd='./'
df = str_descript(cwd)
df

>(出力)
f:id:ataruto:20210401214525p:plain
今回は、3つのcifファイルを用意したので、3つの結晶構造について記述子を獲得できている。
構造記述子は、合計で約1200個程度であることがわかる。

おまけ 組成記述子と構造記述子を同時に作成

実は、cifファイルがあれば、組成情報もcifファイルに書かれているので cifファイルから、組成記述子・構造記述子両方を作成することが可能である。 それが以下の関数になっている。

def getdescripts(path_to_cif):
    cif_list = getciflist(path_to_cif)
    str_holder = []
    comp_holder =[]
    cif_holder = []
    for cif in tqdm(cif_list):#時間がかかる場合があるので、tqmdでprogressバーを表示している
        with open(cif) as r:
            for i in r:
                if '_chemical_formula_sum' in i:
                    comp_str = ''
                    for j in i.split("\'")[1].split():
                        comp_str += j
            comp_holder.append(Composition(comp_str))
            cif_p = CifParser(cif)
            str_holder.append(cif_p.get_structures())
            cif_holder.append(cif)
    df = pd.DataFrame({'cif':cif_holder,'structure':str_holder,'composition':comp_holder})
    df = df.set_index('cif')
    cal_comp = Compositions()
    cal_str = Structures()
    descriptor_comp = cal_comp.transform(df)
    descriptor_str = cal_str.transform(df)
    descriptor_comp_str = pd.merge(descriptor_comp,descriptor_str,left_index=True, right_index=True)
    return descriptor_comp_str

cwd='./'
df = getdescripts(cwd)
df

>(出力)
f:id:ataruto:20210401214759p:plain

組成記述子と構造記述子両方欲しい場合には、こんな感じにプログラムをかくと便利。
#コードが読みにくくて、大変申し訳ない。。。

まとめ

今回の記事のコードを用いれば、簡単に記述子を作成することができる。 また、Pymatgenの記事と、機械学習の基礎に関する記事を読むことでマテリアルズ・インフォマティクスを0からアウトプットまで体験することができる。
訂正点や要望などがあれば、コメントに書いてください!