Source code for aim2dat.io.cp2k

"""
Module of functions to read output-files of CP2K.
"""

# Standard library imports
import os
import re

# Internal library imports
from aim2dat.io.auxiliary_functions import _extract_file_names
from aim2dat.aiida_workflows.cp2k.parser_utils import RestartStructureParser, PDOSParser


[docs] def read_band_structure(file_name): """ Read band structure file from CP2K. Parameters ---------- file_name : str Path of the output-file of CP2K containing the band structure. Returns ------- band_structure : dict Dictionary containing the k-path and the eigenvalues as well as the occupations. """ kpoints = [] bands = [[], []] occupations = [[], []] path_labels = [] point_idx = -1 spin_idx = 0 special_p2 = None is_spin_pol = False with open(file_name, "r") as bands_file: for line in bands_file: l_splitted = line.split() if line.startswith("# Special point 1"): if special_p2 is not None: path_labels.append((point_idx, special_p2)) if l_splitted[-1] != "specifi": path_labels.append((point_idx + 1, l_splitted[-1])) elif line.startswith("# Special point 2") and l_splitted[-1] != "specifi": special_p2 = l_splitted[-1] elif line.startswith("# Point"): # and "Spin 1" in line: if "Spin 1" in line: spin_idx = 0 point_idx += 1 for idx in range(2): bands[idx].append([]) occupations[idx].append([]) kpoints.append([float(l_splitted[idx]) for idx in range(5, 8)]) else: spin_idx = 1 is_spin_pol = True elif not line.startswith("#"): bands[spin_idx][point_idx].append(float(l_splitted[1])) occupations[spin_idx][point_idx].append(float(l_splitted[2])) if special_p2 is not None: path_labels.append((point_idx, special_p2)) if not is_spin_pol: bands = bands[0] occupations = occupations[0] return { "kpoints": kpoints, "unit_y": "eV", "bands": bands, "occupations": occupations, "path_labels": path_labels, }
[docs] def read_atom_proj_density_of_states(folder_path): """ Read the atom projected density of states from CP2K. Parameters ---------- folder_path : str Path to the folder of the pdos files. Returns ------- pdos : dict Dictionary containing the projected density of states for each kind. """ if len(folder_path) > 0: folder_path += "/" pattern = re.compile(r"^[a-zA-Z0-9\.\_]*-([A-Z]*)?_*k\d+-\d+\.pdos$") files = [ file for file in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, file)) ] pdos_files, file_info = _extract_file_names(files, pattern) if len(pdos_files) == 0: raise ValueError("No pDOS files found.") parser = PDOSParser() for file_name, spin in zip(pdos_files, file_info): file_content = open(folder_path + file_name, "r").read() parser.parse_pdos(file_content, spin) return parser.pdos
[docs] def read_optimized_structure(folder_path): """ Read optimized structures from 'restart'-files. Parameters ---------- folder_path : str Path to the folder containing the CP2K ouput-files. Returns ------- dict or list Dictionary containing the structural information. In case of a farming job a list of dictionaries is returned. In case several calculations have been run in the same folder a nested dictionary is returned. """ pattern = re.compile(r"(^\S*)?-1\.restart$") if len(folder_path) > 0: folder_path += "/" files = [ file for file in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, file)) ] restart_files, file_info = _extract_file_names(files, pattern) structures = {} for restart_file, f_info in zip(restart_files, file_info): restart_content = open(folder_path + restart_file, "r").read() str_parser = RestartStructureParser(restart_content) new_structures = str_parser.retrieve_output_structure() if len(new_structures) == 0: continue elif len(new_structures) == 1: structures[f_info] = new_structures[0] else: structures[f_info] = new_structures return list(structures.values())[0] if len(structures.values()) == 1 else structures