Libraries

Pandat软件的调用

命令行调用

import os
import subprocess
import jinja2

# >>> cmds = ['C:/Program Files/CompuTherm LLC/Pandat 2021a Education/bin/Pandat.exe', 'ab48e46002cc9727a1afad43bfc27cdc8eaf006f50400c0dd1e46f3b610fb9baFCC.pbfx', 'D:/Work/calphadmesh/demos/AlMgSi/Liquid_Fcc/.cache/workspace', '0']
# >>> proc = subprocess.Popen(cmds, cwd="D:/Work/calphadmesh/demos/AlMgSi/Liquid_Fcc/.cache/scripts")

pandat_exe = "C:/Program Files/CompuTherm LLC/Pandat 2022a/bin/Pandat.exe"

with open("template.pbfx", "r") as f:
    template = f.read()

elements = "Al Am As Au B Ba Be Bi C Ca Cd Ce Co Cr Cs Cu Dy Er Eu Fe Ga Gd Ge Hf Hg Ho In Ir K La Li Lu Mg Mn Mo N Na Nb Nd Ni Np O Os P Pa Pb Pd Pr Pt Pu Rb Re Rh Ru S Sb Sc Se Si Sm Sn Sr Ta Tb Tc Te Th Ti Tl Tm U V W Y Yb Zn Zr"
elements = elements.split(" ")

cwd = os.getcwd()
task_dir = os.path.join(cwd, "tasks")

for element in elements:
    # foldername: task_dir/element
    foldername = os.path.join(task_dir, element)
    if not os.path.exists(foldername):
        os.makedirs(foldername)

    # filename: task_dir/element/element.pbfx
    template_element = jinja2.Template(template)
    with open(os.path.join(foldername, element + ".pbfx"), "w") as f:
        f.write(template_element.render(element=element))

    cmds = [pandat_exe, element + ".pbfx", foldername, '0']
    proc = subprocess.Popen(cmds, cwd=foldername)
    proc.wait()

Pandat结果文件解析

import xml
import xml.sax
import pandas as pd

class TableHandler( xml.sax.ContentHandler ):
    def __init__(self):
        self.CurrentData = None
        self.ParsedData = []
    
    def startElement(self, tag, attributes):
        self.CurrentData = tag
        if tag == "Default":
            pass
        elif tag == "default":
            if not attributes.getNames():
                return
            names = [each for each in attributes.getNames()]
            self.ParsedData.append(dict(zip(names, [attributes[name] for name in names])))

    def endElement(self, tag):
        if self.CurrentData == "default":
            pass

def PandatTable2Json(table):
    # names = [each for each in table[0]]
    # print(names)
    keys = set()
    for index, row in enumerate(table):
        keys.update(set(row.keys()))
    keys = [key.strip() for key in keys]

    data = {}
    for key in keys:
        data[key] = []

    for index, row in enumerate(table):
        # print(row)
        if index == 0:
            continue
        for key in keys:
            if key in row:
                if key not in data:
                    print("Error: >%s<" % key)
                if row[key] == "-∞":
                    data[key].append("-inf")
                else:
                    data[key].append(row[key])
            else:
                data[key].append("nan")

    return data

def PandatTable(pandat_table_file):
    parser = xml.sax.make_parser()
    # turn off namepsaces
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
    
    # 重写 ContextHandler
    Handler = TableHandler()
    parser.setContentHandler( Handler )

    parser.parse(pandat_table_file)

    # print(Handler.ParsedData)

    # for each in Handler.ParsedData:
    #     print(each)

    return PandatTable2Json(Handler.ParsedData)