def bands_to_bandsdata(bands_info, kpoints, bands): """ Convert the result of parser_dot_bands into a BandsData object :param bands_info: A dictionary of the informations of the bands file. contains field such as eferemi, units, cell :param kpoints: An array of the kpoints of the bands, rows are (kindex, kx, ky, kz, weight) :param bands: The actual bands array :return: A BandsData object :rtype: ``aiida.orm.bands.data.array.bands.BandsData`` """ bands_node = BandsData() # Extract the index of the kpoints kpn_array = np.asarray(kpoints) k_index = kpn_array[:, 0] # We need to restore the order of the kpoints k_sort = np.argsort(k_index) # Sort the kpn_array kpn_array = kpn_array[k_sort] _weights = kpn_array[:, -1] kpts = kpn_array[:, 1:-1] bands_node.set_kpoints(kpts, weights=_weights) # Sort the bands to match the order of the kpoints bands_array = np.asarray(bands)[k_sort] # We need to swap the axes from kpt,spin,engs to spin,kpt,engs bands_array = bands_array.swapaxes(0, 1) # Squeeze the first dimension e.g when there is a single spin if bands_array.shape[0] == 1: bands_array = bands_array[0] bands_array = bands_array * units['Eh'] bands_info = dict(bands_info) # Create a copy # Convert the units for the fermi energies if isinstance(bands_info['efermi'], list): bands_info['efermi'] = [x * units['Eh'] for x in bands_info['efermi']] else: bands_info['efermi'] = bands_info['efermi'] * units['Eh'] bands_node.set_bands(bands_array, units="eV") # PBC is always true as this is PW DFT.... bands_node.set_cell(bands_info['cell'], pbc=(True, True, True)) # Store information from *.bands in the attributes # This is needs as we need to know the number of electrons # and the fermi energy for key, value in bands_info.items(): bands_node.set_attribute(key, value) return bands_node
def bands_from_castepbin(seedname, fmanager): """ Acquire and prepare bands data from the castep_bin file instead """ with fmanager.open(seedname + '.castep_bin', 'rb') as handle: binfile = CastepbinFile(fileobj=handle) bands_node = BandsData() kidx = binfile.kpoints_indices sort_idx = np.argsort(kidx) # Generated sorted arrays kpoints = binfile.kpoints[sort_idx, :] weights = binfile.kpoint_weights[sort_idx].astype(float) eigenvalues = binfile.eigenvalues[:, sort_idx, :] occupancies = binfile.occupancies[:, sort_idx, :] efermi = binfile.fermi_energy bands_node.set_kpoints(kpoints, weights=weights) bands_node.set_bands(eigenvalues, occupations=occupancies, units="eV") bands_node.set_cell(binfile.cell, pbc=(True, True, True)) bands_node.set_attribute('efermi', efermi) return bands_node