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
def _aiida_bands_data(self, data, cell, kpoints_dict): if not data: return False kpt_idx = sorted(data.keys()) # list of kpoint indices try: k_list = [kpoints_dict[i] for i in kpt_idx] # list of k-point triplet except KeyError: # kpoint triplets are not present (true for .qp and so on, can not use BandsData) # We use the internal Yambo Format [ [Eo_1, Eo_2,... ], ...[So_1,So_2,] ] # QP_TABLE [[ib_1,ik_1,isp_1] ,[ib_n,ik_n,isp_n]] # Each entry in DATA has corresponding legend in QP_TABLE that defines its details # like ib= Band index, ik= kpoint index, isp= spin polarization index. # Eo_1 => at ib_1, ik_1 isp_1. pdata = ArrayData() QP_TABLE = [] ORD = [] Eo = [] E_minus_Eo = [] So = [] Z = [] for ky in data.keys(): # kp == kpoint index as a string 1,2,.. for ind in range(len(data[ky]['Band'])): try: Eo.append(data[ky]['Eo'][ind]) except KeyError: pass try: E_minus_Eo.append(data[ky]['E-Eo'][ind]) except KeyError: pass try: So.append(data[ky]['Sc|Eo'][ind]) except KeyError: pass try: Z.append(data[ky]['Z'][ind]) except KeyError: pass ik = int(ky) ib = data[ky]['Band'][ind] isp = 0 if 'Spin_Pol' in list(data[ky].keys()): isp = data[ky]['Spin_Pol'][ind] QP_TABLE.append([ik, ib, isp]) pdata.set_array('Eo', numpy.array(Eo)) pdata.set_array('E_minus_Eo', numpy.array(E_minus_Eo)) pdata.set_array('So', numpy.array(So)) pdata.set_array('Z', numpy.array(Z)) pdata.set_array('qp_table', numpy.array(QP_TABLE)) return pdata quasiparticle_bands = BandsData() quasiparticle_bands.set_cell(cell) quasiparticle_bands.set_kpoints(k_list, cartesian=True) # labels will come from any of the keys in the nested kp_point data, # there is a uniform set of observables for each k-point, ie Band, Eo, ... # ***FIXME BUG does not seem to handle spin polarizes at all when constructing bandsdata*** bands_labels = [ legend for legend in sorted(data[list(data.keys())[0]].keys()) ] append_list = [[] for i in bands_labels] for kp in kpt_idx: for i in range(len(bands_labels)): append_list[i].append(data[kp][bands_labels[i]]) generalised_bands = [numpy.array(it) for it in append_list] quasiparticle_bands.set_bands(bands=generalised_bands, units='eV', labels=bands_labels) return quasiparticle_bands