{ "cells": [ { "cell_type": "markdown", "id": "a37fc0cd", "metadata": {}, "source": [ "# Mapping Molecules\n", "\n", "In this notebook we will cover how to map molecules in different ways and look at some of the things we can do with them. In the first part of the tutorial we will look at different ways to map water molecules and in the second, we will extend this to a more complex molecule system, the room temperature ionic liquid, BMIM-BF4." ] }, { "cell_type": "markdown", "id": "06556740", "metadata": {}, "source": [ "# Water Molecules" ] }, { "cell_type": "markdown", "id": "a27c7e1c", "metadata": {}, "source": [ "In the first part of this demonstration we will load data from a GROMACS simulation and therefore, we need to define a set of units and a file reader object to use. For this reason, we have changed the imports a little bit to keep the code to minimum." ] }, { "cell_type": "code", "execution_count": 1, "id": "9dafbf2b", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2022-01-31 10:46:34.798887: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/slurm/lib:/opt/slurm/lib:\n", "2022-01-31 10:46:34.798913: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n", "2022-01-31 10:46:39.087811: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/slurm/lib:/opt/slurm/lib:\n", "2022-01-31 10:46:39.087996: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcublas.so.11'; dlerror: libcublas.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/slurm/lib:/opt/slurm/lib:\n", "2022-01-31 10:46:39.088161: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcublasLt.so.11'; dlerror: libcublasLt.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/slurm/lib:/opt/slurm/lib:\n", "2022-01-31 10:46:39.091381: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcusolver.so.11'; dlerror: libcusolver.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/slurm/lib:/opt/slurm/lib:\n", "2022-01-31 10:46:39.091545: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcusparse.so.11'; dlerror: libcusparse.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/slurm/lib:/opt/slurm/lib:\n", "2022-01-31 10:46:39.091700: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudnn.so.8'; dlerror: libcudnn.so.8: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/slurm/lib:/opt/slurm/lib:\n", "2022-01-31 10:46:39.091718: W tensorflow/core/common_runtime/gpu/gpu_device.cc:1850] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform.\n", "Skipping registering GPU devices...\n" ] } ], "source": [ "import mdsuite as mds\n", "import mdsuite.file_io.chemfiles_read\n", "from mdsuite.utils import Units\n", "\n", "from zinchub import DataHub\n", "import shutil\n", "\n", "import h5py as hf\n", "import numpy as np" ] }, { "cell_type": "markdown", "id": "c16e2e24", "metadata": {}, "source": [ "### Loading the data\n", "\n", "In this tutorial we are using 50 ns simulations of 14 water molecules in a continuum fluid performed with GROMACS. We will use pure atomistic naming as well as ligand naming, the topology files for which are contained on DataHub." ] }, { "cell_type": "code", "execution_count": 2, "id": "f98b8829", "metadata": {}, "outputs": [], "source": [ "water = DataHub(url=\"https://github.com/zincware/DataHub/tree/main/Water_14_Gromacs\")\n", "water.get_file('./')\n", "file_paths = [\n", " f for f in water.file_raw\n", " ]" ] }, { "cell_type": "markdown", "id": "7572ee3f", "metadata": {}, "source": [ "### Project definition\n", "\n", "Here we create the project and define some custom units used by GROMACS." ] }, { "cell_type": "code", "execution_count": 3, "id": "166ac397", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2022-01-31 10:46:40,563 - INFO: Creating new project Mapping_Molecules\n" ] } ], "source": [ "project = mds.Project(\"Mapping_Molecules\")\n", "\n", "gmx_units = Units(\n", " time=1e-15,\n", " length=1e-10,\n", " energy=1.6022e-19,\n", " NkTV2p=1.6021765e6,\n", " boltzmann=8.617343e-5,\n", " temperature=1,\n", " pressure=100000,\n", " )" ] }, { "cell_type": "markdown", "id": "1ac6d863", "metadata": {}, "source": [ "### Mapping molecules with SMILES\n", "\n", "In this section we take a look at how one can map molecules using SMILES strings." ] }, { "cell_type": "code", "execution_count": 4, "id": "a8f5f996", "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2022-01-31 10:46:40,727 - INFO: Creating a new experiment!\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|███████████████████████████████████| 1/1 [00:00<00:00, 1.63it/s]\n", "2022-01-31 10:46:41.649356: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F FMA\n", "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", "Applying transformation 'Unwrapped_Positions' to 'O': 100%|█| 1/1 [00:\n", "Applying transformation 'Unwrapped_Positions' to 'H': 100%|█| 1/1 [00:\n" ] } ], "source": [ "traj_path = file_paths[2]\n", "topol_path = file_paths[0]\n", "\n", "file_reader = mdsuite.file_io.chemfiles_read.ChemfilesRead(\n", " traj_file_path=traj_path, topol_file_path=topol_path\n", ")\n", "\n", "water_chemical = project.add_experiment(\n", " name=\"water_chemical\",\n", " timestep=0.002,\n", " temperature=300.0,\n", " units=gmx_units,\n", " simulation_data=file_reader,\n", ")\n", "water_chemical.run.CoordinateUnwrapper()" ] }, { "cell_type": "markdown", "id": "41e9a007", "metadata": {}, "source": [ "The first thing we need to do is define the molecule that will be mapped using the in-built MDSuite molecule data-class" ] }, { "cell_type": "code", "execution_count": 5, "id": "ba411ff9", "metadata": {}, "outputs": [], "source": [ "chemical_water = mds.Molecule(\n", " name='water',\n", " smiles=\"[H]O[H]\", \n", " cutoff=1.7, \n", " amount=14, \n", " mol_pbc=True\n", ")" ] }, { "cell_type": "code", "execution_count": 6, "id": "fb70c81d", "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2022-01-31 10:46:42,462 - INFO: Building molecular graph from configuration for water\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|████████████████████████████████| 42/42 [00:00<00:00, 557.49it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "2022-01-31 10:46:42,680 - INFO: Performing molecule number isomorphism test.\n", "2022-01-31 10:46:42,681 - INFO: Amount of molecules test passed.\n", "2022-01-31 10:46:42,682 - INFO: Performing group equality isomorphism test.\n", "2022-01-31 10:46:42,682 - INFO: Group equality isomorphism test passed.\n", "2022-01-31 10:46:42,787 - INFO: Mapping molecule graphs onto trajectory for water\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|███████████████████████████████████| 1/1 [00:00<00:00, 4.78it/s]\n", "Applying transformation 'Unwrapped_Positions' to 'water': 100%|█| 1/1 \n" ] } ], "source": [ "water_chemical.run.MolecularMap(\n", " molecules=[chemical_water]\n", ")" ] }, { "cell_type": "code", "execution_count": 7, "id": "cc06f58f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'water': {'n_particles': 14,\n", " 'mass': 18.015,\n", " 'groups': {'0': {'H': [0, 1], 'O': [0]},\n", " '1': {'H': [2, 3], 'O': [1]},\n", " '2': {'H': [4, 5], 'O': [2]},\n", " '3': {'H': [6, 7], 'O': [3]},\n", " '4': {'H': [8, 9], 'O': [4]},\n", " '5': {'H': [10, 11], 'O': [5]},\n", " '6': {'H': [12, 13], 'O': [6]},\n", " '7': {'H': [14, 15], 'O': [7]},\n", " '8': {'H': [16, 17], 'O': [8]},\n", " '9': {'H': [18, 19], 'O': [9]},\n", " '10': {'H': [20, 21], 'O': [10]},\n", " '11': {'H': [22, 23], 'O': [11]},\n", " '12': {'H': [24, 25], 'O': [12]},\n", " '13': {'H': [26, 27], 'O': [13]}}}}" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "water_chemical.molecules" ] }, { "cell_type": "markdown", "id": "7eb09781", "metadata": {}, "source": [ "### Mapping Molecules with a reference dict\n", "\n", "If you do not have particles with chemical names but you nonetheless wish to construct groups out of particles, this can be achieved by using a reference dict.\n", "\n", "In this example, we use the ligand naming from GROMACS to construct water molecules." ] }, { "cell_type": "code", "execution_count": 8, "id": "cb6f6ee7", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2022-01-31 10:46:43,502 - INFO: Creating a new experiment!\n", "2022-01-31 10:46:44,364 - WARNING: WARNING element OW has been assigned mass=0.0\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|███████████████████████████████████| 1/1 [00:00<00:00, 1.50it/s]\n", "Applying transformation 'Unwrapped_Positions' to 'OW': 100%|█| 1/1 [00\n", "Applying transformation 'Unwrapped_Positions' to 'HW1': 100%|█| 1/1 [0\n", "Applying transformation 'Unwrapped_Positions' to 'HW2': 100%|█| 1/1 [0\n" ] } ], "source": [ "traj_path = file_paths[2]\n", "topol_path = file_paths[1]\n", "\n", "file_reader = mdsuite.file_io.chemfiles_read.ChemfilesRead(\n", " traj_file_path=traj_path, topol_file_path=topol_path\n", ")\n", "\n", "water_ligand = project.add_experiment(\n", " name=\"water_ligand\",\n", " timestep=0.002,\n", " temperature=300.0,\n", " units=gmx_units,\n", " simulation_data=file_reader,\n", ")\n", "water_ligand.run.CoordinateUnwrapper()" ] }, { "cell_type": "markdown", "id": "d631fc86", "metadata": {}, "source": [ "Keep in mind, as the particles are not named from the periodic tables, important properties such as mass will need to be filled in manually." ] }, { "cell_type": "code", "execution_count": 9, "id": "3eaa89cb", "metadata": {}, "outputs": [], "source": [ "water_ligand.species['OW'].mass = [15.999]\n", "water_ligand.species['HW1'].mass = [1.00784]\n", "water_ligand.species['HW2'].mass = [1.00784]" ] }, { "cell_type": "markdown", "id": "ca81a37b", "metadata": {}, "source": [ "In this case, the molecule will be defined a little bit differently." ] }, { "cell_type": "code", "execution_count": 10, "id": "f490ae1a", "metadata": {}, "outputs": [], "source": [ "ligand_water = mds.Molecule(\n", " name='water', \n", " cutoff=1.7, \n", " amount=14, \n", " species_dict={\"HW1\": 1, \"OW\": 1, \"HW2\": 1},\n", " mol_pbc=True\n", ")" ] }, { "cell_type": "code", "execution_count": 11, "id": "d07fb41f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2022-01-31 10:46:47,651 - INFO: Building molecular graph from configuration for water\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|████████████████████████████████| 42/42 [00:00<00:00, 548.19it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "2022-01-31 10:46:47,883 - INFO: Performing molecule number isomorphism test.\n", "2022-01-31 10:46:47,885 - INFO: Amount of molecules test passed.\n", "2022-01-31 10:46:47,886 - INFO: Performing group equality isomorphism test.\n", "2022-01-31 10:46:47,886 - INFO: Group equality isomorphism test passed.\n", "2022-01-31 10:46:47,984 - INFO: Mapping molecule graphs onto trajectory for water\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|███████████████████████████████████| 1/1 [00:00<00:00, 5.09it/s]\n", "Applying transformation 'Unwrapped_Positions' to 'water': 100%|█| 1/1 \n" ] } ], "source": [ "water_ligand.run.MolecularMap(\n", " molecules=[ligand_water]\n", ")" ] }, { "cell_type": "code", "execution_count": 12, "id": "581f71f0", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'water': {'n_particles': 14,\n", " 'mass': 18.014680000000002,\n", " 'groups': {'0': {'HW1': [0], 'OW': [0], 'HW2': [0]},\n", " '1': {'HW1': [1], 'OW': [1], 'HW2': [1]},\n", " '2': {'HW1': [2], 'OW': [2], 'HW2': [2]},\n", " '3': {'HW1': [3], 'OW': [3], 'HW2': [3]},\n", " '4': {'HW1': [4], 'OW': [4], 'HW2': [4]},\n", " '5': {'HW1': [5], 'OW': [5], 'HW2': [5]},\n", " '6': {'HW1': [6], 'OW': [6], 'HW2': [6]},\n", " '7': {'HW1': [7], 'OW': [7], 'HW2': [7]},\n", " '8': {'HW1': [8], 'OW': [8], 'HW2': [8]},\n", " '9': {'HW1': [9], 'OW': [9], 'HW2': [9]},\n", " '10': {'HW1': [10], 'OW': [10], 'HW2': [10]},\n", " '11': {'HW1': [11], 'OW': [11], 'HW2': [11]},\n", " '12': {'HW1': [12], 'OW': [12], 'HW2': [12]},\n", " '13': {'HW1': [13], 'OW': [13], 'HW2': [13]}}}}" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "water_ligand.molecules" ] }, { "cell_type": "markdown", "id": "bde229b5", "metadata": {}, "source": [ "### What information is stored?\n", "\n", "So the molecule mapping itself was quick and easy, but what information has been stored along the way?\n", "\n", "All meta-data about the molecules is stored in the experiment class under molecules. Let's take a look at what this contains." ] }, { "cell_type": "code", "execution_count": 13, "id": "9b55224a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dict_keys(['water'])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "water_chemical.molecules.keys()" ] }, { "cell_type": "markdown", "id": "ccc0fcfe", "metadata": {}, "source": [ "This dict will contain all of the molecules that have been mapped, but this is not the information about the molecules, for that, we need to look at the water molecule." ] }, { "cell_type": "code", "execution_count": 14, "id": "fdf2091f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dict_keys(['n_particles', 'mass', 'groups'])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "water_chemical.molecules['water'].keys()" ] }, { "cell_type": "markdown", "id": "656208df", "metadata": {}, "source": [ "Three of these are fairly trivial and we can look at them quickly, groups will require some more attention." ] }, { "cell_type": "code", "execution_count": 15, "id": "d024e00b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "n_particles: 14\n", "mass: 18.015\n" ] } ], "source": [ "print(f\"n_particles: {water_chemical.molecules['water']['n_particles']}\")\n", "print(f\"mass: {water_chemical.molecules['water']['mass']}\")" ] }, { "cell_type": "markdown", "id": "15a6a3c2", "metadata": {}, "source": [ "Now let's take a look at the groups key." ] }, { "cell_type": "code", "execution_count": 16, "id": "71efe836", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'0': {'H': [0, 1], 'O': [0]}, '1': {'H': [2, 3], 'O': [1]}, '2': {'H': [4, 5], 'O': [2]}, '3': {'H': [6, 7], 'O': [3]}, '4': {'H': [8, 9], 'O': [4]}, '5': {'H': [10, 11], 'O': [5]}, '6': {'H': [12, 13], 'O': [6]}, '7': {'H': [14, 15], 'O': [7]}, '8': {'H': [16, 17], 'O': [8]}, '9': {'H': [18, 19], 'O': [9]}, '10': {'H': [20, 21], 'O': [10]}, '11': {'H': [22, 23], 'O': [11]}, '12': {'H': [24, 25], 'O': [12]}, '13': {'H': [26, 27], 'O': [13]}}\n" ] } ], "source": [ "print(water_chemical.molecules['water']['groups'])" ] }, { "cell_type": "markdown", "id": "1dcdb0ef", "metadata": {}, "source": [ "The groups key contains direct information about which atoms belong to which molecule, for example, the 10th molecule of water (id=9) consists of Hydrogen atoms 18 and 19 and oxygen atom 10." ] }, { "cell_type": "code", "execution_count": 17, "id": "a59a2e7f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'H': [18, 19], 'O': [9]}\n" ] } ], "source": [ "print(water_chemical.molecules['water']['groups']['9'])" ] }, { "cell_type": "markdown", "id": "c2b19cab", "metadata": {}, "source": [ "With this information you can compute values, e.g. diffusion coefficients with only the atoms belonging to a single molecule using the atom_select arguments in the calculator." ] }, { "cell_type": "markdown", "id": "dd908e51", "metadata": {}, "source": [ "### Analysis with molecules\n", "\n", "Now that we have seen how we can build molecules and what information this gives is, let's look at what we can analyse using them." ] }, { "cell_type": "markdown", "id": "2275128d", "metadata": {}, "source": [ "#### Angular Distribution Functions (ADFs)\n", "\n", "First things first, let's confirm we are working with water by looking at the angular distribution function of the atoms." ] }, { "cell_type": "code", "execution_count": 18, "id": "55c668ef", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ " 0%| | 0/1 [00:00, ?it/s]2022-01-31 10:47:05.284391: W tensorflow/core/framework/cpu_allocator_impl.cc:82] Allocation of 4877315008 exceeds 10% of free system memory.\n", "100%|███████████████████████████████████| 1/1 [00:32<00:00, 32.20s/it]\n" ] }, { "data": { "text/html": [ "\n", "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "\n", "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " const force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " const JS_MIME_TYPE = 'application/javascript';\n", " const HTML_MIME_TYPE = 'text/html';\n", " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", " const CLASS_NAME = 'output_bokeh rendered_html';\n", "\n", " /**\n", " * Render data to the DOM node\n", " */\n", " function render(props, node) {\n", " const script = document.createElement(\"script\");\n", " node.appendChild(script);\n", " }\n", "\n", " /**\n", " * Handle when an output is cleared or removed\n", " */\n", " function handleClearOutput(event, handle) {\n", " const cell = handle.cell;\n", "\n", " const id = cell.output_area._bokeh_element_id;\n", " const server_id = cell.output_area._bokeh_server_id;\n", " // Clean up Bokeh references\n", " if (id != null && id in Bokeh.index) {\n", " Bokeh.index[id].model.document.clear();\n", " delete Bokeh.index[id];\n", " }\n", "\n", " if (server_id !== undefined) {\n", " // Clean up Bokeh references\n", " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", " cell.notebook.kernel.execute(cmd_clean, {\n", " iopub: {\n", " output: function(msg) {\n", " const id = msg.content.text.trim();\n", " if (id in Bokeh.index) {\n", " Bokeh.index[id].model.document.clear();\n", " delete Bokeh.index[id];\n", " }\n", " }\n", " }\n", " });\n", " // Destroy server and session\n", " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", " cell.notebook.kernel.execute(cmd_destroy);\n", " }\n", " }\n", "\n", " /**\n", " * Handle when a new output is added\n", " */\n", " function handleAddOutput(event, handle) {\n", " const output_area = handle.output_area;\n", " const output = handle.output;\n", "\n", " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", " return\n", " }\n", "\n", " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", "\n", " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", " // store reference to embed id on output_area\n", " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " }\n", " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " const bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " const script_attrs = bk_div.children[0].attributes;\n", " for (let i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", " }\n", "\n", " function register_renderer(events, OutputArea) {\n", "\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " const toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[toinsert.length - 1]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " /* Handle when an output is cleared or removed */\n", " events.on('clear_output.CodeCell', handleClearOutput);\n", " events.on('delete.Cell', handleClearOutput);\n", "\n", " /* Handle when a new output is added */\n", " events.on('output_added.OutputArea', handleAddOutput);\n", "\n", " /**\n", " * Register the mime type and append_mime function with output_area\n", " */\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " /* Is output safe? */\n", " safe: true,\n", " /* Index of renderer in `output_area.display_order` */\n", " index: 0\n", " });\n", " }\n", "\n", " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", " if (root.Jupyter !== undefined) {\n", " const events = require('base/js/events');\n", " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", "\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " }\n", "\n", " \n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " const NB_LOAD_WARNING = {'data': {'text/html':\n", " \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"\\n\"+\n",
" \"\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"