{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ " **Chapter 2: [Diffraction](CH2_00-Diffraction.ipynb)** \n", "\n", "\n", "
\n", "\n", "\n", "\n", "# The Electron \n", "\n", "\n", "[Download](https://raw.githubusercontent.com/gduscher/MSE672-Introduction-to-TEM//main/Diffraction/CH2_01-Electron.ipynb)\n", "\n", "[![OpenInColab](https://colab.research.google.com/assets/colab-badge.svg)](\n", " https://colab.research.google.com/github/gduscher/MSE672-Introduction-to-TEM/blob/main//Diffraction/CH2_01-Electron.ipynb)\n", " \n", "part of\n", "\n", " **[MSE672: Introduction to Transmission Electron Microscopy](../_MSE672_Intro_TEM.ipynb)**\n", "\n", "**Spring 2024**\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Gerd Duscher Khalid Hattar
Microscopy Facilities Tennessee Ion Beam Materials Laboratory
Materials Science & Engineering Nuclear Engineering
Institute of Advanced Materials & Manufacturing
The University of Tennessee, Knoxville
\n", "\n", "Background and methods to analysis and quantification of data acquired with transmission electron microscopes.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we load the code to make figures from pyTEMlib\n", "## Import packages for figures and \n", "### Check Installed Packages" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "done\n" ] } ], "source": [ "import sys\n", "import importlib.metadata\n", "def test_package(package_name):\n", " \"\"\"Test if package exists and returns version or -1\"\"\"\n", " try:\n", " version = importlib.metadata.version(package_name)\n", " except importlib.metadata.PackageNotFoundError:\n", " version = '-1'\n", " return version\n", "\n", "if test_package('pyTEMlib') < '0.2024.1.0':\n", " print('installing pyTEMlib')\n", " !{sys.executable} -m pip install --upgrade pyTEMlib -q\n", "if 'google.colab' in sys.modules:\n", " !{sys.executable} -m pip install numpy==1.24.4\n", "print('done')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Please restart the session (in Runtime menu) in Google Colab.\n", "\n", "### Load the plotting and figure packages" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "%matplotlib widget\n", "import matplotlib.pylab as plt\n", "import numpy as np\n", "import sys\n", "if 'google.colab' in sys.modules:\n", " from google.colab import output\n", " output.enable_custom_widget_manager()\n", "\n", "import scipy # we will use the constants part only" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Interaction of Common Particles with Matter\n", "\n", "We generally use electron, photons, and neutrons for diffraction/scattering\n", "experiments.\n", "\n", "These particles interact with differently with matter:\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
X-rays$\\leftrightarrow$electron density
neutrons$\\leftrightarrow$mass of nucleus
neutrons$\\leftrightarrow$magnetic moment
electrons$\\leftrightarrow$screened charge of nucleus
\n", "\n", "We will deal with the nature of electrons more closely in the following" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Non-relativistic de Broglie Wavelength\n", "\n", "\n", "The electron is a elementary particle with spin $\\frac{1}{2}$ (lepton).\n", "\n", "\n", "**Non--relativistic De Broglie wavelength** of electron: \n", "\n", "$\\lambda = \\frac{h}{p} = \\frac{h}{\\sqrt{2m_0E_{kin}}} \\approx \\frac{1.22}{\\sqrt{E_{kin}}}$\n", "\n", "\n", "E is the kinetic energy of the electron: $E_{kin} = eU $ [eV].\n", "\n", "The wave length in a TEM is usually\n", "a couple of picometers . This is a\n", "factor of 100 smaller than your\n", "XRD-source.\n", "\n", "Obvioulsy, we are in the wave picture right now." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Classic wave length is 2.24 pm for acceleration voltage 300.0 kV\n", " which is a velocity of 324852582.95 m/s or 108.36% of the speed of light\n" ] } ], "source": [ "# --------- input ---------------------------\n", "acceleration_voltage_V = U = 300.0 * 1000.0 #V \n", "# --------------------------------------------\n", "## energy\n", "E_kin = acceleration_voltage_V * scipy.constants.elementary_charge\n", "h = scipy.constants.Planck\n", "m0 = scipy.constants.electron_mass\n", "c = scipy.constants.speed_of_light\n", "\n", "wave_length_m = h/np.sqrt(2*m0*E_kin) # non-relativistic wavelength in m\n", "\n", "# # please note that we will keep all length units in Angstrom if possible.\n", "# # otherwise we use only SI units!!!\n", "wave_length_A = wave_length_m *1e10 # now in Angstrom\n", "\n", "print(f'Classic wave length is {wave_length_A*100.:.2f} pm for acceleration voltage {acceleration_voltage_V/1000.:.1f} kV')\n", "# Notice that we change units in the output to make them most readable.\n", "\n", "print(f' which is a velocity of {np.sqrt(2/m0*E_kin):.2f} m/s or {np.sqrt(2/m0*E_kin)/c*100:.2f}% of the speed of light')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Relativistic Correction\n", "In the table below we see that the speeds of the electron is rather close to the speed of light $c$\n", "\n", "The formula for relativistic corrected wavelength is:\n", "$\\lambda = \\frac{h}{\\sqrt{2m_e E_{kin} *(1+\\frac{E_{kin}}{2 m_e c^2})}}$\n", "\n", "**Please note:** All units are internally in SI units: kg, s, V, J, except the length wihich is in nm!\n", "\n", "We multiply with the appropriate factors for the output" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The relativistically corrected wave length is 1.97 pm for acceleration voltage 300.0 kV\n" ] } ], "source": [ "# ---------Input: Acceleration Voltage --\n", "E0 = acceleration_voltage_V = 300.0 *1000.0 # V\n", "# ---------------------------------------\n", "E_kin = acceleration_voltage_V * scipy.constants.elementary_charge\n", "h = scipy.constants.Planck\n", "m0 = scipy.constants.electron_mass\n", "c = scipy.constants.speed_of_light\n", "\n", "#relativisitic wavelength\n", "wave_length = h/np.sqrt(2* m0 * E_kin * (1 + E_kin / (2 * m0 * c**2))) #in m\n", "\n", "print(f'The relativistically corrected wave length is {wave_length*1e12:.2f} pm for acceleration voltage {acceleration_voltage_V/1000:.1f} kV')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "100kV : $\\lambda$ = 4 pm $<$ than diameter of an atom\n", "\n", "The relativistic parameters are:\n", "\n", "\n", "|E (keV)|$\\lambda$ (pm) | M/m$_0$ | v/c|\n", "--------|---------------|---------|----|\n", "|10 | 12.2 | 1.0796 | 0.1950 |\n", "|30 | 6.98 | 1.129 | 0.3284 |\n", "|100 | 3.70 | 1.1957 | 0.5482|\n", "|200 | 2.51 | 1.3914 | 0.6953|\n", "|400 | 1.64 | 1.7828 | 0.8275 |\n", "|1000 | 0.87 | 2.9569 | 0.9411|\n", "\n", "The same functionality (and code) is used in the kinematic_scattering library and we can test the values of above table.\n", "\n", "Please change the acceleration voltage (**acceleration_voltage_V**) above.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### Relativistic velocity\n", "\n", "$$\\frac{v^2}{c^2} = \\frac{E_{kin}(E_{kin}+2m_e c^2)}{(E_{kin}+m_e c^2)^2}$$" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "For an acceleration voltage of 300keV: \n", "The classic velocity of the electron is 324852582.95 m/s or 108.36% of the speed of light\n", "The relativistic velocity of the electron is 232796486.28 m/s or 77.65% of the speed of light\n" ] } ], "source": [ "v = np.sqrt(E_kin * (E_kin + 2 * m0 * c**2)/(E_kin + m0 * c**2) **2)*c\n", "\n", "print(f'For an acceleration voltage of {acceleration_voltage_V/1000:.0f}keV: ')\n", "print(f'The classic velocity of the electron is {np.sqrt(2/m0 * E_kin):.2f} m/s or {np.sqrt(2 / m0 * E_kin)/c * 100:.2f}% of the speed of light')\n", "print(f'The relativistic velocity of the electron is {v:.2f} m/s or {v/c*100:.2f}% of the speed of light')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## That means that the resolution is not limited by the wavelength!" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The relativistically corrected wave length is 6.98 pm for acceleration voltage 30.0 kV\n" ] } ], "source": [ "# Import Kinematic Scattering Library\n", "import pyTEMlib.kinematic_scattering as ks # Kinematic scattering Library\n", "\n", "acceleration_voltage= 30*1e3\n", "wave_length = ks.get_wavelength(acceleration_voltage)\n", "print(f'The relativistically corrected wave length is {wave_length*1e2:.2f} pm for acceleration voltage {acceleration_voltage/1000:.1f} kV')\n", "\n", "# Wavelength in Angstrom\n", "def get_wavelength(acceleration_voltage):\n", " \"\"\"\n", " Calculates the relativistic corrected de Broglie wave length of an electron\n", "\n", " Input:\n", " ------\n", " acceleration voltage in volt\n", " Output:\n", " -------\n", " wave length in Angstrom\n", " \"\"\"\n", " E = acceleration_voltage * scipy.constants.elementary_charge\n", " h = scipy.constants.Planck\n", " m0 = scipy.constants.electron_mass\n", " c = scipy.constants.speed_of_light\n", " \n", " wavelength = h / np.sqrt(2 * m0 * E * (1 + (E / (2 * m0 * c ** 2))))\n", " return wavelength * 10**10\n" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function get_wavelength in module pyTEMlib.kinematic_scattering:\n", "\n", "get_wavelength(acceleration_voltage)\n", " Calculates the relativistic corrected de Broglie wavelength of an electron in Angstrom\n", " \n", " Parameter:\n", " ---------\n", " acceleration_voltage: float\n", " acceleration voltage in volt\n", " Returns:\n", " -------\n", " wavelength: float\n", " wave length in Angstrom\n", "\n" ] } ], "source": [ "help(ks.get_wavelength)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on module pyTEMlib.kinematic_scattering in pyTEMlib:\n", "\n", "NAME\n", " pyTEMlib.kinematic_scattering\n", "\n", "DESCRIPTION\n", " kinematic_scattering\n", " Copyright by Gerd Duscher\n", " \n", " The University of Tennessee, Knoxville\n", " Department of Materials Science & Engineering\n", " \n", " Sources:\n", " Scattering Theory:\n", " Zuo and Spence, \"Advanced TEM\", 2017\n", " \n", " Spence and Zuo, Electron Microdiffraction, Plenum 1992\n", " \n", " Atomic Form Factor:\n", " Kirkland: Advanced Computing in Electron Microscopy 2nd edition\n", " Appendix C\n", " \n", " Units:\n", " everything is in SI units, except length which is given in Angstrom.\n", " \n", " Usage:\n", " See the notebooks for examples of these routines\n", " \n", " All the input and output is done through a ase.Atoms object and the dictionary in the info attribute\n", "\n", "FUNCTIONS\n", " Zuo_fig_3_18(verbose=True)\n", " Input for Figure 3.18 in Zuo and Spence \"Advanced TEM\", 2017\n", " \n", " This input acts as an example as well as a reference\n", " \n", " Parameters:\n", " -----------\n", " verbose: boolean:\n", " optional to see output\n", " Returns:\n", " -------\n", " atoms: ase.Atoms\n", " Silicon crystal structure\n", " e\n", " dictionary: tags is the dictionary of all input and output parameter needed to reproduce that figure.\n", " \n", " check_sanity(atoms, verbose_level=0)\n", " Check sanity of input parameters\n", " \n", " example(verbose=True)\n", " same as Zuo_fig_3_18\n", " \n", " feq(element, q)\n", " Atomic form factor parametrized in 1/Angstrom but converted to 1/Angstrom\n", " \n", " The atomic form factor is from Kirkland: Advanced Computing in Electron Microscopy 2nd edition, Appendix C.\n", " From Appendix C of Kirkland, \"Advanced Computing in Electron Microscopy\", 3Ard ed.\n", " Calculation of electron form factor for specific q:\n", " Using equation Kirkland C.15\n", " \n", " Parameters\n", " ----------\n", " element: string\n", " element name\n", " q: float\n", " magnitude of scattering vector in 1/Angstrom -- (=> exp(-i*g.r), physics negative convention)\n", " \n", " Returns\n", " -------\n", " fL+fG: float\n", " atomic scattering vector\n", " \n", " find_angles(zone)\n", " Microscope stage coordinates of zone\n", " \n", " find_nearest_zone_axis(tags)\n", " Test all zone axis up to a maximum of hkl_max\n", " \n", " get_dynamically_allowed(atoms, verbose=False)\n", " \n", " get_metric_tensor(matrix)\n", " The metric tensor of the lattice.\n", " \n", " get_rotation_matrix(tags)\n", " zone axis in global coordinate system\n", " \n", " get_wavelength(acceleration_voltage)\n", " Calculates the relativistic corrected de Broglie wavelength of an electron in Angstrom\n", " \n", " Parameter:\n", " ---------\n", " acceleration_voltage: float\n", " acceleration voltage in volt\n", " Returns:\n", " -------\n", " wavelength: float\n", " wave length in Angstrom\n", " \n", " kinematic_scattering(atoms, verbose=False)\n", " All kinematic scattering calculation\n", " \n", " Calculates Bragg spots, Kikuchi lines, excess, and deficient HOLZ lines\n", " \n", " Parameters\n", " ----------\n", " atoms: ase.Atoms\n", " object with crystal structure:\n", " and with experimental parameters in info attribute:\n", " 'acceleration_voltage_V', 'zone_hkl', 'Sg_max', 'hkl_max'\n", " Optional parameters are:\n", " 'mistilt', convergence_angle_mrad', and 'crystal_name'\n", " verbose = True will give extended output of the calculation\n", " verbose: boolean\n", " default is False\n", " \n", " Returns\n", " -------\n", " atoms:\n", " There are three sub_dictionaries in info attribute:\n", " ['allowed'], ['forbidden'], and ['HOLZ']\n", " ['allowed'] and ['forbidden'] dictionaries contain:\n", " ['Sg'], ['hkl'], ['g'], ['structure factor'], ['intensities'],\n", " ['ZOLZ'], ['FOLZ'], ['SOLZ'], ['HOLZ'], ['HHOLZ'], ['label'], and ['Laue_zone']\n", " the ['HOLZ'] dictionary contains:\n", " ['slope'], ['distance'], ['theta'], ['g_deficient'], ['g_excess'], ['hkl'], ['intensities'],\n", " ['ZOLZ'], ['FOLZ'], ['SOLZ'], ['HOLZ'], and ['HHOLZ']\n", " Please note that the Kikuchi lines are the HOLZ lines of ZOLZ\n", " \n", " There are also a few parameters stored in the main dictionary:\n", " ['wave_length_nm'], ['reciprocal_unit_cell'], ['inner_potential_V'], ['incident_wave_vector'],\n", " ['volume'], ['theta'], ['phi'], and ['incident_wave_vector_vacuum']\n", " \n", " kinematic_scattering2(atoms, verbose=False)\n", " All kinematic scattering calculation\n", " \n", " Calculates Bragg spots, Kikuchi lines, excess, and deficient HOLZ lines\n", " \n", " Parameters\n", " ----------\n", " atoms: ase.Atoms\n", " object with crystal structure:\n", " and with experimental parameters in info attribute:\n", " 'acceleration_voltage_V', 'zone_hkl', 'Sg_max', 'hkl_max'\n", " Optional parameters are:\n", " 'mistilt', convergence_angle_mrad', and 'crystal_name'\n", " verbose = True will give extended output of the calculation\n", " verbose: boolean\n", " default is False\n", " \n", " Returns\n", " -------\n", " ato,s:\n", " There are three sub_dictionaries in info attribute:\n", " ['allowed'], ['forbidden'], and ['HOLZ']\n", " ['allowed'] and ['forbidden'] dictionaries contain:\n", " ['Sg'], ['hkl'], ['g'], ['structure factor'], ['intensities'],\n", " ['ZOLZ'], ['FOLZ'], ['SOLZ'], ['HOLZ'], ['HHOLZ'], ['label'], and ['Laue_zone']\n", " the ['HOLZ'] dictionary contains:\n", " ['slope'], ['distance'], ['theta'], ['g_deficient'], ['g_excess'], ['hkl'], ['intensities'],\n", " ['ZOLZ'], ['FOLZ'], ['SOLZ'], ['HOLZ'], and ['HHOLZ']\n", " Please note that the Kikuchi lines are the HOLZ lines of ZOLZ\n", " \n", " There are also a few parameters stored in the main dictionary:\n", " ['wave_length_nm'], ['reciprocal_unit_cell'], ['inner_potential_V'], ['incident_wave_vector'],\n", " ['volume'], ['theta'], ['phi'], and ['incident_wave_vector_vacuum']\n", " \n", " make_pretty_labels(hkls, hex_label=False)\n", " Make pretty labels\n", " \n", " Parameters\n", " ----------\n", " hkls: np.ndarray\n", " a numpy array with all the Miller indices to be labeled\n", " hex_label: boolean - optional\n", " if True this will make for Miller indices.\n", " \n", " Returns\n", " -------\n", " hkl_label: list\n", " list of labels in Latex format\n", " \n", " read_poscar(filename)\n", " \n", " ring_pattern_calculation(atoms, verbose=False)\n", " Calculate the ring diffraction pattern of a crystal structure\n", " \n", " Parameters\n", " ----------\n", " atoms: Crystal\n", " crystal structure\n", " verbose: verbose print-outs\n", " set to False\n", " Returns\n", " -------\n", " tags: dict\n", " dictionary with diffraction information added\n", " \n", " scattering_matrix(tags, verbose_level=1)\n", " Scattering matrix\n", " \n", " stage_rotation_matrix(alpha, beta)\n", " Microscope stage coordinate system\n", " \n", " vector_norm(g)\n", " Length of vector\n", " \n", " depreciated - use np.linalg.norm\n", " \n", " zone_mistilt(zone, angles)\n", " Rotation of zone axis by mistilt\n", " \n", " Parameters\n", " ----------\n", " zone: list or numpy array of int\n", " zone axis in Miller indices\n", " angles: ist or numpy array of float\n", " list of mistilt angles in degree\n", " \n", " Returns\n", " -------\n", " new_zone_axis: np.ndarray (3)\n", " new tilted zone axis\n", "\n", "DATA\n", " a_l = 0.3336\n", " base_l = [(0.6666666666666666, 0.3333333333333333, 0.5), (0.3333333333...\n", " c_l = 0.4754\n", " cdb = {'ag': {'a': 4.0853, 'crystal_name': 'silver', 'elements': 'Ag',...\n", " crystal_data_base = {'ag': {'a': 4.0853, 'crystal_name': 'silver', 'el...\n", " electronFF = {'Ac': {'Z': 89, 'bond_length': [2.09, 1.88, 1.7, 0], 'ch...\n", " inputKeys = ['acceleration_voltage_V', 'zone_hkl', 'Sg_max', 'hkl_max'...\n", " jmol_colors = array([[1. , 0. , 0. ],\n", " [1. , 1. ...02, 0...\n", " optional_inputKeys = ['crystal', 'lattice_parameter_nm', 'convergence_...\n", "\n", "FILE\n", " c:\\users\\gduscher\\appdata\\local\\anaconda3\\lib\\site-packages\\pytemlib\\kinematic_scattering.py\n", "\n", "\n" ] } ], "source": [ "help(ks)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Particle Flux and Current\n", "\n", "It is important todetermine the order of magitude of how many electrons are hitting the sample.\n", "\n", "The electron sources deliver in the order of $\\mu$A current, but most of these electrons are not used. \n", "\n", "In a modern electron microscope, we talk about a range of 1pA to 1nA in the electron beam.\n", "\n", "We start with the defition of an Ampere:\n", "$$A = \\frac{C}{s}$$\n", "\n", "That definition is enough to calculate the number ofelectron per time unit (flux)." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " elementary charge: 1.6022e-19 C\n", "\n", " 1pA is 6.24e+06 electrons/s or 6242 electrons/ms\n", " 10pA is 6.24e+07 electrons/s\n", "100pA is 6.24e+08 electrons/s\n", "\n", " at 10pA an electron will hit the sample every 16.02 ns \n" ] } ], "source": [ "print(f\" elementary charge: {scipy.constants.physical_constants['elementary charge'][0]:.5g} {scipy.constants.physical_constants['elementary charge'][1]}\")\n", "print(f'\\n 1pA is {1e-12/scipy.constants.elementary_charge:.3} electrons/s or {1e-12/scipy.constants.elementary_charge/1000:.0f} electrons/ms')\n", "print(f' 10pA is {10e-12/scipy.constants.elementary_charge:.3} electrons/s')\n", "print(f'100pA is {100e-12/scipy.constants.elementary_charge*1 :.3} electrons/s')\n", "\n", "print(f'\\n at 10pA an electron will hit the sample every {scipy.constants.elementary_charge/10e-12 * 1e9:.2f} ns ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see that we have much lower fluence in the TEM than in a laser (how could they do femtosecond pulses otherwise).\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Question\n", "How long does one have to integrate a detector to register 1 electron with an electron beam of 1.6pA?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Navigation\n", "- **Back Chapter 1: [Introduction](../Introduction/CH1_00-Introduction.ipynb)** \n", "- **Next: [Atomic Form Factor](CH2_02-Atomic_Form_Factor.ipynb)** \n", "- **Chapter 2: [Diffraction](CH2_00-Diffraction.ipynb)** \n", "- **List of Content: [Front](../_MSE672_Intro_TEM.ipynb)** " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.10.12" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": { "height": "472.5px", "left": "204px", "top": "194.45px", "width": "168.5px" }, "toc_section_display": true, "toc_window_display": true }, "vscode": { "interpreter": { "hash": "838e0debddb5b6f29d3d8c39ba50ae8c51920a564d3bac000e89375a158a81de" } } }, "nbformat": 4, "nbformat_minor": 4 }