.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "gallery/arpes_fermisurf_simulation.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_gallery_arpes_fermisurf_simulation.py: ================================== ARPES Fermi surface map simulation ================================== .. GENERATED FROM PYTHON SOURCE LINES 7-116 .. image-sg:: /gallery/images/sphx_glr_arpes_fermisurf_simulation_001.png :alt: Ag ARPES Fermimap (001), $h\nu = 665\,\mathrm{eV}$ with $k_z$ curvature and broadening :srcset: /gallery/images/sphx_glr_arpes_fermisurf_simulation_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none /home/docs/checkouts/readthedocs.org/user_builds/fplore/envs/latest/lib/python3.8/site-packages/pymatgen/symmetry/kpath.py:178: UserWarning: The input structure does not match the expected standard primitive! The path can be incorrect. Use at your own risk. warn( Getting interpolator... Got interpolator. Doing interpolation... | .. code-block:: Python import numpy as np from scipy.stats import norm from fplore import FPLORun from fplore.util import rot_v1_v2 from fplore.plot import plot_bz from fplore.arpes import k_arpes, TPS45A1 import matplotlib.pyplot as plt kz_broadening = True kz_curvature = True e_broadening = True kxky_broadening = True run = FPLORun("../example_data/Ag") analyzer_direction = run.high_symm_kpoints['L'] # 111 lens_axis = run.high_symm_kpoints['X'] # 100 # vector rejection of normal to get perpendicular component to surface normal: lens_axis = lens_axis - (lens_axis @ analyzer_direction) / (analyzer_direction @ analyzer_direction) * analyzer_direction R = rot_v1_v2(analyzer_direction, [0, 0, 1]) R = rot_v1_v2(R @ lens_axis, [1, 0, 0]) @ R # usage: # for multiplying from the left R @ calc coords(3) -> msmt coords(3) # R.T @ msmt coords(3) -> calc coords(3) # for multiplying from the right: calc coords(...,3) @ R.T -> msmt coords(...,3) # msmt coords(...,3) @ R -> calc coords(...,3) thetacenter, thetawidth = 0, 36 mintheta, maxtheta = thetacenter - thetawidth / 2, thetacenter + thetawidth / 2 theta = np.linspace(np.deg2rad(mintheta), np.deg2rad(maxtheta), 401) theta2center, theta2width = 6, 23 # 1.3, 12 mintheta2, maxtheta2 = theta2center - theta2width / 2, theta2center + theta2width / 2 theta2 = np.linspace(np.deg2rad(mintheta2), np.deg2rad(maxtheta2), 400) extent = (mintheta, maxtheta, mintheta2, maxtheta2) theta, theta2 = np.meshgrid(theta, theta2, indexing='ij') v0 = 10 workfunc_analyzer = 3.8 e_photon = 665 if kz_broadening: imfp = 10 # angstroms, see https://doi.org/10.1384/jsa.9.285 Delta_kz = 1 / imfp # standard deviation in reciprocal angstroms (∆o)² = - ² surface_normal = R @ analyzer_direction # perfectly flat surface perpendicular to analyzer direction n_kz = 47 # 13 kz_deltas = np.linspace(-3 * Delta_kz, 3 * Delta_kz, n_kz) # shape (N,) kz_weights_pdf = norm.cdf(kz_deltas, scale=Delta_kz) kz_limits = np.hstack([[-np.inf], (kz_deltas[1:] + kz_deltas[:-1]) / 2, [np.inf]]) kz_weights = np.array([norm.cdf(u, scale=Delta_kz) - norm.cdf(l, scale=Delta_kz) for l, u in zip(kz_limits, kz_limits[1:])]) weights = kz_weights.reshape((1, 1, n_kz, 1)) kz_deltas = kz_deltas.reshape((1, 1, n_kz, 1)) * surface_normal.reshape(1, 1, 1, 3) # to shape (1, 1, N, 3) else: kz_deltas = 0 weights = 1 k_p_mean = k_arpes(theta=theta, e_photon=e_photon, phi_det=workfunc_analyzer, v0=v0, theta2=theta2, geometry=TPS45A1) if not kz_curvature: k_p_mean[:, :, 2] = k_p_mean[:, :, 2].max() k_p = k_p_mean[:, :, np.newaxis] + kz_deltas # add kz broadening sample points in 3rd dimension k = k_p @ R # aligned -> calculation (since R == R⁻¹.T) k_1bz = run.backfold_k(k) fig = plt.figure(figsize=(5, 6), constrained_layout=True, dpi=196) #fig.subplots_adjust(wspace=0.6, hspace=0.6) ax_bz = fig.add_subplot(2, 1, 1, projection='3d') ax_bz.plot_surface(*(k_p_mean[::40, ::40]).T, alpha=0.3) # don't draw all the points # - [0, 0, 8] @ run.primitive_lattice.reciprocal_lattice.matrix @ R midpoint = k.mean(axis=(0, 1, 2)) offset = midpoint @ run.primitive_lattice.reciprocal_lattice.inv_matrix offset = np.rint(offset) plot_bz(run, ax_bz, k_points=False, vectors=None, offset=offset, rot=R.T) ax_bz.view_init(elev=15., azim=-81.) ax = fig.add_subplot(2, 1, 2) ax.set_xlabel(r'$\theta_\mathrm{Lens} / \mathrm{deg}$', ) ax.set_ylabel(r'$\theta_\mathrm{Defl} / \mathrm{deg}$') level_indices = run.band.bands_within(0.2) # (*energy_window) print('Getting interpolator...') ip = run.band.get_interpolator(bands=level_indices) print('Got interpolator. Doing interpolation...') data = ip(k_1bz) if not e_broadening: scale = 0.01 # FWHM, eV else: scale = 0.1 # FWHM, eV scale = scale / 2.355 # FWHM -> std im = run.band.smooth_overlap(data, e=0, scale=scale, axis=2, weights=weights) if kxky_broadening: from scipy.ndimage import gaussian_filter im = gaussian_filter(im, (1, 1)) ax.imshow(im, extent=extent, origin='lower', aspect='equal', cmap='inferno') plt.suptitle(f'Ag ARPES Fermimap (001), $h\\nu = {e_photon}\\,\\mathrm{{eV}}$\nwith $k_z$ curvature and broadening') ax_bz.set_box_aspect([ub - lb for lb, ub in (getattr(ax_bz, f'get_{a}lim')() for a in 'xyz')]) plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 10.169 seconds) .. _sphx_glr_download_gallery_arpes_fermisurf_simulation.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: arpes_fermisurf_simulation.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: arpes_fermisurf_simulation.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_