{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Graphene deflector scan\n\nSimple workflow for analyzing a deflector scan data of graphene as simulated\nfrom a third nearest neighbor tight binding model.\nThe same workflow can be applied to any tilt-, polar- or deflector-scan.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Import the \"fundamental\" python libraries for a generic data analysis:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\nimport matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Instead of loading the file as for example:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# from navarp.utils import navfile\n# file_name = r\"nxarpes_simulated_cone.nxs\"\n# entry = navfile.load(file_name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we build the simulated graphene signal with a dedicated function defined\njust for this purpose:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from navarp.extras.simulation import get_tbgraphene_deflector\n\nentry = get_tbgraphene_deflector(\n scans=np.linspace(-5., 5., 51),\n angles=np.linspace(-7, 7, 300),\n ebins=np.linspace(-3.3, 0.4, 450),\n tht_an=-18,\n phi_an=0,\n hv=120\n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot a single analyzer image at scan = 0\nFirst I have to extract the isoscan from the entry, so I use the isoscan\nmethod of entry:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "iso0 = entry.isoscan(scan=0, dscan=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then to plot it using the 'show' method of the extracted iso0:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "iso0.show(yname='ekin')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or by string concatenation, directly as:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "entry.isoscan(scan=0, dscan=0).show(yname='ekin')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fermi level determination\nThe initial guess for the binding energy is: ebins = ekins - (hv - work_fun).\nHowever, the better way is to proper set the Fermi level first and then\nderives everything form it. The Fermi level can be given directly as a value using:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "entry.set_efermi(114.8)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or it can be detected from a fit using the method autoset_efermi.\nIn both cases the binding energy and the photon energy will be updated\nconsistently. Note that the work function depends on the beamline or\nlaboratory. If not specified is 4.5 eV.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "entry.autoset_efermi(scan_range=[-5, 5], energy_range=[115.2, 115.8])\nprint(\"Energy of the Fermi level = {:.0f} eV\".format(entry.efermi))\nprint(\"Energy resolution = {:.0f} meV\".format(entry.efermi_fwhm*1000))\n\nentry.plt_efermi_fit()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot a single analyzer image at scan = 0 with the Fermi level aligned\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "entry.isoscan(scan=0, dscan=0).show(yname='eef')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plotting iso-energetic cut at ekin = efermi\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "entry.isoenergy(0).show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plotting in the reciprocal space (k-space)\nI have to define first the reference point to be used for the transformation.\nMeaning a point in the angular space which I know it correspond to a\nparticular point in the k-space. In this case the graphene Dirac-point which\nis at ekin = 114.3 eV, in angle is at (tht_p, phi_p) = (0.1, 0) and in the\nk-space has to correspond to (kx, ky) = (1.7, 0).\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "entry.set_kspace(\n tht_p=0.1,\n k_along_slit_p=1.7,\n scan_p=0,\n ks_p=0,\n e_kin_p=114.3,\n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once it is set, all the isoscan or isoenergy extracted from the entry will\nnow get their proper k-space scales:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "entry.isoscan(0).show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# sphinx_gallery_thumbnail_number = 7\n\nentry.isoenergy(0).show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I can also place together in a single figure different images:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, axs = plt.subplots(1, 2)\n\nentry.isoscan(0).show(ax=axs[0])\nentry.isoenergy(0).show(ax=axs[1])\n\nplt.tight_layout()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For the isoenergy case, I can also rotate the image around its origin.\nWhich can be useful sometime if the sample was not exactly aligned during\nthe data acquisition. Or if you are a fun on what I consider as a very\nbad practice, you can repeat the same image at each symmetric point.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, axs = plt.subplots(2, 2, constrained_layout=True)\n\nax = axs[0][0]\nentry.isoenergy(0).show(ax=ax)\nax.set_title('No rotation'.format())\n\nrot_ang = 30\nax = axs[0][1]\nax.set_title('Rotation of {} degrees'.format(rot_ang))\nentry.isoenergy(0).show(ax=ax, rotate=rot_ang)\n\nrot_ang = 90\nax = axs[1][0]\nax.set_title('Rotation of {} degrees'.format(rot_ang))\nentry.isoenergy(0).show(ax=ax, rotate=rot_ang)\n\nrot_angs = [0, 60, 120, 180, 240, 300]\nax = axs[1][1]\nax.set_title('Repetition at every 60 degrees')\nisoen_fs = entry.isoenergy(0)\nfor rot_ang in rot_angs:\n isoen_fs.show(ax=ax, rotate=rot_ang)\n\nfor ax in axs.ravel():\n ax.set_aspect('equal')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Many other options:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, axs = plt.subplots(2, 2)\n\nscan = 0.8\ndscan = 0.05\nebin = -0.4\ndebin = 0.05\n\nentry.isoscan(scan, dscan).show(ax=axs[0][0], xname='tht', yname='ekin')\nentry.isoscan(scan, dscan).show(ax=axs[0][1], cmap='binary')\n\naxs[0][0].axhline(ebin-debin+entry.efermi)\naxs[0][0].axhline(ebin+debin+entry.efermi)\n\naxs[0][1].axhline(ebin-debin)\naxs[0][1].axhline(ebin+debin)\n\nentry.isoenergy(ebin, debin).show(\n ax=axs[1][0], xname='tht', yname='phi', cmap='cividis')\nentry.isoenergy(ebin, debin).show(\n ax=axs[1][1], cmap='magma', cmapscale='log')\n\naxs[1][0].axhline(scan, color='w')\n\nx_note = 0.05\ny_note = 0.98\n\nfor ax in axs[0][:]:\n ax.annotate(\n \"$scan \\: = \\: {} \\pm {} \\; ^\\circ$\".format(scan, dscan),\n (x_note, y_note),\n xycoords='axes fraction',\n size=8, rotation=0, ha=\"left\", va=\"top\",\n bbox=dict(\n boxstyle=\"round\", fc='w', alpha=0.65, edgecolor='None', pad=0.05\n )\n )\n\nfor ax in axs[1][:]:\n ax.annotate(\n \"$E-E_F \\: = \\: {} \\pm {} \\; eV$\".format(ebin, debin),\n (x_note, y_note),\n xycoords='axes fraction',\n size=8, rotation=0, ha=\"left\", va=\"top\",\n bbox=dict(\n boxstyle=\"round\", fc='w', alpha=0.65, edgecolor='None', pad=0.05\n )\n )\n\nplt.tight_layout()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.10.13" } }, "nbformat": 4, "nbformat_minor": 0 }