def parse_value(value, unit=None, value_unit=None): """ Converts a float/str to proper value """ if isinstance(value, str): value, value_unit = value.split() if len(value_unit) == 0: value_unit = None if value_unit is None: value_unit = unit value = float(value) # Now parse unit if unit == value_unit: return value return value * units(value_unit, unit)
def __call__(dos_self, parser, ns, value, option_string=None): import matplotlib.pyplot as plt if not hasattr(ns, '_weight'): # Try and read in the k-point-weights ns._weight = kpSileSiesta( str(self.file).replace('EIG', 'KP')).read_data()[1] if ns._Emap is None: # We will plot the DOS in the entire energy window ns._Emap = [ns._eigs.min(), ns._eigs.max()] if len(ns._weight) != ns._eigs.shape[1]: raise SileError( str(self) + ' --dos the number of k-points for the eigenvalues and k-point weights ' 'are different, please use --weight correctly.') # Specify default settings dE = 0.005 # 5 meV kT = units('K', 'eV') * 300 distr = get_distribution('gaussian', smearing=kT) out = None if len(value) > 0: i = 0 try: dE = float(value[i]) i += 1 except: pass try: kT = float(value[i]) i += 1 except: pass try: distr = get_distribution(value[i], smearing=kT) i += 1 except: pass try: out = value[i] except: pass # Now we are ready to process E = np.arange(ns._Emap[0] - kT * 4, ns._Emap[1] + kT * 4, dE) def myplot(ax, legend, E, eig, w): DOS = np.zeros(len(E)) for ib in range(eig.shape[0]): for e in eig[ib, :]: DOS += distr(E - e) * w[ib] ax.plot(E, DOS, label=legend) ax.set_ylim(0, None) plt.figure() ax = plt.gca() ax.set_title('DOS kT={:.1f} K'.format(kT * units('eV', 'K'))) ax.set_xlabel('E - Ef [eV]') ax.set_xlim(E.min(), E.max()) ax.set_ylabel('DOS [1/eV]') if ns._eigs.shape[0] == 2: for i, ud in enumerate(['up', 'down']): myplot(ax, ud, E, ns._eigs[i, :, :], ns._weight) plt.legend() else: myplot(ax, '', E, ns._eigs[0, :, :], ns._weight) if out is None: plt.show() else: plt.savefig(out)