From 42a0f91c184232403d3e215c7c6e6d018a3a1ee5 Mon Sep 17 00:00:00 2001 From: Vincent Stimper Date: Fri, 11 Nov 2022 20:42:07 +0100 Subject: [PATCH] Remove checkpionts --- .../Fig1_Data_preprocessing-checkpoint.ipynb | 274 ----------- ..._Four_DFTs_Reconstruction-checkpoint.ipynb | 314 ------------- ..._Theory_vs_Reconstruction-checkpoint.ipynb | 246 ---------- ...mations_to_reconstruction-checkpoint.ipynb | 162 ------- .../Fig3_HexagonalZernike-checkpoint.ipynb | 249 ---------- ...x_and_basis_decomposition-checkpoint.ipynb | 417 ----------------- .../Fig5_K_and_Mprime-checkpoint.ipynb | 244 ---------- ...along_high-symmetry_lines-checkpoint.ipynb | 330 ------------- ...ig4_Hyperparameter_tuning-checkpoint.ipynb | 361 --------------- ...ests_on_synthetic_2D_data-checkpoint.ipynb | 330 ------------- ...ests_on_synthetic_3D_data-checkpoint.ipynb | 437 ------------------ ...n_with_different_theories-checkpoint.ipynb | 428 ----------------- ...uction_with_scaled_theory-checkpoint.ipynb | 246 ---------- ...ta_and_initial_conditions-checkpoint.ipynb | 356 -------------- 14 files changed, 4394 deletions(-) delete mode 100644 figures/.ipynb_checkpoints/Fig1_Data_preprocessing-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/Fig2_SFig5_Four_DFTs_Reconstruction-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/Fig2_Theory_vs_Reconstruction-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/Fig3_Approximations_to_reconstruction-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/Fig3_HexagonalZernike-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/Fig3_SFig13_Similarity_matrix_and_basis_decomposition-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/Fig5_K_and_Mprime-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/SFig14_Approximation_along_high-symmetry_lines-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/SFig4_Hyperparameter_tuning-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/SFig6_Tests_on_synthetic_2D_data-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/SFig6_Tests_on_synthetic_3D_data-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/SFig9_Reconstruction_with_different_theories-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/SFig9_Reconstruction_with_scaled_theory-checkpoint.ipynb delete mode 100644 figures/.ipynb_checkpoints/SFig9_Synthetic_data_and_initial_conditions-checkpoint.ipynb diff --git a/figures/.ipynb_checkpoints/Fig1_Data_preprocessing-checkpoint.ipynb b/figures/.ipynb_checkpoints/Fig1_Data_preprocessing-checkpoint.ipynb deleted file mode 100644 index 35740e6..0000000 --- a/figures/.ipynb_checkpoints/Fig1_Data_preprocessing-checkpoint.ipynb +++ /dev/null @@ -1,274 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Stages of data preprocessing" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import numpy as np\n", - "from fuller.mrfRec import MrfRec\n", - "from fuller.generator import rotosymmetrize\n", - "from fuller.utils import saveHDF\n", - "from mpes import analysis as aly, fprocessing as fp\n", - "\n", - "import os\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib as mpl\n", - "from matplotlib.ticker import MultipleLocator, FormatStrFormatter\n", - "%matplotlib inline\n", - "\n", - "# mpl.rcParams['font.family'] = 'sans-serif'\n", - "# mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Before we start with the preprocessing, we determine the location of the high symmetry points which we need for plotting the data. For simplicity and linearity of the code, we do this using the symmetrized data from file but of course we could also do the preprocessing first before plotting the resulting data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fdata = fp.readBinnedhdf5('../data/pes/1_sym.h5')\n", - "mc = aly.MomentumCorrector(fdata['V'])\n", - "\n", - "mc.selectSlice2D(selector=slice(30, 32), axis=2)\n", - "mc.featureExtract(mc.slice, method='daofind', sigma=6, fwhm=20, symscores=False)\n", - "\n", - "# False detection filter, if needed\n", - "try:\n", - " mc.pouter_ord = mc.pouter_ord[[0,1,3,5,6,9],:]\n", - "except:\n", - " pass" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mc.view(image=mc.slice, annotated=True, points=mc.features)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Define high-symmetry points\n", - "G = mc.pcent # Gamma point\n", - "K = mc.pouter_ord[0,:] # K point\n", - "K1 = mc.pouter_ord[1,:] # K' point\n", - "M = (K + K1) / 2 # M point\n", - "\n", - "# Define cutting path\n", - "pathPoints = np.asarray([G, M, K, G])\n", - "nGM, nMK, nKG = 70, 39, 79\n", - "segPoints = [nGM, nMK, nKG]\n", - "rowInds, colInds, pathInds = aly.points2path(pathPoints[:,0], pathPoints[:,1], npoints=segPoints)\n", - "nSegPoints = len(rowInds)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Define plotting function\n", - "\n", - "def plot_path(mrf, vmax, save_path):\n", - " # Normalize data\n", - " imNorm = mrf.I / mrf.I.max()\n", - "\n", - " # Sample the data along high-symmetry lines (k-path) connecting the corresponding high-symmetry points\n", - " pathDiagram = aly.bandpath_map(imNorm, pathr=rowInds, pathc=colInds, eaxis=2)\n", - "\n", - " Evals = mrf.E\n", - " ehi, elo = Evals[0], Evals[449]\n", - "\n", - " f, ax = plt.subplots(figsize=(10, 6))\n", - " colornames = ['#646464', '#666666', '#6a6a6a', '#6f6f6f', '#737373', '#787878', '#7d7d7d', '#828282', '#878787', '#8d8d8d', '#929292', '#989898', '#9e9e9e', '#a4a4a4', '#aaaaaa', '#b0b0b0', '#b6b6b6', '#bcbcbc', '#c2c2c2', '#c9c9c9', '#cfcfcf', '#d6d6d6', '#dcdcdc', '#e3e3e3', '#eaeaea', '#efefee', '#efeee5', '#efeddc', '#efecd3', '#eeebca', '#eeeac0', '#eee9b7', '#eee8ad', '#ede7a4', '#ede69a', '#ede590', '#ede487', '#ece37d', '#ece273', '#ece069', '#ecdf5f', '#ebde55', '#ebdd4b', '#ebdc41', '#ebdb37', '#ebd333', '#ebc933', '#ecbe32', '#ecb432', '#eda931', '#ee9e31', '#ee9330', '#ef8830', '#ef7d2f', '#f0722f', '#f0672e', '#f15c2e', '#f2512d', '#f2462d', '#f33b2c', '#f3302c', '#f4252b', '#f4192b', '#ef182f', '#e81834', '#e21939', '#db1a3e', '#d51a43', '#ce1b48', '#c71b4d', '#c11c52', '#ba1c58', '#b31d5d', '#ac1d62', '#a61e67', '#9f1e6c', '#981f72', '#911f77', '#8a207c', '#842182']\n", - " custom_cmap = mpl.colors.LinearSegmentedColormap.from_list('custom', colornames, N=256)\n", - " plt.imshow(pathDiagram[:450, :], cmap=custom_cmap, aspect=10.9, extent=[0, nSegPoints, elo, ehi], vmin=0, vmax=vmax)\n", - " ax.set_xticks(pathInds)\n", - " ax.set_xticklabels(['$\\overline{\\Gamma}$', '$\\overline{\\mathrm{M}}$',\n", - " '$\\overline{\\mathrm{K}}$', '$\\overline{\\Gamma}$'], fontsize=15)\n", - " for p in pathInds[:-1]:\n", - " ax.axvline(x=p, c='r', ls='--', lw=2, dashes=[4, 2])\n", - " # ax.axhline(y=0, ls='--', color='r', lw=2)\n", - " ax.yaxis.set_major_locator(MultipleLocator(2))\n", - " ax.yaxis.set_minor_locator(MultipleLocator(1))\n", - " ax.yaxis.set_label_position(\"right\")\n", - " ax.yaxis.tick_right()\n", - " ax.set_ylabel('Energy (eV)', fontsize=15, rotation=-90, labelpad=20)\n", - " ax.tick_params(axis='x', length=0, pad=6)\n", - " ax.tick_params(which='both', axis='y', length=8, width=2, labelsize=15)\n", - " \n", - " plt.savefig(save_path, dpi=200)\n", - " plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Load data\n", - "data = fp.readBinnedhdf5('../data/pes/0_binned.h5')\n", - "I = data['V']\n", - "E = data['E']\n", - "kx = data['kx']\n", - "ky = data['ky']\n", - "\n", - "# Create reconstruction object from data file\n", - "mrf = MrfRec(E=E, kx=kx, ky=ky, I=I)\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Main Figure 1c: photoemission band mapping data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "plot_path(mrf, 0.5, '../results/figures/fig_1c.png')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Main Figure 1d: Pattern symmetrization in $(k_x, k_y)$ plane (rotation and reflection)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "mrf.symmetrizeI()\n", - "plot_path(mrf, 0.5, '../results/figures/fig_1d.png')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Main Figure 1e: Normalization and contrast enhancement (MCLAHE)\n", - "MCLAHE stands for multidimensional contrast limited adaptive histogram equalization (see publication [here](https://ieeexplore.ieee.org/document/8895993))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "mrf.normalizeI(kernel_size=(20, 20, 25), n_bins=256, clip_limit=0.15, use_gpu=True)\n", - "plot_path(mrf, 1, '../results/figures/fig_1e.png')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Main Figure 1f: Multidimensional smoothing using Gaussian filter" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mrf.smoothenI(sigma=(.8, .8, 1.))\n", - "plot_path(mrf, 1, '../results/figures/fig_1f.png')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, - "outputs": [], - "source": [ - "# # Save data to disc if needed\n", - "# data_save = [['axes', {'E': mrf.E, 'kx': mrf.kx, 'ky': mrf.ky}], ['binned', {'V': mrf.I}]]\n", - "# saveHDF(*data_save, save_addr='../data/preprocessed.h5')" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - }, - "pycharm": { - "stem_cell": { - "cell_type": "raw", - "metadata": { - "collapsed": false - }, - "source": "" - } - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/Fig2_SFig5_Four_DFTs_Reconstruction-checkpoint.ipynb b/figures/.ipynb_checkpoints/Fig2_SFig5_Four_DFTs_Reconstruction-checkpoint.ipynb deleted file mode 100644 index da96bb5..0000000 --- a/figures/.ipynb_checkpoints/Fig2_SFig5_Four_DFTs_Reconstruction-checkpoint.ipynb +++ /dev/null @@ -1,314 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Reconstruction with four DFT calculations as initializations" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import os\n", - "import numpy as np\n", - "import fuller\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib as mpl\n", - "from mpl_toolkits.axes_grid1.inset_locator import inset_axes\n", - "from mpes import fprocessing as fp, analysis as aly\n", - "from scipy import io as sio\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams['font.family'] = 'sans-serif'\n", - "mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42\n", - "\n", - "colornames = ['#646464', '#666666', '#6a6a6a', '#6f6f6f', '#737373', '#787878', '#7d7d7d', '#828282', '#878787', '#8d8d8d', '#929292', '#989898', '#9e9e9e', '#a4a4a4', '#aaaaaa', '#b0b0b0', '#b6b6b6', '#bcbcbc', '#c2c2c2', '#c9c9c9', '#cfcfcf', '#d6d6d6', '#dcdcdc', '#e3e3e3', '#eaeaea', '#efefee', '#efeee5', '#efeddc', '#efecd3', '#eeebca', '#eeeac0', '#eee9b7', '#eee8ad', '#ede7a4', '#ede69a', '#ede590', '#ede487', '#ece37d', '#ece273', '#ece069', '#ecdf5f', '#ebde55', '#ebdd4b', '#ebdc41', '#ebdb37', '#ebd333', '#ebc933', '#ecbe32', '#ecb432', '#eda931', '#ee9e31', '#ee9330', '#ef8830', '#ef7d2f', '#f0722f', '#f0672e', '#f15c2e', '#f2512d', '#f2462d', '#f33b2c', '#f3302c', '#f4252b', '#f4192b', '#ef182f', '#e81834', '#e21939', '#db1a3e', '#d51a43', '#ce1b48', '#c71b4d', '#c11c52', '#ba1c58', '#b31d5d', '#ac1d62', '#a61e67', '#9f1e6c', '#981f72', '#911f77', '#8a207c', '#842182']\n", - "custom_cmap = mpl.colors.LinearSegmentedColormap.from_list('custom', colornames, N=256)\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Load preprocessed photoemission data\n", - "bcsm = np.load(r'../data/processed/hslines/WSe2_vcut.npy')\n", - "Evals = fp.readBinnedhdf5(r'../data/pes/3_smooth.h5')['E']\n", - "ehi, elo = Evals[0], Evals[469]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Main Figure 2a" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Specify the band shift hyperparameters (including the global shift of 0.65)\n", - "dftbands = sio.loadmat('../data/theory/hslines/initials_DFT_G-M.mat') \n", - "lda_th_shift = dftbands['LDA'][100:125, 0].max()\n", - "pbe_th_shift = dftbands['PBE'][100:125, 0].max()\n", - "pbesol_th_shift = dftbands['PBEsol'][100:125, 0].max()\n", - "hse_th_shift = dftbands['HSE'][100:125, 0].max()\n", - "eshift = 0.65\n", - "\n", - "lda_shift = np.array([0.4, 0.2, 0.3, 0.25, 0.22, 0.3, 0.3, 0.25, 0.2, 0.32, 0.4, 0.4, 0.4, 0.4]) + eshift\n", - "pbe_shift = np.array([0, -0.3, -0.2, -0.25, -0.35, -0.3, -0.25, -0.2, -0.4, -0.4, -0.4, -0.4, -0.37, -0.4]) + eshift\n", - "pbesol_shift = np.array([0, -0.2, -0.1, -0.15, -0.2, -0.05, 0, 0, -0.2, -0.1, -0.1, -0.1, 0, 0]) + eshift\n", - "hse_shift = np.array([-0.15, -0.4, -0.2, -0.2, -0.2, -0.15, 0, 0, 0.1, 0, 0.1, 0.1, 0.2, 0.2]) + eshift" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot initializations vs theories\n", - "bseg = bcsm[:, :70]\n", - "\n", - "f, ax = plt.subplots(2, 2, figsize=(4.5, 9))\n", - "ax[0,0].imshow(bseg, cmap=custom_cmap, extent=[0, 69, elo, ehi], aspect=17)\n", - "ax[0,1].imshow(bseg, cmap=custom_cmap, extent=[0, 69, elo, ehi], aspect=17)\n", - "ax[1,0].imshow(bseg, cmap=custom_cmap, extent=[0, 69, elo, ehi], aspect=17)\n", - "ax[1,1].imshow(bseg, cmap=custom_cmap, extent=[0, 69, elo, ehi], aspect=17)\n", - "\n", - "# Plot original theory energy bands after zero adjustment\n", - "ax[0,0].plot(dftbands['LDA'][:69,:14] - lda_th_shift, 'r-')\n", - "ax[0,0].plot(dftbands['LDA'][:69, 13] - lda_th_shift, 'r-', label='Theory')\n", - "ax[0,1].plot(dftbands['PBE'][:69,:14] - pbe_th_shift, 'r-')\n", - "ax[1,0].plot(dftbands['PBEsol'][:69,:14] - pbesol_th_shift, 'r-')\n", - "ax[1,1].plot(dftbands['HSE'][:69,:14] - hse_th_shift, 'r-')\n", - "\n", - "# Plot shift-aligned energy bands\n", - "for ib in range(14):\n", - " ax[0,0].plot(dftbands['LDA'][:69,ib] + lda_shift[ib], '--', color='#F0FF24', dashes=[5, 2])\n", - " ax[0,1].plot(dftbands['PBE'][:69,ib] + pbe_shift[ib], '--', color='#F0FF24', dashes=[5, 2])\n", - " ax[1,0].plot(dftbands['PBEsol'][:69,ib] + pbesol_shift[ib], '--', color='#F0FF24', dashes=[5, 2])\n", - " ax[1,1].plot(dftbands['HSE'][:69,ib] + hse_shift[ib], '--', color='#F0FF24', dashes=[5, 2])\n", - "ax[0,0].plot(dftbands['LDA'][:69,ib] + lda_shift[ib], '--', color='#F0FF24', dashes=[5, 2], label='Initialization')\n", - "\n", - "ax[0,0].set_title('LDA', fontsize=15, x=0.8, y=0.88)\n", - "ax[0,1].set_title('PBE', fontsize=15, x=0.8, y=0.88)\n", - "ax[1,0].set_title('PBEsol', fontsize=15, x=0.75, y=0.88)\n", - "ax[1,1].set_title('HSE06', fontsize=15, x=0.76, y=0.88)\n", - "\n", - "for i in range(2):\n", - " for j in range(2):\n", - " ax[i,j].tick_params(axis='both', length=8, width=2, labelsize=15)\n", - " ax[i,j].set_ylim([elo, ehi])\n", - "\n", - "ax[0,0].set_xticks([])\n", - "ax[0,1].set_xticks([])\n", - "ax[0,1].set_yticks([])\n", - "ax[1,1].set_yticks([])\n", - "ax[0,0].set_yticks(range(-7, 1))\n", - "ax[1,0].set_yticks(range(-7, 1))\n", - "\n", - "ax[0,0].set_ylabel('Energy (eV)', fontsize=20)\n", - "ax[1,0].set_ylabel('Energy (eV)', fontsize=20)\n", - "\n", - "ax[1,0].tick_params(axis='x', width=0, pad=0)\n", - "ax[1,1].tick_params(axis='x', width=0, pad=0)\n", - "\n", - "ax[1,0].set_xticks([0, 69])\n", - "ax[1,0].set_xticklabels(['$\\overline{\\Gamma}$', '$\\overline{\\mathrm{M}}$'])\n", - "ax[1,1].set_xticks([0, 69])\n", - "ax[1,1].set_xticklabels(['$\\overline{\\Gamma}$', '$\\overline{\\mathrm{M}}$'])\n", - "\n", - "lg = ax[0,0].legend(fontsize=15, ncol=2, facecolor='#A9CCE3', edgecolor='#A9CCE3', bbox_to_anchor=(2.21, 1.18))\n", - "\n", - "plt.subplots_adjust(hspace=0.02, wspace=0.15)\n", - "plt.savefig('../results/figures/fig_2a.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Main Figure 2c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "paths = np.load(r'../data/processed/hslines/WSe2_kpath.npz')\n", - "\n", - "reconbands = {}\n", - "for name in ['LDA', 'PBE', 'PBEsol', 'HSE']:\n", - " bands = np.load(r'../data/processed/wse2_recon/postproc_refrotsym_bands_'+name.lower()+'.npy')\n", - " bdi = aly.bandpath_map(np.moveaxis(bands, 0, 2), pathr=paths['rowInds'], pathc=paths['colInds'], eaxis=2)\n", - " reconbands[name] = bdi.T" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pos = paths['pathInds']\n", - "pos[-1] -= 1\n", - "\n", - "ff, axa = plt.subplots(1, 1, figsize=(10.5, 8))\n", - "im = axa.imshow(bcsm, cmap=custom_cmap, extent=[0, 185, elo, ehi], aspect=12)\n", - "# axa.plot(dftbands['HSE'][:,:14] - hse_th_shift, 'r--', zorder=2)\n", - "for ib in range(14):\n", - " axa.plot(reconbands['LDA'][:,ib] + 0.65, color='r', zorder=1);\n", - "axa.tick_params(axis='y', length=8, width=2, labelsize=15)\n", - "axa.tick_params(axis='x', length=0, labelsize=15, pad=8)\n", - "axa.set_ylim([elo, ehi])\n", - "axa.set_xticks(pos)\n", - "axa.set_xticklabels(['$\\overline{\\Gamma}$', '$\\overline{\\mathrm{M}}$',\n", - " '$\\overline{\\mathrm{K}}$', '$\\overline{\\Gamma}$']);\n", - "axa.set_ylabel('Energy (eV)', fontsize=20)\n", - "for p in pos[:-1]:\n", - " axa.axvline(x=p, c='k', ls='--', lw=2, dashes=[4, 2])\n", - " \n", - "axa.set_title('Reconstruction', fontsize=15, x=0.8, y=0.9)\n", - "cax = inset_axes(axa, width=\"3%\", height=\"30%\", bbox_to_anchor=(220, 90, 440, 200))\n", - "cb = plt.colorbar(im, cax=cax, ticks=[])\n", - "cb.ax.set_ylabel('Intensity', fontsize=15, rotation=-90, labelpad=17)\n", - "\n", - "plt.savefig('../results/figures/fig_2c.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dftbands = {}\n", - "for dft in ['LDA','PBE','PBEsol','HSE']:\n", - " dftbands[dft] = sio.loadmat(r'../data/theory/hslines/WSe2_bandlines_'+dft+'_186.mat')['lines']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f, axs = plt.subplots(2, 2, figsize=(17, 10))\n", - "axs[0,0].imshow(bcsm, cmap=custom_cmap, extent=[0, 185, elo, ehi], aspect=12)\n", - "axs[0,1].imshow(bcsm, cmap=custom_cmap, extent=[0, 185, elo, ehi], aspect=12)\n", - "axs[1,0].imshow(bcsm, cmap=custom_cmap, extent=[0, 185, elo, ehi], aspect=12)\n", - "axs[1,1].imshow(bcsm, cmap=custom_cmap, extent=[0, 185, elo, ehi], aspect=12)\n", - "\n", - "c_over = '#FFD54F'\n", - "axs[0,0].plot(dftbands['LDA'][:,:14] - lda_th_shift, color=c_over, ls='--', dashes=[3, 1], zorder=2)\n", - "axs[0,1].plot(dftbands['PBE'][:,:14] - pbe_th_shift, color=c_over, ls='--', dashes=[3, 1], zorder=2)\n", - "axs[1,0].plot(dftbands['PBEsol'][:,:14] - pbesol_th_shift, color=c_over, ls='--', dashes=[3, 1], zorder=2)\n", - "axs[1,1].plot(dftbands['HSE'][:,:14] - hse_th_shift, color=c_over, ls='--', dashes=[3, 1], zorder=2)\n", - "\n", - "axs[0,0].set_title('LDA', fontsize=15, x=0.8, y=0.9)\n", - "axs[0,1].set_title('PBE', fontsize=15, x=0.8, y=0.9)\n", - "axs[1,0].set_title('PBEsol', fontsize=15, x=0.8, y=0.9)\n", - "axs[1,1].set_title('HSE06', fontsize=15, x=0.8, y=0.9)\n", - "\n", - "for i in range(2):\n", - " for j in range(2):\n", - " axs[i,j].tick_params(axis='y', length=8, width=2, labelsize=15)\n", - " axs[i,j].tick_params(axis='x', length=0, labelsize=15, pad=8)\n", - " axs[i,j].set_yticks(np.arange(-8, 1))\n", - " axs[i,j].set_ylim([elo, ehi])\n", - " axs[i,j].set_xticks(pos)\n", - " axs[i,j].set_xticklabels(['$\\overline{\\Gamma}$', '$\\overline{\\mathrm{M}}$',\n", - " '$\\overline{\\mathrm{K}}$', '$\\overline{\\Gamma}$'])\n", - " \n", - " for p in pos[:-1]:\n", - " axs[i,j].axvline(x=p, c='k', ls='--', lw=2, dashes=[3, 1.7])\n", - " \n", - "for ib in range(14):\n", - " axs[0,0].plot(reconbands['LDA'][:,ib] + 0.65, '-', color='r', zorder=1)\n", - " axs[0,1].plot(reconbands['PBE'][:,ib] + 0.65, '-', color='r', zorder=1)\n", - " axs[1,0].plot(reconbands['PBEsol'][:,ib] + 0.65, '-', color='r', zorder=1)\n", - " axs[1,1].plot(reconbands['HSE'][:,ib] + 0.65, '-', color='r', zorder=1)\n", - "\n", - "# Add legend\n", - "axs[0,0].plot(dftbands['LDA'][:,0] - lda_th_shift, color=c_over, ls='--', dashes=[3, 1], zorder=2, label='LDA Calc.')\n", - "axs[0,0].plot(reconbands['LDA'][:,ib] + 0.65, '-', color='r', zorder=1, label='LDA Recon.')\n", - "lg = axs[0,0].legend(fontsize=15, ncol=1, facecolor='w', edgecolor='k', framealpha=1, bbox_to_anchor=(0.94, 0.1))\n", - "lg.get_frame().set_linewidth(2)\n", - "\n", - "axs[0,1].plot(dftbands['PBE'][:,0] - pbe_th_shift, color=c_over, ls='--', dashes=[3, 1], zorder=2, label='PBE Calc.')\n", - "axs[0,1].plot(reconbands['PBE'][:,ib] + 0.65, '-', color='r', zorder=1, label='PBE Recon.')\n", - "lg = axs[0,1].legend(fontsize=15, ncol=1, facecolor='w', edgecolor='k', framealpha=1, bbox_to_anchor=(0.94, 0.1))\n", - "lg.get_frame().set_linewidth(2)\n", - "\n", - "axs[1,0].plot(dftbands['PBEsol'][:,0] - pbesol_th_shift, color=c_over, ls='--', dashes=[3, 1], zorder=2, label='PBEsol Calc.')\n", - "axs[1,0].plot(reconbands['PBEsol'][:,ib] + 0.65, '-', color='r', zorder=1, label='PBEsol Recon.')\n", - "lg = axs[1,0].legend(fontsize=15, ncol=1, facecolor='w', edgecolor='k', framealpha=1, bbox_to_anchor=(0.98, 0.1))\n", - "lg.get_frame().set_linewidth(2)\n", - "\n", - "axs[1,1].plot(dftbands['HSE'][:,0] - hse_th_shift, color=c_over, ls='--', dashes=[3, 1], zorder=2, label='HSE06 Calc.')\n", - "axs[1,1].plot(reconbands['HSE'][:,ib] + 0.65, '-', color='r', zorder=1, label='HSE06 Recon.')\n", - "lg = axs[1,1].legend(fontsize=15, ncol=1, facecolor='w', edgecolor='k', framealpha=1, bbox_to_anchor=(0.94, 0.1))\n", - "lg.get_frame().set_linewidth(2)\n", - "\n", - "plt.subplots_adjust(hspace=0.2, wspace=0.1)\n", - "plt.savefig('../results/figures/sfig_5.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/Fig2_Theory_vs_Reconstruction-checkpoint.ipynb b/figures/.ipynb_checkpoints/Fig2_Theory_vs_Reconstruction-checkpoint.ipynb deleted file mode 100644 index 4fda052..0000000 --- a/figures/.ipynb_checkpoints/Fig2_Theory_vs_Reconstruction-checkpoint.ipynb +++ /dev/null @@ -1,246 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Comparison between initialization (LDA-DFT) with reconstruction" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import os\n", - "import fuller\n", - "from natsort import natsorted\n", - "import glob as g\n", - "import numpy as np\n", - "import scipy.io as sio\n", - "from mpes import analysis as aly\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib as mpl\n", - "from scipy import interpolate\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams['font.family'] = 'sans-serif'\n", - "mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42\n", - "colornames = ['#646464', '#666666', '#6a6a6a', '#6f6f6f', '#737373', '#787878', '#7d7d7d', '#828282', '#878787', '#8d8d8d', '#929292', '#989898', '#9e9e9e', '#a4a4a4', '#aaaaaa', '#b0b0b0', '#b6b6b6', '#bcbcbc', '#c2c2c2', '#c9c9c9', '#cfcfcf', '#d6d6d6', '#dcdcdc', '#e3e3e3', '#eaeaea', '#efefee', '#efeee5', '#efeddc', '#efecd3', '#eeebca', '#eeeac0', '#eee9b7', '#eee8ad', '#ede7a4', '#ede69a', '#ede590', '#ede487', '#ece37d', '#ece273', '#ece069', '#ecdf5f', '#ebde55', '#ebdd4b', '#ebdc41', '#ebdb37', '#ebd333', '#ebc933', '#ecbe32', '#ecb432', '#eda931', '#ee9e31', '#ee9330', '#ef8830', '#ef7d2f', '#f0722f', '#f0672e', '#f15c2e', '#f2512d', '#f2462d', '#f33b2c', '#f3302c', '#f4252b', '#f4192b', '#ef182f', '#e81834', '#e21939', '#db1a3e', '#d51a43', '#ce1b48', '#c71b4d', '#c11c52', '#ba1c58', '#b31d5d', '#ac1d62', '#a61e67', '#9f1e6c', '#981f72', '#911f77', '#8a207c', '#842182']\n", - "custom_cmap = mpl.colors.LinearSegmentedColormap.from_list('custom', colornames, N=256)\n", - "\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Load energy bands from reconstrucion\n", - "recbands = np.load(r'../data/processed/wse2_recon/postproc_refrotsym_bands_lda.npy')\n", - "reconfile = r'../data/processed/wse2_recon/lda_recon_mrf_rec_00.h5'\n", - "einband = fuller.utils.loadHDF(reconfile, groups=['axes'])\n", - "kx, ky = einband['kx'], einband['ky']\n", - "nkx, nky = kx.size, ky.size\n", - "\n", - "# Load energy bands from theory (used as initialization for the reconstruction)\n", - "theory = sio.loadmat(r'../data/theory/WSe2_LDA_bands.mat')\n", - "bslda = theory['evb']\n", - "kxxth, kyyth = theory['kxxsc'], theory['kyysc']\n", - "kxth, kyth = kxxth[:,0], kyyth[0,:]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate the path for the auxiliary lines on figure\n", - "verts = np.array([[ 80.2399401 , 208.0445881 ],\n", - " [175.36646777, 208.04459675],\n", - " [221.9318386 , 126.24592903],\n", - " [175.36871023, 44.44731539],\n", - " [ 80.23765786, 44.44726939],\n", - " [ 33.69597945, 126.24588838]])\n", - "pks = np.vstack((verts, verts[0,:]))\n", - "kxip = interpolate.interp1d(np.arange(0, 256), kx)\n", - "kyip = interpolate.interp1d(np.arange(0, 256), ky)\n", - "kpks = np.asarray([[kxip(i)-0.04, kyip(j)] for (i, j) in pks])\n", - "msk = aly.circmask(recbands[0,...], 128, 125, 105, sign='xnan', method='algebraic')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Main Figure 2d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ksc = 1.1 # Hyperparameter used in reconstruction to align the theory and data to same resolution\n", - "kxshift = 0.05 # Corrections for imperfect axis calibration\n", - "f, axs = plt.subplots(7, 2, figsize=(8.3, 30))\n", - "for i, ind in enumerate(range(0, 7)):\n", - " \n", - " intFunc = interpolate.RegularGridInterpolator((kx/ksc, ky/ksc), bslda[2*ind,33:-30, 41:-42],\n", - " bounds_error=False, fill_value=None)\n", - " kxx, kyy = np.meshgrid(kx, ky, indexing='ij')\n", - " kxx = np.reshape(kxx, (nkx * nky,))\n", - " kyy = np.reshape(kyy, (nkx * nky,))\n", - " Ek_scaled = np.reshape(intFunc(np.column_stack((kxx, kyy))), (nkx, nky))\n", - " \n", - " axs[i,0].imshow(Ek_scaled.T*msk, cmap=custom_cmap,\n", - " extent=[kx[0]+kxshift, kx[-1]+kxshift, ky[0], ky[-1]])\n", - " axs[i,0].spines['right'].set_color('none')\n", - " axs[i,0].spines['top'].set_color('none')\n", - " axs[i,0].tick_params(axis='both', length=8, width=2, labelsize=28)\n", - " axs[i,0].set_xlabel('$k_x \\, (\\mathrm{\\AA}^{-1})$', fontsize=20) #, transform=axs[i,0].transAxes\n", - " axs[i,0].xaxis.set_label_coords(0.88, 0.15)\n", - " axs[i,0].set_ylabel('$k_y \\, (\\mathrm{\\AA}^{-1})$', fontsize=20, rotation=0)\n", - " axs[i,0].yaxis.set_label_coords(0.20, 0.90)\n", - " if i < 6:\n", - " axs[i,0].set_xticklabels('')\n", - " axs[i,0].text(0.85, 0.93, '# '+str(ind+1), transform=axs[i,0].transAxes, fontsize=20)\n", - " axs[i,0].axvline(x=0, ls='--', lw=1, color='k', dashes=[5, 4])\n", - " axs[i,0].axhline(y=0, ls='--', lw=1, color='k', dashes=[5, 4])\n", - " \n", - " # Draw hexagon\n", - " axs[i,0].plot(kpks[:,1]-0.02, kpks[:,0], '--k', lw=1, dashes=[5, 4])\n", - " \n", - " # Draw the reconstruction side\n", - " axs[i,1].imshow(recbands[ind,...]*msk, cmap=custom_cmap, extent=[kx[0]+kxshift, kx[-1]+kxshift, ky[0], ky[-1]])\n", - " axs[i,1].spines['right'].set_color('none')\n", - " axs[i,1].spines['top'].set_color('none')\n", - " axs[i,1].tick_params(axis='both', length=8, width=2, labelsize=28)\n", - " axs[i,1].set_xlabel('$k_x \\, (\\mathrm{\\AA}^{-1})$', fontsize=20)\n", - " axs[i,1].xaxis.set_label_coords(0.88, 0.15)\n", - " axs[i,1].set_ylabel('$k_y \\, (\\mathrm{\\AA}^{-1})$', fontsize=20, rotation=0)\n", - " axs[i,1].yaxis.set_label_coords(0.20, 0.90)\n", - " if i < 6:\n", - " axs[i,1].set_xticklabels('')\n", - " axs[i,1].set_yticklabels('')\n", - " axs[i,1].text(0.85, 0.93, '# '+str(ind+1), transform=axs[i,1].transAxes, fontsize=20)\n", - " axs[i,1].axvline(x=0, ls='--', lw=1, color='k', dashes=[5, 4])\n", - " axs[i,1].axhline(y=0, ls='--', lw=1, color='k', dashes=[5, 4])\n", - " \n", - " # Draw hexagon\n", - " axs[i,1].plot(kpks[:,1]-0.01, kpks[:,0], '--k', lw=1, dashes=[5, 4])\n", - " \n", - " \n", - "axs[0,0]. set_title('Theory', fontsize=20, y=1.05)\n", - "axs[0,1]. set_title('Reconstruction', fontsize=20, y=1.05)\n", - "plt.subplots_adjust(wspace=0.08, hspace=0.08)\n", - "plt.savefig('../results/figures/fig_2d1.png', bbox_inches='tight', transparent=False, dpi=300)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "ksc = 1.1 # Hyperparameter used in reconstruction to align the theory and data to same resolution\n", - "f, axs = plt.subplots(7, 2, figsize=(8.3, 30))\n", - "for i, ind in enumerate(range(7, 14)):\n", - " \n", - " intFunc = interpolate.RegularGridInterpolator((kx/ksc, ky/ksc), bslda[2*ind,33:-30, 41:-42],\n", - " bounds_error=False, fill_value=None)\n", - " kxx, kyy = np.meshgrid(kx, ky, indexing='ij')\n", - " kxx = np.reshape(kxx, (nkx * nky,))\n", - " kyy = np.reshape(kyy, (nkx * nky,))\n", - " Ek_scaled = np.reshape(intFunc(np.column_stack((kxx, kyy))), (nkx, nky))\n", - " \n", - " axs[i,0].imshow(Ek_scaled.T*msk, cmap=custom_cmap,\n", - " extent=[kx[0]+0.05, kx[-1]+0.05, ky[0], ky[-1]])\n", - " axs[i,0].spines['right'].set_color('none')\n", - " axs[i,0].spines['top'].set_color('none')\n", - " axs[i,0].tick_params(axis='both', length=8, width=2, labelsize=28)\n", - " axs[i,0].set_xlabel('$k_x \\, (\\mathrm{\\AA}^{-1})$', fontsize=20) #, transform=axs[i,0].transAxes\n", - " axs[i,0].xaxis.set_label_coords(0.88, 0.15)\n", - " axs[i,0].set_ylabel('$k_y \\, (\\mathrm{\\AA}^{-1})$', fontsize=20, rotation=0)\n", - " axs[i,0].yaxis.set_label_coords(0.20, 0.90)\n", - " if i < 6:\n", - " axs[i,0].set_xticklabels('')\n", - " axs[i,0].text(0.85, 0.93, '# '+str(ind+1), transform=axs[i,0].transAxes, fontsize=20)\n", - " axs[i,0].axvline(x=0, ls='--', lw=1, color='k', dashes=[5, 4])\n", - " axs[i,0].axhline(y=0, ls='--', lw=1, color='k', dashes=[5, 4])\n", - " \n", - " # Draw hexagon\n", - " axs[i,0].plot(kpks[:,1]-0.02, kpks[:,0], '--k', lw=1, dashes=[5, 4])\n", - " \n", - " # Draw the reconstruction side\n", - " axs[i,1].imshow(recbands[ind,...]*msk, cmap=custom_cmap, extent=[kx[0]+kxshift, kx[-1]+kxshift, ky[0], ky[-1]])\n", - " axs[i,1].spines['right'].set_color('none')\n", - " axs[i,1].spines['top'].set_color('none')\n", - " axs[i,1].tick_params(axis='both', length=8, width=2, labelsize=28)\n", - " axs[i,1].set_xlabel('$k_x \\, (\\mathrm{\\AA}^{-1})$', fontsize=20)\n", - " axs[i,1].xaxis.set_label_coords(0.88, 0.15)\n", - " axs[i,1].set_ylabel('$k_y \\, (\\mathrm{\\AA}^{-1})$', fontsize=20, rotation=0)\n", - " axs[i,1].yaxis.set_label_coords(0.20, 0.90)\n", - " if i < 6:\n", - " axs[i,1].set_xticklabels('')\n", - " axs[i,1].set_yticklabels('')\n", - " axs[i,1].text(0.85, 0.93, '# '+str(ind+1), transform=axs[i,1].transAxes, fontsize=20)\n", - " axs[i,1].axvline(x=0, ls='--', lw=1, color='k', dashes=[5, 4])\n", - " axs[i,1].axhline(y=0, ls='--', lw=1, color='k', dashes=[5, 4])\n", - " \n", - " # Draw hexagon\n", - " axs[i,1].plot(kpks[:,1]-0.01, kpks[:,0], '--k', lw=1, dashes=[5, 4])\n", - " \n", - " \n", - "axs[0,0]. set_title('Theory', fontsize=20, y=1.05)\n", - "axs[0,1]. set_title('Reconstruction', fontsize=20, y=1.05)\n", - "plt.subplots_adjust(wspace=0.08, hspace=0.08)\n", - "plt.savefig('../results/figures/fig_2d2.png', bbox_inches='tight', transparent=False, dpi=300)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/Fig3_Approximations_to_reconstruction-checkpoint.ipynb b/figures/.ipynb_checkpoints/Fig3_Approximations_to_reconstruction-checkpoint.ipynb deleted file mode 100644 index 217e3c8..0000000 --- a/figures/.ipynb_checkpoints/Fig3_Approximations_to_reconstruction-checkpoint.ipynb +++ /dev/null @@ -1,162 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Illustration of approximations to a reconstructed band" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import os\n", - "import numpy as np\n", - "import fuller\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib as mpl\n", - "from tqdm import tqdm_notebook as tqdm\n", - "from matplotlib.ticker import AutoMinorLocator\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams['font.family'] = 'sans-serif'\n", - "mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "bandcuts = np.load(r'../data/processed/wse2_recon_1BZ/postproc_bandcuts_lda.npz')['bandcuts']\n", - "plt.imshow(bandcuts[3,...])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Approximations using different numbers of basis terms and in different orders\n", - "idx = 3\n", - "recon = np.zeros_like(bandcuts[0,...])\n", - "indarr = list(range(5, 400, 1))\n", - "# errors for summation in default polynomial order (errseq) and in coefficient-ranked order (errmaj)\n", - "errseq, errmaj = [], []\n", - "# The pixel-averaged versions of errseq and errmaj\n", - "errseqavg, errmajavg = [], []\n", - "reconms = []\n", - "bandref = np.nan_to_num(bandcuts[idx,...])\n", - "bcf, bss0 = fuller.generator.decomposition_hex2d(bandref, nterms=400, ret='all')\n", - "npixbz = np.sum(bss0[0,...] == 1) # Number of pixels within the first Brillouin zone\n", - "magind = np.argsort(np.abs(bcf))[::-1]\n", - "\n", - "for nt in tqdm(indarr):\n", - " # Generate mask\n", - " currcf = np.zeros_like(bcf)\n", - " currcfm = np.zeros_like(bcf)\n", - " currcf[:nt] = bcf[:nt]\n", - " currcfm[magind[:nt]] = bcf[magind[:nt]]\n", - " recon = fuller.generator.reconstruction_hex2d(currcf, bss0)\n", - " reconm = fuller.generator.reconstruction_hex2d(currcfm, bss0)\n", - "\n", - " reconms.append(reconm)\n", - " errseq.append(np.linalg.norm(recon - bandref)/np.linalg.norm(bandref))\n", - " errmaj.append(np.linalg.norm(reconm - bandref)/np.linalg.norm(bandref))\n", - " errseqavg.append(np.linalg.norm(recon - bandref)/np.sqrt(npixbz))\n", - " errmajavg.append(np.linalg.norm(reconm - bandref)/np.sqrt(npixbz))\n", - "\n", - "errseq, errmaj, errseqavg, errmajavg = list(map(np.asarray, [errseq, errmaj, errseqavg, errmajavg]))\n", - "reconms = np.asarray(reconms)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Main Figure 3b" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f, ax = plt.subplots(figsize=(5, 3.5))\n", - "\n", - "ax.plot(indarr, errmajavg*1000, '-', lw=2, c='#0000FF')\n", - "ax.plot(indarr, errseqavg*1000, '-', lw=2, c='#CC6600')\n", - "\n", - "ax.set_xlabel('Number of terms', fontsize=18)\n", - "ax.set_ylabel('Avg. approx. error (meV)', fontsize=18)\n", - "ax.set_xticks(range(0, 181, 20))\n", - "ax.set_ylim([0, 200])\n", - "ax.set_xlim([0, 100])\n", - "\n", - "ax.tick_params(which='major', axis='both', length=8, width=2, labelsize=18)\n", - "ax.tick_params(which='minor', axis='both', length=8, width=1, labelsize=18)\n", - "\n", - "ax.axvline(x=5, ls='--', c='k', dashes=(5, 3))\n", - "ax.axvline(x=15, ls='--', c='k', dashes=(5, 3))\n", - "ax.axvline(x=45, ls='--', c='k', dashes=(5, 3))\n", - "\n", - "ax.xaxis.set_minor_locator(AutoMinorLocator(4))\n", - "ax.yaxis.set_minor_locator(AutoMinorLocator(5))\n", - "ax.set_title('Polynomial\\n approximation\\n to band #4', fontsize=18, x=0.7, y=0.68, transform=ax.transAxes)\n", - "\n", - "ax2 = ax.twinx()\n", - "ax2.set_yticks(np.arange(0, 0.11, 0.02))\n", - "ax2.set_ylim([0, 200*errmaj[0]/(errmajavg[0]*1000)])\n", - "ax2.set_ylabel('Rel. approx. error', fontsize=18, rotation=-90, labelpad=25)\n", - "ax2.tick_params(which='major', axis='both', length=8, width=2, labelsize=18)\n", - "ax2.tick_params(which='minor', axis='both', length=8, width=1, labelsize=18)\n", - "ax2.yaxis.set_minor_locator(AutoMinorLocator(2))\n", - "plt.savefig('../results/figures/fig_3b.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/Fig3_HexagonalZernike-checkpoint.ipynb b/figures/.ipynb_checkpoints/Fig3_HexagonalZernike-checkpoint.ipynb deleted file mode 100644 index d66b970..0000000 --- a/figures/.ipynb_checkpoints/Fig3_HexagonalZernike-checkpoint.ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Digitization of reconstructed bands using hexagonal Zernike polynomials" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import os\n", - "import numpy as np\n", - "import fuller\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib as mpl\n", - "from mpl_toolkits.axes_grid1 import make_axes_locatable\n", - "from matplotlib.ticker import (MultipleLocator, FormatStrFormatter,\n", - " AutoMinorLocator)\n", - "import matplotlib.colors as cs\n", - "import itertools as it\n", - "from tqdm import tqdm_notebook as tqdm\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams['font.family'] = 'sans-serif'\n", - "mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42\n", - "\n", - "colornames = ['#646464', '#666666', '#6a6a6a', '#6f6f6f', '#737373', '#787878', '#7d7d7d', '#828282', '#878787', '#8d8d8d', '#929292', '#989898', '#9e9e9e', '#a4a4a4', '#aaaaaa', '#b0b0b0', '#b6b6b6', '#bcbcbc', '#c2c2c2', '#c9c9c9', '#cfcfcf', '#d6d6d6', '#dcdcdc', '#e3e3e3', '#eaeaea', '#efefee', '#efeee5', '#efeddc', '#efecd3', '#eeebca', '#eeeac0', '#eee9b7', '#eee8ad', '#ede7a4', '#ede69a', '#ede590', '#ede487', '#ece37d', '#ece273', '#ece069', '#ecdf5f', '#ebde55', '#ebdd4b', '#ebdc41', '#ebdb37', '#ebd333', '#ebc933', '#ecbe32', '#ecb432', '#eda931', '#ee9e31', '#ee9330', '#ef8830', '#ef7d2f', '#f0722f', '#f0672e', '#f15c2e', '#f2512d', '#f2462d', '#f33b2c', '#f3302c', '#f4252b', '#f4192b', '#ef182f', '#e81834', '#e21939', '#db1a3e', '#d51a43', '#ce1b48', '#c71b4d', '#c11c52', '#ba1c58', '#b31d5d', '#ac1d62', '#a61e67', '#9f1e6c', '#981f72', '#911f77', '#8a207c', '#842182']\n", - "custom_cmap = mpl.colors.LinearSegmentedColormap.from_list('custom', colornames, N=256)\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Main Figure 3a" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate hexagonal Zernike basis\n", - "basis = fuller.generator.ppz.hexike_basis(nterms=100, npix=257, vertical=True, outside=0)\n", - "\n", - "# Mask the region beyond the hexagonal boundary\n", - "bmask = fuller.generator.hexmask(hexdiag=257, imside=257, padded=False, margins=[1, 1, 1, 1])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plotting a selection of hexagonal Zernike polynomials\n", - "ff, axs = plt.subplots(5, 1, figsize=(3, 10))\n", - "\n", - "for ind, ibs in enumerate([3, 10, 27, 41, 89]):\n", - " im = axs[ind].imshow(basis[ibs,...]*bmask[...], cmap=custom_cmap, vmin=-1.8, vmax=1.8)\n", - " axs[ind].axis('off')\n", - " axs[ind].text(5, 5, str(ind+1), fontsize=15, fontname=\"Arial\")\n", - "\n", - "cax = ff.add_axes([0.36, 0.08, 0.3, 0.02])\n", - "cb = plt.colorbar(im, cax=cax, ticks=[-1.8, 1.8], orientation='horizontal')\n", - "cb.ax.tick_params(axis='both', length=0)\n", - "cb.ax.set_xticklabels(['low', 'high'], fontsize=15) #'{0}'.format(u'\\u2014')\n", - "# cb.ax.set_ylabel('Height', rotation=-90, fontsize=15)\n", - "plt.subplots_adjust(hspace=0.1)\n", - "plt.savefig('../results/figures/fig_3a1.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate the decomposition coefficients for all bands\n", - "bandout = np.nan_to_num(np.load(r'../data/processed/wse2_recon_1BZ/postproc_bandcuts_lda.npz')['bandcuts'])\n", - "bases_recon = fuller.generator.ppz.hexike_basis(nterms=400, npix=175, vertical=True, outside=0)\n", - "cfs_rec_lda = []\n", - "for i in tqdm(range(14)):\n", - " cfs_rec_lda.append(fuller.generator.decomposition_hex2d(bandout[i,...], bases=bases_recon, baxis=0, ret='coeffs'))\n", - "cfs_rec_lda = np.array(cfs_rec_lda)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Collect the large coefficients needed for approximating each energy band\n", - "cfs_large = fuller.utils.binarize(cfs_rec_lda, threshold=1e-2, vals=[0, 1])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cl = plt.cm.tab20(np.linspace(0,1,14))\n", - "f, ax = plt.subplots(figsize=(6, 10))\n", - "xs = np.arange(1, 400)\n", - "for i in range(14):\n", - " ax.plot(xs, cfs_rec_lda[i,1:]-i/3, lw=1, color=cl[i])\n", - " ax.axhline(y=-i/3, lw=1, color=cl[i])\n", - " ax.text(320, -i/3+0.08, 'Band #'+str(i+1), fontsize=15, fontname=\"Arial\")\n", - "\n", - "ax.bar(xs, (np.abs(cfs_large[:,1:])).sum(axis=0)/40, bottom=-4.9, width=1, color=(0.3, 0.3, 0.3))\n", - "ax.axhline(y=-4.9, lw=1, color=(0.3, 0.3, 0.3))\n", - "# ax.set_title('HSE06', fontsize=15, y=0.88)\n", - "ax.text(320, -4.9+0.08, 'All bands', fontsize=15, fontname=\"Arial\")\n", - "# ax.text('Counts', transform=ax.transAxes)\n", - "\n", - "ax.set_xticks(list(range(0, 401, 50)))\n", - "ax.set_yticks([])\n", - "ax.set_ylim([-5, 1])\n", - "ax.tick_params(axis='x', length=8, width=2, labelsize=15)\n", - "ax.set_ylabel('Amplitude (a. u.)', fontsize=15)\n", - "ax.set_xlim([0, 400])\n", - "ax.set_xlabel('Coefficient index', fontsize=15)\n", - "ax.spines['left'].set_visible(False)\n", - "ax.spines['right'].set_visible(False)\n", - "ax.spines['top'].set_visible(False)\n", - "ax.text(-22, -4.5, 'Counts', rotation=90, fontsize=15);\n", - "plt.savefig('../results/figures/fig_3a2.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Main Figure 3c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate the pairwise correlation matrix\n", - "ncfs = 14\n", - "dcm = np.zeros((ncfs, ncfs))\n", - "ids = list(it.product(range(ncfs), repeat=2))\n", - "for ipair, pair in enumerate(ids):\n", - " i, j = pair[0], pair[1]\n", - " dcm[i,j] = fuller.metrics.dcos(cfs_rec_lda[i,1:], cfs_rec_lda[j,1:])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Construct new colormap 'KRdBu' and 'KRdBu_r' (based on 'RdBu' with black blended into the very end of the red side)\n", - "cmap_rdbu = mpl.cm.get_cmap('RdBu')\n", - "cmap_gr = mpl.cm.get_cmap('Greys_r')\n", - "colors = [cmap_gr(0.1), cmap_rdbu(0.1)]\n", - "nk = 13\n", - "\n", - "KRd = cs.LinearSegmentedColormap.from_list('KRdBu', colors, N=nk)\n", - "KRdvals = KRd(np.linspace(0, 1, nk))\n", - "RdBuvals = cmap_rdbu(np.linspace(0.1, 1, 256-nk))\n", - "KRdBu_vals = np.concatenate((KRdvals, RdBuvals))\n", - "KRdBu_r_vals = np.flipud(KRdBu_vals)\n", - "KRdBu = cs.ListedColormap(KRdBu_vals)\n", - "KRdBu_r = cs.ListedColormap(KRdBu_r_vals)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot the pairwise correlation matrix for reconstructed bands\n", - "f, ax = plt.subplots(figsize=(6, 6))\n", - "im = ax.matshow(dcm, cmap=KRdBu_r, extent=[0, 14, 14, 0], origin='upper', vmin=-1, vmax=1)\n", - "tks = list(np.arange(0.5, 14, 1))\n", - "ax.set_xticks(tks)\n", - "ax.set_yticks(tks)\n", - "ax.set_xticklabels(['#' + str(int(i+0.5)) for i in tks], fontsize=15, rotation=90)\n", - "ax.set_yticklabels(['#' + str(int(i+0.5)) for i in tks], fontsize=15, rotation=0)\n", - "ax.tick_params(axis='both', size=8, width=2, labelsize=15)\n", - "ax.tick_params(axis='x', bottom=False)\n", - "ax.tick_params(axis='x', pad=8)\n", - "# ax.set_title('HSE06', fontsize=15, x=0.5, y=1.15)\n", - "divider = make_axes_locatable(ax)\n", - "cax = divider.append_axes(\"right\", size=\"5%\", pad=0.2)\n", - "cax.tick_params(axis='y', size=8)\n", - "cb = plt.colorbar(im, cax=cax, ticks=np.arange(-1, 1.01, 0.2))\n", - "cb.ax.set_ylabel('Cosine similarity', fontsize=15, rotation=-90, labelpad=20)\n", - "cb.ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "# plt.colorbar(im, cax=cax, ticks=[])\n", - "ax.text(-0.18, 1.08, ' Band\\n index', rotation=-45, transform=ax.transAxes, fontsize=15)\n", - "plt.savefig('../results/figures/fig_3c.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/Fig3_SFig13_Similarity_matrix_and_basis_decomposition-checkpoint.ipynb b/figures/.ipynb_checkpoints/Fig3_SFig13_Similarity_matrix_and_basis_decomposition-checkpoint.ipynb deleted file mode 100644 index 2301ed7..0000000 --- a/figures/.ipynb_checkpoints/Fig3_SFig13_Similarity_matrix_and_basis_decomposition-checkpoint.ipynb +++ /dev/null @@ -1,417 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Construct similarity matrix between theoretical and reconstructed band structures" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import numpy as np\n", - "import fuller\n", - "from mpes import analysis as aly\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib.colors as cs\n", - "from mpl_toolkits.axes_grid1 import make_axes_locatable\n", - "import itertools as it\n", - "import scipy.spatial.distance as ssd\n", - "from numpy.linalg import norm\n", - "from tqdm import tqdm_notebook as tqdm\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Create plot folder if needed\n", - "import os\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams['font.family'] = 'sans-serif'\n", - "mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "bases = fuller.generator.ppz.hexike_basis(nterms=400, npix=207, vertical=True, outside=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "bandout = np.nan_to_num(fuller.utils.loadHDF(r'../data/theory/bands_1BZ/wse2_pbesol_bandcuts.h5')['bands'])\n", - "cfs_pbesol = []\n", - "for i in tqdm(range(14)):\n", - " cfs_pbesol.append(fuller.generator.decomposition_hex2d(bandout[i,...], bases=bases, baxis=0, ret='coeffs'))\n", - "cfs_pbesol = np.array(cfs_pbesol)\n", - "\n", - "bandout = np.nan_to_num(fuller.utils.loadHDF(r'../data/theory/bands_1BZ/wse2_pbe_bandcuts.h5')['bands'])\n", - "cfs_pbe = []\n", - "for i in tqdm(range(14)):\n", - " cfs_pbe.append(fuller.generator.decomposition_hex2d(bandout[i,...], bases=bases, baxis=0, ret='coeffs'))\n", - "cfs_pbe = np.array(cfs_pbe)\n", - "\n", - "bandout = np.nan_to_num(fuller.utils.loadHDF(r'../data/theory/bands_1BZ/wse2_hse_bandcuts.h5')['bands'])\n", - "cfs_hse = []\n", - "for i in tqdm(range(14)):\n", - " cfs_hse.append(fuller.generator.decomposition_hex2d(bandout[i,...], bases=bases, baxis=0, ret='coeffs'))\n", - "cfs_hse = np.array(cfs_hse)\n", - "\n", - "bandout = np.nan_to_num(fuller.utils.loadHDF(r'../data/theory/bands_1BZ/wse2_lda_bandcuts.h5')['bands'])\n", - "cfs_lda = []\n", - "for i in tqdm(range(14)):\n", - " cfs_lda.append(fuller.generator.decomposition_hex2d(bandout[i,...], bases=bases, baxis=0, ret='coeffs'))\n", - "cfs_lda = np.array(cfs_lda)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "bases_recon = fuller.generator.ppz.hexike_basis(nterms=400, npix=175, vertical=True, outside=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "bandout = np.nan_to_num(np.load(r'../data/processed/wse2_recon_1BZ/postproc_bandcuts_pbe.npz')['bandcuts'])\n", - "cfs_rec_pbe_sym = []\n", - "for i in tqdm(range(14)):\n", - " cfs_rec_pbe_sym.append(fuller.generator.decomposition_hex2d(bandout[i,...], bases=bases_recon, baxis=0, ret='coeffs'))\n", - "cfs_rec_pbe_sym = np.array(cfs_rec_pbe_sym)\n", - "\n", - "bandout = np.nan_to_num(np.load(r'../data/processed/wse2_recon_1BZ/postproc_bandcuts_pbesol.npz')['bandcuts'])\n", - "cfs_rec_pbesol_sym = []\n", - "for i in tqdm(range(14)):\n", - " cfs_rec_pbesol_sym.append(fuller.generator.decomposition_hex2d(bandout[i,...], bases=bases_recon, baxis=0, ret='coeffs'))\n", - "cfs_rec_pbesol_sym = np.array(cfs_rec_pbesol_sym)\n", - "\n", - "bandout = np.nan_to_num(np.load(r'../data/processed/wse2_recon_1BZ/postproc_bandcuts_lda.npz')['bandcuts'])\n", - "cfs_rec_lda_sym = []\n", - "for i in tqdm(range(14)):\n", - " cfs_rec_lda_sym.append(fuller.generator.decomposition_hex2d(bandout[i,...], bases=bases_recon, baxis=0, ret='coeffs'))\n", - "cfs_rec_lda_sym = np.array(cfs_rec_lda_sym)\n", - "\n", - "bandout = np.nan_to_num(np.load(r'../data/processed/wse2_recon_1BZ/postproc_bandcuts_hse.npz')['bandcuts'])\n", - "cfs_rec_hse_sym = []\n", - "for i in tqdm(range(14)):\n", - " cfs_rec_hse_sym.append(fuller.generator.decomposition_hex2d(bandout[i,...], bases=bases_recon, baxis=0, ret='coeffs'))\n", - "cfs_rec_hse_sym = np.array(cfs_rec_hse_sym)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Main Figure 3d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def demean(bscoefs):\n", - " c = np.mean(bscoefs[:,0])\n", - " bscoefsdm = bscoefs.copy()\n", - " bscoefsdm[:, 0] -= c\n", - " return bscoefsdm" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate distance metrics with zeroed DFT band structure\n", - "# Per-band Euclidean distance between band structures\n", - "cfs = [cfs_lda, cfs_pbe, cfs_pbesol, cfs_hse, cfs_rec_lda_sym, cfs_rec_pbe_sym, cfs_rec_pbesol_sym, cfs_rec_hse_sym]\n", - "ncfs = len(cfs)\n", - "dcdcent = np.zeros((ncfs, ncfs))\n", - "ids = list(it.product(range(ncfs), repeat=2))\n", - "for ipair, pair in enumerate(ids):\n", - " i, j = pair[0], pair[1]\n", - " icfsdc, jcfsdc = demean(cfs[i]), demean(cfs[j])\n", - " dnorm = 0\n", - " for ii in range(14):\n", - " dnorm += norm(icfsdc[ii,:] - jcfsdc[ii,:])\n", - " dcdcent[i,j] = dnorm / 14\n", - "\n", - "dcmstdsym = np.zeros((ncfs, ncfs))\n", - "ids = list(it.product(range(ncfs), repeat=2))\n", - "for ipair, pair in enumerate(ids):\n", - " i, j = pair[0], pair[1]\n", - " iest, jest = cfs[i].copy(), cfs[j].copy()\n", - " icfsdc, jcfsdc = demean(iest), demean(jest)\n", - " dnorms = []\n", - " for ii in range(14):\n", - " dnorms.append(norm(icfsdc[ii,:] - jcfsdc[ii,:]))\n", - " dcmstdsym[i,j] = np.std(dnorms)/np.sqrt(14)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "nr, nc = dcdcent.shape\n", - "dcm = dcdcent.copy()\n", - "dcmstd = dcmstdsym.copy()\n", - "\n", - "# Combine two triangular matrix plots\n", - "matnan = np.ones((8, 8))*np.nan\n", - "ut = np.triu(dcm, k=0) + np.tril(matnan, k=-1)\n", - "lt = np.tril(dcmstd, k=-1) + np.triu(matnan, k=0)\n", - "f, ax = plt.subplots(figsize=(6, 6))\n", - "fup = ax.matshow(ut*1000, cmap='viridis', vmin=0, vmax=250)\n", - "flo = ax.matshow(lt*1000, cmap='viridis', vmin=0)\n", - "\n", - "divider = make_axes_locatable(ax)\n", - "caxu = divider.append_axes(\"right\", size=\"5%\", pad=0.2)\n", - "caxu.tick_params(axis='y', size=8, length=8, width=2, labelsize=15)\n", - "caxl = divider.append_axes(\"bottom\", size=\"5%\", pad=0.2)\n", - "caxl.tick_params(axis='x', size=8, length=8, width=2, labelsize=15)\n", - "cbup = f.colorbar(fup, orientation='vertical', cax=caxu, ticks=np.arange(0, 351, 50))\n", - "cblo = f.colorbar(flo, orientation='horizontal', cax=caxl, ticks=np.arange(0, 31, 5))\n", - "cbup.ax.set_yticklabels(np.arange(0, 351, 50))\n", - "cbup.ax.set_ylabel('Band structure distance (meV/band)', fontsize=15, rotation=-90, labelpad=20)\n", - "# cbup.ax.set_ylim([0, 250])\n", - "cblo.ax.set_xlabel('Standard error (meV/band)', fontsize=15, rotation=0, labelpad=5)\n", - "\n", - "meths = ['LDA', 'PBE', 'PBEsol', 'HSE06', 'LDA \\nrecon.', 'PBE \\nrecon.', 'PBEsol \\nrecon.', 'HSE06 \\nrecon.']\n", - "ax.set_xticklabels([''] + meths, fontsize=15, rotation=90)\n", - "ax.set_yticklabels([''] + meths, fontsize=15, rotation=0)\n", - "ax.tick_params(axis='both', size=8, width=2)\n", - "ax.tick_params(axis='x', bottom=False, pad=8)\n", - "ax.tick_params(axis='y', pad=4)\n", - "\n", - "dcm_merged = np.zeros_like(dcm) + np.triu(dcm, k=1) + np.tril(dcmstd, k=-1)\n", - "dcm_merged = np.rint(dcm_merged*1000).astype('int')\n", - "for i in range(nr):\n", - " for j in range(nc):\n", - " if i == j:\n", - " ax.text(j, i, 0, ha='center', va='center', color='w', fontsize=15, fontweight='bold')\n", - " else:\n", - " ax.text(j, i, dcm_merged[i, j], ha='center', va='center', color='#FF4500', fontsize=15, fontweight='bold')\n", - " \n", - "plt.savefig('../results/figures/fig_3d.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 13e-h" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Construct new colormap 'KRdBu' and 'KRdBu_r' (based on 'RdBu' with black blended into the very end of the red side)\n", - "cmap_rdbu = mpl.cm.get_cmap('RdBu')\n", - "cmap_gr = mpl.cm.get_cmap('Greys_r')\n", - "colors = [cmap_gr(0.1), cmap_rdbu(0.1)]\n", - "nk = 13\n", - "\n", - "KRd = cs.LinearSegmentedColormap.from_list('KRdBu', colors, N=nk)\n", - "KRdvals = KRd(np.linspace(0, 1, nk))\n", - "RdBuvals = cmap_rdbu(np.linspace(0.1, 1, 256-nk))\n", - "KRdBu_vals = np.concatenate((KRdvals, RdBuvals))\n", - "KRdBu_r_vals = np.flipud(KRdBu_vals)\n", - "KRdBu = cs.ListedColormap(KRdBu_vals)\n", - "KRdBu_r = cs.ListedColormap(KRdBu_r_vals)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def similarity_matrix_plot(cmat, title=''):\n", - " \"\"\" Plot similarity matrix in the manuscript.\n", - " \"\"\"\n", - " \n", - " f, ax = plt.subplots(figsize=(6, 6))\n", - " im = ax.matshow(cmat, cmap=KRdBu_r, extent=[0, 14, 14, 0], origin='upper', vmin=-1, vmax=1)\n", - " tks = list(np.arange(0.5, 14, 1))\n", - " ax.set_xticks(tks)\n", - " ax.set_yticks(tks)\n", - " ax.set_xticklabels(['#' + str(int(i+0.5)) for i in tks], fontsize=15, rotation=90)\n", - " ax.set_yticklabels(['#' + str(int(i+0.5)) for i in tks], fontsize=15, rotation=0)\n", - " ax.tick_params(axis='both', size=8, width=2, labelsize=15)\n", - " ax.tick_params(axis='x', bottom=False)\n", - " ax.tick_params(axis='x', pad=8)\n", - " ax.set_title(title, fontsize=15, y=1.15)\n", - " # ax.set_title('HSE06', fontsize=15, x=0.5, y=1.15)\n", - " divider = make_axes_locatable(ax)\n", - " cax = divider.append_axes(\"right\", size=\"5%\", pad=0.2)\n", - " cax.tick_params(axis='y', size=8)\n", - " cb = plt.colorbar(im, cax=cax, ticks=np.arange(-1, 1.01, 0.2))\n", - " cb.ax.set_ylabel('Cosine similarity', fontsize=15, rotation=-90, labelpad=20)\n", - " cb.ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - " # plt.colorbar(im, cax=cax, ticks=[])\n", - " ax.text(-0.18, 1.08, ' Band\\n index', rotation=-45, transform=ax.transAxes, fontsize=15)\n", - " \n", - " return ax" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "# Plot the cosince similarity matrices for each DFT calculation (indicated in figure title)\n", - "dcm_lda = fuller.metrics.similarity_matrix(cfs_lda, fmetric=fuller.metrics.dcos)\n", - "similarity_matrix_plot(dcm_lda, title='LDA')\n", - "plt.savefig('../results/figures/sfig_13e.png', bbox_inches='tight', transparent=True, dpi=300)\n", - "\n", - "dcm_pbe = fuller.metrics.similarity_matrix(cfs_pbe, fmetric=fuller.metrics.dcos)\n", - "similarity_matrix_plot(dcm_pbe, title='PBE')\n", - "plt.savefig('../results/figures/sfig_13f.png', bbox_inches='tight', transparent=True, dpi=300)\n", - "\n", - "dcm_pbesol = fuller.metrics.similarity_matrix(cfs_pbesol, fmetric=fuller.metrics.dcos)\n", - "similarity_matrix_plot(dcm_pbesol, title='PBEsol')\n", - "plt.savefig('../results/figures/sfig_13g.png', bbox_inches='tight', transparent=True, dpi=300)\n", - "\n", - "dcm_hse = fuller.metrics.similarity_matrix(cfs_hse, fmetric=fuller.metrics.dcos)\n", - "similarity_matrix_plot(dcm_hse, title='HSE06');\n", - "plt.savefig('../results/figures/sfig_13h.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 13a-d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def decomposition_plot(coefs, coef_count, title):\n", - " \n", - " cl = plt.cm.tab20(np.linspace(0,1,14))\n", - " f, ax = plt.subplots(figsize=(6, 10))\n", - " xs = np.arange(1, 400)\n", - " for i in range(14):\n", - " ax.plot(xs, coefs[i,1:]-i/3, lw=1, color=cl[i])\n", - " ax.axhline(y=-i/3, lw=1, color=cl[i])\n", - " ax.text(320, -i/3+0.08, 'Band #'+str(i+1), fontsize=15, fontname=\"Arial\")\n", - " ax.bar(xs, coef_count, bottom=-4.9, width=1, color=(0.3, 0.3, 0.3))\n", - " ax.axhline(y=-4.9, lw=1, color=(0.3, 0.3, 0.3))\n", - " ax.set_title(title, fontsize=15, y=0.88)\n", - " ax.text(320, -4.9+0.08, 'All bands', fontsize=15, fontname=\"Arial\")\n", - " # ax.text('Counts', transform=ax.transAxes)\n", - "\n", - " # ax.tick_params(axis='y', length=0)\n", - " ax.set_xticks(list(range(0, 401, 50)))\n", - " ax.set_yticks([])\n", - " ax.set_ylim([-5, 1])\n", - " ax.tick_params(axis='x', length=8, width=2, labelsize=15)\n", - " ax.set_ylabel('Amplitude (a. u.)', fontsize=15)\n", - " ax.set_xlim([0, 400])\n", - " ax.set_xlabel('Coefficient index', fontsize=15)\n", - " ax.spines['left'].set_visible(False)\n", - " ax.spines['right'].set_visible(False)\n", - " ax.spines['top'].set_visible(False)\n", - " \n", - " return ax" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "cfs_lda_large = fuller.utils.binarize(cfs_lda, threshold=1e-2)[:,1:].sum(axis=0)/40\n", - "decomposition_plot(cfs_lda, cfs_lda_large, title='LDA')\n", - "plt.savefig('../results/figures/sfig_13a.png', bbox_inches='tight', transparent=True, dpi=300)\n", - "\n", - "cfs_pbe_large = fuller.utils.binarize(cfs_pbe, threshold=1e-2)[:,1:].sum(axis=0)/40\n", - "decomposition_plot(cfs_pbe, cfs_pbe_large, title='PBE')\n", - "plt.savefig('../results/figures/sfig_13b.png', bbox_inches='tight', transparent=True, dpi=300)\n", - "\n", - "cfs_pbesol_large = fuller.utils.binarize(cfs_pbesol, threshold=1e-2)[:,1:].sum(axis=0)/40\n", - "decomposition_plot(cfs_pbesol, cfs_pbesol_large, title='PBEsol')\n", - "plt.savefig('../results/figures/sfig_13c.png', bbox_inches='tight', transparent=True, dpi=300)\n", - "\n", - "cfs_hse_large = fuller.utils.binarize(cfs_hse, threshold=1e-2)[:,1:].sum(axis=0)/40\n", - "decomposition_plot(cfs_hse, cfs_hse_large, title='HSE06');\n", - "plt.savefig('../results/figures/sfig_13d.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/Fig5_K_and_Mprime-checkpoint.ipynb b/figures/.ipynb_checkpoints/Fig5_K_and_Mprime-checkpoint.ipynb deleted file mode 100644 index 4cf565d..0000000 --- a/figures/.ipynb_checkpoints/Fig5_K_and_Mprime-checkpoint.ipynb +++ /dev/null @@ -1,244 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Compare reconstructed and refined band patches around high-symmetry points" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import os\n", - "import numpy as np\n", - "from mpes import analysis as aly\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "from mpl_toolkits.axes_grid1.inset_locator import inset_axes\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams['font.family'] = 'sans-serif'\n", - "mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42\n", - "\n", - "colornames = ['#646464', '#666666', '#6a6a6a', '#6f6f6f', '#737373', '#787878', '#7d7d7d', '#828282', '#878787', '#8d8d8d', '#929292', '#989898', '#9e9e9e', '#a4a4a4', '#aaaaaa', '#b0b0b0', '#b6b6b6', '#bcbcbc', '#c2c2c2', '#c9c9c9', '#cfcfcf', '#d6d6d6', '#dcdcdc', '#e3e3e3', '#eaeaea', '#efefee', '#efeee5', '#efeddc', '#efecd3', '#eeebca', '#eeeac0', '#eee9b7', '#eee8ad', '#ede7a4', '#ede69a', '#ede590', '#ede487', '#ece37d', '#ece273', '#ece069', '#ecdf5f', '#ebde55', '#ebdd4b', '#ebdc41', '#ebdb37', '#ebd333', '#ebc933', '#ecbe32', '#ecb432', '#eda931', '#ee9e31', '#ee9330', '#ef8830', '#ef7d2f', '#f0722f', '#f0672e', '#f15c2e', '#f2512d', '#f2462d', '#f33b2c', '#f3302c', '#f4252b', '#f4192b', '#ef182f', '#e81834', '#e21939', '#db1a3e', '#d51a43', '#ce1b48', '#c71b4d', '#c11c52', '#ba1c58', '#b31d5d', '#ac1d62', '#a61e67', '#9f1e6c', '#981f72', '#911f77', '#8a207c', '#842182']\n", - "custom_cmap = mpl.colors.LinearSegmentedColormap.from_list('custom', colornames, N=256)\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Region around $\\overline{\\text{M}^\\prime}$ point" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Load reconstruction outcome\n", - "recon = np.load(r'../data/processed/wse2_recon/postproc_refrotsym_bands_lda.npy')\n", - "rm, cm = 128, 203\n", - "mofs = 25\n", - "mpatch = recon[:2, rm-mofs:rm+mofs, cm-mofs:cm+mofs]\n", - "\n", - "# Load line (pointwise) fitting results using reconstruction as initialization\n", - "brec = np.load(r'../data/processed/patches/WSe2_Mpoint_recon_.npz')\n", - "bands = brec['bands']\n", - "kx = brec['kx']\n", - "ky = brec['ky']\n", - "kxx, kyy = np.meshgrid(kx+0.05, ky-0.05)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure 5c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot comparison between reconstruction and line fitting\n", - "f, ax = plt.subplots(2, 2, figsize=(7, 7))\n", - "ax[0, 0].set_title('Reconstruction', fontsize=15)\n", - "ax[0, 1].set_title('Line fitting', fontsize=15)\n", - "\n", - "ax[0, 0].set_xticks([])\n", - "ax[0, 0].tick_params(axis='both', labelsize=15, length=8, width=2)\n", - "ax[0, 0].set_ylabel('$k_y$ ($\\mathrm{\\AA}^{-1}$)', fontsize=15)\n", - "\n", - "ax[1, 0].tick_params(axis='both', labelsize=15, length=8, width=2)\n", - "ax[1, 0].set_xlabel('$k_x$ ($\\mathrm{\\AA}^{-1}$)', fontsize=15)\n", - "ax[1, 0].set_ylabel('$k_y$ ($\\mathrm{\\AA}^{-1}$)', fontsize=15)\n", - "\n", - "for i in range(1, 2):\n", - " ax[0, i].set_yticks([])\n", - " ax[0, i].set_xticks([])\n", - " ax[1, i].tick_params(axis='both', labelsize=15, length=8, width=2)\n", - " ax[1, i].set_yticks([])\n", - " ax[1, i].set_xlabel('$k_x$ ($\\mathrm{\\AA}^{-1}$)', fontsize=15)\n", - " \n", - "cs00 = ax[0, 0].contourf(kxx, kyy, mpatch[0,...], 20, cmap=custom_cmap, vmin=-1.6, vmax=-1)\n", - "ax[0, 0].contour(cs00, colors='k', linestyles='-', linewidths=0.5)\n", - "ax[0, 0].text(0.65, 0.9, 'Band #1', fontsize=15, transform=ax[0,0].transAxes)\n", - "\n", - "cs10 = ax[1, 0].contourf(kxx, kyy, mpatch[1,:,:], 20, cmap=custom_cmap, vmin=-1.95, vmax=-1.4)\n", - "ax[1, 0].contour(cs10, colors='k', linestyles='-', linewidths=0.5)\n", - "ax[1, 0].text(0.65, 0.9, 'Band #2', fontsize=15, transform=ax[1,0].transAxes)\n", - " \n", - "cs01 = ax[0, 1].contourf(kxx, kyy, bands[0,...], 20, cmap=custom_cmap, vmin=-1.6, vmax=-1)\n", - "ax[0, 1].contour(cs01, colors='k', linestyles='-', linewidths=0.5)\n", - "\n", - "cs11 = ax[1, 1].contourf(kxx, kyy, bands[1,...], 20, cmap=custom_cmap, vmin=-1.95, vmax=-1.4)\n", - "ax[1, 1].contour(cs11, colors='k', linestyles='-', linewidths=0.5)\n", - "\n", - "plt.subplots_adjust(hspace=0.08, wspace=0.08)\n", - "plt.savefig('../results/figures/fig_5c.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Region around $\\overline{\\text{K}}$ point" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Load reconstruction and line (pointwise) fitting result\n", - "rfb = np.load(r'../data/processed/patches/WSe2_Kpoint_linefit.npz')\n", - "rcfb = np.load(r'../data/processed/patches/WSe2_Kpoint_recon.npz')\n", - "fitbs = np.load(r'../data/processed/patches/WSe2_Kpoint_TWfitting.npz')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure 5e" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot comparison between reconstruction, line fitting, and model fitting\n", - "ofs = 6\n", - "kxx, kyy = np.meshgrid(rfb['kx'][ofs:-ofs]+0.05, rfb['ky'][ofs:-ofs])\n", - "\n", - "minsft = 0.26\n", - "kxext = [rfb['kx'][0], rfb['kx'][-1]]\n", - "kyext = [rfb['ky'][0], rfb['ky'][-1]]\n", - "\n", - "f, ax = plt.subplots(2, 4, figsize=(14, 7))\n", - "ax[0, 0].set_title('Reconstruction', fontsize=15)\n", - "ax[0, 1].set_title('Line fitting (LF)', fontsize=15)\n", - "ax[0, 2].set_title('TW model fitting', fontsize=15)\n", - "ax[0, 3].set_title('Difference (TW$-$LF)', fontsize=15)\n", - "\n", - "ax[0, 0].set_xticks([])\n", - "ax[0, 0].tick_params(axis='both', labelsize=15, length=8, width=2)\n", - "ax[0, 0].set_ylabel('$k_y$ ($\\mathrm{\\AA}^{-1}$)', fontsize=15)\n", - "\n", - "ax[1, 0].tick_params(axis='both', labelsize=15, length=8, width=2)\n", - "ax[1, 0].set_xlabel('$k_x$ ($\\mathrm{\\AA}^{-1}$)', fontsize=15)\n", - "ax[1, 0].set_ylabel('$k_y$ ($\\mathrm{\\AA}^{-1}$)', fontsize=15)\n", - "for i in range(1, 4):\n", - " ax[0, i].set_yticks([])\n", - " ax[0, i].set_xticks([])\n", - " ax[1, i].tick_params(axis='both', labelsize=15, length=8, width=2)\n", - " ax[1, i].set_yticks([])\n", - " ax[1, i].set_xlabel('$k_x$ ($\\mathrm{\\AA}^{-1}$)', fontsize=15)\n", - " \n", - "cs00 = ax[0, 0].contourf(kxx, kyy, rcfb['bands'][0,ofs+1:-ofs+1,ofs:-ofs], 23, cmap=custom_cmap, vmax=-0.7, vmin=-1.2+minsft)\n", - "ax[0, 0].contour(cs00, colors='k', linestyles='-', linewidths=0.5)\n", - "ax[0, 0].text(0.65, 0.9, 'Band #1', fontsize=15, transform=ax[0,0].transAxes)\n", - "\n", - "cs10 = ax[1, 0].contourf(kxx, kyy, rcfb['bands'][1,ofs+1:-ofs+1,ofs:-ofs], 23, cmap=custom_cmap, vmax=-1.15, vmin=-1.55+minsft)\n", - "ax[1, 0].contour(cs10, colors='k', linestyles='-', linewidths=0.5)\n", - "ax[1, 0].text(0.65, 0.9, 'Band #2', fontsize=15, transform=ax[1,0].transAxes)\n", - " \n", - "cs01 = ax[0, 1].contourf(kxx, kyy, rfb['bands'][0,ofs+1:-ofs+1,ofs:-ofs], 23, cmap=custom_cmap, vmax=-0.7, vmin=-1.2+minsft)\n", - "ax[0, 1].contour(cs01, colors='k', linestyles='-', linewidths=0.5)\n", - "\n", - "cs11 = ax[1, 1].contourf(kxx, kyy, rfb['bands'][1,ofs+1:-ofs+1,ofs:-ofs], 23, cmap=custom_cmap, vmax=-1.15, vmin=-1.55+minsft)\n", - "ax[1, 1].contour(cs11, colors='k', linestyles='-', linewidths=0.5)\n", - "\n", - "cs02 = ax[0, 2].contourf(kxx, kyy, fitbs['b1'], 23, cmap=custom_cmap, vmax=-0.7, vmin=-1.2+minsft)\n", - "ax[0, 2].contour(cs02, colors='k', linestyles='-', linewidths=0.5)\n", - "\n", - "cs12 = ax[1, 2].contourf(kxx, kyy, fitbs['b2'], 23, cmap=custom_cmap, vmax=-1.15, vmin=-1.55+minsft)\n", - "ax[1, 2].contour(cs12, colors='k', linestyles='-', linewidths=0.5)\n", - "\n", - "cs03 = ax[0, 3].contourf(kxx, kyy, 1e3*(fitbs['b1'] - rfb['bands'][0,ofs+1:-ofs+1,ofs:-ofs]), 23, cmap='RdBu_r', vmax=12, vmin=-12)\n", - "ax[0, 3].contour(cs03, colors='k', linestyles='-', linewidths=0.5)\n", - "\n", - "cs13 = ax[1, 3].contourf(kxx, kyy, 1e3*(fitbs['b2'] - rfb['bands'][1,ofs+1:-ofs+1,ofs:-ofs]), 23, cmap='RdBu_r', vmax=12, vmin=-12)\n", - "ct = ax[1, 3].contour(cs13, colors='k', linestyles='-', linewidths=0.5)\n", - "# cbar = f.colorbar(ct)\n", - "cax = inset_axes(ax[1,3], width=\"3%\", height=\"30%\", bbox_to_anchor=(585, -210, 350, 400))\n", - "# cb = plt.colorbar(cs13, cax=cax, ticks=np.arange(-15, 16, 5))\n", - "cb = plt.colorbar(cs13, cax=cax, ticks=np.arange(-12, 13, 4))\n", - "cb.ax.tick_params(axis='both', labelsize=15, length=8, width=2)\n", - "cb.ax.set_title('meV', fontsize=15, x=1.2)\n", - "\n", - "plt.subplots_adjust(hspace=0.08, wspace=0.08)\n", - "plt.savefig('../results/figures/fig_5e.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/SFig14_Approximation_along_high-symmetry_lines-checkpoint.ipynb b/figures/.ipynb_checkpoints/SFig14_Approximation_along_high-symmetry_lines-checkpoint.ipynb deleted file mode 100644 index 677f71c..0000000 --- a/figures/.ipynb_checkpoints/SFig14_Approximation_along_high-symmetry_lines-checkpoint.ipynb +++ /dev/null @@ -1,330 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Approximation of reconstructed bands viewed from high-symmetry lines" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import os\n", - "import numpy as np\n", - "import fuller\n", - "from mpes import analysis as aly\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib as mpl\n", - "from tqdm import tqdm_notebook as tqdm\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# mpl.rcParams['font.family'] = 'sans-serif'\n", - "# mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate hexagonal Zernike basis\n", - "bss = fuller.generator.ppz.hexike_basis(nterms=400, npix=175, vertical=True, outside=0)\n", - "\n", - "with np.load('../data/processed/LDARecon_Approx_Polynomials.npz') as fl:\n", - " bandcuts = fl['bands']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "center = np.array([88.04458508, 85.93048041])\n", - "corners = np.array([[ 43.96685519, 162.03029721],\n", - " [132.1174288 , 162.02202934],\n", - " [175.73285949, 85.93552008],\n", - " [132.11926251, 9.83338561],\n", - " [ 43.96347185, 9.85004975],\n", - " [ 0.36015304, 85.93011921]])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Define high-symmetry points\n", - "G = center\n", - "K = corners[0,:]\n", - "K1 = corners[1,:]\n", - "M = (K + K1) / 2\n", - "\n", - "# Define high-symmetry lines (k-path)\n", - "pathPoints = np.asarray([G, M, K, G])\n", - "nGM, nMK, nKG = 70, 39, 79\n", - "segPoints = [nGM, nMK, nKG]\n", - "rowInds, colInds, pathInds = aly.points2path(pathPoints[:,0], pathPoints[:,1], npoints=segPoints)\n", - "nSegPoints = len(rowInds)\n", - "bandDiagramRecon = aly.bandpath_map(np.moveaxis(bandcuts, 0, 2), pathr=rowInds, pathc=colInds, eaxis=2)\n", - "\n", - "lda_shift = -0.86813 + 0.15 # Global energy shift" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Test plot\n", - "plt.plot(bandDiagramRecon.T)\n", - "plt.axis('off');" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Approximation of all 14 energy bands by polynomials in coefficient order" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "# Approximation by polynomials in coefficient order\n", - "allbcf = []\n", - "allapprox, approx = {}, []\n", - "nterms = [5, 45, 150]\n", - "for iband in tqdm(range(14)):\n", - " brec = np.nan_to_num(bandcuts[iband,...])\n", - " bcf = fuller.generator.decomposition_hex2d(brec, nterms=400, bases=bss, ret='coeffs')\n", - " \n", - " allbcf.append(bcf)\n", - " for nt in nterms:\n", - " currcf = bcf.copy()\n", - " currcf[nt:] = 0\n", - " recon = fuller.generator.reconstruction_hex2d(currcf, bss)\n", - " try:\n", - " allapprox[str(nt)].append(recon)\n", - " except:\n", - " allapprox[str(nt)] = []\n", - " allapprox[str(nt)].append(recon)\n", - "\n", - "allbcf = np.asarray(allbcf)\n", - "for k, v in allapprox.items():\n", - " allapprox[k] = np.asarray(v)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "bci_approx = {}\n", - "for k in allapprox.keys():\n", - " bci_approx[k] = aly.bandpath_map(np.moveaxis(allapprox[k], 0, 2), pathr=rowInds, pathc=colInds, eaxis=2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 14i" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f, axs = plt.subplots(3, 1, figsize=(7.5, 14))\n", - "\n", - "for i, nt in enumerate(nterms):\n", - " axs[i].plot(bandDiagramRecon.T - lda_shift, c='b')\n", - " axs[i].plot(bandDiagramRecon[-1,:] - lda_shift, c='b', label='Reconstruction')\n", - " axs[i].plot(bci_approx[str(nt)].T - lda_shift, c='r')\n", - " axs[i].plot(bci_approx[str(nt)][-1,:] - lda_shift, c='r', label='Approximation')\n", - " axs[i].set_xlim([0, nSegPoints])\n", - " axs[i].tick_params(axis='y', length=8, width=2, labelsize=15)\n", - " axs[i].set_yticks(np.arange(-8, 0.1, 1))\n", - " axs[i].set_ylim([-7.5, 0.8])\n", - " axs[i].set_ylabel('Energy (eV)', fontsize=15)\n", - " axs[i].set_title(str(nt)+' terms', x=0.76, y=0.9, fontsize=15)\n", - " axs[i].legend(fontsize=15, frameon=False, borderpad=0, bbox_to_anchor=(0.5, 0.2))\n", - "# axs[i].axhline(y=0, lw=2, c='k', ls='dashed')\n", - " if i < 2:\n", - " axs[i].tick_params(axis='x', length=0, labelsize=0)\n", - " \n", - " for p in pathInds[:-1]:\n", - " axs[i].axvline(x=p, c='k', ls='--', lw=2, dashes=[4, 2])\n", - "\n", - "axs[-1].set_xticks(pathInds)\n", - "axs[-1].set_xticklabels(['$\\overline{\\Gamma}$', '$\\overline{\\mathrm{M}}$',\n", - " '$\\overline{\\mathrm{K}}$', '$\\overline{\\Gamma}$'])\n", - "axs[-1].tick_params(axis='x', length=8, width=2, labelsize=15)\n", - "plt.suptitle('Approximation by polynomials in default order', y=0.9, fontsize=15)\n", - "plt.subplots_adjust(hspace=0.08, wspace=0)\n", - "\n", - "plt.savefig('../results/figures/sfig_14i.png', dpi=300, bbox_inches='tight', transparent=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Approximation of all 14 energy bands by polynomials in default order" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Approximation by polynomials in default order\n", - "allbcf = []\n", - "allapproxx, approx = {}, []\n", - "nterms = [5, 45, 150]\n", - "for iband in tqdm(range(14)):\n", - " brec = np.nan_to_num(bandcuts[iband,...])\n", - " bcf = fuller.generator.decomposition_hex2d(brec, nterms=400, bases=bss, ret='coeffs')\n", - " \n", - " order = np.argsort(np.abs(bcf))[::-1]\n", - " ordcf = bcf[order]\n", - " ordbss = bss[order,...]\n", - " \n", - " allbcf.append(bcf)\n", - " for nt in nterms:\n", - " currcf = ordcf.copy()\n", - " currcf[nt:] = 0\n", - " recon = fuller.generator.reconstruction_hex2d(currcf, ordbss)\n", - " try:\n", - " allapproxx[str(nt)].append(recon)\n", - " except:\n", - " allapproxx[str(nt)] = []\n", - " allapproxx[str(nt)].append(recon)\n", - "\n", - "allbcf = np.asarray(allbcf)\n", - "for k, v in allapproxx.items():\n", - " allapproxx[k] = np.asarray(v)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "bci_approxx = {}\n", - "for k in allapproxx.keys():\n", - " bci_approxx[k] = aly.bandpath_map(np.moveaxis(allapproxx[k], 0, 2), pathr=rowInds, pathc=colInds, eaxis=2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 14j" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f, axs = plt.subplots(3, 1, figsize=(7.5, 14))\n", - "\n", - "for i, nt in enumerate(nterms):\n", - " axs[i].plot(bandDiagramRecon.T - lda_shift, c='b')\n", - " axs[i].plot(bandDiagramRecon[-1,:] - lda_shift, c='b', label='Reconstruction')\n", - " axs[i].plot(bci_approxx[str(nt)].T - lda_shift, c='r')\n", - " axs[i].plot(bci_approxx[str(nt)][-1,:] - lda_shift, c='r', label='Approximation')\n", - " axs[i].set_xlim([0, nSegPoints])\n", - " axs[i].tick_params(axis='y', length=8, width=2, labelsize=15)\n", - " axs[i].set_yticks(np.arange(-8, 0.1, 1))\n", - " axs[i].set_ylim([-7.5, 0.8])\n", - " axs[i].set_ylabel('Energy (eV)', fontsize=15)\n", - " axs[i].set_title(str(nt)+' terms', x=0.76, y=0.9, fontsize=15)\n", - " axs[i].legend(fontsize=15, frameon=False, borderpad=0, bbox_to_anchor=(0.5, 0.2))\n", - "# axs[i].axhline(y=0, lw=2, c='k', ls='dashed')\n", - " if i < 2:\n", - " axs[i].tick_params(axis='x', length=0, labelsize=0)\n", - " \n", - " for p in pathInds[:-1]:\n", - " axs[i].axvline(x=p, c='k', ls='--', lw=2, dashes=[4, 2])\n", - "\n", - "axs[-1].set_xticks(pathInds)\n", - "axs[-1].set_xticklabels(['$\\overline{\\Gamma}$', '$\\overline{\\mathrm{M}}$',\n", - " '$\\overline{\\mathrm{K}}$', '$\\overline{\\Gamma}$'])\n", - "axs[-1].tick_params(axis='x', length=8, width=2, labelsize=15)\n", - "plt.suptitle('Approximation by polynomials in coefficient order', y=0.9, fontsize=15)\n", - "plt.subplots_adjust(hspace=0.08, wspace=0)\n", - "\n", - "plt.savefig('../results/figures/sfig_14j.png', dpi=300, bbox_inches='tight', transparent=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# np.savez('LDARecon_approx_bands.npz', allapprox=allapprox, allapproxord=allapproxx,\n", - "# linecut=bci_approx, linecutord=bci_approxx)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/SFig4_Hyperparameter_tuning-checkpoint.ipynb b/figures/.ipynb_checkpoints/SFig4_Hyperparameter_tuning-checkpoint.ipynb deleted file mode 100644 index b707f07..0000000 --- a/figures/.ipynb_checkpoints/SFig4_Hyperparameter_tuning-checkpoint.ipynb +++ /dev/null @@ -1,361 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Example visualizations of hyperparameter tuning for reconstruction" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import os\n", - "import numpy as np\n", - "import fuller\n", - "import matplotlib.pyplot as plt\n", - "from matplotlib.figure import figaspect\n", - "from h5py import File\n", - "import natsort as nts\n", - "import glob as g\n", - "from mpes import analysis as aly, visualization as vis\n", - "import matplotlib as mpl\n", - "import scipy.io as sio\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams['font.family'] = 'sans-serif'\n", - "mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42\n", - "\n", - "colornames = ['#646464', '#666666', '#6a6a6a', '#6f6f6f', '#737373', '#787878', '#7d7d7d', '#828282', '#878787', '#8d8d8d', '#929292', '#989898', '#9e9e9e', '#a4a4a4', '#aaaaaa', '#b0b0b0', '#b6b6b6', '#bcbcbc', '#c2c2c2', '#c9c9c9', '#cfcfcf', '#d6d6d6', '#dcdcdc', '#e3e3e3', '#eaeaea', '#efefee', '#efeee5', '#efeddc', '#efecd3', '#eeebca', '#eeeac0', '#eee9b7', '#eee8ad', '#ede7a4', '#ede69a', '#ede590', '#ede487', '#ece37d', '#ece273', '#ece069', '#ecdf5f', '#ebde55', '#ebdd4b', '#ebdc41', '#ebdb37', '#ebd333', '#ebc933', '#ecbe32', '#ecb432', '#eda931', '#ee9e31', '#ee9330', '#ef8830', '#ef7d2f', '#f0722f', '#f0672e', '#f15c2e', '#f2512d', '#f2462d', '#f33b2c', '#f3302c', '#f4252b', '#f4192b', '#ef182f', '#e81834', '#e21939', '#db1a3e', '#d51a43', '#ce1b48', '#c71b4d', '#c11c52', '#ba1c58', '#b31d5d', '#ac1d62', '#a61e67', '#9f1e6c', '#981f72', '#911f77', '#8a207c', '#842182']\n", - "custom_cmap = mpl.colors.LinearSegmentedColormap.from_list('custom', colornames, N=256)\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(154, 256, 256)" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Load reconstruction data\n", - "fdir = r'../data/hyperparameter/tuning_SFig3'\n", - "flist = fuller.utils.findFiles(fdir, fstring='/*', ftype='h5')\n", - "\n", - "recband = []\n", - "for f in flist:\n", - " with File(f) as file:\n", - " recband.append(file['bands/Eb'][:])\n", - "recband = np.asarray(recband)\n", - "recband.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(35, 256, 256)" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Reshape the reconstruction data into a grid for plotting\n", - "smaband = recband.reshape((14, 11, 256, 256))[::2, 1::2, ...].reshape((35, 256, 256))\n", - "smaband.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate circular mask for the data\n", - "msk = aly.circmask(recband[0,...], 128, 125, 115, sign='xnan', method='algebraic')\n", - "\n", - "# Ranges of hyperparameters\n", - "etas = np.around(np.arange(0.02, 0.29, 0.02), decimals=2)\n", - "shifts = np.around(np.arange(0.0, 0.51, 0.05), decimals=2)\n", - "\n", - "# Obtain axis values of kx, ky\n", - "axes = fuller.utils.loadHDF(flist[0], groups=['axes'])\n", - "kx, ky = axes['kx'], axes['ky']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 4a" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans.\n", - "findfont: Generic family 'sans-serif' not found because none of the following families were found: Arial\n" - ] - }, - { - "data": { - "image/png": "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3zZq1qxpSDIuvPBCY9asWcbKlSuNjz76yBg7dqxRq1YtQ5Lx29/+1ti/f3/Y9ZEFKIs8CGR2HpQy6/k+s+6HHMCpyIJAscyCaD5vSBbATviO5BhZv369//cLLrhAL730kqpVq3bacVdccYX/99zc3GiUZoqytaakpFR5fHJysiQpLy/PlueRpGeffVarVq2SJF1//fXq0KFDyPchSYZhaNy4cZKk++67T1deeWW5x51xxhkaP368JGn58uX+714oq/R7ISRpzpw55d5P2X8vezzsgSwIFOss+Pnnn1VcXCxJ2rhxo5577jk1atRIr776qg4fPqxjx45p6dKl6tKliyRpxYoVuv3220OqtRRZgFLkQKBIHqvNEM16yQGURRYEinUWlFq2bJleeuklJSQk6MUXX5TP5zP9HGQByiILAtklC6699lqtXbtWd955p9avX68hQ4booosuUs+ePTV27FjVrFlTf//737Vs2TI1aNAgrHOQBTgVeRDIqjww6/k+M+6HHEB5yIJAscyCaD1vSBbAbqz/JnCUa8OGDf7fn376aSUlJZV7XNkva69du3bI59m4cWPItzlVWlpayLc5fvy4//fq1atXeXxiYqIkKT8/35bnWbp0qR588EFJUv369fXCCy+EdPuyvvrqK23btk2SdOONN1Z6bPfu3f2/r1y5Uueff37A33v37q0GDRrohx9+0GuvvabHH3884Mmt4uJizZ07V1LJPPbo0SPsumENsiBQrLPg6NGjAfdZs2ZNZWVl6de//rX/37t3765PP/1UF110kTZs2KB///vf+uyzz9S5c+eQaiYLUIocCBRuDpglmvWSAyiLLAgU6yyQpIKCAt11110yDEPDhw/Xb37zG0vOQxagLLIgkB2yQCrJg9mzZ+vtt9+WYRin/f2HH37Qq6++qmbNmunaa68N6xxkAU5FHgSyIg/Mer7PrPshB1AesiBQLLMgWs8bkgWwGzaSY6T0AaB27doBrxY61c6dO/2/n3vuuSGfx6onO6pS9gGtoKCgyuNPnDghSapRo4btzvPll1/quuuu08mTJ5WUlKT58+erfv36IdVZ1po1a/y/X3TRRUHfbv/+/af9W0JCgm655RY9++yz2rFjh7Kzs9WtWzf/3z/55BN9//33kqRbb71VcXF8CIHdkAWBYp0Fp/7H+J133hnwH4OlatSooSeeeELXXHONJOnNN98MeSOZLEApciBQuDlglmjWSw6gLLIgUKyzQJKefPJJbd68WU2bNtUjjzxi2XnIApRFFgSyQxYcPXpUV111lZYtW6b4+Hj95S9/0dChQ9W8eXMdP35cn332mR577DFlZ2erX79+mjBhgkaMGBHyecgCnIo8CGR2Hpj1fJ+ZzxuSAygPWRAollkQrecNyQLYDV0RI6UPAD169Kj0lTZffPGFpJJXg5xxxhlRqc0MtWrV8v8ezMdMlL6aJ5iPr4jmebZv365evXrpyJEjio+P1xtvvBHwKp9wHDhwIKzbHTt2rNx/r+zjKfhYCvsjCwLFOgvK3o8k9erVq8L7uPzyy/2v9ly9enXQtZYiC1CKHAgUbg6YJZr1kgMoiywIFOss2Lx5s5566ilJ0j/+8Q//R+hZgSxAWWRBoFhngSSNHTtWy5YtkyS9/PLLGjdunFq2bKnq1asrNTVVPXv2VFZWlnr06CHDMDRq1KiAd48FiyzAqciDQGbmgVnP95n9vCE5gPKQBYFimQXRet6QLIDd8I7kGMjLy/N/NEH79u0rPbb0OxCqOq4imzZtCut2ZaWlpYX8cRhJSUmqU6eOfvzxR+3Zs6fSY48cOeJ/AGjSpIltzvP999/riiuu0Pfffy+fz6dXXnlFv/vd70KqrzxFRUX+3xctWqRzzjknqNtV9Eqo9u3b64ILLtDGjRs1f/58/eMf/1BiYqKOHj2qhQsXSpI6dOig1q1bR1w7zEUWBLJDFiQmJqpevXo6ePBglXUkJSWpbt262r9/v//4UJAFkMiBU0WSA2aJZr3kAEqRBYHskAXPPvusCgoK1Lx5cx07dkxvvPHGaceUHctPP/3U/w6Avn37hrTxTBagFFkQyA5ZYBiGXnnlFUlSixYtNGTIkHKPS0hI0OOPP66LL75YxcXFmjlzpp599tmQzkUWoCzyIJCZeWDW831WPG9IDuBUZEGgWGdBtJ43JAtgN2wkx8DGjRv9X8p+4YUXVnhcYWGhvvrqqyqPq8wFF1wQ1u3KmjFjhm677baQb9e6dWstW7ZMW7du1cmTJwO+p6GszZs3+39v1aqVLc5z6NAh9ezZU999952kknchmPWKnDp16vh/r127tikfGzJ48GCNGjVKP/30kxYtWqQbb7xR//73v/0PrLyayJ7IgkB2yYI2bdpoyZIlkgL/w608pX+v6FyVIQsgkQOnijQHzBKteskBlCILAtkhC0o/Mu+7777TgAEDqjz+8ccf9/++ffv2kDaSyQKUIgsC2SELfvjhBx0+fFhS1WPdoUMH/+9law8WWYCyyINAZuWBWc/3WfW8ITmAU5EFgeyQBdF43pAsgN3w0dYxUPYjjip7hdDXX3/tfwIj3FcSxdLFF18sqeTjJtauXVvhcUuXLvX/npGREfPz/Pzzz+rdu7f/wffpp5/WH//4x5DrqkjZB/Ply5ebcp+33nqr4uPjJUmvvvqqpF8+lqJatWpBPfmF6CMLAtklC8p+hE3pf1CWJycnR4cOHZIkNW7cOOR6yQJI5MCpIs0Bs0SrXnIApciCQHbJgmghC1CKLAhkhywo+8TvyZMnKz22sLCw3NsFiyxAWeRBIDPywKzn+6x83pAcwKnIgkB2yIJoPG9IFsB2DETdPffcY0gy6tSpU+lxs2bNMiQZkoxt27ZFqTrzfPbZZ/7677777nKPKSoqMlq1amVIMmrXrm0UFBTE9DxHjx41MjIy/Pf38MMPh1xPVYqKioy0tDRDktG8eXMjPz/flPvt3bu3IcmoVq2asXHjRiM+Pt6QZPTt29eU+4f5yIJf2CkLNmzY4L+fW2+9tcLzzZw503/c448/HnK9ZAEMgxwoy4wcKM/27dv95x4yZIit6iUHUIos+IWdsqAqjzzyiP8+s7Kywr4fsgClyIJf2CULioqKjNTUVEOScdZZZxmFhYUVHrto0SL/ff/5z38OuTayAGWRB78wIw/Mer7P6ucNyQGciiz4hV2yIBrPG5IFsBs2kmOgS5cuhiTj8ssvr/S44cOHG5KM1NRUo7i4OErVmatbt26GJCMhIcFYsWLFaX9/5pln/IH6yCOPVHg/pcecffbZlp3nxIkTRq9evfzHDRs2LIgrDM/zzz/vP89NN91kHD9+vMJjf/75Z+Mf//hHlff52muv+e+zTZs2/t/nz59vZukwEVnwCztlgWEYxlVXXWVIMuLi4oyPP/74tL/v27fP/x901atXN/bs2VPhfVWGLAA58AuzcuBU4W4emVVvVcgBGAZZUJbdsqAyZm0kGwZZgBJkwS/slAUDBgzw32bs2LHlHnP48GGjdevW/uM+/PDDoO77VGQBSpEHv4g0D8x6vi9azxuSAyiLLPiFXbLAMKLzvCFZADthIznKioqKjOTkZEOSMXLkyEqP7dGjhyHJ6N69e5SqM9/nn39u1KhRw5BkpKSkGE8++aSxcuVK49NPPzXuuusuf1i1aNHCyMnJqfB+qvofh2ac5/rrr/cfd9lllxlffPGFsXHjxgp/vvnmm7DHpbi42Ljuuuv85zv33HONZ555xliyZImxbt06Y+nSpcbUqVONAQMGGMnJyVW+6swwDOPYsWNGrVq1/PcpyTjjjDMqfZBB7JAF9s0CwzCMb775xqhdu7YhyUhKSjIefPBB47///a+xevVqY8qUKf7/GJRkjBs3LuxxIQu8jRywJgeWLVtmzJgxw/8zfvx4/20yMjIC/jZjxgzL660KOQCywN5ZUBkzN5LJApAF9s2Cr7/+2qhZs6b/dn379jUWLFhgfP7558aKFSuMSZMmGU2bNvX/vaon+ytDFsAwyAOz88Cs5/ui9bwhOYBSZIE9s8AwovO8IVkAO2EjOcq2bNniX6Rz5syp9NgzzzzTkGTcd999UarOGu+8847/o6DK+2nRooXx7bffVnofVf2PQzPOU9HtKvoJ9hXPFSkoKDD+8Ic/GD6fr8pzNWvWLKj7HDp0aMDtKvooEMQeWWDfLCi1bNkyo0GDBhXej8/nM/7v//4v1GE4DVngXeSANTkwZMiQkB7Pra43GOSAt5EF9s+Cipi5kWwYZIHXkQX2zoKPPvrIqFu3bpW3v+yyy4zDhw9HMixkAcgDk/MglAyoLE/Mup9gkAMwDLLArllQKhrPG5IFsAs2kqNs/vz5/kW6cePGCo/btWuX/7hXXnklihVaY8eOHcbw4cONFi1aGDVr1jRq165tdOzY0Rg3bpxx9OjRKm8fbIBHcp5o/gdhWV988YXx5z//2bjggguMX/3qV0Z8fLzxq1/9ymjfvr1xxx13GAsWLAj6VUFLliwJqHH58uWm1AjzkQX2zYKyDh06ZDzyyCNGu3btjNTUVCMpKclo1qyZMXToUOPzzz8P+n6CQRZ4DzlgTQ6YvXlkVp4EgxzwJrLAGVlQHrM3kkuRBd5EFtg/Cw4dOmSMGzfOuPTSS4169eoZ1apVM2rUqGE0a9bMuPnmm4233nrL1I8TJQu8izwwNw/Mer4vFs8bkgPeRhbYMwvKitbzhmQBYs1nGIYh2M6iRYt07bXXSpI+//xzXXjhhTGuCEAskAUAyAEAElkAoARZAKAUeQBAIgsAWC8u1gWgfOvXr5ckVatWTW3atIltMQBihiwAQA4AkMgCACXIAgClyAMAElkAwHpsJNtU6QNA69atVb169dgWAyBmyAIA5AAAiSwAUIIsAFCKPAAgkQUArMdGsk2VPgC0b98+pnUAiC2yAAA5AEAiCwCUIAsAlCIPAEhkAQDrsZFsQzk5Odq+fbskHgAALyMLAJADACSyAEAJsgBAKfIAgEQWAIgONpJt6IsvvpBhGJJ4AAC8jCwAQA4AkMgCACXIAgClyAMAElkAIDp8RmnSAAAAAAAAAAAAAAAg3pEMAAAAAAAAAAAAADgFG8kAAAAAAAAAAAAAgABsJAMAAAAAAAAAAAAAArCRDAAAAAAAAAAAAAAIwEYyAAAAAAAAAAAAACAAG8kAAAAAAAAAAAAAgAAJsS7ADMnJyTp+/Lji4+NVv379WJcDwAQHDhxQUVGRkpKSdPTo0aBuQxYA7kMWAJDIAgAlQs0CcgBwJ7IAgEQWACgRzvMFCI3PMAwj1kVEKj4+XsXFxbEuA4AF4uLiVFRUFNSxZAHgXmQBAIksAFAi2CwgBwB3IwsASGQBgBKhPF+A0LjiHcmlDwJxcXFq1KhRrMsBYIJ9+/apuLhY8fHxQd+GLADchywAIJEFAEqEmgXkAOBOZAEAiSwAUCKc5wsQGldsJNevX1979+5Vo0aNtGfPnliXA8AEaWlp2rt3b0gfNUMWAO5DFgCQyAIAJULNAnIAcCeyAIBEFgAoEc7zBQhNXKwLAAAAAAAAAAAAAADYCxvJAAAAAAAAAAAAAIAAbCQDAAAAAAAAAAAAAAKwkQwAAAAAAAAAAAAACMBGMgAAAAAAAAAAAAAgABvJAAAAAAAAAAAAAIAAbCQDAAAAAAAAAAAAAAIkxLoAoDyZmZlBHTd9+nSLKwEQS2QBAIksAFCCLABADgCQyAIAJcgCIDrYSEZUBRvuZt8fDxaAvZAFACSyAEAJsgAAOQBAIgsAlCALAHthIxmWMDvsI1VRPTw4ANYiCwBIZAGAEmQBAHIAgEQWAChBFgDOwEYyTGG30A/WqXXzoABEhiwAIJEFAEqQBQDIAQASWQCgBFkAOBMbyQiLU0O/KjwoAKEhCwBIZAGAEmQBAHIAgEQWAChBFgDuwEYyguLW0K8KDwpAILKgBFkAryMLSpAF8DqyoARZAC8jB0qQA/A6sqAEWQCvIwtKkAVwGzaSUSGvBn9lyo4JDwjwCrLgdGQBvIgsOB1ZAC8iC05HFsBryIHTkQPwIrLgdGQBvIgsOB1ZALdhIxmnIfyDwwMC3I4sCA5ZALcjC4JDFsDtyILgkAVwM3IgOOQA3I4sCA5ZALcjC4JDFsAN2EiGH+EfvtKx48EAbkAWhI8sgJuQBeEjC+AmZEH4yAK4BTkQPnIAbkIWhI8sgJuQBeEjC+BUbCR7FIFvDb4PAU5DFliDLIDTkAXWIAvgNGSBNcgCOAk5YA1yAE5DFliDLIDTkAXWIAvgNGwkewzhH128ygh2RRZEF1kAuyILoossgF2RBdFFFsCOyIHoIgdgV2RBdJEFsCuyILrIAtgdG8keQfjHFg8GsAuyILbIAtgFWRBbZAHsgiyILbIAdkAOxBY5ALsgC2KLLIBdkAWxRRbArthIdjnC3154MECskAX2QhYgVsgCeyELECtkgb2QBYgFcsBeyAHECllgL2QBYoUssBeyIDz79u1TWlpalceNGDFCI0aMiEJF7sFGsksR/vbGgwGihSywN7IA0UIW2BtZgGghC+yNLEA0kAP2Rg4gWsgCeyMLEC1kgb2RBaEpLi7W3r17qzwuJycnCtW4CxvJLkP4OwsPBrAKWeAsZAGsQhY4C1kAq5AFzkIWwArkgLOQA7AKWeAsZAGsQhY4C1kQnLi4ODVq1KjK41JTU6NQjbuwkewShL+z8WAAs5AFzkYWwCxkgbORBTALWeBsZAHMQA44GzkAs5AFzkYWwCxkgbORBZVr1KiR9uzZE+syXCku1gUgcjwAuAdziUjQP+7BXCIS9I97MJeIBP3jHswlwkXvuAdziUjQP+7BXCIS9I97MJeINt6R7GAEhjvxyiKEiixwJ7IAoSIL3IksQKjIAnciCxAKcsCdyAGEiixwJ7IAoSIL3IksQDTxjmSH4gHA/ZhjBIM+cT/mGMGgT9yPOUYw6BP3Y45RFXrE/ZhjBIM+cT/mGMGgT9yPOUY08I5khyEYvIVXFqEiZIG3kAWoCFngLWQBKkIWeAtZgPKQA95CDqAiZIG3kAWoCFngLWQBrBb0O5KHDx+u9evXW1gKqsIDgHcx9yiLfvAu5h5l0Q/exdyjLPrBu5h7lKIXvIu5R1n0g3cx9yiLfvAu5h5WCXojefLkyerQoYPatm2rCRMmaN++fVbWhVMQAsjMzKQPQA+ALIAksgBkAUrQAyALwPyDHIBEFoAsQAl6AGQBrBDSdyQbhqEvv/xSo0ePVtOmTdW7d2/NnTtX+fn5VtUH8QCAQPSDdzH3KIt+8C7mHmXRD97F3KMs+sGbmHeURT94F3OPsugH72LuURb9ADMFvZH84YcfauDAgapZs6YMw1BRUZE+/vhjDRo0SA0bNtTtt9+urKwsK2v1JBY8ykNfeA9zjvLQF97DnKM89IX3MOcoD33hLcw3ykNfeA9zjvLQF97DnKM89AXMkhDsgT179lTPnj117NgxLVy4UHPmzNEnn3yi4uJi5ebmatasWZo1a5bS0tI0cOBADRo0SC1btrSydldjkaMqpT0yffr0GFcCK5EFqApZ4A1kAapCFngDWYCqkAXuRw6gKuSAN5AFqApZ4A1kAapCFsAMIX20tSTVrFlTAwcO1Icffqjdu3frmWeeUdu2bWUYhgzD0O7du/X000+rTZs26tSpk6ZMmaIff/zRitpdiwcAABJZAKAEWQBAIgsAkAMASpAFACSyAED0hLyRXFajRo30wAMPaP369dqwYYNGjhyps846y7+pvHbtWt13331q3Lix+vXrp4ULF6qwsNCs2l2JBwCEip5xJ+YVoaJn3Il5RajoGXdiXhEqesZ9mFOEip5xJ+YVoaJn3Il5RajoGUQi6I+2rsoFF1yg8ePH65lnntEnn3yiOXPmaOHChTp69KgKCgq0aNEiLVq0SGeccYZ+//vfa9CgQerSpYtZp3c8FjIiwUdUuAdZgEiQBe5BFiASZIF7kAWIBFngDuQAIkEOuAdZgEiQBe5BFiASZAHCZdpGcimfz6crrrhCV1xxhV544QX/9yl/+umnKioq0uHDh/XCCy9o6tSpOnnypNmndxzCH2biwcC5yAKYiSxwLrIAZiILnIssgJnIAmciB2AmcsC5yAKYiSxwLrIAZiILEKqIPtq6KmW/T3n9+vVq06aNfD6fJMkwDCtP7Qg8AMAq9JazMF+wCr3lLMwXrEJvOQvzBavQW87BXMEq9JazMF+wCr3lLMwXrEJvIViWbiQXFhZq4cKFuv7669WhQwd99dVXVp7OUViksBo95gzME6xGjzkD8wSr0WPOwDzBavSY/TFHsBo95gzME6xGjzkD8wSr0WMIhiUbycuXL9c999yjhg0b6qabbtLbb7+tgoICGYahlJQUDR06VFlZWVac2hFYnIgWes3emB9EC71mb8wPooVeszfmB9FCr9kXc4NoodfsjflBtNBr9sb8IFroNVTFtI3kb7/9VmPGjNG5556r7t27a/r06Tpy5IgMw1BcXJx69+6t1157TT/88INefvllde/e3axTOwqLEtFGz9kT84Joo+fsiXlBtNFz9sS8INroOfthThBt9Jw9MS+INnrOnpgXRBs9h8pEtJF86NAh/fOf/1Tnzp3VsmVLPfHEE9q+fbsMw5BhGLrgggs0fvx47d69W++//74GDBigpKQks2p3HBYjYoXesxfmA7FC79kL84FYoffshflArNB79sFcIFboPXthPhAr9J69MB+IFXoPFQl5I/nEiROaN2+err32WjVu3FjDhg3TmjVr/JvHDRo00PDhw7Vu3Tpt2LBBI0eOVMOGDa2o3VFYhIg1etAemAfEGj1oD8wDYo0etAfmAbFGD8Yec4BYowftgXlArNGD9sA8INboQZQn6I3kJUuW6M4771TDhg01YMAAvfvuuyosLJRhGEpMTNTNN9+sxYsXa8+ePZo4caLatWtnZd2OwuKDXdCLscX4wy7oxdhi/GEX9GJsMf6wC3oxdhh72AW9GFuMP+yCXowtxh92QS/iVEFvJF922WWaMWOGfv75ZxmGIUm6+OKLNW3aNO3fv19vvPGGrr76asXHx1tWrBOx6GA39GRsMO6wG3oyNhh32A09GRuMO+yGnow+xhx2Q0/GBuMOu6EnY4Nxh914uScPHDigxYsXa8yYMbrqqqtUt25d+Xw++Xw+3XbbbbEuLyYSQjnYMAyde+65GjRokAYNGqRmzZpZVRcAAAAAAAAAAAAAREWDBg1iXYLtBP2O5LvuukvZ2dn69ttvNWbMGDaRg+DlV23A3ujN6GK8YVf0ZnQx3rArejO6GG/YFb0ZPYw17IrejC7GG3ZFb0YX4w27ojelpk2bqlevXrEuI+aC3kh+8cUX1bVrVytrcRUWGeyOHo0Oxhl2R49GB+MMu6NHo4Nxht3Ro9ZjjGF39Gh0MM6wO3o0Ohhn2J0Xe3TMmDFatGiR9u/fr507d2rq1KmxLinmgt5IDsa2bdv06quvasKECXrsscd06NAhM+/eMby4uOBM9Kq1GF84Bb1qLcYXTkGvWovxhVPQq9ZhbOEU9Kq1GF84Bb1qLcYXTuG1Xn300Ud1zTXX8BHXZZiykfz555+re/fuatGihYYMGaLRo0fr0Ucf1YEDBwKOmzJliurXr6/zzz9fhYWFZpzadry2qOB89Kw1GFc4DT1rDcYVTkPPWoNxhdPQs+ZjTOE09Kw1GFc4DT1rDcYVTkPPelvEG8mLFy9WRkaGli9fLsMw/D/lGTx4sPLz8/Xdd99p8eLFkZ7adlhMcCp611yMJ5yK3jUX4wmnonfNxXjCqehd8zCWcCp611yMJ5yK3jUX4wmnone9K6KN5H379mnAgAE6ceKEWrdurffff1+5ubkVHl+rVi1de+21kqT3338/klMDAAAAAAAAAAAAACwS0Ubys88+q6NHj+rss8/WsmXL1Lt3byUnJ1d6m0svvVSGYWjt2rWRnNp2eDUGnI4eNgfjCKejh83BOMLp6GFzMI5wOno4cowhnI4eNgfjCKejh83BOMLp6GFvimgj+YMPPpDP59PIkSNVu3btoG7TsmVLSdL27dsjObWtsHjgFvRyZBg/uAW9HBnGD25BL0eG8YNb0MvhY+zgFvRyZBg/uAW9HBnGD25h117et2+f0tLSqvyZNGlSrEt1nIg2knfu3ClJ6tSpU9C3SU1NlSTl5eVFcmrbsOuiAcJFT4eHcYPb0NPhYdzgNvR0eBg3uA09HTrGDG5DT4eHcYPb0NPhYdzgNnbs6eLiYu3du7fKn5ycnFiX6jgRbSSfPHlSUskEBevnn3+WJKWkpERyaluw42IBzEBvh4bxglvR26FhvOBW9HZoGC+4Fb0dPMYKbkVvh4bxglvR26FhvOBWduvtuLg4NW7cuMqf0je7IngRbSQ3bNhQkvTdd98FfZtVq1ZJkpo2bRrJqWPObosEMBs9HhzGCW5HjweHcYLb0ePBYZzgdvR41RgjuB09HhzGCW5HjweHcYLb2anHGzVqpD179lT5M2LEiFiX6jgRbSR369ZNhmFo/vz5QR1fUFCgqVOnyufz6dJLL43k1AAAAAAAAAAAAAAAi0S0kXzbbbdJkt555x199NFHlR5bUFCgwYMHa9u2bfL5fLZ6pQKA8rFOAUhkAYASZAEAiSwAQA4AKEEWAJDIAi+IaCP50ksv1e9//3sZhqG+fftq9OjR/o+ulqQdO3ZoxYoVGj9+vNq0aaP58+fL5/PpnnvuUZs2bSIuPlZYGPAS+r1ijA28hH6vGGMDL6HfK8bYwEvo9/IxLvAS+r1ijA28hH6vGGMDL6Hf3S0h0juYOXOmcnNz9d5772nChAmaMGGCfD6fJKlv377+4wzDkCRdf/31mjx5cqSnBQAAAAAAAAAAAABYJKJ3JEtSYmKiFi9erKlTp6p58+YyDKPcn7S0ND3//PNasGCB4uPjzag9JnhlBbyIvj8dYwIvou9Px5jAi+j70zEm8CL6PhDjAS+i70/HmMCL6PvTMSbwIvrevSJ+R3KpzMxMZWZm6quvvtKaNWt04MABFRUVqU6dOrrwwgv129/+1v9OZadiIcDLMjMzNX369FiXYQtkAbyMLPgFWQAvIwt+QRbAy8iCEuQAvIwc+AVZAC8jC35BFsDL3JAF2dnZ2rp1q///P3TokP/3rVu3aubMmQHH33bbbVGqLHZM20gu1bp1a7Vu3drsuwUAAAAAAAAAAAAAS7z00kuaNWtWuX9bvny5li9fHvBvXthIjvijrb2CVxIBkMgCACXIAgASWQCAHABQgiwAIJEFANyJjWQAAAAAAAAAAAAAnjZz5kwZhhH0jxewkRwEXkkElPD6WvD69QOlvL4WvH79QCmvrwWvXz9QystrwcvXDpTl9bXg9esHSnl9LXj9+oFSrAX3YSMZAAAAAAAAAAAAABCAjeQq8OoJIJBX14RXrxuoiFfXhFevG6iIV9eEV68bqIgX14QXrxmojFfXhFevG6iIV9eEV68bqAhrInz16tXT5ZdfrgceeEBz5szRxo0bdfLkyZjWlBDTswMAAAAAAAAAAACAxx0+fFhZWVnKysry/1v16tXVunVrtW/fXu3bt1e7du3Uvn17/epXv4pKTbwjuRK8agIon9fWhteuFwiW19aG164XCJbX1obXrhcIlpfWhpeuFQiF19aG164XCJbX1obXrhcIFmsjPMOHD9dll12mOnXqyOfzyefzqbCwUBs2bNDMmTN1//33q0ePHjrjjDPUrFkz9evXT2PHjtW///1vbd++3ZKaeEcyAAAAAAAAAAAAAMTQhAkT/L9///332rBhg/9n9erVAZvFu3bt0s6dO/XOO+/4/y01NVVt27YNePfyb37zGyUmJoZdE+9IrgCvlgAq55U14pXrBMLllTXilesEwuWVNeKV6wTC5YU14oVrBCLhlTXilesEwuWVNeKV6wTCxRqJzFlnnaWrrrpKDz74oCZNmqQzzzxThmHoyiuv1D//+U/deeedSk9PV40aNfzvXs7NzVV2dnbA31NSUiKqg43kctDcQHDcvlbcfn2AWdy+Vtx+fYBZ3L5W3H59gFncvFbcfG2Amdy+Vtx+fYBZ3L5W3H59gFlYK5Fbs2aNOnbsqDVr1sjn8+mDDz5Q48aNNXXqVH322WfKy8vTpk2b9Oqrr+qBBx5Qz549Vb9+ff/mclFRUUTn56OtAQAAAAAAAAAAAMBG3njjDd1+++06fvy4UlJS1LVrV3300UcaMmSIVq1apfPPP18+n0+tWrVSq1atNGDAAP9t9+3bp/Xr12v9+vUR1WDZO5L379+vtWvXau3atdq3b59VpzEdr44AQuPWNePW6wKs4tY149brAqzi1jXj1usCrOLGNePGawKs5NY149brAqzi1jXj1usCrMKaCc+YMWN0yy236MSJEzr77LOVnZ2txYsXq2vXrsrJydF1112nY8eOVXj7Ro0a6aqrrtJf//rXiOowdSO5qKhI//znP/XrX/9ajRs3VqdOndSpUyelpaWpRYsWmjx5sgoLC808JQAAAAAAAAAAAAA43rFjx3TDDTfob3/7m3w+n7p06aJVq1apbdu2SkhI0IIFC3TWWWfpq6++0tChQy2vJ+iN5Msuu0yXX365du7cWe7fc3Jy1LNnTw0bNkxbt26VYRgBP9u2bdOIESPUs2dP5eTkmHYBAAAAAAAAAAAAAOBku3fv1sUXX6x///vf8vl8uvXWW7VkyRLVq1fPf0yDBg30r3/9S4mJiZo/f74mTpxoaU1BbyQvWbJES5Ys0dGjR8v9+2233aYlS5bIMAwlJCTo6quv1gMPPKBRo0apT58+qlatmgzD0LJly2z7Nna71gXYndvWjtuuB4gWt60dt10PEC1uWztuux4gWty0dtx0LUA0uW3tuO16gGhx29px2/UA0cLaCU7nzp21fv16xcXF6W9/+5tmz56tatWqnXZcp06dNGXKFPl8Pj344IPKysqyrKYEM+5kyZIleuutt+Tz+dS+fXstWLBAzZo1Czhm+/btuuGGG7R+/XotWLBAn332mTp37mzG6QEAAAAAAAAAAADAsX744QfVrFlTr776qvr161fpsbfffrvWrFmjqVOnqn///lq7dq3S0tJMr8mU70ieOXOmJKlOnTr64IMPTttElqRmzZrp/fffV926dSVJs2bNMuPUpuHVEEBk3LKG3HIdQKy4ZQ255TqAWHHLGnLLdQCx4oY15IZrAGLJLWvILdcBxIpb1pBbrgOIFdZQ1dLS0pSdnV3lJnKp5557ThkZGTp48KBuuOEGS2oyZSN5xYoV8vl8uueeewI+p/tUDRo00F133SXDMLRixQozTg0AAAAAAAAAAAAAjrZq1Sq1b98+6OMTEhK0YMECpaWlafXq1ZbUZMpG8v79+yVJl1xySZXH9ujRQ1LJF0YDAAAAAAAAAAAAgNvNmDFDe/furfDvDRo0CPk+69evr4ULFyopKSmS0ipkykZyUVGRJFX6buRSpR9tnZeXZ8apTcHb6QFzOH0tOb1+wC6cvpacXj9gF05fS06vH7ALJ68lJ9cO2InT15LT6wfswulryen1A3bh9bV05513as6cOabfb8eOHTVlyhTT71cyaSP5nHPOkRTc5nB+fr4kKTU11YxTAwAAAAAAAAAAAICtnXnmmdqyZUvQxx89elRZWVl68sknqzx26NChkZRWoYRQb/D888+rfv36Af/m8/kkSZs3b1bXrl0rvf2OHTsk/fLOZAAAAAAAAAAAAAAIx759+5SWllblcSNGjNCIESOiUFH5+vTpo1dffVUdO3bUvffee9rft2/frpUrV2rFihVasWKFNm7c6P9U6Iceeija5UoKYyP5hRdeqPBvn376qW6//fZKb79y5UpJUvPmzUM9tSW8/jZ6wGyZmZmaPn16rMsIGVkAmIssACCRBQBKODELyAHAXE7MAYksAMxGFgCQrMmC4uLiSr97uFROTo6p5w3V3//+d+3YsUN/+tOf9Nprr2nEiBHavn27VqxYoZUrV+qHH36QVPIG3sTERKWnp6tz587q1KlTzGoOaSPZMIxK//72228rJyenwo+tLioq0r/+9S/5fD5ddNFFoZwaAAAAAAAAAAAAAALExcWpUaNGVR4X66/drV27trKysjRp0iSNHTtWN910k6SSjeMWLVqod+/e6tSpkzp37qx27dopISHk9wObLugKiouLIz7Z+++/r4SEBDVt2lSXXHJJxPcHAAAAAAAAAAAAwLsaNWqkPXv2xLqMoPh8Po0cOVIDBgzQ6NGjNXfuXNWoUUODBw/WyJEjVb169ViXGCAumie75pprtGPHDm3fvl3dunWL5qkBAAAAAAAAAAAAIObOOusszZkzR9nZ2WrVqpUefvhhtW7dWu+8806sSwsQ1Y1k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2DF9I9mteCUFAIksAFCCLAAgkQUAyAEAJcgCABJZALjBSy+9pFmzZpX7t+XLl2v58uUB/+aFjWTTPtoaAAAAAAAAAAAAAOAObCQHgVcSASW8vha8fv1AKa+vBa9fP1DK62vB69cPlPLyWvDytQNleX0teP36gVJeXwtev36glNPXwsyZM2UYRtA/XsBGMgAAAAAAAAAAAAAgABvJVXD6qycAs3l1TXj1uoGKeHVNePW6gYp4dU149bqBinhxTXjxmoHKeHVNePW6gYp4dU149bqBirAm3CUh1gUAAAAAAAAAAAAAgJfVq1dPbdu21YUXXqh27dqpffv2atWqlRISYredyzuSK8GrJoDyeW1teO16gWB5bW147XqBYHltbXjteoFgeWlteOlagVB4bW147XqBYHltbXjteoFgsTbCc/jwYWVlZWnSpEkaMmSI2rVrp5SUFP32t7/V7bffrueee05Lly7Vzz//HLWaeEcyAAAAAAAAAAAAAMTQ8OHDtX79em3YsEGHDx+WJBUWFmrDhg1av359wLFnn322/13Lpf+3WbNmptfEO5IrwKslgMp5ZY145TqBcHlljXjlOoFweWWNeOU6gXB5YY144RqBSHhljXjlOoFweWWNeOU6gXCxRkI3YcIEffzxxzp48KB2796txYsX64knntDNN9+s5s2by+fz+X927dqld955R4899phuuOEGnXvuuapdu7a6d++u++67T6+88orWrl2rEydORFQTG8nloLmB4Lh9rbj9+gCzuH2tuP36ALO4fa24/foAs7h5rbj52gAzuX2tuP36ALO4fa24/foAs7BWwnfWWWfpqquu0oMPPqhJkybpzDPPlGEYuvLKK/XPf/5Td955p9LT01WjRg3/5nJubq6ys7MD/p6SkhJRHXy0NQAAAAAAAAAAAADYzJo1a/S73/1O+/btk8/n0wcffKC7775bf/jDHyRJhmFo8+bNWr9+vf9nw4YNOnjwoCSpqKgoovOH/Y7koqIiffzxx3r00UfVv39/ZWRkqF27dmrRooXatWunjIwM9e/fX48++qg+/vjjiAuNFl4dAYTGrWvGrdcFWMWta8at1wVYxa1rxq3XBVjFjWvGjdcEWMmta8at1wVYxa1rxq3XBViFNRO+N954Q927d9e+ffuUkpKinj17SpKGDBmib7/9VpLk8/nUqlUrDRgw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i0QiWrt2rX75y19q6NChKikpUVZWliZOnBhzsQAAAAAAAAAAAADglksuuUT/+c9/dMstt6hXr15q06aNOnTooP79++vBBx/Uhg0bdMIJJ7h2/LKyMr300ksaM2aMbrjhBtm2Lalmz9WyLH33u9/V7373O3366adasWKFrrvuukabyPW1a9curk1kKYYrkrt376758+dr1KhRKi0t1eOPP67HH39cbdu21QknnKCcnBy1a9dOrVq1UkVFhUpKSlRQUKCtW7fq4MGDkiTbttW6dWs988wzOuaYY+IqGAAAAAAAAAAAAADc0qNHD02fPl3Tp09P2jFfeOEFvfjii3r11VdVUlIiqeH3Ho8aNUpjxoxR//79k1ZT1BvJUs0OfH5+viZOnKj8/HxJUklJiTZt2qRNmzY1+Te1u+SSdPbZZ2vGjBk69dRT468YAAAAAAAAAAAAAAJk1KhRsm27bvM4IyOj7nuPhw8frtTU1KTXFNNGslRzb/B33nlHa9eu1d/+9jfl5+fro48+0ueff97ouR07dlSfPn00ZMgQjRw5UgMGDHCkaAAAAAAAAAAAAAAIkpSUlMN+73HS64n3DwcMGKD7779fb7/9tvbt26fS0lLt27dPu3btqvu/P/vsM7399tu6//77fbOJPHv2bK9LAELFr2vOr3UBQeXXNefXuoCg8uua82tdQFD5cc35sSYgyPy65vxaFxBUfl1zfq0LCCrW3DfuvffeqL/3OFliviK5ORkZGcrIyHDq5QAAAAAAAAAAAAAgFO68806vS2gk7iuSAQAAAAAAAAAAAADBxEYyAAAAAAAAAAAAABiuffv2mjRpkmOvx0YyAAAAAAAAAAAAABju0KFDqqiocOz12EgGAAAAAAAAAAAAADQQyo3k2bNne10CEAp+X2t+rw8ICr+vNb/XBwSF39ea3+sDgsLPa83PtQFB4ve15vf6gKDw+1rze31AULDW/C+UG8kAAAAAAAAAAAAAgOaxkQwAAAAAAAAAAAAAaICNZAAAAAAAAAAAAABAA6HdSOa+64C7TFljptQJmMqUNWZKnYCpTFljptQJmMqENWZCjYDJTFljptQJmMqUNWZKnYCpWGNmCO1GMgAAAAAAAAAAAACgaWwkAwAAAAAAAAAAAAAacGwjed68eZo3b56Ki4vrfvb111/X/dyPuGwecIdpa8u0egFTmLa2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+c+rra2tJq/zwgsv6Pzzz9dtt90mqb9+mkwmtXDhQi1cuFALFizQnDlzNGnSJE2ePFnJZFKbN2/W5s2btWnTJj322GN65JFH9NBDD+nFF1/UunXr9JWvfEUXX3yxvvzlL+ucc85RNBodd/saWkh+5ZVXZFmWHMeRZVmNfGkAAAAAAAAAAAAAGNHtt9+uU045RV1dXe73+vr69Oijj+rRRx/VT3/6U915553aZZddqnqdG264QUuWLFGhUFAkEtGHP/xhnXzyyTr22GOVSqWG/b0pU6ZoypQp2mWXXbT//vu733/mmWd044036sYbb9Rrr72m8847T1deeaVefPHFcbex4UtbO47T6JcEAAAAAAAAAAAAgBE99thj+tSnPqWuri61t7frggsu0IMPPqi//OUvWrp0qaT+WcRHHXWUuru7q3qtNWvWKBwO63Of+5zWrFmj3//+9zrllFNGLCKPZPfdd9cFF1ygl19+Wb/61a80f/78qleHbmgh2bZt96tYLDbypSXJ3cEAGstrx57X2gMEhdeOPa+1BwgKrx17XmsPEBReOva81BYgSLx27HmtPUBQeO3Y81p7gKDw0rF39tlnK51OKxKJ6I9//KPOP/987bfffjr00EN15ZVX6rvf/a6k/mLyJZdcUtVrHX744VqzZo2uuOIKzZo1qxbNdx133HF6/PHHdcstt1T1PA2fkQwAAAAAAAAAAAAAXvLwww/r/vvvlyR99rOf1X777TfoMcuXL9fcuXMlSZdddpny+fy4X2/ffffV9ttvP+7fr8QnPvGJqn6fQjIAAAAAAAAAAACAQPvNb37j/nvJkiVDPiYUCmnx4sWSpC1btmjlypWNaFrTUEgGAAAAAAAAAAAAEGirVq2SJKVSKe21117DPu7ggw92//3AAw/U7PXPOOMM3XPPPTV7vlqgkAwAAAAAAAAAAAAg0J599llJ0i677KJIJDLs43bbbbdBv1MLV111lQ499FDtuOOOOv/88/Xcc8/V7LnHa/itMIpisaiVK1fqgQce0LPPPqu1a9eqp6dH6XRayWRS7e3tmjVrlubOnasDDjhAhxxyiMLhcC3bDgAAAAAAAAAAACDANmzYoJkzZ476uGXLlmnZsmVD/iyTyeitt96SpFGfa9KkSUqlUurt7dXatWvH3uBhWJYlSXrttdf0ne98R9/5zne011576ZRT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qVOnDvscuVxOr7zyiizLGl+LAQAAAAAAAAAAAMDnotGozjvvvKa9/piWtl66dKluvPHGQffpMF+33nqr5s+frwceeKBe7QUAAAAAAAAAAAAA1FnFheQHHnhA1157rSzL0pw5c3T77berp6dHb7/9tm699VYtXLhQjuNo48aNOvzww3XHHXfUs91VYd11oDG8fqx5vX2AX3j9WPN6+wC/8Pqx5vX2AX7h5WPNy20D/MTrx5rX2wf4hdePNa+3D/ALjjXvq7iQ/LOf/UySNGPGDD344IM66qij1NbWpkmTJunYY4/V3/72N1188cWKRCJKp9P6xCc+oRtuuKFuDQcAAAAAAAAAAAAkcUtVoA7GNCPZsiwtX75ckydPHvRz87M//elPmjRpkgqFgk477TT9+Mc/rmmDAQAAAAAAAAAAAEkKhUJKJpNqb29XKpVSJBJpdpMA36i4kPz6669Lkvbbb78RH3fwwQfrvvvu0/bbby/btvX5z39e3/ve96prJQAAAAAAAAAAAPD/RCIRJZNJdXR0aJttttHEiRPV0dGhjo4OCspAjVRcSM7n85KkcDg86mN333133X///dppp53kOI7OO+88/fd///f4WwkAAAAAAAAAAIDAsyxLsVhMiURCbW1tSqVS7pf5/7a2NiWTSSUSCZa8BqpQcSF52rRpkqTXXnutosfvtNNOuv/++zV37lw5jqNvf/vbWr58+fhaCQAAAAAAAAAAgECzLEvRaFTxeFzxeFyJREKJRML9f1M8Nl/msRSTgfGpuJA8b948SdL9999f8ZNvv/32uu+++7TnnnvKcRz9z//8j84555wxN7KWli5d2tTXB4LGq8ecV9sF+JVXjzmvtgvwK68ec15tF+BXXjzmvNgmwM+8esx5tV2AX3n1mPNqu1BeRDYzkhOJhJLJpPtlisoUk1sHx5y3VVxIXrRokRzH0c033yzHcSp+gSlTpmjlypXaf//95TiO/vrXv46roQAAAAAAAAAAAAie0iJyaZE4mUy6M5GTyaTa2tooJgM1VHEh+aMf/agk6fXXX9dtt902phfp6OjQn/70Jx122GFjKkIDAAAAAAAAAAAguAYWkc1s5KGKyCMVk83y1xSTgcpFKn3gXnvtpUWLFmnDhg265ppr9MlPfnJML5RMJnXHHXfoxBNP1K9//esxNxQAAAAAAAAAAADBYVmW4vG4otHoiEXkZDKpSCSicDhc0fNms1kmPsLz8vm8Hn30UT311FN688039eabbyqTyWjy5MmaNm2aZs6cqf33318zZsyoWxsqLiRL0n333VfVi0WjUd16661VPQcAAAAAAAAAAACCJxQKDSoily5fXSwWK34uisnwonfeeUfXXnutfvvb3+rvf/+7MpnMqL+z44476pBDDtEJJ5ygww47TKFQxQtSj2pMhWQAAAAAAAAAAACgGcwS1aVFZPPveDyuQqHgPta27VGfj2IyvOLhhx/WZZddpttuu03ZbFZS/4z8SpZif/XVV3XVVVfpqquu0qxZs/T5z39eZ511ltrb26tuF4VkAAAAAAAAAAAAeFYoFBqxiJxMJhWLxZTP58f83BSTMZRXX31VP/jBD3TnnXdq7dq1isfj2nnnnXXCCSfo85//vNra2mryOi+88ILOP/983XbbbZL6i8fJZFILFy7UwoULtWDBAs2ZM0eTJk3S5MmTlUwmtXnzZm3evFmbNm3SY489pkceeUQPPfSQXnzxRa1bt05f+cpXdPHFF+vLX/6yzjnnHEWj0XG3r6GF5Pe85z3uvy3L0po1axr58gAAAAAAAAAAAGgx5t7Ipng8sIjc1tamaDSqWCwmSYOWuC6dnTzUTOVKlg9GcNx+++065ZRT1NXV5X6vr69Pjz76qB599FH99Kc/1Z133qlddtmlqte54YYbtGTJEhUKBUUiEX34wx/WySefrGOPPVapVGrY35syZYqmTJmiXXbZRfvvv7/7/WeeeUY33nijbrzxRr322ms677zzdOWVV+rFF18cdxsbWkh+5ZVXZFmWHMepaCo2AAAAAAAAAAAAgseyLMXjccXjcXc2cmkxubSI3NbWplgsVra09VjkcrmKlsKG/z322GP61Kc+pXQ6rfb2dv3Xf/2XDjnkEKXTaf3yl7/UihUr9MILL+ioo47So48+qgkTJoz7tdasWaNwOKwzzjhD//Vf/6VZs2ZV1fbdd99dF1xwgS644ALdcsst+va3v60nn3yyquds+NLWLA8AAAAAAAAAAACAkZgJiQNnIw9VRE4kEopGo4pEIhUXhEOhkPvvWCzGrGRIks4++2yl02lFIhH98Y9/1H777ef+7NBDD9Wuu+6qL3/5y3rhhRd0ySWX6Otf//q4X+vwww/XGWecoe23374GLS933HHH6bjjjnOXzB6v0OgPqR3btt2vgcsKNMLSpUsb/poAvHfsea09QFB47djzWnuAoPDasee19gBB4aVjz0ttAYLEa8ee19oDBIXXjj2vtSfILMtSLBYrm43c1tZWVkBub29XW1ubIpH+OZOO019/ikQibtG5ra1tyN8dOMM5Ho+XFZbRWF459h5++GHdf//9kqTPfvazZUVkY/ny5Zo7d64k6bLLLhvXfbmNfffdty5F5FKf+MQnqvp9jgoAAAAAAAAAAAB4ilnaurTYa2YgT5kyRR0dHe49kQuFgjKZbNnS1olEQqlUyi0mm+eJRqPu85n7KpsvBNtvfvMb999LliwZ8jGhUEiLFy+WJG3ZskUrV65sRNOahkIyAAAAAAAAAAAAPGNgEdnMKI7H40qlUu5s5VgsOuTvRyIRd0nsVCqlaHToxwGlVq1aJUlKpVLaa6+9hn3cwQcf7P77gQceqNnrn3HGGbrnnntq9ny1QCEZAAAAAAAAAAAAntFfJO4vFg91P+RQKCTHsVUoDH8b1VAo5BahS5fABobz7LPPSpJ22WWXEfvLbrvtNuh3auGqq67SoYceqh133FHnn3++nnvuuZo993hRSAYAAAAAAAAAAIAnWJalSCSiaDRatvR0NBp1C8xmhnHpUtYDmeeIxWLuvy3LatSfgRaTyWT01ltvSZJmzpw54mMnTZqkVColSVq7dm3N2mBZlizL0muvvabvfOc7mjdvnhYsWKDLLrtMb775Zs1eZyzGPfyiWCxq5cqVeuCBB/Tss89q7dq16unpUTqdVjKZVHt7u2bNmqW5c+fqgAMO0CGHHKJwOFzLtgMAAAAAAAAAAMBHHMeRbdsqFosqFovK5XIqFAoqFovK5/MqFAqKRCKybXvU5yr9/UKhIMdxGvAXoNE2bNgwavFXkpYtW6Zly5YN+bPu7m733+3t7aM+VyqVUm9vr3p6eipv6Cjuvfde3XrrrbrtttvcAvXq1au1evVqnXvuuTriiCN06qmn6uMf/7ji8XjNXnckYy4k9/b26pJLLtFll12mLVu2DPq54zjuiI6HHnrI/f7EiRN1zjnnaNmyZW6VHgAAAAAAAAAAACiVzWbLZiOn02n3nsl9fX2ybXvEpYcjkYhCIUuFQlGZTEZ9fX3K5/MN/AvQSLZta/369aM+rqura9ifZTIZ99+xWGzU5zKF3HQ6XUELK3PAAQfogAMO0KWXXqpHHnlEt9xyi26++Wa9+uqrKhaLuvPOO3XnnXeqo6NDxx13nE499dSy+zXXw5gKyWvWrNHHPvYxvfDCC4NGbaRSKaVSKcXjcWWzWfX29qq3t9f9+ebNm/X1r39dv/jFL3TnnXdqp512qs1fAAAAAAAAAAAAAN8oFovKZrPK5XLK5XLq6+tTPB53/ytJiURiyGJyJBJRJBKWbTvK5XLKZDIUkX0uFAqps7Nz1Md1dHQM+7NEIuH+O5fLjfpc2WxWkpRMJito4dgtWLBACxYs0F577aWTTjpJjuNo8uTJ2rx5s7q7u/Xzn/9cP//5zzV79mydfPLJWrx4cdm9m41isahnnnlG2WxW73vf+8bc3ooLyel0WkcddZRefPFFOY6juXPnavHixTr44IO12267aeLEiYN+Z8uWLXruued077336tprr9Wzzz6r5557TkcddZT+8Y9/lO0UAAAAAAAAAAAAQOpfATeTybizkhOJhJLJpPr6+tzHmGJyKBRSLBZ1v2/bjjsTOZfLVbQMNlpXZ2en1q1bV9VzTJgwwf13JctVm8m0lSyDXSsbN27U3XffrRtuuEG333670um01q5dq+985zv6zne+o7333lunnHKKTjrpJE2bNk133HGH/uM//kMbN26U1D8p+Otf/7qWL19e8WuGKn3g5ZdfrhdeeEGSdPHFF+vpp5/Weeedp3333XfIIrLUv5z1vvvuq/POO09PP/20LrroIknS888/r8svv7ziRgIAAAAAAAAAACAYHKd/NnE2m1Umk3GLwul0Wul0Wn19fert7VUmk1GhUFAoFJJlhf7fLOS8+/je3l7lcjnl8/3fG+rfZtZzJbNQ4V+JREJTpkyRpFGL0ps3b3YLybNmzap724xIJKKPfexj+sUvfqE33nhD11xzjY444ghFIhFZlqVHH31U55xzjmbMmKGPfOQjOu644+Q4ji666CJ99atflW3bOvfcc3XllVdW/JoVF5JvuukmWZalpUuXavny5e59kCtlWZbOPfdcLV26VI7j6KabbhrT79fCihUrGv6aALx37HmtPUBQeO3Y81p7gKDw2rHntfYAQeGlY89LbQGCxGvHntfaAwSF1449r7Un6BzHkeM4bjE5m80qnU4rk8mUFZP7+vrcn2cyGfX09Ojtt9/Wli1btHXrVr3zzjvavHmzurq6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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Plot a grid of reconstructed bands\n", - "ims, axs = vis.sliceview3d(smaband*msk[None,...], axis=0, ncol=7, vmin=-1, vmax=0,\n", - " colormap=custom_cmap, axisreturn='nested', numbered=False, figsize=(20, 20*5/7),\n", - " imkwds={'extent':[kx[0]+0.05, kx[-1]+0.05, ky[0]-0.02, ky[-1]-0.02]});\n", - "\n", - "# Annotate the plot-frames of good reconstructions\n", - "pairs = [[1, 4], [1, 5], [1, 6], [2, 0], [2, 1], [2, 2]]\n", - "for ri, ci in pairs:\n", - " [i.set_linewidth(4) for i in axs[ri, ci].spines.values()]\n", - " [i.set_color('#FFA500') for i in axs[ri, ci].spines.values()]\n", - "\n", - "# Annotate figures on the uppermost and bottommost rows\n", - "for j in range(7):\n", - " jj = j*2\n", - " axs[0, j].set_title('$\\eta$ = '+str(\"%1.2f\" %etas[jj])+' eV', fontsize=20, pad=10)\n", - " \n", - " axs[-1, j].get_xaxis().set_visible(True)\n", - " axs[-1, j].set_xticks(np.arange(-1.5, 1.6, 0.5))\n", - " axs[-1, j].set_xticklabels(['', '-1', '', '0', '', '1', ''])\n", - " axs[-1, j].tick_params(axis='x', length=8, width=2, labelsize=20)\n", - " axs[-1, j].set_xlabel('$k_x$ ($\\mathrm{\\AA}^{-1}$)', fontsize=20)\n", - "\n", - "# Annotate figures on leftmost and rightmost columns\n", - "for i in range(5):\n", - " ii = i+1\n", - " axs[i, 0].get_yaxis().set_visible(True)\n", - " axs[i, 0].set_yticks([])\n", - " axs[i, 0].set_ylabel('$\\Delta$E = '+str(\"%1.2f\" %shifts[ii])+' eV', fontsize=20, labelpad=5)\n", - " \n", - " axs[i, -1].get_yaxis().set_visible(True)\n", - " axs[i, -1].yaxis.set_label_position(\"right\")\n", - " axs[i, -1].yaxis.tick_right()\n", - " axs[i, -1].set_yticks(np.arange(-1.5, 1.6, 0.5))\n", - " axs[i, -1].set_yticklabels(['', '-1', '', '0', '', '1', ''])\n", - " axs[i, -1].tick_params(axis='y', length=8, width=2, labelsize=20)\n", - " axs[i, -1].set_ylabel('$k_y$ ($\\mathrm{\\AA}^{-1}$)', fontsize=20, rotation=-90, labelpad=25)\n", - "\n", - "plt.subplots_adjust(\n", - " left=0.05,\n", - " right=0.95,\n", - " bottom=0.05,\n", - " top=0.95,\n", - " wspace=0.05,\n", - " hspace=0.05)\n", - "\n", - "plt.savefig(r'../results/figures/sfig_4a.png', transparent=False, bbox_inches='tight', dpi=300)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot the colorbar\n", - "fig = plt.figure(figsize=(8, 3))\n", - "ax = fig.add_axes([0.05, 0.80, 0.04, 0.5])\n", - "norm = mpl.colors.Normalize(vmin=-1, vmax=0)\n", - "cb = mpl.colorbar.ColorbarBase(ax, cmap=custom_cmap,\n", - " norm=norm, ticks=[-1, 0],\n", - " orientation='vertical')\n", - "# cb.ax.set_yticks([-1, 0])\n", - "cb.ax.set_yticklabels(['low', 'high'], fontsize=20)\n", - "cb.ax.set_ylabel('E (eV)', fontsize=20, rotation=-90, labelpad=-10)\n", - "cb.ax.tick_params(axis='y', length=0, pad=5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Energy coordinates\n", - "elo, ehi = (0.0, -8.252199)\n", - "eshift = 0.65 # global shift\n", - "elo += eshift\n", - "ehi += eshift\n", - "\n", - "# Extract high-symmetry lines from reconstructed bands\n", - "pth = np.load(r'../data/hyperparameter/tuning_SFig3/path_coords.npz')\n", - "# pth = np.load(r'../data/processed/hslines/WSe2_kpath.npz')\n", - "rowInds, colInds = pthr, pthc = pth['pathr'], pth['pathc']\n", - "bcuts = aly.bandpath_map(smaband, pathr=rowInds, pathc=colInds, eaxis=0)\n", - "bcuts = bcuts.reshape((5, 7, 186))\n", - "\n", - "# Photoemission data cut along high-symmetry lines\n", - "vcut = np.load(r'../data/processed/hslines/WSe2_vcut.npy')\n", - "\n", - "# Load LDA-DFT band structure calculation along high-symmetry lines\n", - "bandlines = sio.loadmat(r'../data/theory/hslines/WSe2_bandlines_LDA_186.mat')['lines']\n", - "bandlines.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 4b" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot a grid of photoemission data cuts along high symmetry lines\n", - "ims, axs = vis.sliceview3d(np.tile(vcut[::-1,:], (35, 1, 1)), axis=0, ncol=7, imkwds={'extent':[0, 185, ehi, elo]},\n", - " colormap='Blues', axisreturn='nested', numbered=False, figsize=(20, 10));\n", - "\n", - "# Annotate the plot-frames of good reconstructions\n", - "shifts_small = np.arange(0.10, 0.31, 0.05)\n", - "pairs = [[1, 4], [1, 5], [1, 6], [2, 0], [2, 1], [2, 2]]\n", - "pairs = [[1, 4], [1, 5], [1, 6], [2, 0], [2, 1], [2, 2]]\n", - "for ri, ci in pairs:\n", - " [i.set_linewidth(4) for i in axs[ri, ci].spines.values()]\n", - " [i.set_color('#FFA500') for i in axs[ri, ci].spines.values()]\n", - "\n", - "# Plot reconstructions and initializations\n", - "pos = np.array([ 0, 69, 107, 185]) # High-symmetry point locations\n", - "for j in range(7):\n", - " for i in range(5):\n", - " axs[i, j].plot(bcuts[i, j, :] + 0.65, '-', c='r', lw=1, zorder=2) # Plot reconstruction\n", - " axs[i, j].plot(bandlines[:, 1] + 0.65 + 0.02*i, '-', c='#00FF00', lw=1, zorder=1) # Plot initialization\n", - " \n", - " # Annotate high symmetry positions\n", - " for p in pos[:-1]:\n", - " axs[i, j].axvline(x=p, c='k', ls='--', lw=2, dashes=[4, 3])\n", - "\n", - "# Annotate figures on the uppermost and bottommost rows\n", - "for j in range(7):\n", - " jj = j*2\n", - " axs[0, j].set_title('$\\eta$ = '+str(\"%1.2f\" %etas[jj])+' eV', fontsize=20, pad=10)\n", - " \n", - " axs[-1, j].get_xaxis().set_visible(True)\n", - " axs[-1, j].tick_params(axis='both', length=8, width=2, labelsize=15)\n", - " axs[-1, j].set_ylim([ehi, elo])\n", - " axs[-1, j].set_xticks(pos)\n", - " axs[-1, j].set_xticklabels(['$\\overline{\\Gamma}$', '$\\overline{\\mathrm{M}}$',\n", - " '$\\overline{\\mathrm{K}}$', '$\\overline{\\Gamma}$'])\n", - "\n", - "# Annotate figures on leftmost and rightmost columns\n", - "for i in range(5):\n", - " ii = 1 + i*2\n", - " axs[i, 0].get_yaxis().set_visible(True)\n", - " axs[i, 0].set_yticks([])\n", - " axs[i, 0].set_ylabel('$\\Delta$E = '+str(\"%1.2f\" %shifts[i])+' eV', fontsize=20, labelpad=5)\n", - " \n", - " axs[i, -1].get_yaxis().set_visible(True)\n", - " axs[i, -1].set_yticks(np.arange(-7, 0.1))\n", - " axs[i, -1].set_yticklabels(['', '-6', '', '-4', '', '-2', '', '0'])\n", - " axs[i, -1].set_ylabel('E (eV)', fontsize=20, rotation=-90, labelpad=20)\n", - " axs[i, -1].yaxis.set_label_position(\"right\")\n", - " axs[i, -1].yaxis.tick_right()\n", - " axs[i, -1].tick_params(axis='y', length=8, width=2, labelsize=20)\n", - "\n", - "plt.subplots_adjust(\n", - " left=0.05,\n", - " right=0.95,\n", - " bottom=0.05,\n", - " top=0.95,\n", - " wspace=0.05,\n", - " hspace=0.08)\n", - "\n", - "plt.savefig(r'../results/figures/sfig_4b.png', transparent=True, bbox_inches='tight', pad_inches=0.05, dpi=300)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot the figure legend\n", - "fig, ax = plt.subplots(figsize=(8, 3))\n", - "ax.imshow(vcut, cmap='Blues', extent=[0, 185, ehi, elo], aspect=12)\n", - "ax.tick_params(axis='both', length=0)\n", - "ax.set_xticklabels([])\n", - "ax.set_yticklabels([])\n", - "ax.plot(bandlines[:, 1] + 0.65 + 0.05*i, '-', c='#00FF00', lw=1, zorder=1, label='Initialization')\n", - "ax.plot(bcuts[i, j, :] + 0.65, '-', c='r', lw=1, zorder=2, label='Reconstruction')\n", - "ax.legend(loc=9, fontsize=15, frameon=True, bbox_to_anchor=(1.2, 0.2), facecolor='#C0C0C0')" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/SFig6_Tests_on_synthetic_2D_data-checkpoint.ipynb b/figures/.ipynb_checkpoints/SFig6_Tests_on_synthetic_2D_data-checkpoint.ipynb deleted file mode 100644 index 1715d34..0000000 --- a/figures/.ipynb_checkpoints/SFig6_Tests_on_synthetic_2D_data-checkpoint.ipynb +++ /dev/null @@ -1,330 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Tests of the Markov random field model for reconstructing 2D synthetic data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import numpy as np\n", - "import fuller\n", - "import matplotlib.pyplot as plt\n", - "from mpes import analysis as aly\n", - "import matplotlib as mpl\n", - "import matplotlib.gridspec as gridspec\n", - "import os\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams['font.family'] = 'sans-serif'\n", - "mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2D single sinosodial band" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Data generation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate synthetic data\n", - "kx = np.arange(-1, 1, 0.01)\n", - "band_sin2d = 3*np.sin(13*kx) + 2*np.cos(12*kx) - 4\n", - "b2d_min, b2d_max = band_sin2d.min(), band_sin2d.max()\n", - "# plt.plot(kx, band_sin2d)\n", - "\n", - "Evals = np.arange(b2d_min-2, b2d_max+2, 0.01)\n", - "pes_data_2d = aly.voigt(feval=True, vardict={'amp':1, 'xvar':Evals[:,None],\n", - " 'ctr':band_sin2d, 'sig':1, 'gam':0.3})\n", - "plt.imshow(pes_data_2d[::-1,:], aspect=0.1, extent=[-1, 1, b2d_min-2, b2d_max+2], cmap='Blues')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Construct initialization\n", - "init = np.zeros_like(kx)\n", - "plt.plot(kx, band_sin2d, c='r', label='ground truth')\n", - "plt.plot(kx, init, c='b', label='initialization')\n", - "plt.legend(loc='lower left', fontsize=12)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Reconstruction" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "I = np.transpose(pes_data_2d)\n", - "I = I / I.max()\n", - "mrf = fuller.mrfRec.MrfRec(E=Evals, kx=kx, ky=np.array([0.]), I=np.reshape(I, (len(kx), 1, len(Evals))),\n", - " eta=1, E0=init[:, None])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mrf.iter_seq(200)\n", - "recon = mrf.getEb()[:, 0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 5a" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Summary plot\n", - "gs = gridspec.GridSpec(1, 2, width_ratios=[5,5])\n", - "fig = plt.figure()\n", - "axs = []\n", - "for i in range(2):\n", - " axs.append(fig.add_subplot(gs[i]))\n", - " \n", - "im = axs[0].imshow(pes_data_2d[::-1,:], aspect=0.15, extent=[-1, 1, b2d_min-2, b2d_max+2], cmap='Blues')\n", - "axs[0].plot(kx, band_sin2d, 'r')\n", - "axs[0].set_aspect(aspect=0.15)\n", - "axs[0].set_ylabel('Energy (a.u.)', fontsize=15)\n", - "cax = fig.add_axes([0.94, 0.54, 0.03, 0.2])\n", - "cb = fig.colorbar(im, cax=cax, orientation='vertical', ticks=[])\n", - "cb.ax.set_ylabel('Intensity', fontsize=15, rotation=-90, labelpad=18)\n", - "\n", - "axs[1].plot(kx, band_sin2d, 'r', label='ground truth')\n", - "axs[1].plot(kx, init, 'b', label='initialization')\n", - "axs[1].plot(kx, recon, 'g', label='reconstruction')\n", - "axs[1].set_xlim([-1, 1])\n", - "axs[1].set_ylim([b2d_min-2, b2d_max+2])\n", - "axs[1].set_aspect(aspect=0.15)\n", - "axs[1].set_yticks([])\n", - "lg = axs[1].legend(fontsize=15, bbox_to_anchor=(1.04,0.5), frameon=False,\n", - " borderpad=0, labelspacing=0.8, handlelength=1.2, handletextpad=0.5)\n", - "\n", - "for i in range(2):\n", - " axs[i].set_xlabel('$k$ (a.u.)', fontsize=15)\n", - " axs[i].tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "\n", - "plt.subplots_adjust(wspace=0.1)\n", - "plt.savefig('../results/figures/sfig_6a.png', dpi=300, bbox_inches='tight', transparent=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2D band crossing" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Data generation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate synthetic data\n", - "kx = np.arange(-1, 1, 0.014)\n", - "band_pb2d_up = 5*kx**2 - kx/5 - 5\n", - "band_pb2d_down = -(0.2*kx**2 + kx/4 + 2.5)\n", - "plt.figure(figsize=(5,4))\n", - "b2d_min, b2d_max = band_pb2d_down.min(), band_pb2d_up.max()\n", - "# plt.plot(kx, band_pb2d_up)\n", - "# plt.plot(kx, band_pb2d_down)\n", - "\n", - "Evals = np.arange(b2d_min-4, b2d_max+2, 0.012)\n", - "pes_data_2d_up = aly.voigt(feval=True, vardict={'amp':1.6, 'xvar':Evals[:,None],\n", - " 'ctr':band_pb2d_up, 'sig':0.07, 'gam':0.15})\n", - "pes_data_2d_down = aly.voigt(feval=True, vardict={'amp':1, 'xvar':Evals[:,None],\n", - " 'ctr':band_pb2d_down, 'sig':0.07, 'gam':0.1})\n", - "pes_data_2d = pes_data_2d_up + pes_data_2d_down\n", - "plt.imshow(pes_data_2d[::-1,:], aspect=0.2, extent=[-1, 1, b2d_min-4, b2d_max+2], cmap='Blues')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Construct initialization\n", - "band_init2d_up = 3.5 * kx ** 2 - kx / 20 - 4\n", - "band_init2d_down = -3 * np.ones_like(kx)\n", - "\n", - "plt.plot(kx, band_pb2d_up, c='r')\n", - "plt.plot(kx, band_pb2d_down, c='r', label='ground truth')\n", - "plt.plot(kx, band_init2d_up, c='b')\n", - "plt.plot(kx, band_init2d_down, c='b', label='initialization')\n", - "plt.legend(loc='upper center', fontsize=12)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Reconstruction" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Reconstruct first band\n", - "I = np.transpose(pes_data_2d)\n", - "I = I / I.max()\n", - "mrf = fuller.mrfRec.MrfRec(E=Evals, kx=kx, ky=np.array([0.]), I=np.reshape(I, (len(kx), 1, len(Evals))),\n", - " eta=0.085, E0=band_init2d_down[:, None])\n", - "mrf.iter_seq(500)\n", - "recon_down = mrf.getEb()[:, 0]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Reconstruct second band\n", - "mrf = fuller.mrfRec.MrfRec(E=Evals, kx=kx, ky=np.array([0.]), I=np.reshape(I, (len(kx), 1, len(Evals))),\n", - " eta=0.2, E0=band_init2d_up[:, None])\n", - "mrf.iter_seq(500)\n", - "recon_up = mrf.getEb()[:, 0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 6b" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Summary plot\n", - "emin, emax = Evals.min(), Evals.max()\n", - "\n", - "gs = gridspec.GridSpec(1, 2, width_ratios=[8,8])\n", - "fig = plt.figure()\n", - "axs = []\n", - "for i in range(2):\n", - " axs.append(fig.add_subplot(gs[i]))\n", - " \n", - "im = axs[0].imshow(pes_data_2d, aspect=0.2, extent=[-1, 1, emin, emax], cmap='Blues', origin='lower', vmax=2)\n", - "axs[0].plot(kx, band_pb2d_up, 'r')\n", - "axs[0].plot(kx, band_pb2d_down, 'r')\n", - "axs[0].set_aspect(aspect=0.2)\n", - "axs[0].set_ylabel('Energy (a.u.)', fontsize=15)\n", - "cax = fig.add_axes([0.94, 0.54, 0.03, 0.2])\n", - "cb = fig.colorbar(im, cax=cax, orientation='vertical', ticks=[])\n", - "cb.ax.set_ylabel('Intensity', fontsize=15, rotation=-90, labelpad=18)\n", - "\n", - "axs[1].plot(kx, band_pb2d_up, 'r')\n", - "axs[1].plot(kx, band_pb2d_down, 'r', label='ground truth')\n", - "axs[1].plot(kx, band_init2d_up, 'b')\n", - "axs[1].plot(kx, band_init2d_down, 'b', label='initialization')\n", - "axs[1].plot(kx, recon_up, 'g')\n", - "axs[1].plot(kx, recon_down, 'g', label='reconstruction')\n", - "axs[1].set_xlim([-1, 1])\n", - "axs[1].set_ylim([emin, emax])\n", - "axs[1].set_aspect(aspect=0.2)\n", - "axs[1].set_yticks([])\n", - "lg = axs[1].legend(fontsize=15, bbox_to_anchor=(1.04,0.5), frameon=False,\n", - " borderpad=0, labelspacing=0.8, handlelength=1.2, handletextpad=0.5)\n", - "\n", - "for i in range(2):\n", - " axs[i].set_xlabel('$k$ (a.u.)', fontsize=15)\n", - " axs[i].tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "\n", - "plt.subplots_adjust(wspace=0.1)\n", - "plt.savefig('../results/figures/sfig_6b.png', dpi=300, bbox_inches='tight', transparent=True)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/SFig6_Tests_on_synthetic_3D_data-checkpoint.ipynb b/figures/.ipynb_checkpoints/SFig6_Tests_on_synthetic_3D_data-checkpoint.ipynb deleted file mode 100644 index 37686f8..0000000 --- a/figures/.ipynb_checkpoints/SFig6_Tests_on_synthetic_3D_data-checkpoint.ipynb +++ /dev/null @@ -1,437 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Tests of the Markov random field model for reconstructing 3D synthetic data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import numpy as np\n", - "import fuller\n", - "import matplotlib.pyplot as plt\n", - "from mpes import analysis as aly\n", - "import matplotlib as mpl\n", - "import matplotlib.gridspec as gridspec\n", - "from mpl_toolkits.mplot3d import Axes3D\n", - "import matplotlib.tri as mtri\n", - "import tifffile as ti\n", - "from scipy import io\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams['font.family'] = 'sans-serif'\n", - "mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42\n", - "\n", - "colornames = ['#646464', '#666666', '#6a6a6a', '#6f6f6f', '#737373', '#787878', '#7d7d7d', '#828282', '#878787', '#8d8d8d', '#929292', '#989898', '#9e9e9e', '#a4a4a4', '#aaaaaa', '#b0b0b0', '#b6b6b6', '#bcbcbc', '#c2c2c2', '#c9c9c9', '#cfcfcf', '#d6d6d6', '#dcdcdc', '#e3e3e3', '#eaeaea', '#efefee', '#efeee5', '#efeddc', '#efecd3', '#eeebca', '#eeeac0', '#eee9b7', '#eee8ad', '#ede7a4', '#ede69a', '#ede590', '#ede487', '#ece37d', '#ece273', '#ece069', '#ecdf5f', '#ebde55', '#ebdd4b', '#ebdc41', '#ebdb37', '#ebd333', '#ebc933', '#ecbe32', '#ecb432', '#eda931', '#ee9e31', '#ee9330', '#ef8830', '#ef7d2f', '#f0722f', '#f0672e', '#f15c2e', '#f2512d', '#f2462d', '#f33b2c', '#f3302c', '#f4252b', '#f4192b', '#ef182f', '#e81834', '#e21939', '#db1a3e', '#d51a43', '#ce1b48', '#c71b4d', '#c11c52', '#ba1c58', '#b31d5d', '#ac1d62', '#a61e67', '#9f1e6c', '#981f72', '#911f77', '#8a207c', '#842182']\n", - "custom_cmap = mpl.colors.LinearSegmentedColormap.from_list('custom', colornames, N=256)\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3D single band: Second-order Griewank function" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Data generation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "kx = np.arange(-6, 6, 0.04)\n", - "ky = np.arange(-6, 6, 0.04)\n", - "kyy, kxx = np.meshgrid(kx, ky)\n", - "\n", - "band_griewank = 1/4000*sum((kxx/2)**2 + (kyy/2)**2) - np.cos(2*kxx)*np.cos(2*(np.sqrt(2)/2)*kyy) - 1.5\n", - "b3d_min, b3d_max = band_griewank.min(), band_griewank.max()\n", - "\n", - "Evals = np.linspace(b3d_min-2, b3d_max+2, 400)\n", - "pes_data_3d = aly.voigt(feval=True, vardict={'amp':1, 'xvar':Evals[:, None, None],\n", - " 'ctr':band_griewank, 'sig':1, 'gam':0.3})\n", - "\n", - "plt.imshow(pes_data_3d[:, :, 150], cmap='Blues')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Reconstruction" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Create model\n", - "I = np.transpose(pes_data_3d, (1, 2, 0))\n", - "I = I / I.max()\n", - "E0 = np.zeros_like(band_griewank)\n", - "\n", - "mrf = fuller.mrfRec.MrfRec(E=Evals, kx=kx, ky=ky, I=I, E0=E0, eta=1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Perform reconstruction\n", - "mrf.iter_para(200)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 5d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Summary plot\n", - "\n", - "recon3d = mrf.getEb()\n", - "\n", - "gs = gridspec.GridSpec(1, 3, width_ratios=[5,5,5])\n", - "fig = plt.figure(figsize=(10, 4))\n", - "axs = []\n", - "for i in range(3):\n", - " axs.append(fig.add_subplot(gs[i]))\n", - " \n", - "im = axs[0].imshow(band_griewank, aspect=1, extent=[-6, 6, -6, 6], vmin=-2.2, vmax=0, cmap=custom_cmap)\n", - "axs[0].set_yticks(range(-6, 7, 2))\n", - "axs[0].set_ylabel('$k_y$ (a.u.)', fontsize=15)\n", - "axs[0].set_title('Ground truth', fontsize=15)\n", - "cax = fig.add_axes([0.93, 0.2, 0.02, 0.2])\n", - "cb = fig.colorbar(im, cax=cax, orientation='vertical', ticks=np.arange(-2, 0.1, 1))\n", - "cb.ax.set_title('Energy\\n(a.u.)', fontsize=15, pad=10)\n", - "cb.ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "\n", - "axs[1].imshow(E0, cmap=custom_cmap, extent=[-6, 6, -6, 6], vmin=-2.2, vmax=0)\n", - "axs[1].set_title('Initialization', fontsize=15)\n", - "axs[1].tick_params(axis='y', length=0)\n", - "axs[1].set_yticks([])\n", - "\n", - "axs[2].imshow(recon3d, aspect=1, extent=[-6, 6, -6, 6], vmin=-2.2, vmax=0, cmap=custom_cmap)\n", - "axs[2].set_yticks([])\n", - "axs[2].set_title('Reconstruction', fontsize=15)\n", - "\n", - "for i in [0,1,2]:\n", - " axs[i].set_xticks(range(-6, 7, 2))\n", - " axs[i].set_xlabel('$k_x$ (a.u.)', fontsize=15)\n", - " axs[i].tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "\n", - "plt.subplots_adjust(wspace=0.15)\n", - "plt.savefig('../results/figures/sfig_6d1.png', dpi=300, bbox_inches='tight', transparent=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f, ax = plt.subplots(figsize=(4, 3))\n", - "im = ax.imshow(recon3d - band_griewank, cmap='RdBu_r', vmax=0.1, vmin=-0.1, extent=[-6, 6, -6, 6])\n", - "ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "ax.set_xticks(range(-6, 7, 2))\n", - "ax.set_xlabel('$k_x$ (a.u.)', fontsize=15)\n", - "ax.set_yticks(range(-6, 7, 2))\n", - "ax.set_ylabel('$k_y$ (a.u.)', fontsize=15, rotation=-90, labelpad=20)\n", - "ax.yaxis.set_label_position(\"right\")\n", - "ax.yaxis.tick_right()\n", - "ax.set_title('Difference', fontsize=15)\n", - "cax = f.add_axes([-0.02, 0.53, 0.05, 0.25])\n", - "cb = plt.colorbar(im, cax=cax, orientation='vertical')\n", - "cb.ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "cb.ax.set_title('Energy\\n(a.u.)', fontsize=15, pad=10)\n", - "plt.savefig('../results/figures/sfig_6d2.png', dpi=300, bbox_inches='tight', transparent=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3D band near-crossing: graphene band struction nearby Fermi level" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Data generation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "kx = np.arange(-1, 1, 0.01)\n", - "ky = np.arange(-1, 1, 0.01)\n", - "kyy, kxx = np.meshgrid(kx, ky)\n", - "\n", - "sq3 = np.sqrt(3)\n", - "t, a = 1, 2*np.pi / (sq3)\n", - "band_graphene = 1 + 4 * (np.cos(sq3 * kyy * a / 2) ** 2) + 4 * np.cos(sq3 * kyy * a / 2) * np.cos(3 * kxx * a / 2)\n", - "band_graphene[band_graphene < 0] = 1.e-10\n", - "band_graphene_upper = t*np.sqrt(band_graphene)\n", - "band_graphene_lower = - t*np.sqrt(band_graphene)\n", - "b3d_max, b3d_min = band_graphene_upper.max(), band_graphene_lower.min()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f = plt.figure(figsize=(6, 5))\n", - "ax = f.add_subplot(111, projection='3d')\n", - "\n", - "tri = mtri.Triangulation(kyy.flatten(), kxx.flatten())\n", - "ax.plot_trisurf(kxx.flatten(), kyy.flatten(), band_graphene_upper.flatten(),\n", - " triangles=tri.triangles, cmap=custom_cmap, antialiased=False)\n", - "ax.plot_trisurf(kxx.flatten(), kyy.flatten(), band_graphene_lower.flatten(),\n", - " triangles=tri.triangles, cmap=custom_cmap, antialiased=False)\n", - "\n", - "ax.set_xlabel('$k_x$', labelpad=15)\n", - "ax.set_ylabel('$k_y$', labelpad=15)\n", - "ax.set_zlabel('Energy', labelpad=15);" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Evals = np.linspace(b3d_min-2, b3d_max+2, 400)\n", - "pes_data_3d_upper = aly.voigt(feval=True, vardict={'amp':1, 'xvar':Evals[:, None, None],\n", - " 'ctr':band_graphene_upper, 'sig':0.2, 'gam':0.3})\n", - "pes_data_3d_lower = aly.voigt(feval=True, vardict={'amp':1, 'xvar':Evals[:, None, None],\n", - " 'ctr':band_graphene_lower, 'sig':0.2, 'gam':0.3})\n", - "pes_data_3d = pes_data_3d_upper + pes_data_3d_lower\n", - "\n", - "plt.imshow(pes_data_3d[:, 90, :], aspect=0.15, extent=[-1, 1, b3d_min-2, b3d_max+2], cmap='Blues')\n", - "plt.xlabel('$k_x$', fontsize=15)\n", - "plt.ylabel('Energy', fontsize=15)\n", - "plt.tick_params(axis='both', length=8, width=2, labelsize=15)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Reconstruction" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "I = np.transpose(pes_data_3d, (1, 2, 0))\n", - "I = I / I.max()\n", - "\n", - "results = np.zeros((2,) + band_graphene.shape)\n", - "E0 = np.ones((2,) + band_graphene.shape) * 4\n", - "E0[1, :, :] *= -1\n", - "\n", - "for i in range(2):\n", - " mrf = fuller.mrfRec.MrfRec(E=Evals, kx=kx, ky=ky, I=I, E0=E0[i,...], eta=0.3)\n", - " mrf.iter_para(200)\n", - " results[i,...] = mrf.getEb()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 5f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Summary plot\n", - "recon3d_upper = results[0,...]\n", - "recon3d_lower = results[1,...]\n", - "\n", - "init_upper = E0[0,...]\n", - "init_lower = E0[1,...]\n", - "\n", - "gs = gridspec.GridSpec(2, 3)\n", - "fig = plt.figure(figsize=(9.8, 6.5))\n", - "axs = []\n", - "for i in range(6):\n", - " axs.append(fig.add_subplot(gs[i]))\n", - " \n", - "axs[0].imshow(band_graphene_upper, aspect=1, extent=[-1, 1, -1, 1], vmin=0, vmax=3, cmap=custom_cmap)\n", - "axs[0].set_yticks(np.arange(-1, 1.1, 0.5))\n", - "axs[0].set_ylabel('$k_y$ $(\\mathrm{\\AA^{-1}})$', fontsize=15)\n", - "axs[0].set_title('Ground truth', fontsize=15)\n", - "axs[0].tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "axs[0].text(0.15, 0.9, 'Conduction Band', fontsize=15, transform=axs[0].transAxes)\n", - "\n", - "axs[1].imshow(init_upper, cmap=custom_cmap, aspect=1, extent=[-1, 1, -1, 1], vmin=0, vmax=3)\n", - "axs[1].set_title('Initialization', fontsize=15)\n", - "axs[1].tick_params(axis='y', length=0)\n", - "axs[1].set_yticks([])\n", - "\n", - "imu = axs[2].imshow(recon3d_upper, aspect=1, extent=[-1, 1, -1, 1], vmin=0, vmax=3, cmap=custom_cmap)\n", - "axs[2].set_yticks([])\n", - "axs[2].set_title('Reconstruction', fontsize=15)\n", - "axs[2].yaxis.set_label_position(\"right\")\n", - "\n", - "# Upper band colorbar\n", - "caxu = fig.add_axes([0.94, 0.5, 0.02, 0.12])\n", - "cbu = fig.colorbar(imu, cax=caxu, orientation='vertical', ticks=np.arange(0, 3.1, 1))\n", - "cbu.ax.set_title('Energy\\n(eV)', fontsize=15, pad=10)\n", - "cbu.ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "\n", - "iml = axs[3].imshow(band_graphene_lower, aspect=1, extent=[-1, 1, -1, 1], vmin=-3, vmax=0, cmap=custom_cmap)\n", - "axs[3].set_yticks(np.arange(-1, 1.1, 0.5))\n", - "axs[3].set_ylabel('$k_y$ $(\\mathrm{\\AA^{-1}})$', fontsize=15)\n", - "axs[3].text(0.3, 0.9, 'Valence Band', fontsize=15, transform=axs[3].transAxes)\n", - "\n", - "axs[4].imshow(init_lower, cmap=custom_cmap, aspect=1, extent=[-1, 1, -1, 1], vmin=-3, vmax=0)\n", - "axs[4].tick_params(axis='y', length=0)\n", - "axs[4].set_yticks([])\n", - "\n", - "axs[5].imshow(recon3d_lower, aspect=1, extent=[-1, 1, -1, 1], vmin=-3, vmax=0, cmap=custom_cmap)\n", - "axs[5].set_yticks([])\n", - "axs[5].yaxis.set_label_position(\"right\")\n", - "\n", - "# Lower band colorbar\n", - "caxl = fig.add_axes([0.94, 0.03, 0.02, 0.12])\n", - "cbl = fig.colorbar(iml, cax=caxl, orientation='vertical', ticks=np.arange(-3, 0.1, 1))\n", - "cbl.ax.set_title('Energy\\n(eV)', fontsize=15, pad=10)\n", - "cbl.ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "\n", - "for i in [0, 1, 2]:\n", - " axs[i].set_xticks([])\n", - " \n", - "for i in [3, 4, 5]:\n", - " axs[i].set_xticks(np.arange(-1, 1.1, 0.5))\n", - " axs[i].set_xlabel('$k_x$ $(\\mathrm{\\AA^{-1}})$', fontsize=15)\n", - " axs[i].tick_params(axis='both', length=8, width=2, labelsize=15)\n", - " \n", - "plt.subplots_adjust(hspace=0.18, wspace=0.1)\n", - "plt.savefig('../results/figures/sfig_6f1.png', dpi=300, bbox_inches='tight', transparent=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f, ax = plt.subplots(figsize=(4, 3))\n", - "im = ax.imshow(recon3d_upper - band_graphene_upper, cmap='RdBu_r', vmax=0.1, vmin=-0.1, extent=[-1, 1, -1, 1])\n", - "ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "ax.set_xticks(np.arange(-1, 1.1, 0.5))\n", - "ax.set_xlabel('$k_x$ $(\\mathrm{\\AA^{-1}})$', fontsize=15)\n", - "ax.set_yticks(np.arange(-1, 1.1, 0.5))\n", - "ax.set_ylabel('$k_y$ $(\\mathrm{\\AA^{-1}})$', fontsize=15, rotation=-90, labelpad=20)\n", - "ax.yaxis.set_label_position(\"right\")\n", - "ax.yaxis.tick_right()\n", - "ax.set_title('Difference', fontsize=15)\n", - "cax = f.add_axes([-0.02, 0.53, 0.05, 0.25])\n", - "cb = plt.colorbar(im, cax=cax, orientation='vertical')\n", - "cb.ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "cb.ax.set_title('Energy\\n(eV)', fontsize=15, pad=10)\n", - "plt.savefig('../results/figures/sfig_6f2.png', dpi=300, bbox_inches='tight', transparent=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f, ax = plt.subplots(figsize=(4, 3))\n", - "im = ax.imshow(recon3d_lower - band_graphene_lower, cmap='RdBu_r', vmax=0.1, vmin=-0.1, extent=[-1, 1, -1, 1])\n", - "ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "ax.set_xticks(np.arange(-1, 1.1, 0.5))\n", - "ax.set_xlabel('$k_x$ $(\\mathrm{\\AA^{-1}})$', fontsize=15)\n", - "ax.set_yticks(np.arange(-1, 1.1, 0.5))\n", - "ax.set_ylabel('$k_y$ $(\\mathrm{\\AA^{-1}})$', fontsize=15, rotation=-90, labelpad=20)\n", - "ax.yaxis.set_label_position(\"right\")\n", - "ax.yaxis.tick_right()\n", - "ax.set_title('Difference', fontsize=15)\n", - "cax = f.add_axes([-0.02, 0.53, 0.05, 0.25])\n", - "cb = plt.colorbar(im, cax=cax, orientation='vertical')\n", - "cb.ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "cb.ax.set_title('Energy\\n(eV)', fontsize=15, pad=10)\n", - "plt.savefig('../results/figures/sfig_6f3.png', dpi=300, bbox_inches='tight', transparent=True)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/SFig9_Reconstruction_with_different_theories-checkpoint.ipynb b/figures/.ipynb_checkpoints/SFig9_Reconstruction_with_different_theories-checkpoint.ipynb deleted file mode 100644 index afb466e..0000000 --- a/figures/.ipynb_checkpoints/SFig9_Reconstruction_with_different_theories-checkpoint.ipynb +++ /dev/null @@ -1,428 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Reconstruction for synthetic data with different DFT band structures (PBE, PBEsol, HSE06) as initialization " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import os\n", - "import numpy as np\n", - "from numpy import nan_to_num as n2n\n", - "import fuller\n", - "from mpes import fprocessing as fp, analysis as aly\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib as mpl\n", - "from natsort import natsorted\n", - "import glob as g\n", - "from mpl_toolkits.axes_grid1 import make_axes_locatable\n", - "from mpl_toolkits.axes_grid1.inset_locator import inset_axes\n", - "from matplotlib.ticker import AutoMinorLocator\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams['font.family'] = 'sans-serif'\n", - "mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42\n", - "\n", - "colornames = ['#646464', '#666666', '#6a6a6a', '#6f6f6f', '#737373', '#787878', '#7d7d7d', '#828282', '#878787', '#8d8d8d', '#929292', '#989898', '#9e9e9e', '#a4a4a4', '#aaaaaa', '#b0b0b0', '#b6b6b6', '#bcbcbc', '#c2c2c2', '#c9c9c9', '#cfcfcf', '#d6d6d6', '#dcdcdc', '#e3e3e3', '#eaeaea', '#efefee', '#efeee5', '#efeddc', '#efecd3', '#eeebca', '#eeeac0', '#eee9b7', '#eee8ad', '#ede7a4', '#ede69a', '#ede590', '#ede487', '#ece37d', '#ece273', '#ece069', '#ecdf5f', '#ebde55', '#ebdd4b', '#ebdc41', '#ebdb37', '#ebd333', '#ebc933', '#ecbe32', '#ecb432', '#eda931', '#ee9e31', '#ee9330', '#ef8830', '#ef7d2f', '#f0722f', '#f0672e', '#f15c2e', '#f2512d', '#f2462d', '#f33b2c', '#f3302c', '#f4252b', '#f4192b', '#ef182f', '#e81834', '#e21939', '#db1a3e', '#d51a43', '#ce1b48', '#c71b4d', '#c11c52', '#ba1c58', '#b31d5d', '#ac1d62', '#a61e67', '#9f1e6c', '#981f72', '#911f77', '#8a207c', '#842182']\n", - "custom_cmap = mpl.colors.LinearSegmentedColormap.from_list('custom', colornames, N=256)\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Load synthetic data and ground truth band structure (gt)\n", - "data = fuller.utils.loadHDF(r'../data/synthetic/synth_data_WSe2_LDA_top8.h5')\n", - "gtbands = data['bands_padded']\n", - "kxvals, kyvals = data['kx'], data['ky']\n", - "msk = data['mask_tight']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 9e" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Load initializations\n", - "xcfs = ['pbe', 'pbesol', 'hse'] # Names of the exchange-correlation functionals (XCF) used in the DFT calculations\n", - "eshifts = {'pbe':0.33063, 'pbesol':0.49865, 'hse':0.10955} # Energy values to zero the band structure at K points\n", - "\n", - "inits = {}\n", - "for xc in xcfs:\n", - " inits[xc] = fuller.utils.loadHDF(r'../data/theory/bands_padded/wse2_'+xc+'_bands_padded.h5')['bands_padded'] + eshifts[xc]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate errors in initialization (einit) and reconstruction (erec)\n", - "reconbands, erec, einit = {}, {}, {}\n", - "nk = np.sum(~np.isnan(msk))\n", - "\n", - "for xc in xcfs:\n", - " \n", - " folderstr = xc + '_lda'\n", - " recons = {}\n", - " bandidx = list(range(0, 8))\n", - " \n", - " for istp, stp in enumerate(bandidx):\n", - " stepstr = str(istp).zfill(2)\n", - " files = fuller.utils.findFiles(r'../data/synthetic' + '//' + folderstr + r'/mrf_rec_band='+stepstr, fstring=r'*')\n", - " recon = []\n", - " recon.append(fuller.utils.loadH5Parts(files[0], ['bands/Eb'], outtype='vals'))\n", - " recons[stepstr] = np.squeeze(np.array(recon))\n", - "\n", - " brecons = [v for k, v in recons.items() if k != 'init']\n", - " brecons = np.asarray(brecons)\n", - " reconbands[xc] = brecons\n", - "\n", - " errinit, errrecon = [], []\n", - " for i in range(8):\n", - " ediff = (inits[xc][i,...] - gtbands[i,...])**2\n", - " ediffrec = (recons[str(i).zfill(2)] - gtbands[i,...])**2\n", - " ediff = fuller.utils.trim_2d_edge(ediff, edges=24)\n", - " ediffrec = fuller.utils.trim_2d_edge(ediffrec, edges=24)\n", - " errinit.append(np.sqrt(np.sum(n2n(msk*ediff) / nk)))\n", - " errrecon.append(np.sqrt(np.sum(n2n(msk*ediffrec) / nk)))\n", - "\n", - " einit[xc] = np.array(errinit)\n", - " erec[xc] = np.array(errrecon)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot comparison between reconstruction using different DFT theories\n", - "dt=0.12 # horizontal jitter amplitude in visualization (to separate overlapping points)\n", - "f, ax = plt.subplots(figsize=(7, 10))\n", - "for i in range(8):\n", - " ax.axvline(x=i+1, ls='--', lw=1, c='g', zorder=0)\n", - " \n", - " if i < 7:\n", - " ax.scatter(i+1, einit['pbe'][i]*1000, s=100, facecolors='b', edgecolors='b', lw=2, zorder=1)\n", - " ax.scatter(i+1-dt, erec['pbe'][i]*1000, s=100, facecolors='w', edgecolors='b', lw=2, zorder=1)\n", - "\n", - " ax.scatter(i+1, einit['pbesol'][i]*1000, s=100, facecolors='k', edgecolors='k', lw=2, zorder=1)\n", - " ax.scatter(i+1, erec['pbesol'][i]*1000, s=100, facecolors='w', edgecolors='k', lw=2, zorder=1)\n", - "\n", - " ax.scatter(i+1, einit['hse'][i]*1000, s=100, facecolors='m', edgecolors='m', lw=2, zorder=1)\n", - " ax.scatter(i+1+dt, erec['hse'][i]*1000, s=100, facecolors='w', edgecolors='m', lw=2, zorder=1)\n", - " \n", - " if i == 7:\n", - " ax.scatter(i+1, einit['pbe'][i]*1000, s=100, facecolors='b', edgecolors='b', lw=2, zorder=1, label='PBE calc.')\n", - " ax.scatter(i+1-dt, erec['pbe'][i]*1000, s=100, facecolors='w', edgecolors='b', lw=2, zorder=1, label='PBE recon.')\n", - "\n", - " ax.scatter(i+1, einit['pbesol'][i]*1000, s=100, facecolors='k', edgecolors='k', lw=2, zorder=1, label='PBEsol calc.')\n", - " ax.scatter(i+1, erec['pbesol'][i]*1000, s=100, facecolors='w', edgecolors='k', lw=2, zorder=1, label='PBEsol recon.')\n", - "\n", - " ax.scatter(i+1, einit['hse'][i]*1000, s=100, facecolors='m', edgecolors='m', lw=2, zorder=1, label='HSE06 calc.')\n", - " ax.scatter(i+1+dt, erec['hse'][i]*1000, s=100, facecolors='w', edgecolors='m', lw=2, zorder=1, label='HSE06 recon.')\n", - " \n", - "ax.set_ylabel('Average error $\\eta_{\\mathrm{avg}}$ wrt ground truth (meV)', fontsize=18)\n", - "ax.set_yticks(range(0, 551, 50))\n", - "ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "ax.set_xticks(range(1, 9))\n", - "ax.set_xlabel('Band index', fontsize=18)\n", - "# ax.set_ylim([0, 200])\n", - "ax.set_title('Reconstruction from other DFT calculations', fontsize=18)\n", - "lg = ax.legend(loc='best', bbox_to_anchor=(0.56, 0.42), bbox_transform=ax.transAxes, frameon=True, fontsize=15,\n", - " facecolor='w', labelspacing=0.2, handletextpad=0.3)\n", - "frame = lg.get_frame()\n", - "frame.set_facecolor('w')\n", - "frame.set_edgecolor('k')\n", - "frame.set_linewidth(2)\n", - "plt.savefig(r'../results/figures/sfig_9e.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 9g" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Using know positions (ways to obtain these see notebooks in /code/extra/)\n", - "G = np.array([127.0, 127.27828129766911])\n", - "K = np.array([ 23.83002655, 127. ])\n", - "M = np.array([ 49.38033047, 171.8133136 ])\n", - "\n", - "pathPoints = np.asarray([G, M, K, G])\n", - "nGM, nMK, nKG = 70, 39, 79\n", - "segPoints = [nGM, nMK, nKG]\n", - "rowInds, colInds, pathInds = aly.points2path(pathPoints[:,0], pathPoints[:,1], npoints=segPoints)\n", - "nSegPoints = len(rowInds)\n", - "\n", - "pdGT = aly.bandpath_map(np.moveaxis(gtbands, 0, 2), pathr=rowInds, pathc=colInds, eaxis=2)\n", - "pdInit = aly.bandpath_map(np.moveaxis(inits['pbe'], 0, 2), pathr=rowInds, pathc=colInds, eaxis=2)\n", - "pdMPES = aly.bandpath_map(np.moveaxis(data['mpes_padded'], 0, 2), pathr=rowInds, pathc=colInds, eaxis=2)\n", - "Emin, Emax = data['E'].min(), data['E'].max()\n", - "\n", - "# Symmetrize the reconstructed bands\n", - "symrecbands = []\n", - "for i in range(8):\n", - " symmed = fuller.generator.rotosymmetrize(reconbands['pbe'][i,...], (127.5, 127.5), rotsym=6)[0]\n", - " symrecbands.append(fuller.generator.refsym(symmed[None,...], op='nanmean', pbar=False)[0,...])\n", - "symrecbands = np.asarray(symrecbands)\n", - "pdRecon = aly.bandpath_map(np.moveaxis(symrecbands, 0, 2), pathr=rowInds, pathc=colInds, eaxis=2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot comparison between initialization, reconstruction and ground truth along high-symmetry lines\n", - "xaxis = np.array(range(rowInds.size))\n", - "pos = pathInds.copy()\n", - "pos[-1] -= 1\n", - "\n", - "f, ax = plt.subplots(figsize=(8.3, 6))\n", - "imax = ax.imshow(pdMPES, cmap='Blues', origin='lower', extent=[0, nSegPoints, Emin, Emax], aspect=22, vmax=7, zorder=0)\n", - "ax.plot(pdGT.T, c='k', zorder=2)\n", - "ax.plot(pdRecon.T, c='r', zorder=3)\n", - "ax.plot(pdInit.T - eshifts['pbe'], '--', c='g', zorder=1)\n", - "\n", - "ax.plot(xaxis, pdGT[-1, :], c='k', zorder=2, label='Ground truth (LDA)')\n", - "ax.plot(xaxis, pdInit[-1, :] - eshifts['pbe'], '--', c='g', zorder=1, label='Initial. (PBE)')\n", - "ax.plot(xaxis, pdRecon[-1, :], c='r', zorder=3, label='Reconstruction')\n", - "\n", - "ax.tick_params(which='both', axis='y', length=8, width=2, labelsize=15)\n", - "ax.tick_params(axis='x', length=0, width=0, labelsize=15, pad=8)\n", - "ax.set_xlim([pos[0], pos[-1]])\n", - "ax.set_xticks(pos)\n", - "ax.set_xticklabels(['$\\overline{\\Gamma}$', '$\\overline{\\mathrm{M}}$',\n", - " '$\\overline{\\mathrm{K}}$', '$\\overline{\\Gamma}$'])\n", - "ax.set_ylabel('Energy (eV)', fontsize=18)\n", - "ax.set_yticks(np.arange(-4, 1, 1))\n", - "ax.yaxis.set_minor_locator(AutoMinorLocator(2))\n", - "# ax.set_yticks(np.arange(-4.5, 0.6, 0.5))\n", - "# ax.set_ylim([])\n", - "for p in pos[:-1]:\n", - " ax.axvline(x=p, c='k', ls='--', lw=2, dashes=[4, 2])\n", - "ax.legend(loc='lower left', frameon=False, fontsize=15, borderpad=0,\n", - " facecolor='None', labelspacing=0.2, handletextpad=0.3)\n", - "cax = inset_axes(ax, width=\"3%\", height=\"30%\", bbox_to_anchor=(70, -30, 440, 200))\n", - "cb = plt.colorbar(imax, cax=cax, ticks=[])\n", - "cb.ax.set_ylabel('Intensity', fontsize=15, rotation=-90, labelpad=17)\n", - "plt.savefig(r'../results/figures/sfig_9g.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 9h" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cmsk = aly.circmask(np.ones((255, 255)), 127.5, 127.5, 115, sign='xnan', method='algebraic')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Retrieve reconstructions with PBE-DFT as inititalization\n", - "recons = {}\n", - "bandidx = list(range(0, 8))\n", - "for istp, stp in enumerate(bandidx):\n", - " stepstr = str(istp).zfill(2)\n", - " files = fuller.utils.findFiles(r'../data/synthetic/pbe_lda/mrf_rec_band='+stepstr, fstring=r'*')\n", - " recon = []\n", - " recon.append(fuller.utils.loadH5Parts(files[0], ['bands/Eb'], outtype='vals'))\n", - " recons[stepstr] = np.squeeze(np.array(recon))\n", - " \n", - "brecons = [v for k, v in recons.items() if k != 'init']\n", - "brecons = np.asarray(brecons)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f, ax = plt.subplots(8, 2, figsize=(3, 25))\n", - "kxminl, kxmaxl, kxminr, kxmaxr = kxvals[0], kxvals[127], kxvals[128], kxvals[-1]\n", - "kyminl, kymaxl, kyminr, kymaxr = kyvals[0], kyvals[-1], kyvals[0], kyvals[-1]\n", - "\n", - "for i in range(8):\n", - " \n", - " band_gt = gtbands[i,:,:]*cmsk\n", - " band_rec = brecons[i,:,:]*cmsk\n", - " band_init = inits['pbe'][i,:,:]*cmsk\n", - " band_diff = band_rec - band_gt\n", - " vmin_gt, vmax_gt = gtbands[i,:,:].min(), gtbands[i,:,:].max()\n", - " vmin_init, vmax_init = band_init.min(), band_init.max()\n", - " vmin = min([vmin_gt, vmin_init]) - 0.1\n", - " vmax = max([vmax_gt, vmax_init]) + 0.1\n", - " \n", - " ax[i, 0].imshow(band_gt[:, :127], cmap=custom_cmap, extent=[kxminl, kxmaxl, kyminl, kymaxl],\n", - " aspect=1, vmin=vmin, vmax=vmax)\n", - " ax[i, 1].imshow(band_rec[:, 128:], cmap=custom_cmap, extent=[kxminr, kxmaxr, kyminr, kymaxr],\n", - " aspect=1, vmin=vmin, vmax=vmax)\n", - " ax[i, 0].set_xticks(np.arange(-1.5, 0, 0.5))\n", - " ax[i, 0].set_xticklabels(['', '-1', ''])\n", - " ax[i, 1].set_xticks(np.arange(0.5, 1.6, 0.5))\n", - " ax[i, 1].set_xticklabels(['', '1', ''])\n", - " ax[i, 0].set_yticks(np.arange(-1, 1.1, 1))\n", - " ax[i, 0].yaxis.set_minor_locator(AutoMinorLocator(2))\n", - " ax[i, 1].set_yticks([])\n", - " ax[i, 0].tick_params(axis='both', which='both', length=8, width=2, labelsize=18)\n", - " ax[i, 1].tick_params(axis='both', length=8, width=2, labelsize=18)\n", - " ax[i, 0].set_ylabel('$k_y$ $(\\mathrm{\\AA}^{-1})$', fontsize=18)\n", - " ax[i, 0].text(0.1, 0.9, '#'+str(i+1), fontsize=15, transform=ax[i,0].transAxes)\n", - " \n", - " if i < 7:\n", - " ax[i, 0].set_xticks([])\n", - " ax[i, 1].set_xticks([])\n", - "\n", - "ax[0, 0].set_title('Ground\\ntruth (LDA)', fontsize=18)\n", - "ax[0, 1].set_title('Recon-\\nstruction', fontsize=18)\n", - "ax[-1, 0].set_xlabel('$k_x$ $(\\mathrm{\\AA}^{-1})$', fontsize=18, x=1)\n", - "plt.subplots_adjust(wspace=0, hspace=0.1)\n", - "plt.savefig(r'../results/figures/sfig_9h1.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f, ax = plt.subplots(8, 2, figsize=(3, 25))\n", - "kxminl, kxmaxl, kxminr, kxmaxr = kxvals[0], kxvals[127], kxvals[128], kxvals[-1]\n", - "kyminl, kymaxl, kyminr, kymaxr = kyvals[0], kyvals[-1], kyvals[0], kyvals[-1]\n", - "\n", - "for i in range(8):\n", - " \n", - " band_gt = gtbands[i,:,:]*cmsk\n", - " band_rec = brecons[i,:,:]*cmsk\n", - " band_init = inits['pbe'][i,:,:]*cmsk\n", - " init_diff_all = (inits['pbe'] - gtbands)*cmsk\n", - " init_diff = init_diff_all[i,...]\n", - " band_diff_all = (brecons - gtbands)*cmsk\n", - " band_diff = band_diff_all[i,...]\n", - " \n", - " vmin_gt, vmax_gt = gtbands[i,:,:].min(), gtbands[i,:,:].max()\n", - " vmin_rec, vmax_rec = np.nanmin(band_diff_all), np.nanmax(band_diff_all)\n", - " vmin_init, vmax_init = np.nanmin(init_diff_all), np.nanmax(init_diff_all)\n", - " \n", - " vmin = np.nanmin([vmin_init, vmin_rec]) - 0.01\n", - " vmax = np.nanmax([vmax_init, vmax_rec]) + 0.01\n", - " imaxl = ax[i, 0].imshow(init_diff[:, :127], cmap='terrain_r', extent=[kxminl, kxmaxl, kyminl, kymaxl],\n", - " aspect=1, vmin=vmin_init, vmax=vmax_init)\n", - " imax = ax[i, 1].imshow(band_diff[:, 128:], cmap='RdBu_r', extent=[kxminr, kxmaxr, kyminr, kymaxr],\n", - " aspect=1, vmin=-0.2, vmax=0.2)\n", - "\n", - " ax[i, 0].set_xticks(np.arange(-1.5, 0, 0.5))\n", - " ax[i, 0].set_xticklabels(['', '-1', ''])\n", - " ax[i, 1].set_xticks(np.arange(0.5, 1.6, 0.5))\n", - " ax[i, 1].set_xticklabels(['', '1', ''])\n", - " ax[i, 0].set_yticks([])\n", - " ax[i, 1].set_yticks([])\n", - " ax[i, 0].tick_params(axis='both', length=8, width=2, labelsize=18)\n", - " ax[i, 1].tick_params(axis='both', length=8, width=2, labelsize=18)\n", - " ax[i, 0].text(0.1, 0.9, '#'+str(i+1), fontsize=15, transform=ax[i,0].transAxes)\n", - " \n", - " if i < 7:\n", - " ax[i, 0].set_xticks([])\n", - " ax[i, 1].set_xticks([])\n", - " \n", - "ax[0, 0].set_title('\\ninitial.-g.t.', fontsize=18)\n", - "ax[0, 1].set_title('\\nrecon.-g.t.', fontsize=18)\n", - "plt.suptitle('Energy difference', y=0.902, fontsize=18)\n", - "ax[-1, 0].set_xlabel('$k_x$ $(\\mathrm{\\AA}^{-1})$', fontsize=18, x=1)\n", - "\n", - "caxl = inset_axes(ax[6,0], width=\"3%\", height=\"30%\", bbox_to_anchor=(-130, 122, 350, 400))\n", - "cbl = plt.colorbar(imaxl, cax=caxl, ticks=np.arange(0.0, 0.61, 0.1))\n", - "cbl.ax.set_title('eV', fontsize=15)\n", - "cbl.ax.tick_params(axis='y', width=2, length=6, labelsize=15)\n", - "\n", - "cax = inset_axes(ax[7,0], width=\"3%\", height=\"30%\", bbox_to_anchor=(-130, -50, 350, 400))\n", - "cb = plt.colorbar(imax, cax=cax, ticks=np.arange(-0.2, 0.21, 0.1))\n", - "# cb.ax.set_ylabel('Intensity', fontsize=15, rotation=-90, labelpad=17)\n", - "cb.ax.set_title('eV', fontsize=15)\n", - "cb.ax.tick_params(axis='y', width=2, length=6, labelsize=15)\n", - "\n", - "plt.subplots_adjust(wspace=0, hspace=0.1)\n", - "plt.savefig(r'../results/figures/sfig_9h2.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/SFig9_Reconstruction_with_scaled_theory-checkpoint.ipynb b/figures/.ipynb_checkpoints/SFig9_Reconstruction_with_scaled_theory-checkpoint.ipynb deleted file mode 100644 index 236a123..0000000 --- a/figures/.ipynb_checkpoints/SFig9_Reconstruction_with_scaled_theory-checkpoint.ipynb +++ /dev/null @@ -1,246 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Reconstruction for synthetic data with scaled theoretical band structure (LDA-DFT) as initialization" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import os\n", - "import numpy as np\n", - "from numpy import nan_to_num as n2n\n", - "import fuller\n", - "from mpes import fprocessing as fp, analysis as aly\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib as mpl\n", - "from natsort import natsorted\n", - "import glob as g\n", - "from mpl_toolkits.axes_grid1 import make_axes_locatable\n", - "from mpl_toolkits.axes_grid1.inset_locator import inset_axes\n", - "from matplotlib.ticker import AutoMinorLocator\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams['font.family'] = 'sans-serif'\n", - "mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Load synthetic data and ground truth band structure (gt)\n", - "data = fuller.utils.loadHDF(r'../data/synthetic/synth_data_WSe2_LDA_top8.h5')\n", - "gtbands = data['bands_padded']\n", - "kxvals, kyvals = data['kx'], data['ky']\n", - "msk = data['mask_tight']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 9d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Load reconstructions and corresponding initializations\n", - "scales = ['0.8', '1.2']\n", - "\n", - "recons, inits = {}, {}\n", - "for isc, sc in enumerate(scales):\n", - " scalestr = str(sc)\n", - " files = fuller.utils.findFiles(r'../data/synthetic/sc='+scalestr+'_lda', fstring=r'/*')\n", - " recon = []\n", - " for f in files:\n", - " recon.append(fuller.utils.loadH5Parts(f, ['bands/Eb'], outtype='vals'))\n", - " \n", - " recons[scalestr] = np.squeeze(np.array(recon))\n", - " inits[scalestr] = data[scalestr]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate errors in initialization (einit) and reconstruction (erec)\n", - "bands_tight = fuller.utils.trim_2d_edge(gtbands, edges=24, axes=(1, 2))\n", - "erec = fuller.metrics.abserror(recons, bands_tight, [0.8, 1.2], ofs=24, mask=msk, outkeys=[0.8, 1.2], ret='dict')\n", - "einit = fuller.metrics.abserror(inits, bands_tight, [0.8, 1.2], ofs=24, mask=msk, outkeys=[0.8, 1.2], ret='dict')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot comparison between reconstruction using scaled DFT calculations\n", - "dt=0.08 # horizontal jitter amplitude in visualization (to separate overlapping points)\n", - "f, ax = plt.subplots(figsize=(8.5, 5.5))\n", - "for i in range(8):\n", - " ax.axvline(x=i+1, ls='--', lw=1, c='g', zorder=0)\n", - " \n", - " if i < 7:\n", - " ax.scatter(i+1-dt, einit['0.8'][i]*1000, s=100, facecolors='b', edgecolors='b', lw=2, zorder=1)\n", - " ax.scatter(i+1-dt, erec['0.8'][i]*1000, s=100, facecolors='w', edgecolors='b', lw=2, zorder=1)\n", - "\n", - " ax.scatter(i+1+dt, einit['1.2'][i]*1000, s=100, facecolors='k', edgecolors='k', lw=2, zorder=1)\n", - " ax.scatter(i+1+dt, erec['1.2'][i]*1000, s=100, facecolors='w', edgecolors='k', lw=2, zorder=1)\n", - " \n", - " if i == 7:\n", - " ax.scatter(i+1-dt, einit['0.8'][i]*1000, s=100, facecolors='b', edgecolors='b', lw=2, zorder=1,\n", - " label=r'Scaled LDA (0.8$\\times$)')\n", - " ax.scatter(i+1-dt, erec['0.8'][i]*1000, s=100, facecolors='w', edgecolors='b', lw=2, zorder=1,\n", - " label=r'Recon. with 0.8$\\times$')\n", - "\n", - " ax.scatter(i+1+dt, einit['1.2'][i]*1000, s=100, facecolors='k', edgecolors='k', lw=2, zorder=1,\n", - " label=r'Scaled LDA (1.2$\\times$)')\n", - " ax.scatter(i+1+dt, erec['1.2'][i]*1000, s=100, facecolors='w', edgecolors='k', lw=2, zorder=1,\n", - " label=r'Recon. with 1.2$\\times$')\n", - " \n", - "ax.set_ylabel('Average error $\\eta_{\\mathrm{avg}}$ wrt ground truth (meV)', fontsize=18)\n", - "ax.set_yticks(range(0, 181, 20))\n", - "ax.tick_params(axis='both', length=8, width=2, labelsize=15)\n", - "ax.set_xticks(range(1, 9))\n", - "ax.set_xlabel('Band index', fontsize=18)\n", - "ax.set_ylim([0, 180])\n", - "ax.set_title('Reconstruction from scaled LDA calculations', fontsize=18)\n", - "lg = ax.legend(bbox_transform=ax.transAxes, bbox_to_anchor=(0.45, 0.93), frameon=True, fontsize=15,\n", - " facecolor='w', labelspacing=0.2, handletextpad=0.3)\n", - "frame = lg.get_frame()\n", - "frame.set_facecolor('w')\n", - "frame.set_edgecolor('k')\n", - "frame.set_linewidth(2)\n", - "plt.savefig(r'../results/figures/sfig_9d.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 9f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Using know positions (ways to obtain these see notebooks in /code/extra/)\n", - "G = np.array([127.0, 127.27828129766911])\n", - "K = np.array([ 23.83002655, 127. ])\n", - "M = np.array([ 49.38033047, 171.8133136 ])\n", - "\n", - "pathPoints = np.asarray([G, M, K, G])\n", - "nGM, nMK, nKG = 70, 39, 79\n", - "segPoints = [nGM, nMK, nKG]\n", - "rowInds, colInds, pathInds = aly.points2path(pathPoints[:,0], pathPoints[:,1], npoints=segPoints)\n", - "nSegPoints = len(rowInds)\n", - "\n", - "pdGT = aly.bandpath_map(np.moveaxis(gtbands, 0, 2), pathr=rowInds, pathc=colInds, eaxis=2)\n", - "pdInit = aly.bandpath_map(np.moveaxis(inits['0.8'], 0, 2), pathr=rowInds, pathc=colInds, eaxis=2)\n", - "pdMPES = aly.bandpath_map(np.moveaxis(data['mpes_padded'], 0, 2), pathr=rowInds, pathc=colInds, eaxis=2)\n", - "Emin, Emax = data['E'].min(), data['E'].max()\n", - "\n", - "# Symmetrize the reconstructed bands\n", - "symrecbands = []\n", - "for i in range(8):\n", - " symmed = fuller.generator.rotosymmetrize(recons['0.8'][i,...], (127.5, 127.5), rotsym=6)[0]\n", - " symrecbands.append(fuller.generator.refsym(symmed[None,...], op='nanmean', pbar=False)[0,...])\n", - "symrecbands = np.asarray(symrecbands)\n", - "pdRecon = aly.bandpath_map(np.moveaxis(symrecbands, 0, 2), pathr=rowInds, pathc=colInds, eaxis=2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot comparison between initialization, reconstruction and ground truth along high-symmetry lines\n", - "xaxis = np.array(range(rowInds.size))\n", - "pos = pathInds.copy()\n", - "pos[-1] -= 1\n", - "\n", - "f, ax = plt.subplots(figsize=(8.3, 6))\n", - "imax = ax.imshow(pdMPES, cmap='Blues', origin='lower', extent=[0, nSegPoints, Emin, Emax], aspect=22, vmax=7, zorder=0)\n", - "ax.plot(pdGT.T, c='k', zorder=2)\n", - "ax.plot(pdRecon.T, c='r', zorder=3)\n", - "ax.plot(pdInit.T + 0.12, '--', c='g', zorder=1)\n", - "\n", - "ax.plot(xaxis, pdGT[-1, :], c='k', zorder=2, label='Ground truth (LDA)')\n", - "ax.plot(xaxis, pdInit[-1, :] + 0.12, '--', c='g', zorder=1, label=r'Initial. (0.8$\\times$)')\n", - "ax.plot(xaxis, pdRecon[-1, :], c='r', zorder=3, label='Reconstruction')\n", - "\n", - "ax.tick_params(axis='y', length=8, width=2, labelsize=15)\n", - "ax.tick_params(axis='x', length=0, width=0, labelsize=15, pad=8)\n", - "ax.set_xlim([pos[0], pos[-1]])\n", - "ax.set_xticks(pos)\n", - "ax.set_xticklabels(['$\\overline{\\Gamma}$', '$\\overline{\\mathrm{M}}$',\n", - " '$\\overline{\\mathrm{K}}$', '$\\overline{\\Gamma}$'])\n", - "ax.set_ylabel('Energy (eV)', fontsize=18)\n", - "# ax.set_ylim([])\n", - "for p in pos[:-1]:\n", - " ax.axvline(x=p, c='k', ls='--', lw=2, dashes=[4, 2])\n", - "ax.legend(loc='lower left', frameon=False, fontsize=15,\n", - " facecolor='None', labelspacing=0.2, handletextpad=0.3, borderpad=0)\n", - "plt.savefig('../results/figures/sfig_9f.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/figures/.ipynb_checkpoints/SFig9_Synthetic_data_and_initial_conditions-checkpoint.ipynb b/figures/.ipynb_checkpoints/SFig9_Synthetic_data_and_initial_conditions-checkpoint.ipynb deleted file mode 100644 index 3d6f927..0000000 --- a/figures/.ipynb_checkpoints/SFig9_Synthetic_data_and_initial_conditions-checkpoint.ipynb +++ /dev/null @@ -1,356 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Generate synthetic multiband photoemission data using DFT calculations" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings as wn\n", - "wn.filterwarnings(\"ignore\")\n", - "\n", - "import os\n", - "import numpy as np\n", - "import fuller\n", - "from mpes import analysis as aly\n", - "import matplotlib.pyplot as plt\n", - "from matplotlib.ticker import (MultipleLocator, FormatStrFormatter,\n", - " AutoMinorLocator)\n", - "from tqdm import tqdm_notebook as tqdm\n", - "import tifffile as ti\n", - "import matplotlib as mpl\n", - "from scipy import interpolate\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mpl.rcParams['font.family'] = 'sans-serif'\n", - "mpl.rcParams['font.sans-serif'] = 'Arial'\n", - "mpl.rcParams['axes.linewidth'] = 2\n", - "mpl.rcParams['pdf.fonttype'] = 42\n", - "mpl.rcParams['ps.fonttype'] = 42\n", - "\n", - "# Create plot folder if needed\n", - "if not os.path.exists('../results/figures'):\n", - " os.mkdir('../results/figures')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ncfs = 400\n", - "bases = fuller.generator.ppz.hexike_basis(nterms=ncfs, npix=207, vertical=True, outside=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Compute the polynomial decomposition coefficients\n", - "bandout = np.nan_to_num(fuller.utils.loadHDF('../data/theory/bands_1BZ/wse2_lda_bandcuts.h5')['bands'])\n", - "ldashift = 0.86813 # For zeroing the energy at K points\n", - "bcfs = []\n", - "for i in tqdm(range(14)):\n", - " bcfs.append(fuller.generator.decomposition_hex2d(bandout[i,...] + ldashift, bases=bases, baxis=0, ret='coeffs'))\n", - "bcfs = np.array(bcfs)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate Brillouin zone mask\n", - "bzmsk = fuller.generator.hexmask(hexdiag=207, imside=207, padded=False, margins=[1, 1, 1, 1])\n", - "bzmsk_tight = fuller.generator.hexmask(hexdiag=201, imside=207, padded=True, margins=[3, 3, 3, 3])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate photoemission data without padding\n", - "nbands = 8\n", - "bshape = (207, 207)\n", - "amps = np.ones(bshape)\n", - "xs = np.linspace(-4.5, 0.5, 285, endpoint=True)\n", - "syndat = np.zeros((285, 207, 207))\n", - "gamss = []\n", - "for i in tqdm(range(nbands)):\n", - " gams = 0.05\n", - " syndat += aly.voigt(feval=True, vardict={'amp':amps, 'xvar':xs[:,None,None], 'ctr':(bandout[i,...] + 0.86813),\n", - " 'sig':0.1, 'gam':gams})" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hwd = 103.5 # Half width of projected Brillouin zone in pixels" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate edge-padded bands\n", - "synfbands = []\n", - "padsize = ((24, 24), (24, 24))\n", - "for i in tqdm(range(nbands)): \n", - " impad = fuller.generator.hexpad(bandout[i,...] + 0.86813, cvd=hwd, mask=bzmsk, edgepad=padsize)\n", - " synfbands.append(fuller.generator.restore(impad, method='cubic'))\n", - "synfbands = np.asarray(synfbands)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate edge-padded photoemission data\n", - "bshape = (255, 255)\n", - "amps = np.ones(bshape)\n", - "xs = np.linspace(-4.5, 0.5, 285, endpoint=True)\n", - "synfdat = np.zeros((285, 255, 255))\n", - "gamss = []\n", - "for i in tqdm(range(nbands)):\n", - "# btemp = np.nan_to_num(synbands[i,...])\n", - "# gams = np.abs(synfbands[i,...] - np.nanmean(synfbands[i,...]))/3\n", - " gams = 0.05\n", - "# gamss.append(gams)\n", - " synfdat += aly.voigt(feval=True, vardict={'amp':amps, 'xvar':xs[:,None,None], 'ctr':(synfbands[i,...]),\n", - " 'sig':0.1, 'gam':gams})\n", - "# gamss = np.asarray(gamss)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "xss = np.linspace(-4.5, 0.5, 285, endpoint=True)\n", - "xss[1] - xss[0], xss.size" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.imshow(synfdat[:,80,:], aspect=0.8, origin='lower', cmap='terrain_r')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate mask for large coefficients\n", - "cfmask = fuller.utils.binarize(bcfs, threshold=1e-2, vals=[0, 1])\n", - "cfmask[:, 0] = 0 # No rigid shift modulation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate coefficient-scaled data\n", - "synfscaled = {}\n", - "# errs = np.around(np.arange(0.3, 2.01, 0.05), 2)\n", - "errs = [0.8, 1.0, 1.2]\n", - "bscmod = bcfs.copy()\n", - "\n", - "for err in tqdm(errs):\n", - " \n", - " synbands = []\n", - " for i in range(nbands):\n", - " \n", - " bscmod[i, 1:] = err*bcfs[i, 1:] # Scale only the dispersion terms (leave out the first offset term)\n", - " bandmod = fuller.generator.reconstruction_hex2d(bscmod[i, :], bases=bases)\n", - " \n", - " # Sixfold rotational symmetrization\n", - " symmed = fuller.generator.rotosymmetrize(bandmod, center=(hwd, hwd), rotsym=6)[0]\n", - " symmed = fuller.generator.reflectosymmetrize(symmed, center=(hwd, hwd), refangles=[0, 90])\n", - " padded = fuller.generator.hexpad(symmed, cvd=103.5, mask=bzmsk_tight, edgepad=padsize)\n", - " synbands.append(fuller.generator.restore(padded, method='nearest'))\n", - " \n", - " synfscaled[str(err)] = np.asarray(synbands)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.figure(figsize=(6, 6))\n", - "plt.imshow(synbands[0])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Calibrate momentum axes\n", - "mc = aly.MomentumCorrector(np.asarray(synbands))\n", - "mc.selectSlice2D(selector=slice(0,1), axis=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mc.featureExtract(mc.slice, method='daofind', fwhm=30, sigma=20)\n", - "#mc.view(mc.slice, annotated=True, points=mc.features)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate distances\n", - "dg = 1.27/np.cos(np.radians(30))\n", - "axes = mc.calibrate(mc.slice, mc.pouter_ord[0,:], mc.pcent, dist=dg, equiscale=True, ret='axes')\n", - "dg, axes['axes'][0][0], axes['axes'][0][-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Supplementary Figure 9c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "kx, ky = axes['axes'][0], axes['axes'][1]\n", - "emin, emax = xs.min(), xs.max()\n", - "kxtight = kx[24:-24]\n", - "kytight = ky[24:-24]\n", - "kxmin, kxmax = kxtight.min(), kxtight.max()\n", - "kymin, kymax = kytight.min(), kytight.max()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "islc = 90 # slice index\n", - "f, axs = plt.subplots(1, 2, figsize=(10, 6))\n", - "bands_tight = bandout + ldashift\n", - "\n", - "cs = ['r']\n", - "labels = [0.8]\n", - "for ni, i in enumerate(labels):\n", - " lbl = str(i)\n", - " reconbands = bzmsk_tight*(synfscaled[lbl][:,24:-24,24:-24])\n", - " for j in range(8):\n", - " axs[0].plot(kxtight, reconbands[j, islc, :], c=cs[ni])\n", - " axs[1].plot(kytight, reconbands[j, :, islc], c=cs[ni])\n", - " if j == 7:\n", - " axs[0].plot(kxtight, reconbands[j, islc, :], c=cs[ni], label='Scaled LDA ('+lbl+r'$\\times$)')\n", - " axs[1].plot(kytight, reconbands[j, :, islc], c=cs[ni], label='Scaled LDA ('+lbl+r'$\\times$)')\n", - "\n", - "gtband = bzmsk_tight*bands_tight\n", - "for j in range(8):\n", - " axs[0].plot(kxtight, gtband[j, islc, :], c='k', lw=2)\n", - " axs[1].plot(kytight, gtband[j, :, islc], c='k', lw=2)\n", - " if j == 7:\n", - " axs[0].plot(kxtight, gtband[j, islc, :], c='k', lw=2, label=r'LDA calc. (1.0$\\times$)')\n", - " axs[1].plot(kytight, gtband[j, :, islc], c='k', lw=2, label=r'LDA calc. (1.0$\\times$)')\n", - "\n", - "cs = ['g']\n", - "labels = [1.2]\n", - "for ni, i in enumerate(labels):\n", - " lbl = str(i)\n", - " reconbands = bzmsk_tight*(synfscaled[lbl][:,24:-24,24:-24])\n", - " for j in range(8):\n", - " axs[0].plot(kxtight, reconbands[j, islc, :], c=cs[ni])\n", - " axs[1].plot(kytight, reconbands[j, :, islc], c=cs[ni])\n", - " if j == 7:\n", - " axs[0].plot(kxtight, reconbands[j, islc, :], c=cs[ni], label='Scaled LDA ('+lbl+r'$\\times$)')\n", - " axs[1].plot(kytight, reconbands[j, :, islc], c=cs[ni], label='Scaled LDA ('+lbl+r'$\\times$)')\n", - "\n", - "for i in range(2):\n", - " axs[i].tick_params(which='major', axis='both', length=8, width=2, labelsize=15)\n", - " axs[i].tick_params(which='minor', axis='both', length=8, width=1)\n", - " axs[i].set_xticks(np.arange(-1., 1.1, 1))\n", - " axs[i].xaxis.set_minor_locator(AutoMinorLocator(2))\n", - " axs[i].legend(loc='upper left', frameon=False, fontsize=15, ncol=1, labelspacing=0.1, borderpad=0, columnspacing=1)\n", - " axs[i].set_yticks(np.arange(-4, 2, 1))\n", - " axs[i].set_ylim([-4.2, 1.3])\n", - " \n", - "axs[0].yaxis.set_minor_locator(AutoMinorLocator(2))\n", - "axs[0].set_xlabel('$k_x$ $(\\mathrm{\\AA}^{-1})$', fontsize=18)\n", - "axs[0].set_ylabel('Energy (eV)', fontsize=18)\n", - "axs[1].set_xlabel('$k_y$ $(\\mathrm{\\AA}^{-1})$', fontsize=18)\n", - "axs[1].set_yticks([])\n", - "plt.subplots_adjust(wspace=0.1)\n", - "plt.savefig('../results/figures/sfig_9c.png', bbox_inches='tight', transparent=True, dpi=300)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -}