{ "cells": [ { "cell_type": "markdown", "metadata": { "hideCode": true, "hidePrompt": true }, "source": [ "\n", "\n", " **Chapter 4: [Spectroscopy](CH4_00-Spectroscopy.ipynb)** \n", "\n", "
\n", "\n", "\n", "\n", "# Analysis of Core-Loss Spectra\n", "\n", " **Try this notebook in Google Colab** \n", "\n", "\n", "[Download](https://raw.githubusercontent.com/gduscher/MSE672-Introduction-to-TEM/main/Spectroscopy/CH4_09-Analyse_Core_Loss.ipynb)\n", " \n", "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](\n", " https://colab.research.google.com/github/gduscher/MSE672-Introduction-to-TEM/blob/main/Homework/Homework07-Dynamic_CBED.ipynb)\n", "\n", "\n", "\n", "part of \n", "\n", " **[MSE672: Introduction to Transmission Electron Microscopy](../_MSE672_Intro_TEM.ipynb)**\n", "\n", "**Spring 2025**
\n", "by Gerd Duscher\n", "\n", "Microscopy Facilities
\n", "Institute of Advanced Materials & Manufacturing
\n", "Materials Science & Engineering
\n", "The University of Tennessee, Knoxville\n", "\n", "Background and methods to analysis and quantification of data acquired with transmission electron microscopes.\n" ] }, { "cell_type": "markdown", "metadata": { "hideCode": true, "hidePrompt": true }, "source": [ "## Content\n", "\n", "Quantitative determination of chemical composition from a core-loss EELS spectrum\n", "\n", "Please cite:\n", "\n", "[M. Tian et al. *Measuring the areal density of nanomaterials by electron energy-loss spectroscopy*\n", "Ultramicroscopy Volume 196, 2019, pages 154-160](https://doi.org/10.1016/j.ultramic.2018.10.009)\n", "\n", "as a reference of this quantification method.\n", "\n", "## Load important packages\n", "\n", "### Check Installed Packages" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "done\n" ] } ], "source": [ "import sys\n", "import os\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.4.0':\n", " print('installing pyTEMlib')\n", " !{sys.executable} -m pip install --upgrade pyTEMlib -q\n", "\n", "print('done')" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "### Import all relevant libraries\n", "\n", "Please note that the EELS_tools package from pyTEMlib is essential." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "hideCode": true, "hidePrompt": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The autoreload extension is already loaded. To reload it, use:\n", " %reload_ext autoreload\n", "pyTEM version: 0.2026.1.0\n" ] } ], "source": [ "import sys\n", "%matplotlib ipympl\n", "if 'google.colab' in sys.modules: \n", " from google.colab import output\n", " from google.colab import drive\n", " output.enable_custom_widget_manager()\n", " \n", "import numpy as np\n", "import matplotlib.pylab as plt\n", "\n", "import pyTEMlib\n", "\n", "# For archiving reasons it is a good idea to print the version numbers out at this point\n", "print('pyTEM version: ',pyTEMlib.__version__)\n", "__notebook__ = 'analyse_core_loss'\n", "__notebook_version__ = '2026_01_19'\n", "\n", "if 'google.colab' in sys.modules:\n", " drive.mount(\"/content/drive\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Load and plot a spectrum\n", "\n", "As an example we load the spectrum **1EELS Acquire (high-loss).dm3** from the *example data* folder.\n", "\n", "First a dialog to select a file will apear.\n", "\n", "Once you have selected a main datase, we can plot it in the next code cell\n", "\n", "\n", "Please use the ``Energy Scale`` button in the ``Info`` tab to change the energy scale. When pressed the start and end energies of the selected cursor will be used to reculculate the energy scale\n" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "C:\\Users\\gduscher\\OneDrive - University of Tennessee\\GitHub\\MSE672-Introduction-to-TEM\\Spectroscopy\\../example_data\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "31054783ec2e4f32af5d0c292edb1c85", "version_major": 2, "version_minor": 0 }, "text/plain": [ "VBox(children=(Dropdown(description='directory:', layout=Layout(width='90%'), options=('C:\\\\Users\\\\gduscher\\\\O…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "f9af221be0ff4cb0807b2c874c3d2746", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Button(description='Select Main', layout=Layout(grid_area='header', width='auto'), style=Button…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "if 'google.colab' in sys.modules:\n", " if not os.path.exists('./1EELS Acquire (high-loss).dm3'):\n", " !wget https://github.com/gduscher/MSE672-Introduction-to-TEM/raw/main/example_data/1EELS Acquire (high-loss).dm3\n", " !wget https://github.com/gduscher/MSE672-Introduction-to-TEM/raw/main/example_data/1EELS Acquire (low-loss).dm3\n", " example_path = \".\"\n", "else:\n", " example_path = os.path.join(os.path.abspath(\"\"), \"../example_data\")\n", "file_widget = pyTEMlib.file_tools.FileWidget(dir_name=example_path)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "data type 'np.int16' not understood", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mTypeError\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[33]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mpyTEMlib\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfile_tools\u001b[49m\u001b[43m.\u001b[49m\u001b[43mopen_file\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexample_path\u001b[49m\u001b[43m+\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43m\\\u001b[39;49m\u001b[33;43mEDS.rto\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m~\\OneDrive - University of Tennessee\\GitHub\\MSE672-Introduction-to-TEM\\Spectroscopy\\../../pyTEMlib\\pyTEMlib\\file_tools.py:466\u001b[39m, in \u001b[36mopen_file\u001b[39m\u001b[34m(filename, write_hdf_file, sum_frames, sum_eds, eds_stream)\u001b[39m\n\u001b[32m 463\u001b[39m provenance = \u001b[33m'\u001b[39m\u001b[33mSciFiReader.NionReader\u001b[39m\u001b[33m'\u001b[39m\n\u001b[32m 465\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m extension \u001b[38;5;129;01min\u001b[39;00m [\u001b[33m'\u001b[39m\u001b[33m.rto\u001b[39m\u001b[33m'\u001b[39m]:\n\u001b[32m--> \u001b[39m\u001b[32m466\u001b[39m reader = \u001b[43mSciFiReaders\u001b[49m\u001b[43m.\u001b[49m\u001b[43mBrukerReader\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 467\u001b[39m provenance = \u001b[33m'\u001b[39m\u001b[33mSciFiReader.BrukerReader\u001b[39m\u001b[33m'\u001b[39m\n\u001b[32m 469\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m extension \u001b[38;5;129;01min\u001b[39;00m [\u001b[33m'\u001b[39m\u001b[33m.mrc\u001b[39m\u001b[33m'\u001b[39m]:\n", "\u001b[36mFile \u001b[39m\u001b[32m~\\AppData\\Local\\anaconda3\\Lib\\site-packages\\SciFiReaders\\readers\\microscopy\\em\\sem\\bruker_reader.py:249\u001b[39m, in \u001b[36mBrukerReader.__init__\u001b[39m\u001b[34m(self, file_path, verbose)\u001b[39m\n\u001b[32m 247\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[33m'\u001b[39m\u001b[33mrto\u001b[39m\u001b[33m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m.extension:\n\u001b[32m 248\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m249\u001b[39m \u001b[38;5;28mself\u001b[39m.tags = \u001b[43mget_bruker_dictionary\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfile_path\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 251\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mIOError\u001b[39;00m:\n\u001b[32m 252\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mIOError\u001b[39;00m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mFile \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m.__filename\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m does not seem to be of Bruker\u001b[39m\u001b[33m'\u001b[39m\u001b[33ms .rto format\u001b[39m\u001b[33m\"\u001b[39m)\n", "\u001b[36mFile \u001b[39m\u001b[32m~\\AppData\\Local\\anaconda3\\Lib\\site-packages\\SciFiReaders\\readers\\microscopy\\em\\sem\\bruker_reader.py:142\u001b[39m, in \u001b[36mget_bruker_dictionary\u001b[39m\u001b[34m(filename)\u001b[39m\n\u001b[32m 140\u001b[39m tags[\u001b[33m'\u001b[39m\u001b[33mspectrum\u001b[39m\u001b[33m'\u001b[39m][spectrum_number][\u001b[33m'\u001b[39m\u001b[33mresults\u001b[39m\u001b[33m'\u001b[39m][result_tag[\u001b[33m'\u001b[39m\u001b[33mAtom\u001b[39m\u001b[33m'\u001b[39m]] = {}\n\u001b[32m 141\u001b[39m tags[\u001b[33m'\u001b[39m\u001b[33mspectrum\u001b[39m\u001b[33m'\u001b[39m][spectrum_number][\u001b[33m'\u001b[39m\u001b[33mresults\u001b[39m\u001b[33m'\u001b[39m][result_tag[\u001b[33m'\u001b[39m\u001b[33mAtom\u001b[39m\u001b[33m'\u001b[39m]].update(result_tag)\n\u001b[32m--> \u001b[39m\u001b[32m142\u001b[39m tags[\u001b[33m'\u001b[39m\u001b[33mspectrum\u001b[39m\u001b[33m'\u001b[39m][spectrum_number][\u001b[33m'\u001b[39m\u001b[33mdata\u001b[39m\u001b[33m'\u001b[39m] = \u001b[43mnp\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfrombuffer\u001b[49m\u001b[43m(\u001b[49m\u001b[43mspectrum\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfind\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43m./Channels\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[43mtext\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 143\u001b[39m \u001b[43m \u001b[49m\u001b[43mdtype\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mnp.int16\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msep\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m,\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 144\u001b[39m spectrum_number += \u001b[32m1\u001b[39m\n\u001b[32m 145\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m tags\n", "\u001b[31mTypeError\u001b[39m: data type 'np.int16' not understood" ] } ], "source": [ "pyTEMlib.file_tools.open_file(example_path+'\\EDS.rto')" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "\n", "# Creating arrays with numpy.int16 and numpy.uint16 types\n", "data_int16 = np.array([32767, -32768], dtype=np.int16)\n", "data_uint16 = np.array([65535, 0], dtype=np.uint16)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(np.float64(-50.0), np.float64(-49.75))" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "620b0223a2c845fbb34fa3f202e7501d", "version_major": 2, "version_minor": 0 }, "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAScdJREFUeJzt3Xd4VGX+/vH7TLoJHRISmiRSlL6gGJQiQRAE3dWfujZQkP2iFCGyKjZE0YirLq4FRCm6oOCKBQWVDiqwSFtQWGwRWEhEMBAIqTPP748wI5NJaBNyJpn367rmknlO+5xnZuI9zyljGWOMAAAAEDQcdhcAAACAikUABAAACDIEQAAAgCBDAAQAAAgyBEAAAIAgQwAEAAAIMgRAAACAIEMABAAACDIEQAAAgCBDAAQAAAgyBEAAAIAgQwAEAAAIMgRAAACAIEMABAAACDIEQAAAgCBDAAQAAAgyBEAAAIAgQwAEAAAIMgRAAACAIEMABAAACDIEQAAAgCBDAAQAAAgyBEAAAIAgQwAEAAAIMgRAIEAcOXJE999/v3r37q169erJsiw9/vjjpc7bo0cPWZZV6uP888/3zLdy5coy57MsS7NmzfJaZ+vWrU9Z5+eff67evXsrISFBERERSkhIUI8ePfTMM8+c0f5ed911sixLI0aMOKPlzrVZs2bJsiz9/PPPFbbNlJQUDRs2zPPc/bqtXLmywmooyx133OH1nqpoy5YtU0xMjPbu3WtbDUBVFGp3AQCKHTx4UNOmTVO7du30xz/+UW+88cZJ509MTNScOXN82iMiInzann76aV1xxRU+7UlJSWdU49SpU3X33Xfr+uuv18svv6zatWtrz549WrNmjd577z09+OCDp7We/fv365NPPpEkzZkzR88995wiIyPPqJZz5eqrr9batWsVHx9fIdv76KOP9NVXX+mtt96qkO1VNikpKbrkkkv00EMP6c0337S7HKDKIAACAaJJkybKysqSZVk6cODAKQNgVFSULr300tNad7NmzU573pNJS0tTt27d9N5773m133777XK5XKe9nrfeekuFhYW6+uqrtXDhQr3//vu65ZZb/K6vPNSrV0/16tU75XzHjh3Teeed5/f2nn76af3pT39SgwYN/F5XVTV8+HDddNNNmjhxoho1amR3OUCVwCFgIEC4D8sGsoMHD5Y5MuZwnP6fkxkzZiguLk5vvvmmoqKiNGPGjFLn+/e//60BAwaoTp06ioyMVFJSkkaPHu01z8KFC9W+fXtFRESoadOmeu655/T444979eXPP//sc8jbreSh9tIOAbsPj69evVpdunTReeedp8GDB0uSsrOzNXbsWDVt2lTh4eFq0KCBRo8erZycnFP2w+bNm7V+/Xrdfvvtp5xXkhYsWKDk5GSdd955qlatmq688kqtXbvWM/3bb7+VZVn617/+5WnbuHGjLMtSq1atvNZ1zTXXqGPHjqe13ZLy8vI0btw4r30ePny4Dh065DXf8uXL1aNHD9WpU0dRUVFq3Lixrr/+eh07dswzz5QpU9SuXTvFxMSoWrVqatmypR566CGv9QwYMEAxMTF6/fXXz6peAL4IgEAlVlRU5PMobSTO5XKVOu+ZSk5O1vz58/X444/rP//5j5xO5xmvY82aNdqxY4cGDhyoOnXq6Prrr9fy5cuVnp7uNd/nn3+url27avfu3XrhhRf06aef6pFHHtEvv/zimWfZsmW69tprVa1aNc2dO1d/+9vf9O6772rmzJlnXNepZGRk6LbbbtMtt9yiRYsW6Z577tGxY8fUvXt3vfnmmxo1apQ+/fRTPfDAA5o1a5auueYaGWNOus5PPvlEISEh6tat2ym3//bbb+vaa69V9erV9c4772j69OnKyspSjx499OWXX0qSWrVqpfj4eC1dutSz3NKlSxUVFaXt27dr3759korfN6tWrVKvXr3OuB+MMfrjH/+o5557TrfffrsWLlyo1NRUvfnmm+rZs6fy8/MlFYfuq6++WuHh4ZoxY4Y+++wzPfPMM4qOjlZBQYEkae7cubrnnnvUvXt3ffDBB/rwww81ZswYn/AcHh6uLl26aOHChWdcL4AyGAAB59dffzWSzPjx40ud3r17dyOp1MeQIUM8861YsaLM+SSZPXv2eK2zVatWJ63rhx9+MK1bt/YsHxUVZVJSUszLL79sCgoKTmvfBg8ebCSZHTt2eNX46KOPes2XlJRkkpKSTG5ubpnr6ty5s0lISPCaJzs729SuXduc+OctPT3dSDIzZ870WUfJfp45c6aRZNLT0z1t7v5etmyZ17JpaWnG4XCYr7/+2qv9vffeM5LMokWLyqzdGGP69u1rWrZs6dPu7pMVK1YYY4xxOp0mISHBtGnTxjidTs98R44cMbGxsaZLly6etttuu80kJiZ6nvfq1csMHTrU1KpVy7z55pvGGGO++uorI8ksXrz4pPUZY8ygQYNMkyZNPM8/++wzI8k8++yzXvPNmzfPSDLTpk3z6oMtW7aUue4RI0aYmjVrnrIGY4x5+OGHjcPhMEePHj2t+QGcHCOAQCWVlJSkr7/+2ufx6KOP+sw7adKkUueNi4s7423+5z//0apVqzRhwgT16tVLX3/9tUaMGKHk5GTl5eWddPmjR4/q3XffVZcuXdSyZUtJUvfu3ZWUlKRZs2Z5Ri+/++47/fjjjxoyZEiZF4fk5OTo66+/1nXXXec1T7Vq1TRgwIAz2q/TUatWLfXs2dOr7ZNPPlHr1q3Vvn17r5HVPn36nNZVvPv27VNsbOwpt71z507t27dPt99+u9eh9piYGF1//fVat26d57BqSkqKfvrpJ6WnpysvL09ffvmlrrrqKl1xxRVasmSJpOJRwYiICF1++eWSfEeITzayu3z5cknFVwef6IYbblB0dLSWLVsmSWrfvr3Cw8P1l7/8RW+++aZ++uknn3VdcsklOnTokG6++WZ99NFHOnDgQJnbjY2NlcvlUmZm5in7C8CpEQCBSioyMlKdOnXyeTRp0sRn3sTExFLnDQsLO+PtOhwOdevWTY899pgWLFigffv26aabbtLGjRvLPJfPbd68eTp69KhuvPFGHTp0SIcOHdLhw4d14403as+ePZ6A8uuvv0qSGjZsWOa6srKy5HK5VL9+fZ9ppbX5q7RzH3/55Rdt3bpVYWFhXo9q1arJGHPSQCNJubm5p3X188GDB8usISEhQS6XS1lZWZLkOay7dOlSffnllyosLFTPnj3Vq1cvTzhbunSpLrvsMkVFRUmSnnjiCa/6T3Z1+MGDBxUaGupzoYxlWapfv76n1qSkJC1dulSxsbEaPny4kpKSlJSUpBdffNGzzO23364ZM2Zo165duv766xUbG6vOnTt73gcncvdTbm7uKfsLwKlxFTAAv0RHR2vcuHGaN2+evvnmm5POO336dEnS6NGjfS7mcE/v06ePJ1z873//K3NdtWrVkmVZpY4IlWxzhwf3+Wlu7rByOkq7QKdu3bonvYilbt26J11n3bp19dtvv51y23Xq1JFUfB5iSfv27ZPD4VCtWrUkFYfm5s2ba+nSpTr//PPVqVMn1axZUykpKbrnnnv073//W+vWrdOECRM86/jLX/6i/v37e56XdiuhE2spKirSr7/+6hUCjTHKzMzUxRdf7Gnr2rWrunbtKqfTqQ0bNuill17S6NGjFRcXpz//+c+SpDvvvFN33nmncnJytHr1ao0fP179+/fXd9995/Vlxt1Pp+pTAKeHEUAAp620ACJJO3bskFQ8GlWWHTt2aO3atbr++uu1YsUKn0dKSoo++ugjHTx4UM2bN1dSUpJmzJjhE9rcoqOjdckll+j999/3OvR85MgRffzxx17zxsXFKTIyUlu3bvVq/+ijj05rv8vSv39//fjjj6pTp06pI6ynuoFyy5YtSz00WlKLFi3UoEEDvf32214XluTk5Gj+/PmeK4PdevXqpeXLl2vJkiW68sorJUnNmzdX48aN9dhjj6mwsNDrApCEhASvutu0aVNmLSkpKZKk2bNne7XPnz9fOTk5nuknCgkJUefOnfXKK69IkjZt2uQzT3R0tPr27auHH35YBQUF+vbbb72m//TTT6pTp84Zn7YAoHSMAAIB5NNPP1VOTo6OHDkiSdq+fbvnnnv9+vXz+p98bm6u1q1bV+p6St7z7/vvvy913oYNG3odZs3Ozva5x59UfG+87t27q1WrVkpJSVHfvn2VlJSkvLw8/fvf/9bzzz+vuLg4DRkypMx9c4/+3X///brkkkt8ph85ckTLli3T7Nmzde+99+qVV17RgAEDdOmll2rMmDFq3Lixdu/erc8//9xzA+wnn3xSV111la688krdd999cjqdmjRpkqKjo71G1izL0m233aYZM2YoKSlJ7dq10/r16/X222+XWe/pGD16tObPn69u3bppzJgxatu2rVwul3bv3q3FixfrvvvuU+fOnctcvkePHpoxY4a+++47NW/evMz5HA6Hnn32Wd16663q37+//u///k/5+fn629/+pkOHDvn8CktKSopeffVVHThwQJMnT/ZqnzlzpmrVqnXWt4C58sor1adPHz3wwAPKzs7WZZddpq1bt2r8+PHq0KGD55Y2U6dO1fLly3X11VercePGysvL84yUusPn0KFDFRUVpcsuu0zx8fHKzMxUWlqaatSo4TWSKEnr1q1T9+7dA/5WSUClYfNFKABO0KRJkzKv2C3tqtSyHoWFhcaYU18F/PDDD5/WOrt3726MMea1114z1113nUlMTDTnnXeeCQ8PN0lJSWbY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sj766CObK8PZ4jYwAAAENlsD4JQpU5Samqp+/frp0KFDnnP+atasqcmTJ9tZGs4AVwEDAFC52BoAX3rpJb3++ut6+OGHFRIS4mnv1KmTtm3bZmNlOBOM+AEAULnYGgDT09PVoUMHn/aIiAjl5OTYUBHKA4EQAIDAZmsAbNq0qeen20706aef6qKLLqr4gnBWuAoYAIDKxdargP/6179q+PDhysvLkzFG69ev1zvvvKO0tDS98cYbdpaGM8CIHwAAlYutAfDOO+9UUVGR7r//fh07dky33HKLGjRooBdffFF//vOf7SwNfjjZT/IBAAD72RoAJWno0KEaOnSoDhw4IJfLpdjYWLtLwhnyuQqY/AcAQECz9RzAnj176tChQ5KkunXresJfdna2evbsaWNlOBOM+AEAULnYGgBXrlypgoICn/a8vDx98cUXNlQEAABQ9dlyCHjr1q2ef2/fvl2ZmZme506nU5999pkaNGhgR2k4CwwAAgBQudgSANu3by/LsmRZVqmHeqOiovTSSy/ZUBnKA4EQAIDAZksATE9PlzFGiYmJWr9+verVq+eZFh4ertjYWK9fBkHlwk/BAQAQ2GwJgE2aNJEkuVwuOzaPcsaIHwAAlYvtt4H57rvvtHLlSu3fv98nED722GM2VYUz4fNLIARCAAACmq0B8PXXX9fdd9+tunXrqn79+rIsyzPNsiwCYCVF/gMAILDZGgAnTpyop556Sg888ICdZcBPjPgBAFC52HofwKysLN1www12loBy4PtLICRCAAACma0B8IYbbtDixYvtLAEAACDo2HoI+IILLtCjjz6qdevWqU2bNgoLC/OaPmrUKJsqw5koOeLH+B8AAIHN1gA4bdo0xcTEaNWqVVq1apXXNMuyCICVhO8hYFvKAAAAp8nWAJienm7n5gEAAIKSrecAomrwHfFjCBAAgEBW4SOAqampevLJJxUdHa3U1NSTzvvCCy9UUFXwDzeCBgCgMqnwALh582YVFhZ6/l2WE28KDQAAgPJT4QFwxYoVpf4blVfJET8GAAEACGycAwi/EfgAAKhcCIAod5wDCABAYCMAwm++h4BJgAAABDICIPxG4AMAoHIhAKLccQgYAIDARgCE33wOARMAAQAIaARA+I1zAAEAqFwIgCh3jAACABDYCIDwW8kRPwIgAACBjQAIv3EIGACAyoUAiHLn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RjVu3FhTpkzxzN+tWzclJibqn//8p6etqKhIs2fP1p133nna+3jHHXdow4YNWrBggdauXStjjPr16+cZhRw+fLjy8/O1evVqbdu2TZMmTVJMTIwk6dFHH9X27dv16aefaseOHZoyZYrq1q1b5rZWr16tTp06ebVlZGSoe/fuat++vTZs2KDPPvtMv/zyi2688UZJUmhoqAYOHKhZs2bpxJ93/9e//qWCggLdeuutnrbw8HC1a9dOX3zxxWnvP4AqyADAWTp69KiJjIw0a9as8WofMmSIufnmm40xxqxYscJIMkuXLvVMX7hwoZFkcnNzjTHGdO3a1Tz99NNe6/jnP/9p4uPjPc8lmdGjR3vN07lzZzN8+HCvtssuu8y0a9fO83zSpEnmwgsv9Dz/8MMPTUxMjDl69GiZ+9W9e3dz7733GmOM+e6774wk89VXX3mmHzhwwERFRZl3333XGGNMmzZtzOOPP17qugYMGGDuvPPOMrdV0rXXXmsGDx7s1fboo4+a3r17e7Xt2bPHSDI7d+40xhizY8cOI8ksX77cM0+3bt08r8OJ/vSnP5k77rjjtGsCUPUwAgjgrG3fvl15eXm68sorFRMT43m89dZb+vHHH73mbdu2reff8fHxkqT9+/dLkjZu3KgnnnjCax1Dhw5VRkaGjh075lmu5MjYzp07dckll3i1lXx+xx136IcfftC6deskFZ8Td+ONNyo6OlpffPGF1zbnzJnjs487duxQaGioOnfu7GmrU6eOWrRooR07dkiSRo0apYkTJ+qyyy7T+PHjtXXrVs+8d999t+bOnav27dvr/vvv15o1a07ap7m5uYqMjPRq27hxo1asWOFVa8uWLSXJ088tW7ZUly5dNGPGDE/7F1984TXS6hYVFeXVrwCCT6jdBQCovFwulyRp4cKFatCggde0iIgIr+dhYWGef1uW5bW8y+XShAkTdN111/ls48QwFB0d7TPdvS43c8IhUEmKjY3VgAEDNHPmTCUmJmrRokVauXKlpOJAuWXLFs+8cXFxPusvub4T293bvuuuu9SnTx8tXLhQixcvVlpamp5//nmNHDlSffv21a5du7Rw4UItXbpUKSkpGj58uJ577rlS11u3bl1lZWV5tblcLg0YMECTJk3ymd8dpqXii0FGjBihV155RTNnzlSTJk2UkpLis8xvv/2mpKSkUrcPIDgwAgjgrF100UWKiIjQ7t27dcEFF3g9GjVqdNrr+cMf/qCdO3f6rOOCCy6Qw1H2n6kWLVpo/fr1Xm0bNmzwme+uu+7S3Llz9dprrykpKUmXXXaZpOKRsBO3Va1atVL3saioSP/+9789bQcPHtR3332nCy+80NPWqFEjDRs2TO+//77uu+8+vf76655p9erV0x133KHZs2dr8uTJmjZtWpn71KFDB23fvt2nf7799ludf/75Pv1zYii+8cYbFRISorfffltvvvmm7rzzTp+ALEnffPONOnToUGYNAKo+RgABnLVq1app7NixGjNmjFwuly6//HJlZ2drzZo1iomJ0aBBg05rPY899pj69++vRo0a6YYbbpDD4dDWrVu1bds2z9W+pRk5cqSGDh2qTp06qUuXLpo3b562bt2qxMREr/n69OmjGjVqaOLEiXriiSfOaB+bNWuma6+9VkOHDtVrr72matWq6cEHH1SDBg107bXXSpJGjx6tvn37qnnz5srKytLy5cs94fCxxx5Tx44d1apVK+Xn5+uTTz7xCo4l9enTR+PGjVNWVpZq1aolqfgik9dff10333yz/vrXv6pu3br64YcfNHfuXL3++usKCQmRJMXExOimm27SQw89pMOHD+uOO+7wWf/PP/+svXv3lnnfQADBgRFAAH558skn9dhjjyktLU0XXnih+vTpo48//lhNmzY97XX06dNHn3zyiZYsWaKLL75Yl156qV544QU1adLkpMvdeuutGjdunMaOHas//OEPSk9P1x133OFzDp3D4dAdd9whp9OpgQMHnvE+zpw5Ux07dlT//v2VnJwsY4wWLVrkOaztdDo1fPhwXXjhhbrqqqvUokULvfrqq5KKr7odN26c2rZtq27duikkJERz584tc1tt2rRRp06d9O6773raEhIS9NVXX8npdKpPnz5q3bq17r33XtWoUcNnhHTIkCHKyspSr1691LhxY5/1v/POO+rdu/cp+xZA1WaZsk5wAYBK6Morr1T9+vW9bv0iSUOHDtUvv/yiBQsW2FTZ6Vu0aJHGjh2rb7755qSHwM9Ufn6+mjVrpnfeecdzGBxAcOIQMIBK69ixY5o6dar69OmjkJAQvfPOO1q6dKmWLFnimefw4cP6+uuvNWfOHH300Uc2Vnv6+vXrp++//1579+49o3MpT2XXrl16+OGHCX8AGAEEUHnl5uZqwIAB2rRpk/Lz89WiRQs98sgjXlcT9+jRQ+vXr9f//d//8Ru4AHAcARAAACDIcBEIAABAkCEAAgAABBkCIAAAQJAhAAIAAAQZAiAAAECQIQACAAAEGQIgAABAkCEAAgAABBkCIAAAQJD5/+0fJC8a6UB9AAAAAElFTkSuQmCC", "text/html": [ "\n", "
\n", "
\n", " Figure\n", "
\n", " \n", "
\n", " " ], "text/plain": [ "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "datasets = file_widget.datasets\n", "main_dataset = file_widget.selected_dataset\n", "main_dataset.plot()\n", "main_dataset.energy_loss[0], main_dataset.energy_loss[1]" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "tags": [] }, "outputs": [ { "ename": "AttributeError", "evalue": "module 'pyTEMlib' has no attribute 'eels_dialog'", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mAttributeError\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[14]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m quantification = \u001b[43mpyTEMlib\u001b[49m\u001b[43m.\u001b[49m\u001b[43meels_dialog\u001b[49m.CompositionWidget(datasets=datasets, key=\u001b[33m'\u001b[39m\u001b[33mChannel_000\u001b[39m\u001b[33m'\u001b[39m)\n", "\u001b[31mAttributeError\u001b[39m: module 'pyTEMlib' has no attribute 'eels_dialog'" ] } ], "source": [ "\n" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "c9ff6f69758142e78516a7ff33a2b561", "version_major": 2, "version_minor": 0 }, "text/plain": [ "AppLayout(children=(Tab(children=(GridspecLayout(children=(Dropdown(description='directory:', layout=Layout(gr…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pyTEMlib.info_widget\n", "eelsWidget = pyTEMlib.info_widget.EELSWidget(\".\")" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'edges': {'fit_area': {'fit_start': 150.5, 'fit_end': 609.5},\n", " '0': {'z': 5,\n", " 'symmetry': 'K1',\n", " 'element': 'B',\n", " 'onset': 188.0,\n", " 'end_exclude': 238.0,\n", " 'start_exclude': 183.0,\n", " 'all_edges': {'K1': {'onset': 188.0}},\n", " 'chemical_shift': 0.0,\n", " 'areal_density': 15370.259182290087,\n", " 'original_onset': 188.0,\n", " 'data': array([5.04702221e-09, 5.00509797e-09, 4.96317372e-09, ...,\n", " 1.62111761e-10, 1.61818311e-10, 1.61524861e-10]),\n", " 'X_section_type': 'XRPA',\n", " 'X_section_source': 'pyTEMlib'},\n", " '1': {'z': 7,\n", " 'symmetry': 'K1',\n", " 'element': 'N',\n", " 'onset': 401.6,\n", " 'end_exclude': 451.6,\n", " 'start_exclude': 396.6,\n", " 'all_edges': {'K1': {'onset': 401.6}},\n", " 'chemical_shift': 0.0,\n", " 'areal_density': 15370.259182290087,\n", " 'original_onset': 401.6,\n", " 'data': array([2.00956373e-08, 1.99304356e-08, 1.97652339e-08, ...,\n", " 5.36017470e-10, 5.35104535e-10, 5.34191601e-10]),\n", " 'X_section_type': 'XRPA',\n", " 'X_section_source': 'pyTEMlib'},\n", " 'model': {'background': energy_loss: energy-loss (eV) of size (2048,),\n", " 'background-poly_0': 10.0,\n", " 'background-poly_1': 1.0,\n", " 'background-poly_2': 0.0,\n", " 'background-A': 480931016.6195635,\n", " 'background-r': -1.8392560877024688,\n", " 'spectrum': energy_loss: energy-loss (eV) of size (2048,),\n", " 'blurred': array([139757.54409064, 139617.83997849, 139350.37663315, ...,\n", " 658.92534137, 628.73955145, 612.56324436]),\n", " 'mask': array([0., 0., 0., ..., 0., 0., 1.]),\n", " 'fit_parameter': array([ 4.80931017e+08, -1.83925609e+00, 1.00000000e+01, 1.00000000e+00,\n", " 0.00000000e+00, 1.53702592e+04, 1.53702592e+04]),\n", " 'fit_area_start': 150.5,\n", " 'fit_area_end': 609.5,\n", " 'xsec': array([[5.04702221e-09, 5.00509797e-09, 4.96317372e-09, ...,\n", " 1.62111761e-10, 1.61818311e-10, 1.61524861e-10],\n", " [2.00956373e-08, 1.99304356e-08, 1.97652339e-08, ...,\n", " 5.36017470e-10, 5.35104535e-10, 5.34191601e-10]])}},\n", " 'experiment': {'convergence_angle': 30,\n", " 'collection_angle': 40,\n", " 'acceleration_voltage': 60000,\n", " 'eff_beta': 33.635205259094015}}" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eelsWidget.dataset.metadata" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [], "source": [ "eelsWidget.core_loss.dataset.metadata['experiment'] = {'convergence_angle': 30,\n", " 'collection_angle': 40,\n", " 'acceleration_voltage': 60}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Chemical Composition \n", "The fit of the cross-section and background to the spectrum results in the chemical composition. If the calibration is correct this composition is given as areal density in atoms/nm$^2$\n", "\n", "\n", "### Fit of Data\n", "A dialog window will open, enter the elements first (0 will open a periodic table) and press \n", "``Fit Composition`` button (bottom right). Adjust parameters as needed and check fit by pressing the ``Fit Composition`` button again.\n", "\n", "Select the ``Region`` checkbox to see which parts of the spectrum you choose to fit.\n", "\n", "Changing the multiplier value will make a simulation of your spectrum.\n", "\n", "The ``InfoDialog``, if open, still works to change experimental parameters and the energy scale." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "tags": [] }, "outputs": [ { "ename": "NameError", "evalue": "name 'quantification' is not defined", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[18], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m found_edges \u001b[38;5;241m=\u001b[39m eels\u001b[38;5;241m.\u001b[39mauto_id_edges(\u001b[43mquantification\u001b[49m \u001b[38;5;241m.\u001b[39mdataset)\n\u001b[0;32m 2\u001b[0m found_edges\n\u001b[0;32m 3\u001b[0m to_delete \u001b[38;5;241m=\u001b[39m []\n", "\u001b[1;31mNameError\u001b[0m: name 'quantification' is not defined" ] } ], "source": [ "found_edges = eels.auto_id_edges(quantification .dataset)\n", "found_edges\n", "to_delete = []\n", "if len(found_edges) >0:\n", " for key in quantification.edges:\n", " if key.isdigit():\n", " to_delete.append(key)\n", "for key in to_delete:\n", " del quantification.edges[key]\n", "if '0' not in quantification.edges:\n", " quantification.edges['0'] = {}\n", "selected_elements = []\n", "for key in found_edges:\n", " selected_elements.append(key)\n", "#view.set_elements(selected_elements)\n", "\n", "for index, elem in enumerate(selected_elements):\n", " print(index)\n", " quantification.update_element(elem, index)\n", "quantification.update()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "{'ImageData': {'Calibrations': {'Brightness': {'Origin': 0.0,\n", " 'Scale': 1.0,\n", " 'Units': 'Counts'},\n", " 'Dimension': {'0': {'Origin': -1400.0, 'Scale': 0.25, 'Units': 'eV'}},\n", " 'DisplayCalibratedUnits': 1},\n", " 'Data': 'read',\n", " 'DataType': 2,\n", " 'Dimensions': {'0': 2048},\n", " 'PixelDepth': 4},\n", " 'ImageTags': {'Acquisition': {'Device': {'Active Size (pixels)': [2048, 520],\n", " 'Camera Number': 0,\n", " 'CCD': {'Pixel Size (um)': [14.0, 14.0]},\n", " 'Configuration': {'Transpose': {'Diagonal Flip': 0,\n", " 'Horizontal Flip': 0,\n", " 'Vertical Flip': 0}},\n", " 'Name': 'QUEFINA 1',\n", " 'Source': 'QUEFINA 1'},\n", " 'Frame': {'Area': {'Transform': {'Class Name': 'cm_acquisitiontransform_list',\n", " 'Transform List': {'0': {'Binning': [1, 130],\n", " 'Class Name': 'cm_acquisitiontransform',\n", " 'Sub Area Adjust': [0, 0, 0, 0],\n", " 'Transpose': {'Diagonal Flip': 0,\n", " 'Horizontal Flip': 0,\n", " 'Vertical Flip': 0}}}}},\n", " 'CCD': {'Pixel Size (um)': [1820.0, 14.0]},\n", " 'Intensity': {'Transform': {'Class Name': 'cm_valuetransform_list',\n", " 'Transform List': {'0': {'Class Name': 'cm_valuetransform_affine',\n", " 'Offset': 250.0,\n", " 'Scale': 1.0},\n", " '1': {'ADC Max': 65535.0,\n", " 'ADC Min': 0.0,\n", " 'Class Name': 'cm_valuetransform_adc'}}}}},\n", " 'Parameters': {'Acquisition Write Flags': 4294967295,\n", " 'Base Detector': {'Class Name': 'cm_namedcameradetectorparameterset',\n", " 'Name': 'default'},\n", " 'Detector': {'continuous': 1,\n", " 'exposure (s)': 2.0,\n", " 'hbin': 1,\n", " 'height': 260,\n", " 'left': 0,\n", " 'top': 130,\n", " 'vbin': 130,\n", " 'width': 2048},\n", " 'Environment': {'Mode Name': 'Spectroscopy'},\n", " 'High Level': {'Acquisition Buffer Size': 0,\n", " 'Antiblooming': 0,\n", " 'Binning': [1, 130],\n", " 'CCD Read Area': [130, 0, 390, 2048],\n", " 'CCD Read Ports': 1,\n", " 'Choose Number Of Frame Shutters Automatically': 1,\n", " 'Class Name': 'cm_camera_highlevelparameters',\n", " 'Continuous Readout': 1,\n", " 'Corrections': 305,\n", " 'Corrections Mask': 817,\n", " 'Exposure (s)': 2.0,\n", " 'Number Of Frame Shutters': 1,\n", " 'Processing': 'Dark Subtracted',\n", " 'Quality Level': 1,\n", " 'Read Frame Style': 0,\n", " 'Read Mode': 13,\n", " 'Secondary Shutter Post Exposure Compensation (s)': 0.0,\n", " 'Secondary Shutter Pre Exposure Compensation (s)': 0.0,\n", " 'Shutter': {'Primary Shutter States': 0,\n", " 'Primary Shutter States Mask': 0,\n", " 'Secondary Shutter States': 0,\n", " 'Secondary Shutter States Mask': 0,\n", " 'Shutter Exposure': 0,\n", " 'Shutter Index': 0},\n", " 'Shutter Post Exposure Compensation (s)': 0.0,\n", " 'Shutter Pre Exposure Compensation (s)': 0.0,\n", " 'Transform': {'Diagonal Flip': 0,\n", " 'Horizontal Flip': 0,\n", " 'Vertical Flip': 0}},\n", " 'Objects': {'0': {'Class Name': 'cm_imgproc_finalcombine',\n", " 'Frame Combine Style': 'Copy',\n", " 'Parameter 1': 1.0}},\n", " 'Parameter Set Name': 'Acquire',\n", " 'Parameter Set Tag Path': 'Spectroscopy:Acquire:Acquire',\n", " 'Version': 33947648}},\n", " 'EELS': {'Acquisition': {'Continuous mode': 0,\n", " 'Date': '12/14/2019',\n", " 'End time': '1:31:04 PM',\n", " 'Exposure (s)': 2.0,\n", " 'Integration time (s)': 20.0,\n", " 'Number of frames': 10,\n", " 'Saturation fraction': 0.21766255795955658,\n", " 'Start time': '1:30:41 PM'},\n", " 'Experimental Conditions': {'Collection semi-angle (mrad)': 33.0,\n", " 'Convergence semi-angle (mrad)': 30.0}},\n", " 'EELS Spectrometer': {'Dispersion (eV/ch)': 0.25,\n", " 'Dispersion index': 4,\n", " 'Drift tube enabled': 1,\n", " 'Drift tube voltage (V)': 400.0,\n", " 'Energy loss (eV)': 400.0,\n", " 'HT offset (V)': 0.0,\n", " 'HT offset enabled': 0.0,\n", " 'Instrument ID': 3977,\n", " 'Instrument name': 'Enfinium ER NION',\n", " 'Mode': 0,\n", " 'Prism offset (V)': -0.0,\n", " 'Prism offset enabled ': 1},\n", " 'Meta Data': {'Acquisition Mode': 'Parallel dispersive',\n", " 'Format': 'Spectrum',\n", " 'Signal': 'EELS'},\n", " 'Microscope Info': {'Cs(mm)': 0.0,\n", " 'Emission Current (A)': 0.0,\n", " 'Formatted Indicated Mag': '100x',\n", " 'Formatted Voltage': '200kV',\n", " 'Illumination Mode': 'STEM',\n", " 'Imaging Mode': 'IMAGING',\n", " 'Indicated Magnification': 100.0,\n", " 'Name': 'Unknown',\n", " 'Operation Mode': 'SCANNING',\n", " 'Probe Current (nA)': 0.0,\n", " 'Probe Size (nm)': 0.0,\n", " 'STEM Camera Length': 2.8,\n", " 'Voltage': 200000.0},\n", " 'Session Info': {'Items': {'0': {'Data Type': 20,\n", " 'Label': 'Specimen',\n", " 'Precision': 0,\n", " 'Tag path': 'Session Info:Specimen',\n", " 'Units': '',\n", " 'Value': ''},\n", " '1': {'Data Type': 20,\n", " 'Label': 'Operator',\n", " 'Precision': 0,\n", " 'Tag path': 'Session Info:Operator',\n", " 'Units': '',\n", " 'Value': ''},\n", " '2': {'Data Type': 20,\n", " 'Label': 'Microscope',\n", " 'Precision': 0,\n", " 'Tag path': 'Session Info:Microscope',\n", " 'Units': '',\n", " 'Value': ''}},\n", " 'Microscope': '',\n", " 'Operator': '',\n", " 'Specimen': ''}},\n", " 'Name': '01-EELS Acquire_STO',\n", " 'UniqueID': {'0': 774116825, '1': 412555428, '2': 1897604613, '3': 952377132},\n", " 'DM': {'dm_version': 3,\n", " 'file_size': 322611,\n", " 'full_file_name': 'C:\\\\Users\\\\gduscher\\\\Documents\\\\Github\\\\MSE672-Introduction-to-TEM\\\\example_data\\\\EELS_STO.dm3'},\n", " 'original_filename': 'C:\\\\Users\\\\gduscher\\\\Documents\\\\Github\\\\MSE672-Introduction-to-TEM\\\\example_data\\\\EELS_STO.dm3',\n", " 'ApplicationBounds': [0, 0, 1065, 1916],\n", " 'DocumentObjectList': {'0': {'AnnotationGroupList': {},\n", " 'AnnotationType': 20,\n", " 'BackgroundColor': [-1, -1, -1],\n", " 'BackgroundMode': 2,\n", " 'FillMode': 2,\n", " 'ForegroundColor': [-1, 0, 0],\n", " 'HasBackground': 0,\n", " 'ImageDisplayInfo': {'BackgroundColor': [-5655, -5655, -5655],\n", " 'BackgroundOn': 1,\n", " 'CalibrationSliceId': {'0': 0},\n", " 'CaptionAttributes': 7,\n", " 'CaptionColor': [0, 0, 0],\n", " 'CaptionFaceName': 'Lucida Sans Unicode',\n", " 'CaptionOn': 1,\n", " 'CaptionSize': 10,\n", " 'CursorOn': 0,\n", " 'CursorPosition': 0.0,\n", " 'DimensionLabels': {'0': ''},\n", " 'DynamicContrast': 1,\n", " 'FrameOn': 1,\n", " 'GridColor': [0, -1, -1],\n", " 'GridOn': 1,\n", " 'GroupId': 0,\n", " 'GroupList': {'0': {'DoAutoSurveyHigh': 1,\n", " 'DoAutoSurveyLow': 1,\n", " 'GroupToDisplay': {'Offset': [-0.0, -0.0],\n", " 'Scale': [0.00048828125, 4.16666489400086e-06]},\n", " 'TrackStyleX': 0,\n", " 'TrackStyleY': 0}},\n", " 'LegendOn': 0,\n", " 'MainSliceId': {'0': 0},\n", " 'NumHorizontalTicks': 1,\n", " 'NumVerticalTicks': 1,\n", " 'SliceList': {'0': {'BaseIntensity': 0.0,\n", " 'ComplexMode': 4,\n", " 'DrawFill': 1,\n", " 'DrawLine': 0,\n", " 'DrawTransparent': 0,\n", " 'FillColor': [23644, -16449, -16449],\n", " 'Horz Pos Fixed': 1,\n", " 'Horz Scale Fixed': 1,\n", " 'ImageToGroup': {'Offset': [0.0, 0.0], 'Scale': [1.0, 1.0]},\n", " 'IsVisible': 1,\n", " 'LineColor': [0, -32640, -16449],\n", " 'LineStyle': 0,\n", " 'LineThickness': 1,\n", " 'SliceGroup': 0,\n", " 'SliceId': {'0': 0},\n", " 'Transparency': 0.0,\n", " 'TransparencyStyle': 0,\n", " 'Vert Pos Fixed': 1,\n", " 'Vert Scale Fixed': 1}},\n", " 'SurveyRegion': 1},\n", " 'ImageDisplayType': 3,\n", " 'ImageSource': 0,\n", " 'IsMoveable': 1,\n", " 'IsResizable': 1,\n", " 'IsSelectable': 1,\n", " 'IsTranslatable': 1,\n", " 'IsVisible': 1,\n", " 'ObjectTags': {},\n", " 'Rectangle': [0.0, 0.0, 342.0, 669.0],\n", " 'UniqueID': 8}},\n", " 'DocumentTags': {},\n", " 'HasWindowPosition': 1,\n", " 'Image Behavior': {'DoIntegralZoom': 0,\n", " 'ImageDisplayBounds': [0.0, 0.0, 342.0, 669.0],\n", " 'IsZoomedToWindow': 1,\n", " 'UnscaledTransform': {'Offset': [0.0, 0.0], 'Scale': [1.0, 1.0]},\n", " 'ViewDisplayID': 8,\n", " 'WindowRect': [0.0, 0.0, 342.0, 669.0],\n", " 'ZoomAndMoveTransform': {'Offset': [0.0, 0.0], 'Scale': [1.0, 1.0]}},\n", " 'ImageSourceList': {'0': {'ClassName': 'ImageSource:Simple',\n", " 'Extra Slice Info': {'0': {'Id': {'0': 0}, 'Label': 'Spectrum'}},\n", " 'Id': {'0': 0},\n", " 'ImageRef': 1}},\n", " 'InImageMode': 1,\n", " 'MinVersionList': {'0': {'RequiredVersion': 50659328}},\n", " 'NextDocumentObjectID': 9,\n", " 'Page Behavior': {'DoIntegralZoom': 0,\n", " 'DrawMargins': 1,\n", " 'DrawPaper': 1,\n", " 'IsFixedInPageMode': 0,\n", " 'IsZoomedToWindow': 1,\n", " 'LayedOut': 0,\n", " 'PageTransform': {'Offset': [0.0, 0.0], 'Scale': [1.0, 1.0]},\n", " 'RestoreImageDisplayBounds': [0.0, 0.0, 342.0, 669.5],\n", " 'RestoreImageDisplayID': 8,\n", " 'TargetDisplayID': 4294967295},\n", " 'PageSetup': {'General': [1, 1000, 8500, 11000, 1000, 1000, -1000, -1000],\n", " 'Win32': b'\\x04\\x00\\x00\\x004!\\x00\\x00\\xf8*\\x00\\x00M\\x01\\x00\\x00M\\x01\\x00\\x00\\xfa\\x00\\x00\\x00\\xfa\\x00\\x00\\x00\\xe8\\x03\\x00\\x00\\xe8\\x03\\x00\\x00\\xe8\\x03\\x00\\x00\\xe8\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x01\\x00\\x01\\x00\\x01\\x00\\x01\\x00\\x18\\x00',\n", " 'Win32_DevModeW': b'S\\x00e\\x00n\\x00d\\x00 \\x00T\\x00o\\x00 \\x00O\\x00n\\x00e\\x00N\\x00o\\x00t\\x00e\\x00 \\x002\\x000\\x001\\x000\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x04\\x00\\x06\\xdc\\x00\\x0c\\x03\\x03\\xff\\x00\\x00\\x01\\x00\\x01\\x00\\xea\\no\\x08d\\x00\\x01\\x00\\x0f\\x00X\\x02\\x02\\x00\\x01\\x00X\\x02\\x02\\x00\\x00\\x00L\\x00e\\x00t\\x00t\\x00e\\x00r\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\xff\\xff\\xff\\xff\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00DINU\"\\x00\\xd0\\x00\\x0c\\x03\\x00\\x00\\xc2\\xac\\x90Q\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x05\\x00\\x00\\x00\\x00\\x00\\x07\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xd0\\x00\\x00\\x00SMTJ\\x00\\x00\\x00\\x00\\x10\\x00\\xc0\\x00S\\x00e\\x00n\\x00d\\x00 \\x00T\\x00o\\x00 \\x00M\\x00i\\x00c\\x00r\\x00o\\x00s\\x00o\\x00f\\x00t\\x00 \\x00O\\x00n\\x00e\\x00N\\x00o\\x00t\\x00e\\x00 \\x002\\x000\\x001\\x000\\x00 \\x00D\\x00r\\x00i\\x00v\\x00e\\x00r\\x00\\x00\\x00RESDLL\\x00UniresDLL\\x00PaperSize\\x00LETTER\\x00Orientation\\x00PORTRAIT\\x00Resolution\\x00DPI600\\x00ColorMode\\x0024bpp\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00',\n", " 'Win32_DevNamesW': b'\\x04\\x00*\\x00?\\x00\\x00\\x00S\\x00e\\x00n\\x00d\\x00 \\x00T\\x00o\\x00 \\x00M\\x00i\\x00c\\x00r\\x00o\\x00s\\x00o\\x00f\\x00t\\x00 \\x00O\\x00n\\x00e\\x00N\\x00o\\x00t\\x00e\\x00 \\x002\\x000\\x001\\x000\\x00 \\x00D\\x00r\\x00i\\x00v\\x00e\\x00r\\x00\\x00\\x00S\\x00e\\x00n\\x00d\\x00 \\x00T\\x00o\\x00 \\x00O\\x00n\\x00e\\x00N\\x00o\\x00t\\x00e\\x00 \\x002\\x000\\x001\\x000\\x00\\x00\\x00n\\x00u\\x00l\\x00:\\x00\\x00\\x00'},\n", " 'SentinelList': {},\n", " 'Thumbnails': {'0': {'ImageIndex': 0, 'SourceSize_Pixels': [669, 342]}},\n", " 'WindowPosition': [410, 8, 752, 677]}" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "main_dataset.original_metadata" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'quantification' is not defined", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[19], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m plt\u001b[38;5;241m.\u001b[39mfigure()\n\u001b[1;32m----> 2\u001b[0m plt\u001b[38;5;241m.\u001b[39mplot(\u001b[43mquantification\u001b[49m\u001b[38;5;241m.\u001b[39mdataset\u001b[38;5;241m.\u001b[39mmetadata[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124medges\u001b[39m\u001b[38;5;124m'\u001b[39m][\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m0\u001b[39m\u001b[38;5;124m'\u001b[39m][\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdata\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[0;32m 3\u001b[0m plt\u001b[38;5;241m.\u001b[39mplot(quantification\u001b[38;5;241m.\u001b[39mdataset\u001b[38;5;241m.\u001b[39mmetadata[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124medges\u001b[39m\u001b[38;5;124m'\u001b[39m][\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m1\u001b[39m\u001b[38;5;124m'\u001b[39m][\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdata\u001b[39m\u001b[38;5;124m'\u001b[39m])\n", "\u001b[1;31mNameError\u001b[0m: name 'quantification' is not defined" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "42d481cdb0a8494d96c7a06779f8e127", "version_major": 2, "version_minor": 0 }, "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/GU6VOAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAIyUlEQVR4nO3WMQEAIAzAMMC/5+ECjiYKenbPzCwAADLO7wAAAN4ygAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIuJnkHvKensmIAAAAASUVORK5CYII=", "text/html": [ "\n", "
\n", "
\n", " Figure\n", "
\n", " \n", "
\n", " " ], "text/plain": [ "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.figure()\n", "plt.plot(quantification.dataset.metadata['edges']['0']['data'])\n", "plt.plot(quantification.dataset.metadata['edges']['1']['data'])\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "view.update()\n", "view.find_elements(1)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'datasets' is not defined", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[48], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m datasets[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mChannel_000\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;241m.\u001b[39mmetadata[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124medges\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m0\u001b[39m\u001b[38;5;124m'\u001b[39m: {}, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmodel\u001b[39m\u001b[38;5;124m'\u001b[39m: {}}\n\u001b[0;32m 2\u001b[0m datasets[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mChannel_000\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;241m.\u001b[39mmetadata[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124medges\u001b[39m\u001b[38;5;124m'\u001b[39m][\u001b[38;5;124m'\u001b[39m\u001b[38;5;124muse_low_loss\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[0;32m 4\u001b[0m composition \u001b[38;5;241m=\u001b[39m ieels\u001b[38;5;241m.\u001b[39mCompositionDialog(datasets)\n", "\u001b[1;31mNameError\u001b[0m: name 'datasets' is not defined" ] } ], "source": [ "datasets['Channel_000'].metadata['edges'] = {'0': {}, 'model': {}}\n", "datasets['Channel_000'].metadata['edges']['use_low_loss']=False\n", "\n", "composition = ieels.CompositionDialog(datasets)\n", "view = composition.figure" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Output of Results" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Relative chemical composition of 2EELS Acquire (high-loss)\n", "B: 23.5 %\n", "N: 76.5 %\n" ] } ], "source": [ "main_dataset = quantification.dataset\n", "edges = main_dataset.metadata['edges']\n", "element = []\n", "areal_density = []\n", "for key, edge in edges.items():\n", " if key.isdigit():\n", " element.append(edge['element'])\n", " areal_density.append(edge['areal_density'])\n", " \n", "print('Relative chemical composition of ', main_dataset.title)\n", "\n", "for i in range(len(element)):\n", " print(f'{element[i]}: {areal_density[i]/np.sum(areal_density)*100:.1f} %')\n", " \n", "saved_edges_metadata = edges\n", "\n" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "{'model': {'background': array([-4.04651023e+14, -4.06877535e+14, -4.09110155e+14, ...,\n", " -1.77235423e+16, -1.77382597e+16, -1.77529832e+16]),\n", " 'background-poly_0': -44450023942.34783,\n", " 'background-poly_1': -132.73805028510603,\n", " 'background-poly_2': 0.12179848936383898,\n", " 'background-A': 44450059487.20357,\n", " 'background-r': -43.130456550694994,\n", " 'spectrum': array([108808.06931201, 107956.87904715, 107105.70551897, ...,\n", " 2137.48357259, 2140.30517608, 2143.14351626]),\n", " 'blurred': array([139757.55 , 139617.84 , 139350.38 , ..., 658.92535,\n", " 628.73956, 612.56323], dtype=float32),\n", " 'mask': array([0., 0., 0., ..., 0., 0., 1.]),\n", " 'fit_parameter': array([ 4.44500595e+10, -4.31304566e+01, -4.44500239e+10, -1.32738050e+02,\n", " 1.21798489e-01, 1.08102056e+12, 2.93671332e+12]),\n", " 'fit_area_start': 150.0,\n", " 'fit_area_end': 611.75},\n", " 'use_low_loss': False,\n", " 'fit_area': {'fit_start': 150.0, 'fit_end': 611.75},\n", " '0': {'z': 5,\n", " 'symmetry': 'K1',\n", " 'element': 'B',\n", " 'onset': 188.0,\n", " 'end_exclude': 238.0,\n", " 'start_exclude': 183.0,\n", " 'all_edges': {'K1': {'onset': 188.0}},\n", " 'chemical_shift': 0.0,\n", " 'areal_density': 1081020558242.3635,\n", " 'original_onset': 188.0,\n", " 'data': array([6.65067724e-09, 6.58530109e-09, 6.51992495e-09, ...,\n", " 1.69707960e-10, 1.69447463e-10, 1.69186967e-10]),\n", " 'X_section_type': 'XRPA',\n", " 'X_section_source': 'pyTEMlib'},\n", " '1': {'z': 7,\n", " 'symmetry': 'K1',\n", " 'element': 'N',\n", " 'onset': 401.6,\n", " 'end_exclude': 451.6,\n", " 'start_exclude': 386.6,\n", " 'all_edges': {'K1': {'onset': 401.6}},\n", " 'chemical_shift': 0.0,\n", " 'areal_density': 2936713317469.3164,\n", " 'original_onset': 401.6,\n", " 'data': array([2.64344212e-08, 2.61784122e-08, 2.59224032e-08, ...,\n", " 5.65933272e-10, 5.65105461e-10, 5.64277650e-10]),\n", " 'X_section_type': 'XRPA',\n", " 'X_section_source': 'pyTEMlib'}}" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "edges" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.716611904444078" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2936713317469/ 1081020558242\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "B_areal_density = edges['0']['areal_density'] /main_dataset.metadata['experiment']['flux_ppm']*1e-6\n", "N_areal_density = edges['1']['areal_density'] /main_dataset.metadata['experiment']['flux_ppm']*1e-6\n", "\n", "#the B atom areal density of a single layer of h-BN (18.2 nm−2) \n", "print(f\" B areal density is {B_areal_density:.0f} atoms per square nm, which equates {abs(B_areal_density)/18.2:.1f} atomic layers\")\n", "print(f\" N areal density is {N_areal_density:.0f} atoms per square nm, which equates {abs(N_areal_density)/18.2:.1f} atomic layers\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Log Data\n", "We write all the data to the hdf5 file associated with our dataset.\n", "\n", "In our case that is only the ``metadata``, in which we stored the ``experimental parameters`` and the ``fitting parameters and result``." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "main_dataset.view_metadata()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ELNES\n", "The electron energy-loss near edge structure is determined by fititng the spectrum after quantification model subtraction. \n", "\n", "First smooth the spectrum (2 iterations are ususally sufficient) and then \n", "find the number of peaks you want (Can be repeated as oftern as one wants).\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "def smooth(dataset, iterations, advanced_present):\n", " \"\"\"Gaussian mixture model (non-Bayesian)\n", "\n", " Fit lots of Gaussian to spectrum and let the program sort it out\n", " We sort the peaks by area under the Gaussians, assuming that small areas mean noise.\n", "\n", " \"\"\"\n", "\n", " # TODO: add sensitivity to dialog and the two functions below\n", " peaks = dataset.metadata['peak_fit']\n", "\n", " if advanced_present and iterations > 1:\n", " peak_model, peak_out_list = advanced_eels_tools.smooth(dataset, peaks['fit_start'],\n", " peaks['fit_end'], iterations=iterations)\n", " else:\n", " peak_model, peak_out_list = eels.find_peaks(dataset, peaks['fit_start'], peaks['fit_end'])\n", " peak_out_list = [peak_out_list]\n", "\n", " flat_list = [item for sublist in peak_out_list for item in sublist]\n", " new_list = np.reshape(flat_list, [len(flat_list) // 3, 3])\n", " area = np.sqrt(2 * np.pi) * np.abs(new_list[:, 1]) * np.abs(new_list[:, 2] / np.sqrt(2 * np.log(2)))\n", " arg_list = np.argsort(area)[::-1]\n", " area = area[arg_list]\n", " peak_out_list = new_list[arg_list]\n", "\n", " number_of_peaks = np.searchsorted(area * -1, -np.average(area))\n", "\n", " return peak_model, peak_out_list, number_of_peaks" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import ipywidgets\n", "import matplotlib\n", "import sidpy\n", "import matplotlib.patches as patches\n", "def get_sidebar():\n", " side_bar = ipywidgets.GridspecLayout(16, 3, width='auto', grid_gap=\"0px\")\n", " row = 0\n", " side_bar[row, :3] = ipywidgets.Button(description='Fit Area',\n", " layout=ipywidgets.Layout(width='auto', grid_area='header'),\n", " style=ipywidgets.ButtonStyle(button_color='lightblue'))\n", " row += 1\n", " side_bar[row, :2] = ipywidgets.FloatText(value=7.5,description='Fit Start:', disabled=False, color='black', layout=ipywidgets.Layout(width='200px'))\n", " side_bar[row, 2] = ipywidgets.widgets.Label(value=\"eV\", layout=ipywidgets.Layout(width='20px'))\n", " row += 1\n", " side_bar[row, :2] = ipywidgets.FloatText(value=0.1, description='Fit End:', disabled=False, color='black', layout=ipywidgets.Layout(width='200px'))\n", " side_bar[row, 2] = ipywidgets.widgets.Label(value=\"eV\", layout=ipywidgets.Layout(width='20px'))\n", " \n", " row += 1\n", " side_bar[row, :3] = ipywidgets.Button(description='Peak Finding',\n", " layout=ipywidgets.Layout(width='auto', grid_area='header'),\n", " style=ipywidgets.ButtonStyle(button_color='lightblue'))\n", "\n", " row += 1\n", " \n", " \n", " side_bar[row, :2] = ipywidgets.Dropdown(\n", " options=[('0', 0), ('1', 1), ('2', 2), ('3', 3), ('4', 4)],\n", " value=0,\n", " description='Peaks:',\n", " disabled=False,\n", " layout=ipywidgets.Layout(width='200px'))\n", " \n", " side_bar[row, 2] = ipywidgets.Button(\n", " description='Smooth',\n", " disabled=False,\n", " button_style='', # 'success', 'info', 'warning', 'danger' or ''\n", " tooltip='Do Gaussian Mixing',\n", " layout=ipywidgets.Layout(width='100px'))\n", " \n", " row += 1\n", " side_bar[row, :2] = ipywidgets.FloatText(value=0.1, description='Number:', disabled=False, color='black', layout=ipywidgets.Layout(width='200px'))\n", " side_bar[row, 2] = ipywidgets.Button(\n", " description='Find',\n", " disabled=False,\n", " button_style='', # 'success', 'info', 'warning', 'danger' or ''\n", " tooltip='Find first peaks from Gaussian mixture',\n", " layout=ipywidgets.Layout(width='100px'))\n", " \n", " row += 1\n", " \n", " side_bar[row, :3] = ipywidgets.Button(description='Peaks',\n", " layout=ipywidgets.Layout(width='auto', grid_area='header'),\n", " style=ipywidgets.ButtonStyle(button_color='lightblue'))\n", " row += 1\n", " side_bar[row, :2] = ipywidgets.Dropdown(\n", " options=[('Peak 1', 0), ('Add Peak', -1)],\n", " value=0,\n", " description='Peaks:',\n", " disabled=False,\n", " layout=ipywidgets.Layout(width='200px'))\n", " side_bar[row, 2] = ipywidgets.widgets.Label(value=\"\", layout=ipywidgets.Layout(width='100px'))\n", " row += 1\n", " side_bar[row, :2] = ipywidgets.Dropdown(\n", " options=[ 'Gauss', 'Lorentzian', 'Drude', 'Zero-Loss'],\n", " value='Gauss',\n", " description='Symmetry:',\n", " disabled=False,\n", " layout=ipywidgets.Layout(width='200px'))\n", " row += 1\n", " side_bar[row, :2] = ipywidgets.FloatText(value=0.1, description='Position:', disabled=False, color='black', layout=ipywidgets.Layout(width='200px'))\n", " side_bar[row, 2] = ipywidgets.widgets.Label(value=\"eV\", layout=ipywidgets.Layout(width='100px'))\n", " row += 1\n", " side_bar[row, :2] = ipywidgets.FloatText(value=0.1, description='Amplitude:', disabled=False, color='black', layout=ipywidgets.Layout(width='200px'))\n", " side_bar[row, 2] = ipywidgets.widgets.Label(value=\"eV\", layout=ipywidgets.Layout(width='100px'))\n", " row += 1\n", " side_bar[row, :2] = ipywidgets.FloatText(value=0.1, description='Width FWHM:', disabled=False, color='black', layout=ipywidgets.Layout(width='200px'))\n", " side_bar[row, 2] = ipywidgets.widgets.Label(value=\"eV\", layout=ipywidgets.Layout(width='100px'))\n", " row += 1\n", " side_bar[row, :2] = ipywidgets.FloatText(value=0.1, description='Asymmetry:', disabled=False, color='black', layout=ipywidgets.Layout(width='200px'))\n", " side_bar[row, 2] = ipywidgets.widgets.Label(value=\"a.u.\", layout=ipywidgets.Layout(width='100px'))\n", " row += 1\n", " \n", " side_bar[row, :3] = ipywidgets.Button(description='Analysis',\n", " layout=ipywidgets.Layout(width='auto', grid_area='header'),\n", " style=ipywidgets.ButtonStyle(button_color='lightblue'))\n", " \n", " row += 1\n", " side_bar[row, :2] = ipywidgets.Dropdown(\n", " options=[('None', 0)],\n", " value=0,\n", " description='White-Line Ratio:',\n", " disabled=False,\n", " layout=ipywidgets.Layout(width='200px'))\n", " side_bar[row, 2] = ipywidgets.widgets.Label(value=\" \", layout=ipywidgets.Layout(width='100px'))\n", " row += 1\n", " side_bar[row, :2] = ipywidgets.Dropdown(\n", " options=[('None', 0)],\n", " value=0,\n", " description='White-Line Sum:',\n", " disabled=False,\n", " layout=ipywidgets.Layout(width='200px'))\n", " side_bar[row, 2] = ipywidgets.widgets.Label(value=\" \", layout=ipywidgets.Layout(width='100px'))\n", " return side_bar\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "dataset or first item inhas to be a sidpy dataset", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mTypeError\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[10]\u001b[39m\u001b[32m, line 437\u001b[39m\n\u001b[32m 428\u001b[39m \u001b[38;5;28;01mpass\u001b[39;00m\n\u001b[32m 429\u001b[39m \u001b[38;5;66;03m#self.sidebar[11,0].on_click(self.do_fit)\u001b[39;00m\n\u001b[32m 430\u001b[39m \u001b[38;5;66;03m#self.sidebar[12,2].observe(self.plot)\u001b[39;00m\n\u001b[32m 431\u001b[39m \u001b[38;5;66;03m#self.sidebar[4,2].observe(self.plot)\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 435\u001b[39m \n\u001b[32m 436\u001b[39m \u001b[38;5;66;03m# ieels.Qt_available = False \u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m437\u001b[39m view = \u001b[43mPeakFitWidget\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[10]\u001b[39m\u001b[32m, line 5\u001b[39m, in \u001b[36mPeakFitWidget.__init__\u001b[39m\u001b[34m(self, datasets)\u001b[39m\n\u001b[32m 3\u001b[39m \u001b[38;5;28mself\u001b[39m.datasets = datasets\n\u001b[32m 4\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(datasets, \u001b[38;5;28mdict\u001b[39m):\n\u001b[32m----> \u001b[39m\u001b[32m5\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[33m'\u001b[39m\u001b[33mdataset or first item inhas to be a sidpy dataset\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m 7\u001b[39m \u001b[38;5;28mself\u001b[39m.sidebar = get_sidebar()\n\u001b[32m 8\u001b[39m \u001b[38;5;28mself\u001b[39m.key = \u001b[38;5;28mlist\u001b[39m(\u001b[38;5;28mself\u001b[39m.datasets)[\u001b[32m0\u001b[39m]\n", "\u001b[31mTypeError\u001b[39m: dataset or first item inhas to be a sidpy dataset" ] } ], "source": [ "class PeakFitWidget(object):\n", " def __init__(self, datasets=None):\n", " self.datasets = datasets\n", " if not isinstance(datasets, dict):\n", " raise TypeError('dataset or first item inhas to be a sidpy dataset')\n", " \n", " self.sidebar = get_sidebar()\n", " self.key = list(self.datasets)[0]\n", " self.dataset = datasets[self.key]\n", " if not isinstance(self.dataset, sidpy.Dataset):\n", " raise TypeError('dataset or first item inhas to be a sidpy dataset')\n", " self.spec_dim = ft.get_dimensions_by_type('spectral', self.dataset)\n", " if len(self.spec_dim) != 1:\n", " raise TypeError('We need exactly one SPECTRAL dimension')\n", " self.spec_dim = self.spec_dim[0]\n", " #self.energy_scale = self.dataset._axes[self.spec_dim]\n", " \n", " self.energy_scale = self.spec_dim[1]\n", " \n", "\n", " self.model = np.array([])\n", " self.y_scale = 1.0\n", " self.change_y_scale = 1.0\n", " self.spectrum_ll = None\n", " self.low_loss_key = None\n", "\n", " self.peaks = {}\n", "\n", " self.show_regions = False\n", " \n", " with plt.ioff():\n", " self.fig = plt.figure()\n", " self.fig.canvas.toolbar_position = 'right'\n", " self.fig.canvas.toolbar_visible = True\n", " #self.set_dataset()\n", " self.set_action()\n", " self.y_scale = 1.0\n", " self.change_y_scale = 1.0\n", " self.plot(scale=False)\n", " \n", " if 'peak_fit' not in self.dataset.metadata:\n", " self.dataset.metadata['peak_fit'] = {}\n", " if 'edges' in self.dataset.metadata:\n", " if 'fit_area' in self.dataset.metadata['edges']:\n", " self.dataset.metadata['peak_fit']['fit_start'] = \\\n", " self.dataset.metadata['edges']['fit_area']['fit_start']\n", " self.dataset.metadata['peak_fit']['fit_end'] = self.dataset.metadata['edges']['fit_area']['fit_end']\n", " self.dataset.metadata['peak_fit']['peaks'] = {'0': {'position': self.energy_scale[1],\n", " 'amplitude': 1000.0, 'width': 1.0,\n", " 'type': 'Gauss', 'asymmetry': 0}}\n", "\n", "\n", " self.peaks = self.dataset.metadata['peak_fit']\n", " if 'fit_start' not in self.peaks:\n", " self.peaks['fit_start'].value = self.energy_scale[1]\n", " self.peaks['fit_end'].value = self.energy_scale[-2]\n", "\n", " if 'peak_model' in self.peaks:\n", " self.peak_model = self.peaks['peak_model']\n", " self.model = self.peak_model\n", " if 'edge_model' in self.peaks:\n", " self.model = self.model + self.peaks['edge_model']\n", " else:\n", " self.model = np.array([])\n", " self.peak_model = np.array([])\n", " if 'peak_out_list' in self.peaks:\n", " self.peak_out_list = self.peaks['peak_out_list']\n", " self.set_peak_list()\n", "\n", " # check whether a core loss analysis has been done previously\n", " if not hasattr(self, 'core_loss') and 'edges' in self.dataset.metadata:\n", " self.core_loss = True\n", " else:\n", " self.core_loss = False\n", "\n", " self.update()\n", "\n", " self.selector = matplotlib.widgets.SpanSelector(self.fig.gca(), self.line_select_callback,\n", " direction=\"horizontal\",\n", " interactive=True,\n", " props=dict(facecolor='blue', alpha=0.2))\n", " self.start_cursor = ipywidgets.FloatText(value=0, description='Start:', disabled=False, color='black', layout=ipywidgets.Layout(width='200px'))\n", " self.end_cursor = ipywidgets.FloatText(value=0, description='End:', disabled=False, color='black', layout=ipywidgets.Layout(width='200px'))\n", " self.panel = ipywidgets.VBox([ipywidgets.HBox([ipywidgets.Label('',layout=ipywidgets.Layout(width='100px')), ipywidgets.Label('Cursor:'),\n", " self.start_cursor,ipywidgets.Label('eV'), \n", " self.end_cursor, ipywidgets.Label('eV')]),\n", " self.fig.canvas])\n", " \n", " self.app_layout = ipywidgets.AppLayout(\n", " left_sidebar=self.sidebar,\n", " center=self.panel,\n", " footer=None,#message_bar,\n", " pane_heights=[0, 10, 0],\n", " pane_widths=[4, 10, 0],\n", " )\n", " display(self.app_layout)\n", " \n", " def line_select_callback(self, x_min, x_max):\n", " self.start_cursor.value = np.round(x_min,3)\n", " self.end_cursor.value = np.round(x_max, 3)\n", " self.start_channel = np.searchsorted(self.datasets[self.key].energy_loss, self.start_cursor.value)\n", " self.end_channel = np.searchsorted(self.datasets[self.key].energy_loss, self.end_cursor.value)\n", " \n", " \n", " def set_peak_list(self):\n", " self.peak_list = []\n", " if 'peaks' not in self.peaks:\n", " self.peaks['peaks'] = {}\n", " key = 0\n", " for key in self.peaks['peaks']:\n", " if key.isdigit():\n", " self.peak_list.append((f'Peak {int(key) + 1}', int(key)))\n", " self.peak_list.append((f'add peak', -1))\n", " self.sidebar[7, 0].options = self.peak_list\n", " self.sidebar[7, 0].value = 0\n", "\n", "\n", " def plot(self, scale=True):\n", " \n", " ylim = self.fig.gca().get_ylim()\n", " \n", " ax = self.fig.gca()\n", " ax.clear()\n", " ax.plot(self.energy_scale, self.datasets[self.key]*self.y_scale, label=self.datasets[self.key].title)\n", " ax.set_xlabel(self.datasets[self.key].labels[0])\n", " ax.set_ylabel(self.datasets[self.key].data_descriptor)\n", " ax.ticklabel_format(style='sci', scilimits=(-2, 3))\n", " if scale:\n", " ax.set_ylim(np.array(ylim)*self.change_y_scale)\n", " self.change_y_scale = 1.0\n", " if self.y_scale != 1.:\n", " ax.set_ylabel('scattering probability (ppm/eV)')\n", " self.selector = matplotlib.widgets.SpanSelector(self.fig.gca(), self.line_select_callback,\n", " direction=\"horizontal\",\n", " interactive=True,\n", " props=dict(facecolor='blue', alpha=0.2))\n", " \n", " if len(self.model) > 1:\n", " ax.plot(self.energy_scale, self.model*self.y_scale, label='model')\n", " difference_spec = self.datasets[self.key] - self.model\n", " ax.plot(self.energy_scale, difference_spec*self.y_scale, label='difference')\n", " # axis.plot(self.energy_scale, (self.datasets[key] - self.model) / np.sqrt(self.datasets[key])*self.y_scale, label='Poisson')\n", " \n", " if 'peaks' in self.peaks:\n", " for index, peak in self.peaks['peaks'].items():\n", " p = [peak['position'], peak['amplitude'], peak['width']]\n", " ax.plot(self.energy_scale, eels.gauss(self.energy_scale, p))\n", " \n", " ax.legend()\n", " \n", " \n", " \n", " def set_dataset(self, index=0): \n", " if 'edges' not in self.dataset.metadata or self.dataset.metadata['edges'] == {}:\n", " self.dataset.metadata['edges'] = {'0': {}, 'model': {}, 'use_low_loss': False}\n", " \n", " self.edges = self.dataset.metadata['edges']\n", " if '0' not in self.edges:\n", " self.edges['0'] = {}\n", " \n", " if 'fit_area' not in self.edges:\n", " self.edges['fit_area'] = {}\n", " if 'fit_start' not in self.edges['fit_area']:\n", " self.sidebar[1,0].value = np.round(self.energy_scale[50], 3)\n", " self.edges['fit_area']['fit_start'] = self.sidebar[1,0].value \n", " else:\n", " self.sidebar[1,0].value = np.round(self.edges['fit_area']['fit_start'],3)\n", " if 'fit_end' not in self.edges['fit_area']:\n", " self.sidebar[2,0].value = np.round(self.energy_scale[-2], 3)\n", " self.edges['fit_area']['fit_end'] = self.sidebar[2,0].value \n", " else:\n", " self.sidebar[2,0].value = np.round(self.edges['fit_area']['fit_end'],3)\n", " \n", " if self.dataset.data_type.name == 'SPECTRAL_IMAGE':\n", " if 'SI_bin_x' not in self.dataset.metadata['experiment']:\n", " self.dataset.metadata['experiment']['SI_bin_x'] = 1\n", " self.dataset.metadata['experiment']['SI_bin_y'] = 1\n", "\n", " bin_x = self.dataset.metadata['experiment']['SI_bin_x']\n", " bin_y = self.dataset.metadata['experiment']['SI_bin_y']\n", " # self.dataset.view.set_bin([bin_x, bin_y])\n", " self.update()\n", " \n", " def set_fit_area(self, value):\n", " \"\"\"\n", " if self.sidebar[1,0].value > self.sidebar[2,0].value:\n", " self.sidebar[1,0].value = self.sidebar[2,0].value - 1.0\n", " if float(self.sidebar[1,0].value) < self.energy_scale[0]:\n", " self.sidebar[1,0].value = self.energy_scale[0]\n", " if self.sidebar[2,0].value > self.energy_scale[-1]:\n", " self.sidebar[2,0].value = self.energy_scale[-1]\n", " \"\"\"\n", " self.peaks['fit_start'] = self.sidebar[1, 0].value \n", " self.peaks['fit_end'] = self.sidebar[2, 0].value \n", " \n", " self.plot()\n", " \n", " def set_y_scale(self, value): \n", " self.change_y_scale = 1/self.y_scale\n", " if self.sidebar[12, 0].value:\n", " dispersion = self.energy_scale[1] - self.energy_scale[0]\n", " self.y_scale = 1/self.dataset.metadata['experiment']['flux_ppm'] * dispersion\n", " else:\n", " self.y_scale = 1.0\n", " \n", " self.change_y_scale *= self.y_scale\n", " self.update()\n", " self.plot()\n", " \n", " def update(self, index=0):\n", " \n", " # self.setWindowTitle('update')\n", " self.sidebar[1, 0].value = self.peaks['fit_start']\n", " self.sidebar[2, 0].value = self.peaks['fit_end']\n", "\n", " peak_index = self.sidebar[7, 0].value\n", " self.peak_index = self.sidebar[7, 0].value\n", " if str(peak_index) not in self.peaks['peaks']:\n", " self.peaks['peaks'][str(peak_index)] = {'position': self.energy_scale[1], 'amplitude': 1000.0,\n", " 'width': 1.0, 'type': 'Gauss', 'asymmetry': 0}\n", " self.sidebar[8, 0].value = self.peaks['peaks'][str(peak_index)]['type']\n", " if 'associated_edge' in self.peaks['peaks'][str(peak_index)]:\n", " self.sidebar[7, 2].value = (self.peaks['peaks'][str(peak_index)]['associated_edge'])\n", " else:\n", " self.sidebar[7, 2].value = ''\n", " self.sidebar[9, 0].value = self.peaks['peaks'][str(peak_index)]['position']\n", " self.sidebar[10, 0].value = self.peaks['peaks'][str(peak_index)]['amplitude']\n", " self.sidebar[11, 0].value = self.peaks['peaks'][str(peak_index)]['width']\n", " if 'asymmetry' not in self.peaks['peaks'][str(peak_index)]:\n", " self.peaks['peaks'][str(peak_index)]['asymmetry'] = 0.\n", " self.sidebar[12, 0].value = self.peaks['peaks'][str(peak_index)]['asymmetry']\n", "\n", " \n", " def do_fit(self, value=0):\n", " if 'experiment' in self.dataset.metadata:\n", " exp = self.dataset.metadata['experiment']\n", " if 'convergence_angle' not in exp:\n", " raise ValueError('need a convergence_angle in experiment of metadata dictionary ')\n", " alpha = exp['convergence_angle']\n", " beta = exp['collection_angle']\n", " beam_kv = exp['acceleration_voltage']\n", "\n", " else:\n", " raise ValueError('need a experiment parameter in metadata dictionary')\n", " \n", " eff_beta = eels.effective_collection_angle(self.energy_scale, alpha, beta, beam_kv)\n", "\n", " if self.edges['use_low_loss']:\n", " low_loss = self.spectrum_ll / self.spectrum_ll.sum()\n", " else:\n", " low_loss = None\n", " edges = eels.make_cross_sections(self.edges, np.array(self.energy_scale), beam_kv, eff_beta, low_loss)\n", "\n", " if self.dataset.data_type == sidpy.DataType.SPECTRAL_IMAGE:\n", " spectrum = self.dataset.view.get_spectrum()\n", " else:\n", " spectrum = self.dataset\n", " self.edges = eels.fit_edges2(spectrum, self.energy_scale, edges)\n", " areal_density = []\n", " elements = []\n", " for key in edges:\n", " if key.isdigit(): # only edges have numbers in that dictionary\n", " elements.append(edges[key]['element'])\n", " areal_density.append(edges[key]['areal_density'])\n", " areal_density = np.array(areal_density)\n", " out_string = '\\nRelative composition: \\n'\n", " for i, element in enumerate(elements):\n", " out_string += f'{element}: {areal_density[i] / areal_density.sum() * 100:.1f}% '\n", "\n", " self.model = self.edges['model']['spectrum']\n", " self.update()\n", " self.plot()\n", " \n", " def find_associated_edges(self):\n", " onsets = []\n", " edges = []\n", " if 'edges' in self.dataset.metadata:\n", " for key, edge in self.dataset.metadata['edges'].items():\n", " if key.isdigit():\n", " element = edge['element']\n", " for sym in edge['all_edges']: # TODO: Could be replaced with exclude\n", " onsets.append(edge['all_edges'][sym]['onset'] + edge['chemical_shift'])\n", " # if 'sym' == edge['symmetry']:\n", " edges.append([key, f\"{element}-{sym}\", onsets[-1]])\n", " for key, peak in self.peaks['peaks'].items():\n", " if key.isdigit():\n", " distance = self.energy_scale[-1]\n", " index = -1\n", " for ii, onset in enumerate(onsets):\n", " if onset < peak['position'] < onset+50:\n", " if distance > np.abs(peak['position'] - onset):\n", " distance = np.abs(peak['position'] - onset) # TODO: check whether absolute is good\n", " distance_onset = peak['position'] - onset\n", " index = ii\n", " if index >= 0:\n", " peak['associated_edge'] = edges[index][1] # check if more info is necessary\n", " peak['distance_to_onset'] = distance_onset\n", "\n", " def find_white_lines(self):\n", " if 'edges' in self.dataset.metadata:\n", " white_lines = {}\n", " for index, peak in self.peaks['peaks'].items():\n", " if index.isdigit():\n", " if 'associated_edge' in peak:\n", " if peak['associated_edge'][-2:] in ['L3', 'L2', 'M5', 'M4']:\n", " if peak['distance_to_onset'] < 10:\n", " area = np.sqrt(2 * np.pi) * peak['amplitude'] * np.abs(peak['width']/np.sqrt(2 * np.log(2)))\n", " if peak['associated_edge'] not in white_lines:\n", " white_lines[peak['associated_edge']] = 0.\n", " if area > 0:\n", " white_lines[peak['associated_edge']] += area # TODO: only positive ones?\n", " white_line_ratios = {}\n", " white_line_sum = {}\n", " for sym, area in white_lines.items():\n", " if sym[-2:] in ['L2', 'M4', 'M2']:\n", " if area > 0 and f\"{sym[:-1]}{int(sym[-1]) + 1}\" in white_lines:\n", " if white_lines[f\"{sym[:-1]}{int(sym[-1]) + 1}\"] > 0:\n", " white_line_ratios[f\"{sym}/{sym[-2]}{int(sym[-1]) + 1}\"] = area / white_lines[\n", " f\"{sym[:-1]}{int(sym[-1]) + 1}\"]\n", " white_line_sum[f\"{sym}+{sym[-2]}{int(sym[-1]) + 1}\"] = (\n", " area + white_lines[f\"{sym[:-1]}{int(sym[-1]) + 1}\"])\n", "\n", " areal_density = 1.\n", " if 'edges' in self.dataset.metadata:\n", " for key, edge in self.dataset.metadata['edges'].items():\n", " if key.isdigit():\n", " if edge['element'] == sym.split('-')[0]:\n", " areal_density = edge['areal_density']\n", " break\n", " white_line_sum[f\"{sym}+{sym[-2]}{int(sym[-1]) + 1}\"] /= areal_density\n", "\n", " self.peaks['white_lines'] = white_lines\n", " self.peaks['white_line_ratios'] = white_line_ratios\n", " self.peaks['white_line_sums'] = white_line_sum\n", " self.wl_list = []\n", " self.wls_list = []\n", " if len(self.peaks['white_line_ratios']) > 0:\n", " for key in self.peaks['white_line_ratios']:\n", " self.wl_list.append(key)\n", " for key in self.peaks['white_line_sums']:\n", " self.wls_list.append(key)\n", "\n", " self.sidebar[14, 0].options = self.wl_list\n", " self.sidebar[14, 0].value = 0\n", " self.sidebar[14, 0].value = f\"{self.peaks['white_line_ratios'][self.wl_list[0]]:.2f}\"\n", " \n", " self.sidebar[15, 0].options = self.wls_list\n", " self.sidebar[15, 0].value = 0\n", " self.sidebar[15, 0].value = f\"{self.peaks['white_line_sums'][self.wls_list[0]]*1e6:.4f} ppm\"\n", "\n", " else:\n", " self.wl_list.append('Ratio')\n", " self.wls_list.append('Sum')\n", "\n", " sself.sidebar[14, 0].options = self.wl_list\n", " self.sidebar[14, 0].value = 0\n", " self.sidebar[14, 0].value = ' '\n", " \n", " self.sidebar[15, 0].options = self.wls_list\n", " self.sidebar[15, 0].value = 0\n", " self.sidebar[15, 0].value = ' '\n", "\n", " def find_peaks(self, value=0):\n", " number_of_peaks = int(self.sidebar[5, 0].value)\n", "\n", " # is now sorted in smooth function\n", " # flat_list = [item for sublist in self.peak_out_list for item in sublist]\n", " # new_list = np.reshape(flat_list, [len(flat_list) // 3, 3])\n", " # arg_list = np.argsort(np.abs(new_list[:, 1]))\n", "\n", " self.peak_list = []\n", " self.peaks['peaks'] = {}\n", " for i in range(number_of_peaks):\n", " self.peak_list.append((f'Peak {i+1}', i))\n", " p = self.peak_out_list[i]\n", " self.peaks['peaks'][str(i)] = {'position': p[0], 'amplitude': p[1], 'width': p[2], 'type': 'Gauss',\n", " 'asymmetry': 0}\n", "\n", " self.peak_list.append((f'add peak', -1))\n", " \n", " self.sidebar[7, 0].options = self.peak_list\n", " self.sidebar[7, 0].value = 0\n", " self.find_associated_edges()\n", " self.find_white_lines()\n", "\n", " self.update()\n", " self.plot()\n", "\n", " \n", " def smooth(self, value=0):\n", " \"\"\"Fit lots of Gaussian to spectrum and let the program sort it out\n", "\n", " We sort the peaks by area under the Gaussians, assuming that small areas mean noise.\n", "\n", " \"\"\"\n", " iterations = self.sidebar[4, 0].value\n", " self.sidebar[5, 0].value = 0\n", " advanced_present=False\n", "\n", " self.peak_model, self.peak_out_list, number_of_peaks = smooth(self.dataset, iterations, advanced_present)\n", "\n", " spec_dim = ft.get_dimensions_by_type('SPECTRAL', self.dataset)[0]\n", " if spec_dim[1][0] > 0:\n", " self.model = self.dataset.metadata['edges']['model']['spectrum']\n", " elif 'model' in self.dataset.metadata:\n", " self.model = self.dataset.metadata['model']\n", " else:\n", " self.model = np.zeros(len(spec_dim[1]))\n", "\n", " self.sidebar[5, 0].value = number_of_peaks\n", "\n", " self.dataset.metadata['peak_fit']['edge_model'] = self.model\n", " self.model = self.model + self.peak_model\n", " self.dataset.metadata['peak_fit']['peak_model'] = self.peak_model\n", " self.dataset.metadata['peak_fit']['peak_out_list'] = self.peak_out_list\n", "\n", " self.update()\n", " self.plot()\n", " \n", " \n", " def set_action(self):\n", " self.sidebar[1, 0].observe(self.set_fit_area, names='value')\n", " self.sidebar[2, 0].observe(self.set_fit_area, names='value')\n", " \n", " self.sidebar[4, 2].on_click(self.smooth)\n", " self.sidebar[7,0].observe(self.update)\n", " self.sidebar[5,2].on_click(self.find_peaks)\n", " pass\n", " #self.sidebar[11,0].on_click(self.do_fit)\n", " #self.sidebar[12,2].observe(self.plot)\n", " #self.sidebar[4,2].observe(self.plot)\n", "\n", " #self.sidebar[12,0].observe(self.set_y_scale)\n", " \n", "\n", "# ieels.Qt_available = False \n", "view = PeakFitWidget(file_widget.datasets)" ] }, { "cell_type": "code", "execution_count": 221, "metadata": {}, "outputs": [], "source": [ "view.update()" ] }, { "cell_type": "code", "execution_count": 226, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2, 196.39897203557885)" ] }, "execution_count": 226, "metadata": {}, "output_type": "execute_result" } ], "source": [ "view.sidebar[9, 0].value, view.peaks['peaks'][str(view.peak_index)]['position']\n", "view.peak_index, view.peaks['peaks'][str(3)]['position']" ] }, { "cell_type": "code", "execution_count": 229, "metadata": {}, "outputs": [], "source": [ "view.find_peaks()" ] }, { "cell_type": "code", "execution_count": 230, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'0': {'position': 205.29198729248733,\n", " 'amplitude': -164537.92738566975,\n", " 'width': 16.489991004528846,\n", " 'type': 'Gaussian',\n", " 'asymmetry': 0},\n", " '1': {'position': 209.51854898890775,\n", " 'amplitude': 128179.22805573599,\n", " 'width': 11.327214665710333,\n", " 'type': 'Gaussian',\n", " 'asymmetry': 0},\n", " '2': {'position': 201.89290094322763,\n", " 'amplitude': 125596.26392103347,\n", " 'width': 9.143299311315088,\n", " 'type': 'Gaussian',\n", " 'asymmetry': 0},\n", " '3': {'position': 196.39897203557885,\n", " 'amplitude': 66282.27401083642,\n", " 'width': 3.2456895770650784,\n", " 'type': 'Gaussian',\n", " 'asymmetry': 0}}" ] }, "execution_count": 230, "metadata": {}, "output_type": "execute_result" } ], "source": [ "view.peaks['peaks']" ] }, { "cell_type": "code", "execution_count": 135, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(600.0, 100.0)" ] }, "execution_count": 135, "metadata": {}, "output_type": "execute_result" } ], "source": [ "view.sidebar[2,0].value, view.energy_scale[0]" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'PeakWidget' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn [10], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m peak_dialog \u001b[38;5;241m=\u001b[39m \u001b[43mPeakWidget\u001b[49m(main_dataset)\n", "\u001b[0;31mNameError\u001b[0m: name 'PeakWidget' is not defined" ] } ], "source": [ "peak_dialog = PeakWidget(main_dataset)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "759d2e3aef344945926bdb56a17a38c8", "version_major": 2, "version_minor": 0 }, "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAABpQ0lEQVR4nO3deVhU5eIH8O/MMAyLMIIIOIpbmqm4heZa2k3RcsnqZoVR/vJqXVMztczuraxu0mK22Wrd9qTuNbuWRqiZRooaSoq7uYAs4gLDIswMM+/vD+QwZ2YQkIHZvp/n4XnmnPPOzDtHdL6+q0IIIUBEREREPkPp6goQERERUctiACQiIiLyMQyARERERD6GAZCIiIjIxzAAEhEREfkYBkAiIiIiH8MASERERORjGACJiIiIfAwDIBEREZGPYQAkIiIi8jEMgEREREQ+hgGQiIiIyMcwABIRERH5GAZAIiIiIh/DAEhERETkYxgAiYiIiHwMAyARERGRj2EAJCIiIvIxDIBEREREPoYBkIiIiMjHMAASERER+RgGQCIiIiIfwwBIRERE5GMYAImIiIh8DAMgERERkY9hACQiIiLyMQyARERERD6GAZCIiIjIxzAAEhEREfkYBkAiIiIiH8MASERERORjGACJiIiIfAwDIBEREZGPYQAkIiIi8jEMgEREREQ+hgGQiIiIyMcwABIRERH5GAZAIiIiIh/DAEhERETkYxgAiYiIiHwMAyARERGRj2EAJCIiIvIxDIBEREREPoYBkIiIiMjHMAASERER+RgGQCIiIiIfwwBIRERE5GMYAImIiIh8DAMgERERkY9hACQiIiLyMQyARERERD6GAZCIiIjIxzAAEhEREfkYBkAiIiIiH8MASERERORjGACJiIiIfIyfqyvgySwWC/Ly8hASEgKFQuHq6hAREVEDCCFQWloKnU4HpdI328IYAJsgLy8PMTExrq4GERERXYGcnBx06NDB1dVwCQbAJggJCQFQ/QsUGhrq4toQERFRQ5SUlCAmJkb6HvdFDIBNUNPtGxoaygBIRETkYXx5+JZvdnwTERER+TAGQCIiIiIfwwBIRERE5GMYAImIiIh8DAMgERERkY9hACQiIiLyMQyARERERD6GAZCIiIjIxzAAEhEREfkYBkAiIiIiH8MASERERORjGACJiIiIfAwDoBuqMluw7KfD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", "text/html": [ "\n", "
\n", "
\n", " Figure\n", "
\n", " \n", "
\n", " " ], "text/plain": [ "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "peak_dialog = ieels.PeakFitDialog(file_widget.datasets['Channel_000'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Output" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "areas = []\n", "for p, peak in peak_dialog.peaks['peaks'].items():\n", " area = np.sqrt(2* np.pi)* peak['amplitude'] * np.abs(peak['width'] / np.sqrt(2 *np.log(2))) \n", " areas.append(area)\n", " if 'associated_edge' not in peak:\n", " peak['associated_edge']= ''\n", " print(f\"peak {p}: position: {peak['position']:7.1f}, area: {area:12.3f} associated edge: {peak['associated_edge']}\")\n", "#print(f'\\n M4/M5 peak 2 to peak 1 ratio: {(areas[1])/areas[0]:.2f}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Log Data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "main_dataset.view_metadata()" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": true }, "source": [ "## Save to File\n", "Save the datasets to a file.\n", "\n", "File needs to be closed to be used with other notebooks" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hideCode": false, "hidePrompt": true }, "outputs": [], "source": [ "f = ft.save_dataset(datasets)\n", "f.file.close()" ] }, { "cell_type": "markdown", "metadata": { "hideCode": true, "hidePrompt": true }, "source": [ "## Navigation\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hideCode": true, "hidePrompt": true }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "hide_code_all_hidden": true, "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.13.5" }, "toc": { "base_numbering": "9", "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": "calc(100% - 180px)", "left": "10px", "top": "150px", "width": "270px" }, "toc_section_display": true, "toc_window_display": true }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 4 }