Source code for edrixs.plot_spectrum

__all__ = ['get_spectra_from_poles', 'merge_pole_dicts', 'plot_spectrum', 'plot_rixs_map']

import numpy as np
import matplotlib.pyplot as plt
from .utils import boltz_dist
from .iostream import read_poles_from_file


[docs]def get_spectra_from_poles(poles_dict, omega_mesh, gamma_mesh, temperature): """ Given the dict of poles, calculate XAS or RIXS spectra using continued fraction formula, .. math:: I(\\omega_{i}) =-\\frac{1}{\\pi}\\text{Im} \\left[ \\frac{1}{x - \\alpha_{0} - \\frac{\\beta_{1}^2}{x-\\alpha_{1} - \\frac{\\beta_{2}^2}{x-\\alpha_{2} - ...}} }\\right], where, :math:`x = \\omega_{i}+i\\Gamma_{i} + E_{g}`. Parameters ---------- poles_dict: dict Dict containing information of poles, which are calculated from xas_fsolver and rixs_fsolver. This dict is constructed by :func:`iostream.read_poles_from_file`. omega_mesh: 1d float array Energy grid. gamma_mesh: 1d float array Life-time broadening. temperature: float number Temperature (K) for boltzmann distribution. Returns ------- spectra: 1d float array The calculated XAS or RIXS spectra. See also -------- iostream.read_poles_from_file: read XAS or RIXS poles files. """ nom = len(omega_mesh) spectra = np.zeros(nom, dtype=np.float64) gs_dist = boltz_dist(poles_dict['eigval'], temperature) ngs = len(poles_dict['eigval']) for i in range(ngs): tmp_vec = np.zeros(nom, dtype=complex) neff = poles_dict['npoles'][i] alpha = poles_dict['alpha'][i] beta = poles_dict['beta'][i] eigval = poles_dict['eigval'][i] norm = poles_dict['norm'][i] for j in range(neff-1, 0, -1): tmp_vec = ( beta[j-1]**2 / (omega_mesh + 1j * gamma_mesh + eigval - alpha[j] - tmp_vec) ) tmp_vec = ( 1.0 / (omega_mesh + 1j * gamma_mesh + eigval - alpha[0] - tmp_vec) ) spectra[:] += -1.0 / np.pi * np.imag(tmp_vec) * norm * gs_dist[i] return spectra
[docs]def merge_pole_dicts(list_pole_dict): """ Given a list of dict of poles, merge them into one dict of poles Parameters ---------- list_pole_dict: list of dict Dict containing information of poles, which are calculated from xas_fsolver and rixs_fsolver. Returns ------- new_pole_dict: dict of poles New dict of poles. """ new_pole_dict = { 'eigval': [], 'npoles': [], 'norm': [], 'alpha': [], 'beta': [] } for poles_dict in list(list_pole_dict): new_pole_dict['eigval'].extend(poles_dict['eigval']) new_pole_dict['npoles'].extend(poles_dict['npoles']) new_pole_dict['norm'].extend(poles_dict['norm']) new_pole_dict['alpha'].extend(poles_dict['alpha']) new_pole_dict['beta'].extend(poles_dict['beta']) return new_pole_dict
[docs]def plot_spectrum(file_list, omega_mesh, gamma_mesh, T=1.0, fname='spectrum.dat', om_shift=0.0, fmt_float='{:.15f}'): """ Reading poles :math:`\\alpha` and :math:`\\beta`, and calculate the spectrum using continued fraction formula, .. math:: I(\\omega_{i}) =-\\frac{1}{\\pi}\\text{Im} \\left[ \\frac{1}{x - \\alpha_{0} - \\frac{\\beta_{1}^2}{x-\\alpha_{1} - \\frac{\\beta_{2}^2}{x-\\alpha_{2} - ...}} }\\right], where, :math:`x = \\omega_{i}+i\\Gamma_{i} + E_{g}`. Parameters ---------- file_list: list of string Name of poles file. omega_mesh: 1d float array The frequency mesh. gamma_mesh: 1d float array The broadening factor, in general, it is frequency dependent. T: float (default: 1.0K) Temperature (K). fname: str (default: 'spectrum.dat') File name to store spectrum. om_shift: float (default: 0.0) Energy shift. fmt_float: str (default: '{:.15f}') Format for printing float numbers. """ pole_dict = read_poles_from_file(file_list) spectrum = get_spectra_from_poles(pole_dict, omega_mesh, gamma_mesh, T) space = " " fmt_string = (fmt_float + space) * 2 + '\n' f = open(fname, 'w') for i in range(len(omega_mesh)): f.write(fmt_string.format(omega_mesh[i] + om_shift, spectrum[i])) f.close()
[docs]def plot_rixs_map(rixs_data, ominc_mesh, eloss_mesh, fname='rixsmap.pdf'): """ Given 2d RIXS data, plot a RIXS map and save it to a pdf file. Parameters ---------- rixs_data: 2d float array Calculated RIXS data as a function of incident energy and energy loss. ominc_mesh: 1d float array Incident energy mesh. eloss_mesh: 1d float array Energy loss mesh. fname: string File name to save RIXS map. """ fig, ax = plt.subplots() a, b, c, d = min(eloss_mesh), max(eloss_mesh), min(ominc_mesh), max(ominc_mesh) m, n = np.array(rixs_data).shape if len(ominc_mesh) == m and len(eloss_mesh) == n: plt.imshow( rixs_data, extent=[a, b, c, d], origin='lower', aspect='auto', cmap='rainbow', interpolation='gaussian' ) plt.xlabel(r'Energy loss (eV)') plt.ylabel(r'Energy of incident photon (eV)') elif len(eloss_mesh) == m and len(ominc_mesh) == n: plt.imshow( rixs_data, extent=[c, d, a, b], origin='lower', aspect='auto', cmap='rainbow', interpolation='gaussian' ) plt.ylabel(r'Energy loss (eV)') plt.xlabel(r'Energy of incident photon (eV)') else: raise Exception( "Dimension of rixs_data is not consistent with ominc_mesh or eloss_mesh" ) plt.savefig(fname)