增加扩胞逻辑
This commit is contained in:
@@ -217,17 +217,20 @@ class DatabaseAnalyzer:
|
|||||||
# 更新 _compute_statistics 方法
|
# 更新 _compute_statistics 方法
|
||||||
|
|
||||||
def _compute_statistics(self, report: DatabaseReport):
|
def _compute_statistics(self, report: DatabaseReport):
|
||||||
"""计算统计数据(含扩胞分析)"""
|
"""计算统计数据"""
|
||||||
|
|
||||||
for info in report.all_structures:
|
for info in report.all_structures:
|
||||||
|
# 确保 info 不是 None
|
||||||
|
if info is None:
|
||||||
|
report.invalid_files += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 检查有效性
|
||||||
if info.is_valid:
|
if info.is_valid:
|
||||||
report.valid_files += 1
|
report.valid_files += 1
|
||||||
else:
|
else:
|
||||||
report.invalid_files += 1
|
report.invalid_files += 1
|
||||||
continue
|
continue # 无效文件不继续统计
|
||||||
|
|
||||||
if not info.contains_target_cation:
|
|
||||||
continue
|
|
||||||
|
|
||||||
report.cation_containing_count += 1
|
report.cation_containing_count += 1
|
||||||
|
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ class StructureInspector:
|
|||||||
Returns:
|
Returns:
|
||||||
StructureInfo: 分析结果
|
StructureInfo: 分析结果
|
||||||
"""
|
"""
|
||||||
|
import os
|
||||||
info = StructureInfo(
|
info = StructureInfo(
|
||||||
file_path=file_path,
|
file_path=file_path,
|
||||||
file_name=os.path.basename(file_path)
|
file_name=os.path.basename(file_path)
|
||||||
@@ -139,47 +140,64 @@ class StructureInspector:
|
|||||||
# 尝试读取结构
|
# 尝试读取结构
|
||||||
try:
|
try:
|
||||||
structure = Structure.from_file(file_path)
|
structure = Structure.from_file(file_path)
|
||||||
info.is_valid = True
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
info.error_message = str(e)
|
info.is_valid = False
|
||||||
|
info.error_message = f"读取CIF失败: {str(e)}"
|
||||||
return info
|
return info
|
||||||
|
|
||||||
# 基础信息
|
# 结构读取成功,标记为有效
|
||||||
info.elements = {str(el) for el in structure.composition.elements}
|
info.is_valid = True
|
||||||
info.num_sites = structure.num_sites
|
|
||||||
info.formula = structure.composition.reduced_formula
|
|
||||||
|
|
||||||
# 检查是否为二元化合物
|
# 后续分析用 try-except 包裹,确保即使分析出错也能返回基本信息
|
||||||
info.is_binary_compound = len(structure.composition.elements) == 2
|
try:
|
||||||
|
# 基础信息
|
||||||
|
info.elements = {str(el) for el in structure.composition.elements}
|
||||||
|
info.num_sites = structure.num_sites
|
||||||
|
info.formula = structure.composition.reduced_formula
|
||||||
|
|
||||||
# 检查是否含有目标阳离子
|
# 检查是否为二元化合物
|
||||||
info.contains_target_cation = self.target_cation in info.elements
|
info.is_binary_compound = len(structure.composition.elements) == 2
|
||||||
|
|
||||||
# 检查阴离子类型
|
# 检查是否含有目标阳离子
|
||||||
info.anion_types = info.elements.intersection(self.target_anions)
|
info.contains_target_cation = self.target_cation in info.elements
|
||||||
if len(info.anion_types) == 0:
|
|
||||||
info.anion_mode = "none"
|
|
||||||
elif len(info.anion_types) == 1:
|
|
||||||
info.anion_mode = "single"
|
|
||||||
else:
|
|
||||||
info.anion_mode = "mixed"
|
|
||||||
|
|
||||||
# 检查氧化态
|
# 检查阴离子类型
|
||||||
info.has_oxidation_states = self._check_oxidation_states(structure)
|
info.anion_types = info.elements.intersection(self.target_anions)
|
||||||
|
if len(info.anion_types) == 0:
|
||||||
|
info.anion_mode = "none"
|
||||||
|
elif len(info.anion_types) == 1:
|
||||||
|
info.anion_mode = "single"
|
||||||
|
else:
|
||||||
|
info.anion_mode = "mixed"
|
||||||
|
|
||||||
# 检查共占位(核心分析)
|
# 检查氧化态
|
||||||
self._analyze_partial_occupancy(structure, info)
|
info.has_oxidation_states = self._check_oxidation_states(structure)
|
||||||
|
|
||||||
# 检查水分子
|
# 检查共占位(核心分析)
|
||||||
info.has_water_molecule = self._check_water_molecule(structure)
|
try:
|
||||||
|
self._analyze_partial_occupancy(structure, info)
|
||||||
|
except Exception as e:
|
||||||
|
# 共占位分析失败,记录但继续
|
||||||
|
pass
|
||||||
|
|
||||||
# 检查放射性元素
|
# 检查水分子
|
||||||
info.has_radioactive_elements = bool(
|
try:
|
||||||
info.elements.intersection(self.RADIOACTIVE_ELEMENTS)
|
info.has_water_molecule = self._check_water_molecule(structure)
|
||||||
)
|
except:
|
||||||
|
info.has_water_molecule = False
|
||||||
|
|
||||||
# 判断可处理性
|
# 检查放射性元素
|
||||||
self._evaluate_processability(info)
|
info.has_radioactive_elements = bool(
|
||||||
|
info.elements.intersection(self.RADIOACTIVE_ELEMENTS)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 判断可处理性
|
||||||
|
self._evaluate_processability(info)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# 分析过程出错,但文件本身是有效的
|
||||||
|
# 保留 is_valid = True,但记录错误
|
||||||
|
info.error_message = f"分析过程出错: {str(e)}"
|
||||||
|
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
|||||||
@@ -27,17 +27,17 @@ def analyze_single_file(args: Tuple[str, str, set]) -> Optional[StructureInfo]:
|
|||||||
target_cation=target_cation,
|
target_cation=target_cation,
|
||||||
target_anions=target_anions
|
target_anions=target_anions
|
||||||
)
|
)
|
||||||
return inspector.inspect(file_path)
|
result = inspector.inspect(file_path)
|
||||||
|
return result
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# 返回一个标记失败的结果
|
# 返回一个标记失败的结果(而不是 None)
|
||||||
return StructureInfo(
|
return StructureInfo(
|
||||||
file_path=file_path,
|
file_path=file_path,
|
||||||
file_name=os.path.basename(file_path),
|
file_name=os.path.basename(file_path),
|
||||||
is_valid=False,
|
is_valid=False,
|
||||||
error_message=str(e)
|
error_message=f"Worker异常: {str(e)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def structure_info_to_dict(info: StructureInfo) -> dict:
|
def structure_info_to_dict(info: StructureInfo) -> dict:
|
||||||
"""
|
"""
|
||||||
将 StructureInfo 转换为可序列化的字典
|
将 StructureInfo 转换为可序列化的字典
|
||||||
|
|||||||
Reference in New Issue
Block a user