C2DB数据的读取

C2DB数据库是根据已知二维材料替换元素得到扩充数据路,其包含PBE、HSE、结构稳定性、convexhull以及真空能级等性质,可以作为研究二维材料的数据库之一,这里给出其数据库中的结构提取脚本,方便大家前处理遇到的困苦,加快自己的ideal的推进。方法比较简单粗暴莽夫哲学(亚历山大砍戈耳狄俄斯之结)(https://zh.wikipedia.org/wiki/%E4%BA%9A%E5%8E%86%E5%B1%B1%E5%A4%A7%E5%A4%A7%E5%B8%9D)
)。
最近C2DB做了更新,目前我基于的是其2018年的文章中涉及的数据库,之前还能下,现在也找不到下载的地方了。

'''
Created on 14:35, Mar. 25, 2021

@author: yilinZhang 
@address: Jilin University

These files are needed: c2db.db
'''
import numpy as np
import pandas as pd
import os


def prehandle_c2db():
    import json
    import sqlite3
    # Step1: connect database and get the features
    con = sqlite3.connect("c2db.db")
    df = pd.read_sql_query("SELECT * FROM systems", con)

    # Step2: convert database to csv
    key_value_pairs = []
    for line in df.key_value_pairs:
        key_value_pairs.append(json.loads(line))
    key_value_pairs = pd.DataFrame(key_value_pairs)

    # Step3: rename formula
    formula_values = list(key_value_pairs['folder'].str.split('/'))
    flag = []
    for line in formula_values:
        flag.append(line[-2])
    key_value_pairs['formula'] = flag

    # Step4: sorted the vbm
    key_value_pairs['vbm_to_evac'] = key_value_pairs['vbm'] - key_value_pairs['evac']
    # key_value_pairs['cbm_to_evac'] = key_value_pairs['cbm'] - key_value_pairs['evac']
    hasBandGap = key_value_pairs[key_value_pairs['vbm_to_evac'] <= 0]#肯定要满足价带不能超过静电势能吧
    # hasBandGap = hasBandGap[hasBandGap['gap'] > 0.3]

    hasBandGap = hasBandGap[hasBandGap['ehull'] <= 0]# convexhull也要满足一下
    # hasBandGap = hasBandGap[hasBandGap['dynamic_stability_level'] == 3]
    hasBandGap = hasBandGap.sort_values(by=['vbm_to_evac'], axis=0)
    hasBandGap.to_csv('sorted_by_vbm_to_evac.csv')


def writePOSCAR(atom):

    with open(path + os.sep + filename + '_POSCAR', 'w') as f:
        f.write(self.parameters['SystemName'] + '\n')
        f.write(str(self.parameters['ScalingFactor']) + '\n')

        LatticeMatrix = self.parameters['LatticeMatrix']
        for i in range(len(LatticeMatrix)):
            f.write(float2line(LatticeMatrix[i]))

        AtomsInfo = self.parameters['AtomsInfo']
        string = ['', '']
        for key in AtomsInfo.keys():
            string[0] += key + '    '
            string[1] += str(AtomsInfo[key]) + '    '
        string[0] += '\n'
        string[1] += '\n'
        f.write(string[0])
        f.write(string[1])

        f.write(self.parameters['CoordinateType'] + '\n')

        ElementsPositionMatrix = self.parameters['ElementsPositionMatrix'].copy(
        )
        for key in ElementsPositionMatrix.keys():
            arr = ElementsPositionMatrix[key]
            for i in range(len(arr)):
                f.write(float2line(arr[i]))


def output_structure():
    import ase.db
    from ase.io import write
    dbpath = os.path.join(os.getcwd(), 'c2db.db')
    db = ase.db.connect(dbpath)

    def float2line(mart):
        '''
        将矩阵转换成可输出的字符串形式
        '''
        string = ''
        for line in mart:
            for s in line:
                string += '%21.10f' % float(s)
            string += '\n'
        return string

    def count_element(mart):
        string = ['', '']
        elements = sorted(set(mart), key=mart.index)
        for key in elements:
            string[0] += key + '    '
            string[1] += str(mart.count(key)) + '    '
        string[0] += '\n'
        string[1] += '\n'
        return string

    # with open('bandAlignment_CSV_names', 'r') as f:
    #     lines = f.readlines()

    # for i in range(len(lines)):
    #     os.chdir(lines[i].strip()[:-4])
    csv = pd.read_csv('sorted_by_vbm_to_evac.csv')
    for i in range(len(csv)):
        atom = db.get_atoms(uid=csv.iloc[i]['uid'], add_additional_information=True)
        write('{}.cif'.format(csv.iloc[i]['formula']), atom, format='cif')
        with open(csv.iloc[i]['formula'] + '.vasp', 'w') as f:
            f.write(csv.iloc[i]['uid'] + '\n')
            f.write('1.0\n')
            f.write(float2line(atom.get_cell()))
            atomInfo = count_element(atom.get_chemical_symbols())
            f.write(atomInfo[0])
            f.write(atomInfo[1])
            f.write('Cartesian\n')
            f.write(float2line(atom.get_positions()))


if __name__ == "__main__":
    prehandle_c2db()
    # after_handle()
    output_structure()
    os.system('rm *.cif')

你可能感兴趣的:(C2DB数据的读取)