[docs]defload_structural_data(dir_name:str|Path)->dict[str,Any]:"""Extract the structural data from the input structure of the directory. Args: dir_name: The directory of the completed calculation. Returns: The structural data. The following keys are guaranteed to be present in the returned dictionary: - ``"Structure"`` - ``"Base Structure"``: only assigned if extracted from adsorbate complex name - ``"Adsorbate"`` - ``"Site"`` - ``"Orientation"`` If no data is found, every value will be None. """logger.info(f"Loading structural data for {dir_name!s}")python_script=Path(dir_name).joinpath(SETTINGS.PYTHON_SCRIPT)structure=base_structure=adsorbate=site=orientation=Noneifpython_script.exists():withpython_script.open(mode="r",encoding="utf-8")asfile:structure_name=extract_structure_name(file)structure=structure_name.removeprefix("./").removesuffix(".traj")ifmatch:=_re_adsorbate_complex.match(structure):base_structure,adsorbate,site,orientation=match.group("structure","adsorbate","site","orientation")ifNonein(structure,adsorbate):withsuppress(FileNotFoundError,UnknownFileTypeError):atoms=ase.io.read(Path(dir_name).joinpath(f"{structureor'in'}.traj"))structure=structureorstr(atoms.symbols)adsorbate=adsorbateor"".join(x.symbolforxinatomsifx.tag==ADSORBATE_TAG)# ! Patch for misnamed structuresifstructure:structure=structure.replace("HAB","HIB")ifbase_structure:base_structure=base_structure.replace("HAB","HIB")# TODO: Adsorbed?# Nearest catalyst atom (and distance)final_structure=dir_name.joinpath("final.traj")final_atoms=(ase.io.read(final_structure)iffinal_structure.exists()elseNone)data={"Structure":structure,"Base Structure":base_structure,"Adsorbate":adsorbate,"Site":siteifsiteisNoneelsesite.strip("_"),"Orientation":orientation,"Final Atoms":final_atoms,}ifNoneinlist(data.values()):none=", ".join(kfork,vindata.items()ifvisNone)logger.warning(f"Unable to load structural data for {dir_name!s}. "f"The following values are None: {none}")else:logger.info(f"Successfully loaded structural data for {dir_name!s}")returndata