"""Functions to read band structure and pDOS files of CP2K."""# Internal library importsfromaim2dat.io.utilsimportread_multiple,custom_openimportaim2dat.utils.unitsasunits
[docs]defread_band_structure(file_name:str)->dict:""" 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=-1spin_idx=0special_p2=Noneis_spin_pol=Falsewithcustom_open(file_name,"r")asbands_file:forlineinbands_file:l_splitted=line.split()ifline.startswith("# Special point 1"):ifspecial_p2isnotNone:path_labels.append((point_idx,special_p2))ifl_splitted[-1]!="specifi":path_labels.append((point_idx+1,l_splitted[-1]))elifline.startswith("# Special point 2")andl_splitted[-1]!="specifi":special_p2=l_splitted[-1]elifline.startswith("# Point"):# and "Spin 1" in line:if"Spin 1"inline:spin_idx=0point_idx+=1foridxinrange(2):bands[idx].append([])occupations[idx].append([])kpoints.append([float(l_splitted[idx])foridxinrange(5,8)])else:spin_idx=1is_spin_pol=Trueelifnotline.startswith("#"):bands[spin_idx][point_idx].append(float(l_splitted[1]))occupations[spin_idx][point_idx].append(float(l_splitted[2]))ifspecial_p2isnotNone:path_labels.append((point_idx,special_p2))ifnotis_spin_pol:bands=bands[0]occupations=occupations[0]return{"kpoints":kpoints,"unit_y":"eV","bands":bands,"occupations":occupations,"path_labels":path_labels,}
[docs]@read_multiple(r".*-(?P<spin>[A-Z]+)?_?(?:k\d|list\d).*\.pdos$")defread_atom_proj_density_of_states(folder_path:str)->dict:""" 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. """all_orbitals=["s","px","py","pz","d-2","d-1","d0","d+1","d+2","f-3","f-2","f-1","f0","f+1","f+2","f+3","g-4","g-3","g-2","g-1","g0","g+1","g+2","g+3","g+4","i-5","i-4","i-3","i-2","i-1","i0","i+1","i+2","i+3","i+4","i+5",]indices=[(val,idx)foridx,valinenumerate(folder_path["file_name"])]indices.sort(key=lambdapoint:point[0])_,indices=zip(*indices)pdos=[]efermi=Nonekinds={}foridxinindices:spin_suffix=""iffolder_path["spin"][idx]isnotNone:spin_suffix="_"+folder_path["spin"][idx].lower()energy=[]occupation=[]withcustom_open(folder_path["file"][idx],"r")asdos_file:line_1=dos_file.readline().split()line_2=dos_file.readline().split()if"list"inline_1:kind=line_1[5]else:kind=line_1[6]efermi=float(line_1[-2])*units.energy.Hartreeorbital_labels=line_2[5:]single_pdos={orb+spin_suffix:[]fororbinall_orbitalsiforbinorbital_labels}single_pdos["kind"]=kindforlineindos_file:line_sp=line.split()energy.append(float(line_sp[1])*units.energy.Hartree)occupation.append(float(line_sp[2]))fororb,valinzip(orbital_labels,line_sp[3:]):single_pdos[orb+spin_suffix].append(float(val))ifkindinkinds:pdos[kinds[kind]].update(single_pdos)else:kinds[kind]=len(pdos)pdos.append(single_pdos)return{"energy":energy,"occupation":occupation,"pdos":pdos,"unit_x":"eV","e_fermi":efermi,}