Files
solidstate-tools/softBV/run_softBV.py
2025-09-24 11:57:52 +08:00

158 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import sys
import subprocess
import re
import csv
from pathlib import Path
# --- 配置区 ---
# softBV.x 可执行文件的路径,请根据你的实际情况修改
# 使用 Path.home() 来自动获取用户家目录,比 '~' 更可靠
SOFTBV_EXECUTABLE = Path.home() / "tool/softBV-GUI_linux/bin/softBV.x"
# 固定的命令参数
MOBILE_ION = "Li"
ION_VALENCE = "1"
SF_VALUE = "1000"
# 输出CSV文件的名称
OUTPUT_CSV_FILE = "conductivity_results.csv"
# --- 配置区结束 ---
def check_executable():
"""检查 softBV.x 文件是否存在且可执行"""
if not SOFTBV_EXECUTABLE.is_file():
print(f"错误: 可执行文件未找到: {SOFTBV_EXECUTABLE}")
print("请检查脚本中的 SOFTBV_EXECUTABLE 路径是否正确。")
sys.exit(1)
if not os.access(SOFTBV_EXECUTABLE, os.X_OK):
print(f"错误: 文件存在但不可执行: {SOFTBV_EXECUTABLE}")
print("请使用 'chmod +x' 命令赋予其执行权限。")
sys.exit(1)
def parse_conductivity(output_text):
"""
从 softBV.x 的输出文本中解析电导率(conductivity)。
使用正则表达式来匹配 'MD: conductivity = <value>' 格式的行。
"""
# 正则表达式解释:
# ^ - 匹配行首
# \s* - 匹配任意数量的空白字符
# MD: conductivity - 匹配字面字符串
# \s*=\s* - 匹配等号,前后可以有任意空白
# ([-\d.eE+]+) - 捕获组1: 匹配并捕获一个或多个数字、点、'e'/'E'、'+'/'-' (科学计数法)
pattern = re.compile(r"^\s*MD: conductivity\s*=\s*([-\d.eE+]+)", re.MULTILINE)
match = pattern.search(output_text)
if match:
# 返回捕获到的第一个组 (也就是数值部分)
return match.group(1)
else:
# 如果没有找到匹配的行,返回 None
return None
def main():
"""主函数"""
# 1. 检查命令行参数
if len(sys.argv) != 2:
print(f"用法: python {sys.argv[0]} <cif_folder_name>")
print(f"例如: python {sys.argv[0]} Br")
sys.exit(1)
target_folder = Path(sys.argv[1])
# 检查目标文件夹是否存在
if not target_folder.is_dir():
print(f"错误: 文件夹 '{target_folder}' 不存在。")
sys.exit(1)
# 检查 softBV.x 是否配置正确
check_executable()
# 2. 查找所有 .cif 文件
cif_files = sorted(list(target_folder.glob("*.cif")))
if not cif_files:
print(f"警告: 在文件夹 '{target_folder}' 中没有找到任何 .cif 文件。")
return
print(f"'{target_folder}' 中找到 {len(cif_files)} 个 .cif 文件,开始处理...")
results = [] # 用于存储 (文件名, 电导率)
# 3. 遍历文件,执行命令并提取数据
for cif_file in cif_files:
print(f" -> 正在处理: {cif_file} ...", end="", flush=True)
# 构建命令
command = [
str(SOFTBV_EXECUTABLE),
"--md",
str(cif_file),
MOBILE_ION,
ION_VALENCE,
SF_VALUE
]
try:
# 执行命令并捕获输出
# capture_output=True 将 stdout 和 stderr 分别捕获
# text=True (或 encoding='utf-8') 将输出解码为字符串
# check=True 如果命令返回非零退出码 (表示错误),则会抛出异常
process_result = subprocess.run(
command,
capture_output=True,
text=True,
check=True,
timeout=300 # 设置一个超时时间例如300秒防止程序卡死
)
# 从标准输出中解析数据
conductivity = parse_conductivity(process_result.stdout)
if conductivity is not None:
results.append((cif_file.name, conductivity))
print(f" 成功, conductivity = {conductivity}")
else:
print(" 失败 (无法在输出中找到conductivity)")
# 你也可以选择将错误信息记录下来
# results.append((cif_file.name, "Error: Not Found"))
except subprocess.CalledProcessError as e:
# 命令执行失败
print(f" 失败 (命令执行错误)")
print(f" 错误信息: {e.stderr.strip()}")
# results.append((cif_file.name, "Error: Execution Failed"))
except subprocess.TimeoutExpired:
print(f" 失败 (命令执行超时)")
# results.append((cif_file.name, "Error: Timeout"))
except Exception as e:
# 其他未知错误
print(f" 失败 (发生未知错误: {e})")
# results.append((cif_file.name, f"Error: {e}"))
# 4. 将结果写入CSV文件
if not results:
print("没有成功处理任何文件不生成CSV。")
return
print(f"\n处理完成,正在将 {len(results)} 条结果写入 {OUTPUT_CSV_FILE} ...")
try:
with open(OUTPUT_CSV_FILE, 'w', newline='', encoding='utf-8') as csvfile:
writer = csv.writer(csvfile)
# 写入表头
writer.writerow(['filename', 'conductivity'])
# 写入数据
writer.writerows(results)
print("CSV文件已成功生成")
except IOError as e:
print(f"错误: 无法写入CSV文件: {e}")
if __name__ == "__main__":
main()