pymatgenを使ったMaterials Projectのデータ収集
Last Update:2024/02/07
(2020年2月1日)
1. はじめに
pymatgenは結晶構造やバンド構造などの各種物性データを簡単に取り扱うことができるPythonライブラリである。様々なクラスが導入されているが、そのうちの一つとして、MPResterクラスという物質材料の第一原理計算結果のデータベースであるMaterials Projectのデータをダウンロードできるインターフェースが整備されている。
pymatgenのドキュメント・サンプルはhttps://pymatgen.org/index.htmlやhttps://docs.materialsproject.org/downloading-data/using-the-api、https://github.com/materialsproject/mapidocなど様々なものがあるが、ここではpymatgenを使ってMaterials ProjectにあるABO3系(A, Bは任意の原子、Oは酸素原子)のデータを収集してみる。計算環境としてdocker版のMateriApps LIVE! ver. 4.1を利用するが、他の環境でも本記事で紹介しているpythonスクリプトは実行できる。他のレビュー記事ではpymatgenを利用した物理量計算の例を紹介しているので、もしそちらに興味があれば参照していただきたい。
※Materials ProjectのAPIが更新されたため、最新のデータベースにアクセスするためには新しいAPI記法でPythonスクリプトを作る必要がある。ただし、参考情報として旧データベースのための記法を残しておく。
2. 準備
・Materials ProjectのAPI key
まず、pymatgenを用いてMaterials Projectのデータをダウンロードするために、API keyを作成する必要がある。Materials Projectの公式サイト https://materialsproject.org にアクセスして、Sign Inをしたのち、右上の”API”をクリックする。その後, “API Keys”のところを読んで指示に従いAPI keyを作る。もし、すでに作られている場合は、自分のAPI keyが表示されている。新しいデータベースの場合、自動的にAPIキーが生成されるようである。APIキーはログイン後のダッシュボードからも確認できる。https://next-gen.materialsproject.org/dashboard
・pymatgenのインストール
次に、pymatgenのインストールを行う。pymatgenの公式ドキュメント https://pymatgen.org でのインストール方法を読むとcondaもしくはpipで簡単にインストールをできることがわかる。pipの場合、
pip install pymatgen
とすれば、インストールできる。もし、自分の行いたい計算環境で管理者権限がない場合(研究室クラスター、スーパーコンピュータなど)は
pip install pymatgen --user
とすればlocalの環境にインストールできる。最新のAPIを使うためには
pip install mp_api
も実行する必要がある。
3. Pythonスクリプトの内容・使い方
今回作ってみたのはABO3系のcifファイルダウンロードといくつかの物質についての物理量をMaterials Projectから持ってくるPythonスクリプトである。スクリプトはここからダウンロードできる。もしくはターミナル上で
wget https://ma.issp.u-tokyo.ac.jp/wp-content/uploads/sites/3/2020/02/get113fromNewMP.py
を実行してもダウンロードできる。以下、簡単に中身の説明をしていく。
・1-4行目:importとAPI keyの設定。4行目の”USER API KEY”のところにMaterials ProjectのAPI keyを入力する。
from mp_api.client import MPRester
import os
MY_API_KEY="USER API KEY"
・6-14行目:pymatgenの検索で、物質の特徴量のキーワード名がよくわからなくなるので、下記リンク先に記載されていmpr.summary.available_fieldsの出力結果と関連URLのリンクを記載している。
https://docs.materialsproject.org/downloading-data/using-the-api/querying-data
なお、参考URLのようにmpr.summaryを使うとmpr.materials.summaryを使うようwarningが出力されたため、今回のスクリプトでmpr.materials.summaryを用いている。
・17-47行目:ABO3系のcifファイルをダウンロードするスクリプト箇所。17-29行目にはどのようなABO3のcifファイルをダウンロードした以下の条件が記載されている。
#Get cif files of ABO3 systems
# Only for stable insulators with band_gap < 1 and spacegroup = Pm-3m
band_gap_min = None
band_gap_max = 1.0
sg_symb = "Pm-3m"
_is_stable=True
_is_metal=False
# Only for stable metals (band_gap = 0) with spacegroup = Pm-3m
#band_gap_min = None
#band_gap_max = None
#sg_symb = "Pm-3m"
#_is_stable=True
#_is_metal=True
デフォルトでは、空間群が”Pm-3m”でバンドギャップが1より小さい安定な絶縁体という条件を設定している。31-35行目は以下の通りである。
# define physical properties/infos you want to obtain
properties = ['formula_pretty','material_id','structure','symmetry','is_metal','band_gap']
name = "**O3"
with MPRester( MY_API_KEY ) as mpr:
results = mpr.materials.summary.search(formula=name, band_gap=(band_gap_min, band_gap_max), spacegroup_symbol = sg_symb, is_stable=_is_stable, is_metal=_is_metal, fields=properties)
頭のproperties
は、MaterialsProjectのどのような情報をダウンロードしたいかを決めている。このキーワードは10行目のリスト(12-14行目のURL)から選ぶことができる。今回のスクリプトでは、Materials Projectで管理されている物質名とそのID、対応する結晶構造情報、金属かの情報とバンドギャップの大きさをダウンロードするように指定している。今回は組成式が”ABO3”の物質を対象にするため、name
を”**O3″(A、Bはワイルドカード*で表現している。)と設定しておく。
with文以下では、Materials Projectから情報をダウンロードする手順が記載されている。先ほど設定したproperties
はfields
の入力に使われている。17-29行目で定義した条件を使って検索し、得られた情報をresults
に格納する。
・38-47行目:cifの出力。ABO3_cifディレクトリにcifファイルを出力するよう設定している。ファイル名は物質ID_物質名にしている。
・49-62行目:SrBO3系での計算された物理量をダウンロードするスクリプト箇所。Bに”V”,”Ti”,”Co”のいずれかを含むという条件で情報を出力する。51行目
properties = ['formula_pretty', "band_gap", "formation_energy_per_atom", "symmetry"]
で、出力する物理量を設定している。今回のスクリプトでは、組成式、バンドギャップ値、生成エネルギー、結晶構造の対称性を出力するようにしている。
55行目のformula
とelements
の箇所で、”ABO3″のうち、”Sr”を必ず含み、”V”,”Ti”,”Co”のどれかを含むという条件が書かれている。”V”,”Ti”,”Co”の選択にはfor文を使っている。
・57-62行目:結果の出力。
4. 実行結果
実行すると以下のテキストと実行ディレクトリにABO3_cifというディレクトリが出力される(SummaryDoc関連のログ等は削除している)。デフォルトの条件では、ABO3_cifディレクトリに7個のcifファイルがダウンロードされる(2024年2月現在)。
SrVO3
band_gap: 0.0
formation_energy_per_atom: -2.8762861244999995
symmetry: crystal_system=<CrystalSystem.cubic: 'Cubic'> symbol='Pm-3m' number=221 point_group='m-3m' symprec=0.1 version='2.0.2'
SrTiO3
band_gap: 1.7719999999999998
formation_energy_per_atom: -3.453785062333334
symmetry: crystal_system=<CrystalSystem.cubic: 'Cubic'> symbol='Pm-3m' number=221 point_group='m-3m' symprec=0.1 version='2.0.2'
SrTiO3
band_gap: 1.8487999999999998
formation_energy_per_atom: -3.4542551163333344
symmetry: crystal_system=<CrystalSystem.tet: 'Tetragonal'> symbol='I4/mcm' number=140 point_group='4/mmm' symprec=0.1 version='2.0.2'
SrTiO3
band_gap: 1.7869999999999995
formation_energy_per_atom: -3.454170368333334
symmetry: crystal_system=<CrystalSystem.tet: 'Tetragonal'> symbol='I4/mcm' number=140 point_group='4/mmm' symprec=0.1 version='2.0.2'
SrTiO3
band_gap: 1.7362000000000002
formation_energy_per_atom: -3.4151526450000023
symmetry: crystal_system=<CrystalSystem.hex_: 'Hexagonal'> symbol='P6_3/mmc' number=194 point_group='6/mmm' symprec=0.1 version='2.0.2'
SrCoO3
band_gap: 0.0
formation_energy_per_atom: -1.9789515924999996
symmetry: crystal_system=<CrystalSystem.tet: 'Tetragonal'> symbol='P4/mbm' number=127 point_group='4/mmm' symprec=0.1 version='2.0.2'
SrCoO3
band_gap: 0.0
formation_energy_per_atom: -1.9153837695
symmetry: crystal_system=<CrystalSystem.cubic: 'Cubic'> symbol='Pm-3m' number=221 point_group='m-3m' symprec=0.1 version='2.0.2'
SrCoO3
band_gap: 0.0
formation_energy_per_atom: -1.9619229464999997
symmetry: crystal_system=<CrystalSystem.tet: 'Tetragonal'> symbol='P4/mmm' number=123 point_group='4/mmm' symprec=0.1 version='2.0.2'
SrCoO3
band_gap: 0.0
formation_energy_per_atom: -1.9576723479999991
symmetry: crystal_system=<CrystalSystem.ortho: 'Orthorhombic'> symbol='Amm2' number=38 point_group='mm2' symprec=0.1 version='2.0.2'
SrCoO3
band_gap: 0.0
formation_energy_per_atom: -1.923863617499999
symmetry: crystal_system=<CrystalSystem.tri: 'Triclinic'> symbol='P-1' number=2 point_group='-1' symprec=0.1 version='2.0.2'
SrCoO3
band_gap: 0.0
formation_energy_per_atom: -1.9097275399999993
symmetry: crystal_system=<CrystalSystem.mono: 'Monoclinic'> symbol='P2_1/m' number=11 point_group='2/m' symprec=0.1 version='2.0.2'
5. まとめ
このレビュー記事では、pymatgenを使ったMaterials Projectのデータ収集についてまとめてみた。ダウンロードしたcifや物理量を使って機械学習させることで、何かしらの予測器を作ることもできるであろう。Materials informaticsに興味があれば、是非挑戦してほしい。
2021/7/15: スクリプトや説明文等を追記・修正
2021/7/30: 他記事の紹介やタイポ等を追記・修正
2024/2/7: 新しいAPI形式への対応
===================================================
ここからは旧データベースへのアクセスに関する説明である。
3. Pythonスクリプトの内容・使い方
今回作ってみたのはABO3系のcifファイルダウンロードといくつかの物質についての物理量をMaterials Projectから持ってくるPythonスクリプトである。スクリプトはここからダウンロードできる。もしくはターミナル上で
wget https://ma.issp.u-tokyo.ac.jp/wp-content/uploads/sites/3/2020/02/get113fromMP.py
を実行してもダウンロードできる。以下、簡単に中身の説明をしていく
・1-4行目:importとAPI keyの設定。5行目の”USER API KEY”のところにMaterials ProjectのAPI keyを入力する。
from pymatgen.ext.matproj import MPRester
import os
MY_API_KEY="USER API KEY"
・6-26行目:pymatgenの使い方がわからなくなったとき適宜参照できるよう、よく使いそうな情報とそれらの参考URLを記載している。そのほかにも公式ドキュメントのMPRester箇所やMPRester.query箇所は書き方の参考になる。query箇所に関してはこちらの日本語記事も参考になるであろう。
・28-55行目:ABO3系のcifファイルをダウンロードするスクリプト箇所。28-36行目にはどのようなABO3のcifファイルをダウンロードした以下の条件が記載されている。
#Get cif files of ABO3 systems
# Only for 0 < band_gap < 1 and spacegroup = Pm-3m
criteria_properties = {"spacegroup.symbol" : 'Pm-3m', "$and": [ {"band_gap":{"$gt": 0}}, {"band_gap":{"$lt": 1}} ]}
# Only for (band_gap = 0 nor total_magnetization != 0) and spacegroup = Pm-3m
#criteria_properties = {"spacegroup.symbol" : 'Pm-3m', "$nor": [ {"band_gap": 0}, {"total_magnetization":{"$ne": 0}} ]}
# Only for band_gap > 0 and spacegroup = Pm-3m
#criteria_properties = {"spacegroup.symbol" : 'Pm-3m', "band_gap":{"$gt": 0}}
# Only for band_gap != 0 and spacegroup = Pm-3m (the same result as for band_gap > 0)
#criteria_properties = {"spacegroup.symbol" : 'Pm-3m', "band_gap":{"$ne": 0}}
デフォルトでは、空間群が”Pm-3m”でバンドギャップが0より大きく1より小さい値であるという条件を使っている。なお、”$and: [ ]”や{“$gt”: 0}という表記はmongoDBで使われており、詳しくは12-26行目のコメントを参照していただきたい。日本語ページとしては、ここやここなどがmongoDBの理解の参考になる。
38-47行目は以下の通りである。
# define physical properties/infos you want to obtain
output = ['pretty_formula','task_id','cif']
with MPRester( MY_API_KEY ) as m:
#Get pretty_formula of ABO3 systems
data_pretty_formula = m.parse_criteria("**O3")
my_criteria = data_pretty_formula
#satisfy "criteria_properties" condition
my_criteria.update( criteria_properties )
#Get cif files of materials in "my_criteria"
results = m.query(criteria=my_criteria, properties=output)
このセクションの初めは、MaterialsProjectのどのような情報をダウンロードしたいかを決めている。このキーワードは6-9行目のリスト(公式ページ)から選ぶことができる。今回のスクリプトでは、Materials Projectで管理されている物質名とそのID、対応するcif情報をダウンロードするように指定している。with文以下では、Materials Projectから情報をダウンロードする手順が記載されている。
まず、組成式が”ABO3”(A、Bはワイルドカード*で表現している。)の辞書クラスのリストdata_pretty_forumulaを手に入れる。続いてmy_criteriaにdata_prety_forumulaをコピーする(data_prety_forumulaを再利用しないのでcopy()を使わなくても良い。)。その後28-55行目で定義したcriteria_propertiesをmy_criteriaに追記する。最後にmy_criteriaに記載されている条件からoutputで定義した情報をダウンロードし、resultsに格納する。
・49-55行目:cifの出力。ABO3_cifディレクトリにcifファイルを出力するよう設定している。ファイル名は物質ID_物質名にしている。
・57-69行目:SrBO3系での計算された物理量をダウンロードするスクリプト箇所。59行目
criteria_properties = {"elements": {"$in":["V","Ti","Co"], "$all":["Sr"]}}
では、”Sr”を必ず含み($all)、”V”,”Ti”,”Co”のいずれかを含む($in)という条件が書かれている。
61行目
output = ['pretty_formula', "band_gap", "formation_energy_per_atom", "spacegroup.symbol"]
で、出力する物理量を設定している。今回のスクリプトでは、組成式、バンドギャップ値、生成エネルギー、空間群を出力するようにしている。with文以下は38-47行目と同じである。
・71-73行目:結果の出力。
4. 実行結果
実行すると以下のテキストと実行ディレクトリにABO3_cifというディレクトリが出力される。”UserWarning: No electronegativity”という警告がいくつか出ると思うが、特に気にしなくて良い。ABO3_cifディレクトリには40個程度のcifファイルがダウンロードされている。
{'pretty_formula': 'SrCoO3', 'band_gap': 0.0, 'formation_energy_per_atom': -1.970111289333334, 'spacegroup.symbol': 'P4/mmm'}
{'pretty_formula': 'SrCoO3', 'band_gap': 0.0, 'formation_energy_per_atom': -1.9235721123333342, 'spacegroup.symbol': 'Pm-3m'}
{'pretty_formula': 'SrCoO3', 'band_gap': 0.0, 'formation_energy_per_atom': -1.9179158828333336, 'spacegroup.symbol': 'P2_1/m'}
{'pretty_formula': 'SrCoO3', 'band_gap': 0.0, 'formation_energy_per_atom': -1.932051960333333, 'spacegroup.symbol': 'P-1'}
{'pretty_formula': 'SrCoO3', 'band_gap': 0.0, 'formation_energy_per_atom': -1.9658606908333334, 'spacegroup.symbol': 'Amm2'}
{'pretty_formula': 'SrCoO3', 'band_gap': 0.0, 'formation_energy_per_atom': -1.9871399353333339, 'spacegroup.symbol': 'P4/mbm'}
{'pretty_formula': 'SrTiO3', 'band_gap': 1.8583000000000003, 'formation_energy_per_atom': -3.552249219, 'spacegroup.symbol': 'I4/mcm'}
{'pretty_formula': 'SrTiO3', 'band_gap': 1.8274, 'formation_energy_per_atom': -3.551357205, 'spacegroup.symbol': 'Pm-3m'}
{'pretty_formula': 'SrTiO3', 'band_gap': 1.7869999999999995, 'formation_energy_per_atom': -3.551666971000001, 'spacegroup.symbol': 'I4/mcm'}
{'pretty_formula': 'SrTiO3', 'band_gap': 1.7367000000000004, 'formation_energy_per_atom': -3.513146747666667, 'spacegroup.symbol': 'P6_3/mmc'}
{'pretty_formula': 'SrVO3', 'band_gap': 0.0, 'formation_energy_per_atom': -2.8794546823333342, 'spacegroup.symbol': 'Pm-3m'}