diff --git a/src/analysis/database_analyzer.py b/src/analysis/database_analyzer.py index 6567302..9c0cb5a 100644 --- a/src/analysis/database_analyzer.py +++ b/src/analysis/database_analyzer.py @@ -316,4 +316,46 @@ class DatabaseAnalyzer: if report.cation_containing_count > 0: for anion, count in report.anion_distribution.items(): report.anion_ratios[anion] = \ - count / report.cation_containing_count \ No newline at end of file + count / report.cation_containing_count + + def to_dict(self) -> dict: + """转换为可序列化的字典""" + import json + from dataclasses import asdict, fields + + result = {} + for field in fields(self): + value = getattr(self, field.name) + + # 处理 set 类型 + if isinstance(value, set): + result[field.name] = list(value) + # 处理 StructureInfo 列表 + elif field.name == 'all_structures': + result[field.name] = [] # 不保存详细结构信息,太大 + else: + result[field.name] = value + + return result + + def save(self, path: str): + """保存报告到JSON文件""" + import json + with open(path, 'w', encoding='utf-8') as f: + json.dump(self.to_dict(), f, indent=2, ensure_ascii=False) + print(f"✅ 报告已保存到: {path}") + + @classmethod + def load(cls, path: str) -> 'DatabaseReport': + """从JSON文件加载报告""" + import json + with open(path, 'r', encoding='utf-8') as f: + d = json.load(f) + + # 处理 set 类型 + if 'target_anions' in d: + d['target_anions'] = set(d['target_anions']) + if 'all_structures' not in d: + d['all_structures'] = [] + + return cls(**d) \ No newline at end of file diff --git a/src/analysis/structure_inspector.py b/src/analysis/structure_inspector.py index 56b4bce..4b171f9 100644 --- a/src/analysis/structure_inspector.py +++ b/src/analysis/structure_inspector.py @@ -122,15 +122,7 @@ class StructureInspector: } def inspect(self, file_path: str) -> StructureInfo: - """ - 分析单个CIF文件 - - Args: - file_path: CIF文件路径 - - Returns: - StructureInfo: 分析结果 - """ + """分析单个CIF文件""" import os info = StructureInfo( file_path=file_path, @@ -145,24 +137,29 @@ class StructureInspector: info.error_message = f"读取CIF失败: {str(e)}" return info - # 结构读取成功,标记为有效 info.is_valid = True - # 后续分析用 try-except 包裹,确保即使分析出错也能返回基本信息 try: - # 基础信息 - info.elements = {str(el) for el in structure.composition.elements} + # ===== 关键修复:正确提取元素符号 ===== + # structure.composition.elements 返回 Element 对象列表 + # 需要用 .symbol 属性获取字符串 + element_symbols = set() + for el in structure.composition.elements: + # el 是 Element 对象,el.symbol 是字符串如 "Li" + element_symbols.add(el.symbol) + + info.elements = element_symbols info.num_sites = structure.num_sites info.formula = structure.composition.reduced_formula # 检查是否为二元化合物 - info.is_binary_compound = len(structure.composition.elements) == 2 + info.is_binary_compound = len(element_symbols) == 2 - # 检查是否含有目标阳离子 - info.contains_target_cation = self.target_cation in info.elements + # ===== 关键修复:直接比较字符串 ===== + info.contains_target_cation = self.target_cation in element_symbols # 检查阴离子类型 - info.anion_types = info.elements.intersection(self.target_anions) + info.anion_types = element_symbols.intersection(self.target_anions) if len(info.anion_types) == 0: info.anion_mode = "none" elif len(info.anion_types) == 1: