From 4e9c0345c584e814e243cc0d28db7ff5d6f5511f Mon Sep 17 00:00:00 2001 From: Rose Cersonsky Date: Wed, 4 Dec 2019 14:24:16 +0100 Subject: [PATCH 01/12] Adding tutorials to master --- docs/source/tutorials/Advanced_SOAP.ipynb | 122 ++++ .../tutorials/Benefits_Performance.ipynb | 104 +++ docs/source/tutorials/Converting_Quip.ipynb | 302 ++++++++ docs/source/tutorials/Hyperparameters.ipynb | 97 +++ .../Introduction_to_Atomic_Descriptors.ipynb | 129 ++++ docs/source/tutorials/Kernels.ipynb | 90 +++ .../Property_Prediction_Tutorial.ipynb | 650 ++++++++++++++++++ docs/source/tutorials/Tutorial_Template.ipynb | 94 +++ docs/source/tutorials/index.rst | 43 ++ .../tutorials/utilities/general_utils.py | 123 ++++ .../utilities/hyperparameter_bounds.json | 1 + .../utilities/hyperparameter_presets.json | 1 + .../tutorials/utilities/learning_utils.py | 644 +++++++++++++++++ .../tutorials/utilities/tutorial_utils.py | 0 .../tutorials/utilities/vectors_utils.py | 429 ++++++++++++ .../tutorials/utilities/widget_style.json | 1 + 16 files changed, 2830 insertions(+) create mode 100644 docs/source/tutorials/Advanced_SOAP.ipynb create mode 100644 docs/source/tutorials/Benefits_Performance.ipynb create mode 100644 docs/source/tutorials/Converting_Quip.ipynb create mode 100644 docs/source/tutorials/Hyperparameters.ipynb create mode 100644 docs/source/tutorials/Introduction_to_Atomic_Descriptors.ipynb create mode 100644 docs/source/tutorials/Kernels.ipynb create mode 100644 docs/source/tutorials/Property_Prediction_Tutorial.ipynb create mode 100644 docs/source/tutorials/Tutorial_Template.ipynb create mode 100644 docs/source/tutorials/index.rst create mode 100644 docs/source/tutorials/utilities/general_utils.py create mode 100644 docs/source/tutorials/utilities/hyperparameter_bounds.json create mode 100644 docs/source/tutorials/utilities/hyperparameter_presets.json create mode 100644 docs/source/tutorials/utilities/learning_utils.py create mode 100644 docs/source/tutorials/utilities/tutorial_utils.py create mode 100644 docs/source/tutorials/utilities/vectors_utils.py create mode 100644 docs/source/tutorials/utilities/widget_style.json diff --git a/docs/source/tutorials/Advanced_SOAP.ipynb b/docs/source/tutorials/Advanced_SOAP.ipynb new file mode 100644 index 000000000..d7c03f25b --- /dev/null +++ b/docs/source/tutorials/Advanced_SOAP.ipynb @@ -0,0 +1,122 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "toc": true + }, + "source": [ + "

Table of Contents

\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Advanced SOAP Representations\n", + "\n", + "This notebook is intended showcase some more advanced examples of SOAP representations.\n", + "For more information on the variable conventions, derivation, and utility of atomic descriptors, please refer to (among others): \n", + "\n", + "\n", + "Beyond libRascal, the packages used in this tutorial are: [json](https://docs.python.org/2/library/json.html), [numpy](https://numpy.org/), [ipywidgets](https://ipywidgets.readthedocs.io/en/latest/), [matplotlib](https://matplotlib.org/), and [ase](https://wiki.fysik.dtu.dk/ase/index.html)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "# may omit in final version\n", + "%reload_ext autoreload\n", + "%autoreload 2 \n", + "\n", + "import os\n", + "import time\n", + "import sys\n", + "\n", + "import numpy as np\n", + "import ase\n", + "from ase.io import read\n", + "from matplotlib import pyplot as plt\n", + "import json\n", + "\n", + "wd=!(pwd)\n", + "sys.path.append(f'{wd[0]}/utilities')\n", + "from general_utils import *\n", + "from rascal.representations import SphericalInvariants as SOAP" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## $\\lambda$-SOAP" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Bispectrum" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## DVR" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": true, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/tutorials/Benefits_Performance.ipynb b/docs/source/tutorials/Benefits_Performance.ipynb new file mode 100644 index 000000000..93ffa67c7 --- /dev/null +++ b/docs/source/tutorials/Benefits_Performance.ipynb @@ -0,0 +1,104 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "toc": true + }, + "source": [ + "

Table of Contents

\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# What can libRascal do?\n", + "\n", + "This notebook is intended to _purpose of tutorial_.\n", + "For more information on _nuances of tutorial_, please refer to (among others): \n", + "- [Title (Surname Year)](url) \n", + "- [Title (Surname Year)](url)\n", + "\n", + "Beyond libRascal, the packages used in this tutorial are: [pkg](url), [pkg](url), and [pkg](url)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "# may omit in final version\n", + "%reload_ext autoreload\n", + "%autoreload 2 \n", + "\n", + "import os\n", + "import time\n", + "import sys\n", + "\n", + "import numpy as np\n", + "import ase\n", + "from ase.io import read\n", + "from matplotlib import pyplot as plt\n", + "import json\n", + "\n", + "wd=!(pwd)\n", + "sys.path.append(f'{wd[0]}/utilities')\n", + "from general_utils import *\n", + "from rascal.representations import SphericalInvariants as SOAP" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": true, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/tutorials/Converting_Quip.ipynb b/docs/source/tutorials/Converting_Quip.ipynb new file mode 100644 index 000000000..5138b6447 --- /dev/null +++ b/docs/source/tutorials/Converting_Quip.ipynb @@ -0,0 +1,302 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "toc": true + }, + "source": [ + "

Table of Contents

\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Converting QUIP Workflows to libRascal\n", + "\n", + "Welcome to libRascal!\n", + "\n", + "As you've seen in the last section, there is a lot that librascal can do efficiently. Perhaps the most important functionality is computing atomic descriptors. Here, we'll focus on converting a classic QUIP workflow for atomic descriptors to libRascal.\n", + "\n", + "\n", + "We will be mirroring parts of the [quippy descriptor tutorial](https://libatoms.github.io/QUIP/Tutorials/quippy-descriptor-tutorial.html), albeit with different molecules.\n", + "\n", + "For more information on _nuances of tutorial_, please refer to (among others): \n", + "- [Title (Surname Year)](url) \n", + "- [Title (Surname Year)](url)\n", + "\n", + "Beyond libRascal, the packages used in this tutorial are: [pkg](url), [pkg](url), and [pkg](url).\n", + "\n", + "**WARNING** Some quippy installations are only Python2 compatible. Please check that the notebook kernel corresponds to the python version supported by your quippy installation." + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "# may omit in final version\n", + "%reload_ext autoreload\n", + "%autoreload 2 \n", + "\n", + "import os\n", + "import time\n", + "import sys\n", + "\n", + "import numpy as np\n", + "import ase\n", + "from ase.io import read\n", + "import quippy \n", + "from quippy import descriptors\n", + "from matplotlib import pyplot as plt\n", + "import json\n", + "\n", + "\n", + "wd=!(pwd)\n", + "sys.path.append(f'{wd[0]}/utilities')\n", + "from rascal.representations import SphericalInvariants as SOAP" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Importing data\n", + "\n", + "We'll start out examples by computing the SOAP vectors for a benzene ring." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [], + "source": [ + "benzene = read(f'{wd[0]}/data/molecules/benzene.xyz')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## A simple descriptor: pairwise distances\n", + "\n", + "With quippy, you can compute pairwise distances with a cutoff of 1.5 Angstrom using:" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [], + "source": [ + "desc = descriptors.Descriptor(\"distance_2b Z1=6 Z2=6 cutoff=4\")" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "d=desc.calc(benzene)" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.hist(d['data'])\n", + "plt.gca().set_ylabel(\"PDF\")\n", + "plt.gca().set_xlabel(r\"$\\mathring{A}$\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With librascal, we can get the same results with ?????? " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## A many-body descriptor: SOAP" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [], + "source": [ + "desc = descriptors.Descriptor(\"soap cutoff=3 \\\n", + " l_max=4 n_max=4 \\\n", + " atom_sigma=0.5 \\\n", + " n_Z=1 Z={6} \")" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "51" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "desc.n_dim" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [], + "source": [ + "d=desc.calc(benzene)" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [], + "source": [ + "soap = SOAP(\n", + " soap_type='PowerSpectrum',\n", + " interaction_cutoff=3,\n", + " max_radial=4,\n", + " max_angular=4,\n", + " gaussian_sigma_type='Constant',\n", + " gaussian_sigma_constant=0.5,\n", + " cutoff_smooth_width=0.5,\n", + " \n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [], + "source": [ + "sv = soap.transform(benzene).get_dense_feature_matrix(soap)\n", + "\n", + "sv_inds = [0,2,4,6,8,10]" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(6, 51)" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "d['data'].shape" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Symbols('CHCHCHCHCHCH')" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "benzene.symbols" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": true, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/tutorials/Hyperparameters.ipynb b/docs/source/tutorials/Hyperparameters.ipynb new file mode 100644 index 000000000..f79efd790 --- /dev/null +++ b/docs/source/tutorials/Hyperparameters.ipynb @@ -0,0 +1,97 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "toc": true + }, + "source": [ + "

Table of Contents

\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Optimizing Hyperparameters\n", + "\n", + "This notebook is intended to _purpose of tutorial_.\n", + "For more information on _nuances of tutorial_, please refer to (among others): \n", + "- [Title (Surname Year)](url) \n", + "- [Title (Surname Year)](url)\n", + "\n", + "Beyond libRascal, the packages used in this tutorial are: [pkg](url), [pkg](url), and [pkg](url)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "# may omit in final version\n", + "%reload_ext autoreload\n", + "%autoreload 2 \n", + "\n", + "import os\n", + "import time\n", + "import sys\n", + "\n", + "import numpy as np\n", + "import ase\n", + "from ase.io import read\n", + "from matplotlib import pyplot as plt\n", + "import json\n", + "\n", + "wd=!(pwd)\n", + "sys.path.append(f'{wd[0]}/utilities')\n", + "from general_utils import *\n", + "from rascal.representations import SphericalInvariants as SOAP" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": true, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/tutorials/Introduction_to_Atomic_Descriptors.ipynb b/docs/source/tutorials/Introduction_to_Atomic_Descriptors.ipynb new file mode 100644 index 000000000..b3d35d013 --- /dev/null +++ b/docs/source/tutorials/Introduction_to_Atomic_Descriptors.ipynb @@ -0,0 +1,129 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Introduction to Atomic Descriptors\n", + "\n", + "This notebook is intended as an introductory to calculating and understanding atomic descriptors, primarily SOAP vectors. For more information on the variable conventions, derivation, and utility of atomic descriptors, please refer to (among others): \n", + "- [On representing chemical environments (Bartók 2013)](https://journals.aps.org/prb/abstract/10.1103/PhysRevB.87.184115)\n", + "- [Gaussian approximation potentials: A brief tutorial introduction (Bartók 2015)](https://onlinelibrary.wiley.com/doi/full/10.1002/qua.24927)\n", + "- [Comparing molecules and solids across structural and alchemical space (De 2016)](https://pubs.rsc.org/en/content/articlepdf/2016/cp/c6cp00415f)\n", + "- [Machine Learning of Atomic-Scale Properties Based on Physical Principles (Ceriotti 2018)](https://link.springer.com/content/pdf/10.1007%2F978-3-319-42913-7_68-1.pdf)\n", + "\n", + "Beyond libRascal, the packages used in this tutorial are: [json](https://docs.python.org/2/library/json.html), [numpy](https://numpy.org/), [ipywidgets](https://ipywidgets.readthedocs.io/en/latest/), [matplotlib](https://matplotlib.org/), and [ase](https://wiki.fysik.dtu.dk/ase/index.html)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "# may omit in final version\n", + "%reload_ext autoreload\n", + "%autoreload 2 \n", + "\n", + "import os\n", + "import time\n", + "import sys\n", + "\n", + "import numpy as np\n", + "import ase\n", + "from ase.io import read\n", + "from matplotlib import pyplot as plt\n", + "import json\n", + "\n", + "wd=!(pwd)\n", + "sys.path.append(f'{wd[0]}/utilities')\n", + "from general_utils import *\n", + "from rascal.representations import SphericalInvariants as SOAP" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Disclaimer: Dirac Notation**\n", + "\n", + "This notebook uses Dirac notation, which may be unfamiliar to many. For a refresher on Dirac notation, check out any of these resources: [Wikipedia](https://en.wikipedia.org/wiki/Bra%E2%80%93ket_notation), [GA Tech](http://vergil.chemistry.gatech.edu/notes/intro_estruc/node5.html).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Why do we need atomic descriptors?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## What are some simple atomic descriptors?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## What can atomic descriptors be used for?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## What kind of atomic descriptors does LR calculate?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "celltoolbar": "Raw Cell Format", + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + }, + "toc": { + "base_numbering": 1, + "nav_menu": { + "height": "297px", + "width": "252px" + }, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": "block", + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/tutorials/Kernels.ipynb b/docs/source/tutorials/Kernels.ipynb new file mode 100644 index 000000000..52d2abf11 --- /dev/null +++ b/docs/source/tutorials/Kernels.ipynb @@ -0,0 +1,90 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "toc": true + }, + "source": [ + "

Table of Contents

\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Similarity Kernels for Environments\n", + "\n", + "This notebook is intended to _purpose of tutorial_.\n", + "For more information on _nuances of tutorial_, please refer to (among others): \n", + "- [Title (Surname Year)](url) \n", + "- [Title (Surname Year)](url)\n", + "\n", + "Beyond libRascal, the packages used in this tutorial are: [pkg](url), [pkg](url), and [pkg](url)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "# may omit in final version\n", + "%reload_ext autoreload\n", + "%autoreload 2 \n", + "\n", + "import os\n", + "import time\n", + "import sys\n", + "\n", + "import numpy as np\n", + "import ase\n", + "from ase.io import read\n", + "from matplotlib import pyplot as plt\n", + "import json\n", + "\n", + "wd=!(pwd)\n", + "sys.path.append(f'{wd[0]}/utilities')\n", + "from general_utils import *\n", + "from rascal.representations import SphericalInvariants as SOAP" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": true, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/tutorials/Property_Prediction_Tutorial.ipynb b/docs/source/tutorials/Property_Prediction_Tutorial.ipynb new file mode 100644 index 000000000..17d79a53f --- /dev/null +++ b/docs/source/tutorials/Property_Prediction_Tutorial.ipynb @@ -0,0 +1,650 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Machine Learning Materials Properties\n", + "\n", + "This notebook is intended as an introductory how-to on training a model on materials properties based upon SOAP vectors. For more information on the variable conventions, derivation, utility, and calculation of SOAP vectors, please refer to (among others):\n", + "\n", + "\n", + "\n", + "Beyond libRascal, the packages used in this tutorial are: [json](https://docs.python.org/2/library/json.html), [numpy](https://numpy.org/), [ipywidgets](https://ipywidgets.readthedocs.io/en/latest/), [matplotlib](https://matplotlib.org/), and [ase](https://wiki.fysik.dtu.dk/ase/index.html)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "# may omit in final version\n", + "%reload_ext autoreload\n", + "%autoreload 2 \n", + "\n", + "import os\n", + "import time\n", + "import sys\n", + "\n", + "import numpy as np\n", + "import ase\n", + "from ase.io import read\n", + "from matplotlib import pyplot as plt\n", + "import json\n", + "\n", + "wd=!(pwd)\n", + "sys.path.append(f'{wd[0]}/utilities')\n", + "\n", + "if('/docs/source/tutorials' in wd[0]):\n", + " ref_dir = '../../../reference_data'\n", + "else:\n", + " ref_dir = '../reference_data'\n", + " \n", + "from general_utils import *\n", + "from rascal.representations import SphericalInvariants as SOAP\n", + "from rascal.models import Kernel" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Training a Kernel Ridge Regression (KRR) on Global Properties\n", + "As discussed in [Link to Hyperparameter Tutorial](), the hyperparameters of a SOAP descriptor will decide the amount of information contained in the descriptor. Here we'll use a standard Power Spectrum SOAP representation:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Hyperparameters" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "hyperparameters = dict(soap_type = 'PowerSpectrum', \\\n", + " interaction_cutoff = 3.5, \\\n", + " max_radial = 6, \\\n", + " max_angular = 6, \\\n", + " gaussian_sigma_constant = 0.4, \\\n", + " gaussian_sigma_type = 'Constant', \\\n", + " cutoff_smooth_width = 0.5\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load and Read the Input File\n", + "We'll first look at the [small_molecules-1000.xyz]() file, which contains the per-atom formation energy in eV. Because this is a property of the crystal (opposed to the atoms), we'll want to use the \"Structure\" kernel given by libRascal." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "input_file = f'{ref_dir}/inputs/small_molecules-1000.xyz'\n", + "property_name = \"dft_formation_energy_per_atom_in_eV\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We then read the trajectory, store the desired property, and create our SOAP calculator." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "There are 100 frames.\n" + ] + } + ], + "source": [ + "frames = np.array(read(input_file,\":100\"))\n", + "number_of_frames = len(frames)\n", + "print(f\"There are {number_of_frames} frames.\")\n", + "property_values = np.array([cc.info[property_name] for cc in frames])\n", + "\n", + "representation = SOAP(**hyperparameters)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Preparing Data for KRR" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We also need to define a few parameters for our training model:\n", + "\n", + "\n", + "We also need to split our dataset into a [training and testing set](https://en.wikipedia.org/wiki/Training,_validation,_and_test_sets)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "training_percentage = 0.8\n", + "zeta = 2\n", + "Lambda = 5e-3\n", + "jitter = 1e-8\n", + "kernel_type = \"Structure\"" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def split_dataset(N, training_percentage, seed=20):\n", + " np.random.seed(seed)\n", + " ids = list(range(N))\n", + " np.random.shuffle(ids)\n", + " return ids[:int(training_percentage*N)], ids[int(training_percentage*N):]\n", + "\n", + "train_idx, test_idx = split_dataset(number_of_frames, training_percentage)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we're ready to train the model! We can use our SOAP calculator to compute the features of our training set." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "features = representation.transform(frames[train_idx])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Constructing the KRR and Predicting the Properties\n", + "\n", + "We'll construct a KRR object so that we can reuse the model." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "class KRR(object):\n", + " \n", + " def __init__(self, features, properties,\n", + " kernel_type, representation, \n", + " Lambda, jitter, zeta=2,\n", + " weights=None, kernel_name=\"Cosine\",\n", + " **kwargs):\n", + " \n", + " self.weights = weights\n", + " \n", + " self.X = features\n", + " self.Y = properties\n", + " \n", + " self.kernel = Kernel(representation=representation, name=kernel_name,\n", + " target_type=kernel_type, zeta=zeta, **kwargs)\n", + "\n", + " self.Lambda = Lambda\n", + " self.jitter = jitter\n", + " self.hypers = dict(**kwargs)\n", + " self.calculator = representation\n", + "\n", + " def train(self):\n", + " KXX = self.kernel(self.X, self.X)\n", + "\n", + " delta = np.std(self.Y) / np.mean(KXX.diagonal())\n", + " KXX[np.diag_indices_from(KXX)] += self.Lambda**2 / delta **2 + self.jitter\n", + " \n", + " self.weights = np.linalg.solve(KXX,self.Y)\n", + " self.trained = True\n", + " \n", + " def predict(self, frames):\n", + " \n", + " try:\n", + " print(f\"Our weights have been calculated and have shape {self.weights.shape}\")\n", + " except:\n", + " self.train()\n", + " \n", + " features = self.calculator.transform(frames)\n", + " \n", + " kernel = self.kernel(self.X, features)\n", + " \n", + " return np.dot(self.weights, kernel)\n", + " \n", + " def plot(self, y_known, property_name, frames=None, y=None):\n", + " def calc_R2(yk, yp):\n", + " SStot = ((yk - np.average(yk, axis=0)) ** 2).sum(axis=0,dtype=np.float64)\n", + " SSres = ((yk - yp) ** 2).sum(axis=0,dtype=np.float64)\n", + " return np.mean(1 - (SSres/SStot))\n", + " if(frames!=None):\n", + " y=self.predict(frames)\n", + "\n", + " stats = dict(\n", + " mean_average_error= [np.mean(np.abs(y-y_known))],\n", + " root_mean_squared_error=[np.sqrt(np.mean((y-y_known)**2))],\n", + " R2 = [calc_R2(y_known, y)]\n", + " )\n", + " headers = ['Statistic', 'Value']\n", + " \n", + " display(Markdown(markdown_table_from_dict(stats, headers)))\n", + " \n", + " plt.scatter(y, y_known, s=3)\n", + " plt.axis('scaled')\n", + " plt.xlabel(property_name)\n", + " plt.ylabel('Predicted '+property_name)\n", + " plt.gca().set_aspect('equal')\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Constructing the Kernel\n", + "libRascal provides different kernels through the rascal.models.Kernel class.\n", + "\n", + "Here we'll use the cosine kernel, which uses the $\\zeta$ parameter we defined earlier. The cosine kernel is defined as:\n", + "\n", + "\\begin{equation}\n", + "k(x, y) = \\left(\\frac{xy^T}{||x|| ||y||}\\right)^\\zeta\n", + "\\end{equation}\n", + "\n", + "A Kernel object can be called on a single feature (to give the self-kernel) or a pair of features." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "krr = KRR(features, property_values[train_idx],\n", + " kernel_type=kernel_type, representation=representation,\n", + " Lambda=Lambda, jitter=jitter, weights=None,\n", + " zeta=zeta, **hyperparameters\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Training the KRR\n", + "We must find the kernel K of our training features and adjust it by the [Tikhonov matrix](https://en.wikipedia.org/wiki/Tikhonov_regularization). \n", + "\n", + "The weights $w$ are then the solutions of:\n", + "\n", + "\\begin{equation}\n", + "K w = Y\n", + "\\end{equation}\n", + "\n", + "where Y is the property matrix." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "krr.train()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Predicting Properties using the KRR" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Our weights have been calculated and have shape (80,)\n" + ] + }, + { + "data": { + "text/markdown": [ + "
StatisticValue
Mean Average Error0.032
Root Mean Squared Error0.0448
R20.9178
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "y = krr.predict(frames[test_idx])\n", + "krr.plot(y_known=property_values[test_idx], y=y, property_name=property_name)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Predicting from Another Data Set" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Our weights have been calculated and have shape (80,)\n" + ] + }, + { + "data": { + "text/markdown": [ + "
StatisticValue
Mean Average Error0.0331
Root Mean Squared Error0.0523
R20.904
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "filename=f'{ref_dir}/inputs/small_molecules-1000.xyz'\n", + "new_frames = read(filename,\":400\")\n", + "new_property_values = np.array([cc.info[property_name] for cc in new_frames])\n", + "y_pred = krr.predict(new_frames)\n", + "\n", + "krr.plot(y_known=new_property_values, y=y_pred, property_name=property_name)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Training a KRR on Atomic Properties\n", + "Now let's consider a property that is atom-centric, like the chemical shift. The workflow of predicting this property does not change much--we can use the same hyperparaters and Kernel class--but we will note the changes." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load and Read the Input File\n", + "We'll now look at the [CSD-500.xyz]() file, which contains the chemical shifts (CS) of 500 molecules. Because this is a property of the atoms, we'll want to use the \"Structure\" kernel given by libRascal." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "input_file = f'{ref_dir}/inputs/CSD-500.xyz'\n", + "property_name = \"CS\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We then read the trajectory, store the desired property, and create our SOAP calculator.\n", + "\n", + "**Because the chemical shifts are per-atom properties, they have been stored in ase.arrays, as opposed to ase.info.**" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "There are 100 frames and 13233 environments.\n" + ] + } + ], + "source": [ + "frames = np.array(read(input_file,\":100\"))\n", + "number_of_frames = len(frames)\n", + "property_values = np.array([cc.arrays[property_name] for cc in frames])\n", + "print(f\"There are {number_of_frames} frames and {len(np.concatenate(property_values))} environments.\")\n", + "\n", + "representation = SOAP(**hyperparameters)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Preparing Data for KRR" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We still need to define the training percentage, $\\zeta$, $\\Lambda$, jitter, and the kernel_type, **however only the kernel_type will differ from the earlier example**. We can then split our dataset into training and testing sets and calculate the SOAP vectors." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "kernel_type = \"Atom\"\n", + "train_idx, test_idx = split_dataset(number_of_frames, training_percentage)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "features = representation.transform(frames[train_idx])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Constructing the KRR and Predicting the Properties\n", + "\n", + "The only change here is the properties array. **Because the properties are stored in lists for each molecule, we will need to pass the concatenated list of the properties to our KRR model.**" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "krr = KRR(features, np.concatenate(property_values[train_idx])[:,0],\n", + " kernel_type=kernel_type, representation=representation,\n", + " Lambda=Lambda, jitter=jitter, weights=None,\n", + " zeta=zeta, **hyperparameters\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Training the KRR" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "krr.train()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Our weights have been calculated and have shape (10758,)\n" + ] + }, + { + "data": { + "text/markdown": [ + "
StatisticValue
Mean Average Error11.3622
Root Mean Squared Error21.0806
R20.9145
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "y = krr.predict(frames[test_idx])\n", + "krr.plot(y_known=np.concatenate(property_values[test_idx])[:,0],\n", + " y=y, property_name=property_name)" + ] + } + ], + "metadata": { + "celltoolbar": "Raw Cell Format", + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + }, + "toc": { + "base_numbering": 1, + "nav_menu": { + "height": "12px", + "width": "252px" + }, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": "block", + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/tutorials/Tutorial_Template.ipynb b/docs/source/tutorials/Tutorial_Template.ipynb new file mode 100644 index 000000000..9dbae2740 --- /dev/null +++ b/docs/source/tutorials/Tutorial_Template.ipynb @@ -0,0 +1,94 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "toc": true + }, + "source": [ + "

Table of Contents

\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Title of the Tutorial\n", + "\n", + "This notebook is intended to _purpose of tutorial_.\n", + "For more information on _nuances of tutorial_, please refer to (among others): \n", + "- [Title (Surname Year)](url) \n", + "- [Title (Surname Year)](url)\n", + "\n", + "Beyond libRascal, the packages used in this tutorial are: [pkg](url), [pkg](url), and [pkg](url)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "import time\n", + "\n", + "import numpy as np\n", + "import ase\n", + "from ase.io import read\n", + "from matplotlib import pyplot as plt\n", + "import json\n", + "from IPython.display import display, Markdown\n", + "\n", + "from rascal.representations import SphericalInvariants as SOAP\n", + "from rascal.models import Kernel\n", + "\n", + "wd=!(pwd)\n", + "sys.path.append(f'{wd[0]}/utilities')\n", + "from general_utils import *" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": true, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/tutorials/index.rst b/docs/source/tutorials/index.rst new file mode 100644 index 000000000..a89fc5345 --- /dev/null +++ b/docs/source/tutorials/index.rst @@ -0,0 +1,43 @@ +.. _tutorials: + +Tutorials +========= + +Here you will find some tutorial examples for getting started with librascal, +both as a new user of the library and for getting started developing a new +representation. + + +Introductory Tutorials +~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + Introduction_to_Atomic_Descriptors.ipynb + Hyperparameters.ipynb + Property_Prediction_Tutorial.ipynb + Kernels.ipynb + Benefits_Performance.ipynb + Advanced_SOAP.ipynb + +Coming from QUIP? +~~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + Benefits_Performance.ipynb + Converting_Quip.ipynb + Hyperparameters.ipynb + Property_Prediction_Tutorial.ipynb + Kernels.ipynb + Advanced_SOAP.ipynb + +Intro for developers +~~~~~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + nl-for-user diff --git a/docs/source/tutorials/utilities/general_utils.py b/docs/source/tutorials/utilities/general_utils.py new file mode 100644 index 000000000..25f7bd2d5 --- /dev/null +++ b/docs/source/tutorials/utilities/general_utils.py @@ -0,0 +1,123 @@ +import os +import inspect +import time + +from IPython.display import Markdown, display, clear_output, Image, HTML +import ipywidgets as widgets +import numpy as np +import ase +from ase.io import read +from matplotlib import pyplot as plt +from tqdm import tqdm_notebook as tqdm +import pandas as pd +import json + +# This is for backwards compatibility -- old versions of RASCAL will follow +# the latter schema, newer versions the former. +try: + from rascal.representations import SphericalInvariants as SOAP +except: + from rascal.representations import SOAP + +# These are some imports/helpers for all of the tutorials +style = json.load(open('./utilities/widget_style.json')) +hyper_dict = json.load(open("./utilities/hyperparameter_presets.json")) +hyper_vals = json.load(open("./utilities/hyperparameter_bounds.json")) + + +def mask_body_order(hyperparams): + """ This is for backwards compatibility, as we will soon be moving to using + "body order" in place of "soap_type" + + Author: R. Cersonsky + + Keywords: + hyperparams - full or partial dictionary of hyperparameters + + Returns: + dictionary of hyperparameters suitable for a SOAP object + """ + + soap_types = ["RadialSpectrum", "PowerSpectrum", "BiSpectrum"] + return {"soap_type": soap_types[hyperparams["body_order"]-1], + **{h: hyperparams[h] for h in hyperparams if h != 'body_order'}} + + +def markdown_table_from_dict(d, headers): + """ Function to generate a markdown table from a dictionary + + Author: R. Cersonsky + + Keywords: + d - dictionary of type {parameter: value} + headers - optional headers for the table + + Returns: + markdown string + """ + return '{}'.format(''.join([''.format(h) for h in headers]))+''.join(['{}'.format(key.replace('_',' ').title(), ''.join([''.format(round(v,4)) for v in d[key]])) for key in d])+'
{}
{}
{}
' + + +def compute_kernel(calculator, features1, features2=None, kernel_type='Structure', **kwargs): + """ Function to calculate similarity kernel + + Author: M. Veit or F. Musil, modified by R. Cersonsky + + Keywords: + calculator - soap calculator + features1 - ASE-Atoms-like object to compute kernel of + features2 - ASE-Atoms-like object to compute kernel of. + Default is features1 + kernel_type - "atom" or "structure" + kwargs - hyperparameters of soap calculator + + Returns: + kernel function + """ + from rascal.models import Kernel + + kernel = Kernel(representation=calculator, name='Cosine', target_type=kernel_type, zeta=2, **kwargs) + return kernel(X=features1, Y=features2) + +def readme_button(): + """ Function to generate and display a button to show the package README + + Author: R. Cersonsky + + """ + def show_readme_for_button(b): + clear_output() + display(Markdown(str(''.join(open('../README.rst'))))) + + button = widgets.Button(description="Show README", style=style) + output = widgets.Output() + display(button, output) + + button.on_click(show_readme_for_button) + + +def _button_template_(options, description, disp_func, default=None): + """ Function to generate and display a ToggleButton instance for a set of + options + + Author: R. Cersonsky + + Keywords: + options - list of options + descriptions - string to describe button + disp_func - function object to be called when a button is clicked + default - value of the button, needs to be in list of options + + Returns: + widgets.ToggleButtons Object + """ + button = widgets.ToggleButtons( + options=options, + description=description, + button_style='', + style=style, + value=options[0] if default == None else default + ) + display(button) + button.observe(disp_func, 'value') + return button diff --git a/docs/source/tutorials/utilities/hyperparameter_bounds.json b/docs/source/tutorials/utilities/hyperparameter_bounds.json new file mode 100644 index 000000000..3ca1f73fb --- /dev/null +++ b/docs/source/tutorials/utilities/hyperparameter_bounds.json @@ -0,0 +1 @@ +{"body_order": {"options": [1, 2, 3], "name": "Body Order"}, "interaction_cutoff": {"options": [1.75, 5.0], "name": "$r_{cut}$"}, "max_radial": {"options": [0, 10], "name": "$n_{max}$"}, "max_angular": {"options": [0, 10], "name": "$l_{max}$"}, "gaussian_sigma_constant": {"options": [0.01, 1.0], "name": "$\\sigma$"}, "gaussian_sigma_type": {"fixed": "Constant"}, "cutoff_smooth_width": {"fixed": 0.5}} \ No newline at end of file diff --git a/docs/source/tutorials/utilities/hyperparameter_presets.json b/docs/source/tutorials/utilities/hyperparameter_presets.json new file mode 100644 index 000000000..c3200ef85 --- /dev/null +++ b/docs/source/tutorials/utilities/hyperparameter_presets.json @@ -0,0 +1 @@ +{"Minimal Power Spectrum": {"body_order": 2, "interaction_cutoff": 3.5, "max_radial": 2, "max_angular": 1, "gaussian_sigma_constant": 0.5, "gaussian_sigma_type": "Constant", "cutoff_smooth_width": 0.0}, "Power Spectrum": {"body_order": 2, "interaction_cutoff": 3.5, "max_radial": 6, "max_angular": 6, "gaussian_sigma_constant": 0.4, "gaussian_sigma_type": "Constant", "cutoff_smooth_width": 0.5}, "Radial Spectrum": {"body_order": 1, "interaction_cutoff": 1.75, "max_radial": 6, "max_angular": 0, "gaussian_sigma_constant": 0.25, "gaussian_sigma_type": "Constant", "cutoff_smooth_width": 0.5}} \ No newline at end of file diff --git a/docs/source/tutorials/utilities/learning_utils.py b/docs/source/tutorials/utilities/learning_utils.py new file mode 100644 index 000000000..4bb4c5985 --- /dev/null +++ b/docs/source/tutorials/utilities/learning_utils.py @@ -0,0 +1,644 @@ +import os +import inspect +import time + +from IPython.display import Markdown, display, clear_output, Image, HTML +import ipywidgets as widgets +import numpy as np +import ase +from ase.io import read +from matplotlib import pyplot as plt +from tqdm import tqdm_notebook as tqdm +import pandas as pd +import json + +# This is for backwards compatibility -- old versions of RASCAL will follow +# the latter schema, newer versions the former. +try: + from rascal.representations import SphericalInvariants as SOAP +except: + from rascal.representations import SOAP + +from general_utils import (markdown_table_from_dict, \ + readme_button, _button_template_, + compute_kernel, mask_body_order) + +# These are some imports/helpers for all of the tutorials +style = json.load(open('./utilities/widget_style.json')) +hyper_dict = json.load(open("./utilities/hyperparameter_presets.json")) +hyper_vals = json.load(open("./utilities/hyperparameter_bounds.json")) + +# Properties preset for the learning tutorial +known_properties = dict(CS="Atom", + dft_formation_energy_per_atom_in_eV="Structure") +ignore = ['Natoms', 'numbers', 'Name', + 'positions', 'cutoff', 'nneightol', "NAME"] + +def split_dataset(frames, train_fraction, seed=10): + """ Function to split a dataset into testing and training portions. + + Author: M. Veit or F. Musil + + Keywords: + frames - ASE-Atoms like + train_fraction - float in [0.0,1.0], percentage of frames to train + + Returns: + indices of training and testing frames + """ + + N = len(frames) + ids = np.arange(N) + np.random.seed(seed) + np.random.shuffle(ids) + Ntrain = int(N*train_fraction) + train = ids[:Ntrain] + test = ids[Ntrain:] + return np.array(train), np.array(test) + + +def get_r2(y_pred, y_true): + """ Function to calculate R^2 + Author: M. Veit or F. Musil + + Keywords: + y_pred - list of predicted y values + y_true - list of known y values + + Returns: + float + """ + numerator = ((y_true - y_pred) ** 2).sum(axis=0, dtype=np.float64) + denominator = ((y_true - np.average(y_true, + axis=0)) ** 2).sum(axis=0, + dtype=np.float64) + output_scores = 1 - numerator / denominator + return np.mean(output_scores) + + +def get_score(y_pred, y_true): + """ Function to calculate accuracy statistics + + Author: M. Veit or F. Musil + + Keywords: + y_pred - list of predicted y values + y_true - list of known y values + + Returns: + dictionary containing SUP (supremum), MAE (mean squared error), + RMSD (root mean squared displacement), + and R^2 + """ + return { + "SUP": [np.amax(np.abs((y_pred-y_true)))], + "MAE": [np.mean(np.abs(y_pred-y_true))], + "RMSD": [np.sqrt(np.mean((y_pred-y_true)**2))], + r"$R^2$": [get_r2(y_pred, y_true)] + } + + +class KRR(object): + """ Class for Kernel Ridge Regression + + Author: M. Veit or F. Musil + + Keywords: + zeta - integer + weights - weights of the given by the kernel and the targets given by + the training set + representation - feature set given by soap vectors + kernel_type - "atom" or "Structure" + X - training dataset + + Functions: + predict - given the KRR, predicts the properties for a set of ASE frames + """ + + def __init__(self, weights, features, kernel_type, calculator=None, **kwargs): + self.weights = weights + self.hypers = dict(**kwargs) + self.calculator = calculator if calculator!=None else SOAP(**mask_body_order(kwargs)) + self.X = features + self.kernel_type = kernel_type + + def predict(self, frames): + features = self.calculator.transform(frames) + kernel = compute_kernel(calculator=self.calculator, features1=self.X, \ + features2=features, kernel_type=self.kernel_type, \ + **self.hypers) + return np.dot(self.weights, kernel) + + +def extract_property(frames, property='energy'): + """ Function to read properties from ASE frames object + + Author: M. Veit or F. Musil + + Keywords: + frames - ASE Atoms-like object + property - property to extract + + Returns: + list of the property from the given frames + + Raises error when property is not found in the ASE object + """ + if(property in frames[0].info): + return np.array([cc.info[property] for cc in frames]) + elif(property in frames[0].arrays): + return np.array([cc.arrays[property] for cc in frames]) + else: + print(frames[0].info) + raise KeyError( + "{} is not a property in the given frames".format(property)) + + +class learning_tutorial(object): + """ Class to wrap the learning tutorial + + Author: R. Cersonsky + + Constructor Keywords: + input_file - ASE Atoms-like object containing molecules or + crystals with some property to learn + training_percentage - float, percentage of frames to include in the + training set + interactive - boolean, whether to load the tutorial interactive- + ly in the jupyter notebook + verbose - boolean, whether or not to narrate the actions of + the tutorial + hyperparameters - dictionary, hyperparameters for SOAP calculation + number_of_frames - int, how many frames to include in the dataset + property - string, which property to train the dataset on + + """ + + def __init__(self, input_file='./data/learning/small_molecules-1000.xyz', + training_percentage=0.8, interactive=False, verbose=True, + hyperparameters=dict(**hyper_dict['Power Spectrum']), + number_of_frames=None, property=None): + + # presets given by M. Veit and F. Musil + self.zeta = 2 + self.Lambda = 5e-3 + + self.hyperparameters = hyperparameters + self.verbose = verbose + + # The verbosity wrap serves to limit the amount of text output in the + # jupyter notebook + self.verbosity_wrap = lambda s: (None if not verbose + else display(Markdown(s))) + + # Looks in the examples folder for files suitable for the learning + # tutorial + file_options = ['./data/learning/{}'.format(f) for f in + os.listdir('./data/learning/') if f.endswith('xyz')] + + # If the supplied file is not in the examples folder, includes it in the + # list of suitable files + if(input_file != None): + file_options.insert(0, input_file) + if(input_file in file_options[1:]): + file_options.pop(file_options[1:].index(input_file)+1) + + # Sets the file to the default if not supplied + self.input_file = file_options[0] if input_file == None else input_file + + # Reads input file + self.frames = np.array(read(self.input_file, ":")) + self.train_idx, self.test_idx = None, None + + # This next section is for the jupyter interface. Even if the user has + # specified zero interactivity, the sliders serve as containers for the + # hyperparameters to change when set + self.sliders = {val: + widgets.FloatSlider( + value=self.hyperparameters.get(val, + hyper_vals[val]['options'][0]), + min=hyper_vals[val]['options'][0], + max=hyper_vals[val]['options'][1], + description=hyper_vals[val]['name'], + continuous_update=True, + step=(hyper_vals[val]['options'][1] - + hyper_vals[val]['options'][0])/20., + style=style, + ) + if isinstance(hyper_vals[val]['options'][0], float) else + widgets.IntSlider( + value=self.hyperparameters.get(val, + hyper_vals[val]['options'][0]), + min=hyper_vals[val]['options'][0], + max=hyper_vals[val]['options'][1], + description=hyper_vals[val]['name'], + continuous_update=True, + step=1, + style=style, + ) + if isinstance(hyper_vals[val]['options'][0], int) + and hyper_vals[val]['options'][0] != True + else widgets.Dropdown( + options=hyper_vals[val]['options'], + style=style, + value=self.hyperparameters.get(val, + hyper_vals[val]['options'][0]), + description=hyper_vals[val]['name'], + ) + for val in hyper_vals + if 'fixed' not in hyper_vals[val]} + self.properties = {prop: + extract_property(self.frames, prop) + for prop in sorted([*list(self.frames[0].info.keys()), + *list(self.frames[0].arrays.keys())], + key=lambda p: -int(p in known_properties)) + if prop not in ignore} + + self.sliders['number_of_frames'] = widgets.IntSlider( + value=int(len(self.frames)*0.2) + if number_of_frames == None + else number_of_frames, + min=1, + max=len(self.frames), + description="Number of Frames", + step=1, + style=style) + self.sliders['property_to_ml'] = widgets.Dropdown( + value=list( + self.properties.keys())[0] + if property == None + else property, + options=list( + self.properties.keys()), + description="Property to ML", + style=style) + if(self.sliders['property_to_ml'].value not in known_properties): + self.sliders['kernel_type'] = widgets.Dropdown( + value='Atom', + options=['Atom', 'Structure'], + description="Kernel Type", + style=style) + else: + self.sliders['kernel_type'] = widgets.Dropdown( + value=known_properties[self.sliders['property_to_ml'].value], + options=[ + known_properties[self.sliders['property_to_ml'].value]], + description="Kernel Type", + style=style) + self.sliders['training_percentage'] = widgets.FloatSlider( + value=training_percentage, + min=0, + max=1, + description="Training Percentage", + continuous_update=True, + step=0.05, + style=style, + ) + + # Show and enable the widgets if interactive==True + if(interactive): + self.input_button = widgets.Dropdown(options=[*file_options], # , "Other"], + style=style,\ + value=self.input_file, + description="Input File: ", + ) + self.input_button.observe(self.get_input, names='value') + display(self.input_button) + + self.preset_button = _button_template_(list(hyper_dict.keys()), + "SOAP Presets: ", self.preset_func) + + slider_order = ['property_to_ml', 'kernel_type', + 'number_of_frames', 'training_percentage', + *list(hyper_vals.keys())] + for s in slider_order: + if(s in self.sliders): + self.sliders[s].observe(lambda change: + self.change_func(change), + names='value') + display(self.sliders[s]) + + # Set up one KRR for each possible property for caching reasons + self.krr = {prop: None for prop in self.properties} + self.trained = {prop: False for prop in self.properties} + + # These serve as placeholders for time estimates until any calculation + # is run + self.est_frames, self.est_times = [], [] + self.pred_frames, self.pred_times = [], [] + + def reset_ML(self, inp_change=False): + """ Function to reset the properties, number of frames, and kernel type + if any values affecting the machine learning have changed + + Author: R. Cersonsky + """ + if(inp_change): + self.properties = {prop: + extract_property(self.frames, prop) + for prop in sorted([*list(self.frames[0].info.keys()), + *list(self.frames[0].arrays.keys())], + key=lambda p: -int(p in known_properties)) + if prop not in ignore} + + self.sliders['number_of_frames'].max = len(self.frames) + self.sliders['number_of_frames'].value = int(len(self.frames)*0.2) + + self.sliders['property_to_ml'].options = list( + self.properties.keys()) + self.sliders['property_to_ml'].value = list( + self.properties.keys())[0] + + if(self.sliders['property_to_ml'].value in known_properties): + self.sliders['kernel_type'].options = [ + known_properties[self.sliders['property_to_ml'].value]] + self.sliders['kernel_type'].value = self.sliders['kernel_type'].options[0] + else: + self.sliders['kernel_type'].options = ['Atom', 'Structure'] + self.sliders['kernel_type'].value = 'Atom' + + self.krr = {prop: None for prop in self.properties} + self.trained = {prop: False for prop in self.properties} + + def change_func(self, change): + """ Function for button events + + Author: R. Cersonsky + """ + change['owner'].value = change['new'] + for s in self.hyperparameters: + if(s in self.sliders): + if(self.hyperparameters[s] != self.sliders[s].value): + self.est_frames, self.est_times = [], [] + self.hyperparameters[s] = self.sliders[s].value + + if(change['owner'] == self.sliders['property_to_ml']): + if(self.sliders['property_to_ml'].value in known_properties): + self.sliders['kernel_type'].options = [ + known_properties[self.sliders['property_to_ml'].value]] + self.sliders['kernel_type'].value = self.sliders['kernel_type'].options[0] + else: + self.sliders['kernel_type'].options = ['Atom', 'Structure'] + self.sliders['kernel_type'].value = 'Atom' + + self.reset_ML() + + def preset_func(self, a): + """ Function to change hyperparameters based upon presets + + Author: R. Cersonsky + """ + for s in self.sliders: + if(s in self.hyperparameters): + self.hyperparameters[s] = hyper_dict[self.preset_button.value][s] + self.sliders[s].value = self.hyperparameters[s] + self.reset_ML() + + def get_input(self, a): + """ Function to change input file + + Author: R. Cersonsky + """ + inp = self.input_button.value + self.input_file = inp + self.frames = np.array(read(self.input_file, ":")) + self.reset_ML(True) + + def train_krr_model_func(self, frame_idx, jitter=1e-8, pretend=False): + """ Function to trains the model on the given SOAP representation and + properties. It is used for both the time estimation and the eventual + training. The flag pretend is set to True when it is being used for + estimation, false otherwise. + + Author: R. Cersonsky + + Keywords: + frame_idx - list of indices of the frames to train on + jitter - float, anticipated error to adjust kernel diagonals + pretend - boolean, whether to not show the results + + """ + + if(pretend == False): + self.output_params() + verbosity_wrap = lambda s: self.verbosity_wrap(s) + else: + verbosity_wrap = lambda s: None + + verbosity_wrap("
We will now train a model on {}.".format( + self.sliders['property_to_ml'].value)) + + representation = SOAP(**mask_body_order(self.hyperparameters)) + + if(known_properties[self.sliders['property_to_ml'].value] == 'Atom'): + props = np.concatenate(self.properties[self.sliders['property_to_ml'].value][frame_idx])[:,0] + else: + props = self.properties[self.sliders['property_to_ml'].value][frame_idx] + + training_properties=props + + verbosity_wrap("First, I am going to separate my dataset:") + verbosity_wrap("
Now we will compute the SOAP representation of \ + our training frames.") + + t=time.time() + features=representation.transform(self.frames[frame_idx]) + + verbosity_wrap('This took {} seconds/frame.'.format( + round((time.time()-t)/len(frame_idx), 8))) + + if(pretend == False): + self.estimate_time(N=max(0, 20-len(self.est_frames)), + p="Estimating time to compute kernel...") + est=int(np.poly1d(np.polyfit(self.est_frames, + self.est_times, + deg=2))(len(frame_idx)))+1 + else: + est=0 + + verbosity_wrap("
Next we find the kernel for our training model.\ +
(This step will take approximately {} minutes and \ + {} seconds.)".format(int(est/60), int(est % 60))) + + time.sleep(0.5) + t=time.time() + kernel = compute_kernel(calculator=representation, \ + features1=features, \ + kernel_type=self.sliders['kernel_type'].value, \ + **self.hyperparameters) + + self.est_frames.append(len(frame_idx)) + self.est_times.append(time.time()-t) + + delta=np.std(training_properties) / np.mean(kernel.diagonal()) + kernel[np.diag_indices_from( + kernel)] += self.Lambda**2 / delta ** 2 + jitter + + verbosity_wrap("
We will adjust the our kernel with the tolerance \ + matrix $\\Lambda = ({})I$.".format(\ + round(self.Lambda**2 / delta ** 2 + jitter, 8))) + verbosity_wrap("
Now we can take this kernel to compute the weights \ + of our KRR.") + + weights=np.linalg.solve(kernel, training_properties) + model=KRR(weights, features, \ + kernel_type=self.sliders['kernel_type'].value, + **self.hyperparameters + ) + if(pretend == False): + self.krr[self.sliders['property_to_ml'].value], k=model, kernel + self.trained[self.sliders['property_to_ml'].value]=True + + def train_krr_model(self, jitter= 1e-8): + """ Wrapper to the train_krr_model_func function for use in the tutorial + + Author: R. Cersonsky + + Keywords: + jitter - float, anticipated error to adjust kernel diagonals + + """ + + training_dict={"Training Set": [int(self.sliders['number_of_frames'].value*(self.sliders['training_percentage'].value)),\ + round(100*(self.sliders['training_percentage'].value))], + "Testing Set": [int(self.sliders['number_of_frames'].value*(1-self.sliders['training_percentage'].value)),\ + round(100*(1-self.sliders['training_percentage'].value))]} + headers=["Partition", "Number of Frames", "Percentage"] + self.verbosity_wrap(markdown_table_from_dict(training_dict, headers)) + + self.train_idx, self.test_idx=split_dataset(self.frames[: self.sliders['number_of_frames'].value], + self.sliders['training_percentage'].value) + self.train_krr_model_func(self.train_idx, jitter= jitter) + + def plot_prediction_func(self, y_known= None, frames = None, + frame_idx= [], pretend = False): + """ Function to predict properties from the given SOAP representation and + KRR model. It is used for both the time estimation and the tutorial + prediction. The flag pretend is set to True when it is being used for + estimation, false otherwise. + + Author: R. Cersonsky + + Keywords: + y_known - list, target properties to train on + frames - frames to predict properties of + frame_idx - list of indices of the frames to train on + pretend - boolean, whether to not show the results + """ + if(len(frame_idx) > 0): + frames=self.frames[frame_idx] + y_known = np.concatenate(self.properties[self.sliders['property_to_ml'].value][frame_idx])[: , 0] if self.sliders['kernel_type'].value == 'Atom' else self.properties[self.sliders['property_to_ml'].value][frame_idx] + if(pretend == False): + verbosity_wrap=lambda s: self.verbosity_wrap(s) + else: + verbosity_wrap = lambda s: None + if(self.trained[self.sliders['property_to_ml'].value] == False): + verbosity_wrap("Model has not yet been trained, training now...") + self.train_krr_model() + # np.concatenate(self.properties[self.sliders['property_to_ml'].value][frame_idx])[:,0] if self.sliders['kernel_type'].value=='Atom' else self.properties[self.sliders['property_to_ml'].value][frame_idx] + testing_properties=y_known + + if(pretend == False): + self.estimate_time(x=self.pred_frames, y=self.pred_times, f=self.plot_prediction_func, N=max( + 0, 20-len(self.pred_frames)), ref=len(frames), p="Estimating time to compute prediction...") + est=int(np.poly1d(np.polyfit(self.pred_frames, + self.pred_times, deg=3))(len(frames)))+1 + else: + est=0 + + t=time.time() + verbosity_wrap("Predicting the properties of our data set will take approximately {} minutes and {} seconds.".format( + int(est/60), int(est % 60))) + y_pred=self.krr[self.sliders['property_to_ml'].value].predict(frames) + self.pred_frames.append(len(frame_idx)) + self.pred_times.append(time.time()-t) + verbosity_wrap(markdown_table_from_dict( + get_score(y_pred, testing_properties), headers = ["Statistic", "Value"])) + + if(not pretend): + plt.scatter(y_pred, testing_properties, s=3) + plt.axis('scaled') + plt.xlabel(self.sliders['property_to_ml'].value) + plt.ylabel('Predicted '+self.sliders['property_to_ml'].value) + plt.gca().set_aspect('equal') + plt.show() + + def predict_test_set(self): + """ Wrapper for plot_prediction_func that is used within the tutorial + + Author: R. Cersonsky + """ + self.plot_prediction_func(frame_idx=self.test_idx) + + def predict_new_set(self, filename='./data/small_molecules-1000.xyz', + num_frames=''): + """ Wrapper predicts a new set of data beyond the training set, loaded + from a different file + + Author: R. Cersonsky + + Keywords: + filename - string corresponding to an ASE-like file + num_frames - number of frames to predict + """ + frames=np.array(read(filename, ":{}".format(num_frames))) + properties=extract_property( + frames, self.sliders['property_to_ml'].value) + self.plot_prediction_func(y_known=properties, frames=frames) + + def output_params(self): + """ Function to output the hyperparameters that are currently set + + Author: R. Cersonsky + """ + self.verbosity_wrap('Our input file is {}, of which we are using {} \ + frames.'.format(self.input_file, \ + self.sliders['number_of_frames'].value)) + + hdict={hyper_vals[k]['name']: [self.hyperparameters[k]] + for k in self.hyperparameters + if 'fixed' not in hyper_vals[k]} + headers=["Parameter", "Value"] + + self.verbosity_wrap("
Our hyperparameters are {}".format( + markdown_table_from_dict(hdict, headers))) + + def set(self, value_name, value): + """ Public Setter function for tutorial interface + + Author: R. Cersonsky + + Keywords: + value_name - string, must be in self.sliders + value - value to set + """ + assert value_name in self.sliders + self.sliders[value_name].value=value + + def estimate_time(self, x=None, y=None, f=None, N=20, ref=None, p=None): + """ Helper function for estimating time + + Author: R. Cersonsky + + Keywords: + x - list of numbers of frames computed + y - list, size=size(x), of times to computed frames in x + f - function to estimate the run time of + N - number of trials to run + ref - int, upper limit of trials to run. + Defaults to (number_of_frames in the ultimate computation) / 4 + p - print statement + """ + if(N <= 0): + return + if(x == None or y == None or f == None or ref == None): + x=self.est_frames + y=self.est_times + f=self.train_krr_model_func + ref=int(0.25*self.sliders['number_of_frames'].value * + self.sliders['training_percentage'].value) + + if(p != None and min(N, ref) > 0): + self.verbosity_wrap(p) + for nf in tqdm(np.random.randint(2, ref, size = min(N, ref))): + f(frame_idx=np.random.randint(len(self.frames), size = nf), pretend=True) diff --git a/docs/source/tutorials/utilities/tutorial_utils.py b/docs/source/tutorials/utilities/tutorial_utils.py new file mode 100644 index 000000000..e69de29bb diff --git a/docs/source/tutorials/utilities/vectors_utils.py b/docs/source/tutorials/utilities/vectors_utils.py new file mode 100644 index 000000000..eff2088ea --- /dev/null +++ b/docs/source/tutorials/utilities/vectors_utils.py @@ -0,0 +1,429 @@ +import os +import inspect +import time + +from IPython.display import Markdown, display, clear_output, Image, HTML +import ipywidgets as widgets +import numpy as np +import ase +from ase.io import read +from matplotlib import pyplot as plt +from tqdm import tqdm_notebook as tqdm +import pandas as pd +import json + +# This is for backwards compatibility -- old versions of RASCAL will follow +# the latter schema, newer versions the former. +try: + from rascal.representations import SphericalInvariants as SOAP +except: + from rascal.representations import SOAP + +from general_utils import (markdown_table_from_dict, \ + readme_button, _button_template_, + compute_kernel, mask_body_order) + +# These are some imports/helpers for all of the tutorials +style = json.load(open('./utilities/widget_style.json')) +hyper_dict = json.load(open("./utilities/hyperparameter_presets.json")) +hyper_vals = json.load(open("./utilities/hyperparameter_bounds.json")) + + +def format_positions(positions): + """ Function to format positions for best viewing angle. Does a simple PCA + to find the best direction to view the molecule and rotates position + along these axes + + Author: R. Cersonsky + + Keywords: + positions - list of 3-vectors + + Returns: + positions - list of 3-vectors + """ + from sklearn.decomposition import PCA + pca = PCA(n_components=3) + return pca.fit_transform(positions) + + +class SOAP_tutorial(object): + """ Class to wrap the SOAP vectors tutorial + + Author: R. Cersonsky + + Constructor Keywords: + molecule_file - filename of ASE Atoms-like object + containing molecule + interactive - boolean, whether to load the tutorial interactive- + ly in the jupyter notebook + verbose - boolean, whether or not to narrate the actions of + the tutorial + hyperparameters - dictionary, hyperparameters for SOAP calculation + or string corresponding to one of the SOAP presets + + Functions: + predict - given the KRR, predicts the properties for a set of ASE frames + """ + + def __init__(self, + molecule_file=None, + interactive=False, + verbose=True, + hyperparameters=dict(**hyper_dict['Power Spectrum']), + ): + + # Check if hyperparameters are of type string or dictionary + if(isinstance(hyperparameters, str)): + self.hyperparameters = hyper_dict[hyperparameters] + else: + self.hyperparameters = {h: hyperparameters[h] + if h in hyperparameters + else hyper_dict['Power Spectrum'][h] + for h in hyper_dict['Power Spectrum']} + self.verbose = verbose + self.verbosity_wrap = lambda s: ( + None if not verbose else display(Markdown(s))) + + # Look for and load available molecules + file_options = ['./data/molecules/{}'.format(f) + for f in os.listdir('./data/molecules/') + if f.endswith('xyz')] + + if(molecule_file != None and molecule_file not in file_options): + file_options.append(molecule_file) + + self.frames, self.positions, self.symbols, self.inds, self.labels = {}, {}, {}, {}, {} + self.import_molecules(file_options) + + self.vectors = None + self.interactive = interactive + + # This next section is for the jupyter interface. Even if the user has + # specified zero interactivity, the sliders serve as containers for the + # hyperparameters to change when set + self.sliders = {val: + widgets.FloatSlider( + value=self.hyperparameters.get(val, + hyper_vals[val]['options'][0]), + min=hyper_vals[val]['options'][0], + max=hyper_vals[val]['options'][1], + description=hyper_vals[val]['name'], + continuous_update=True, + step=(hyper_vals[val]['options'][1] - + hyper_vals[val]['options'][0])/20., + style=style, + ) + if isinstance(hyper_vals[val]['options'][0], float) else + widgets.IntSlider( + value=self.hyperparameters.get(val, + hyper_vals[val]['options'][0]), + min=hyper_vals[val]['options'][0], + max=hyper_vals[val]['options'][1], + description=hyper_vals[val]['name'], + continuous_update=True, + step=1, + style=style, + ) + if isinstance(hyper_vals[val]['options'][0], int) and + hyper_vals[val]['options'][0] != True else + widgets.Dropdown(options=hyper_vals[val]['options'], + style=style, + value=self.hyperparameters.get(val, + hyper_vals[val]['options'][0]), + description=hyper_vals[val]['name'], + ) + for val in hyper_vals if 'fixed' not in hyper_vals[val]} + + # Which elements to center smooth gaussians on. Defaults to all elements + # present except for hydrogen. + constituents = list(set([s for k in self.symbols for s in self.symbols[k]])) + self.sliders['center_select']=widgets.SelectMultiple( + options=constituents, + value=[s for s in constituents if s != "H"], + description="Where to Place SOAP Centers", + style=style) + + # Whether to compute the global kernel (average of the environments) or + # atomic kernel. + self.sliders['average'] = widgets.Dropdown( + options=["Environment-Centered", "Average"], + value="Environment-Centered", + description="Type of SOAP Vectors", + style=style) + + # Show and enable the widgets if interactive==True + if(interactive): + self.preset_button = _button_template_(list(hyper_dict.keys()), + "SOAP Presets: ", + self.preset_func) + if(isinstance(hyperparameters, str)): + self.preset_button.value = hyperparameters + + slider_order = ['center_select', + 'average', + *list(hyper_vals.keys())] + + for s in slider_order: + if(s in self.sliders): + display(self.sliders[s]) + self.sliders[s].observe( + lambda change: self.change_func(change), names='value') + + # These buttons allow users to choose up to two molecules to compute + # SOAP vectors and compare. + self.molecule_buttons = [widgets.Dropdown(options=[*self.frames.keys()], # , "Other"], + style=style,\ + value=list( + self.frames.keys())[0], + description="\tMolecule: " + ) for i in range(2)] + + def import_molecules(self, file_list): + """ Function to import ASE-like files and include them in the dictionaries + of available molecules. + + Author: R. Cersonsky + + Keywords: + file_list - list of strings corresponding to ASE-like files + """ + for file in file_list: + for frame in read(file, ":"): + key = str(frame.symbols) + + if(key in self.frames): + print("Overwriting previous entry for {}".format(key)) + + self.frames[key] = frame + self.positions[key] = format_positions(frame.get_positions()) + self.inds[key] = sorted(range(len(self.positions[key])), + key=lambda j: self.positions[key][j][0]) + self.positions[key] = self.positions[key][self.inds[key]] + self.symbols[key] = frame.symbols[self.inds[key]] + super_scripts = ['' if list(self.symbols[key]).count(s) == 1 + else '^{{({})}}'.format(list(self.symbols[key])[:i].count(s)+1) + for i, s in enumerate(list(self.symbols[key]))] + self.labels[key] = np.array([r'${}{}$'.format(self.symbols[key][i], s) + for i, s in enumerate(super_scripts)]) + + def change_func(self, change): + """ Function to import ASE-like files and include them in the dictionaries + of available molecules. + + Author: R. Cersonsky + + Keywords: + file_list - list of strings corresponding to ASE-like files + """ + change['owner'].value = change['new'] + for s in self.hyperparameters: + if(s in self.sliders): + if(self.hyperparameters[s] != self.sliders[s].value): + self.hyperparameters[s] = self.sliders[s].value + self.vectors = None + + def preset_func(self, a): + """ Function to change hyperparameters based upon presets + + Author: R. Cersonsky + """ + for s in self.sliders: + if(s in self.hyperparameters): + self.hyperparameters[s] = hyper_dict[self.preset_button.value][s] + self.sliders[s].value = self.hyperparameters[s] + + def get_soap_vectors(self, key=None, average=False): + """ Get the SOAP vectors for the given molecule, denoted by key + + Author: R. Cersonsky + + Keywords: + key - string corresponding to molecule built by \ + import_molecules + average - whether to compute the average SOAP vector for the + molecule + """ + if(key == None): + key = self.input_file.replace('./data/molecules/', '')[:-4] + + representation = SOAP(**mask_body_order(self.hyperparameters)) + all_frames = [self.frames[k] for k in sorted(self.frames.keys())] + features = representation.transform( + all_frames).get_dense_feature_matrix(representation) + + lengths = [len(self.inds[k]) for k in sorted(self.frames.keys())] + + self.vectors = {k: features[sum(lengths[0:i]):sum(lengths[0:i])+lengths[i]] + for i, k in enumerate(sorted(self.frames.keys()))} + vectors = self.vectors[key] + + # if(average): + # return np.mean(vectors, axis=0) + return vectors[self.inds[key]] + + def make_figure(self, key, img_name): + """ Function to generate an image of the given molecule and cache it + under img_name + + Author: R. Cersonsky + + Keywords: + key - string corresponding to molecule built by + import_molecules + img_name - filename under which to cache the image + """ + from ase.data import covalent_radii, atomic_numbers + from matplotlib import pyplot, patches + from ase.data.colors import jmol_colors + style = { + "horizontalalignment": "center", + "verticalalignment": "center", + "fontsize": 12 + } + fig, ax = pyplot.subplots(1) + + for i, p in enumerate(self.positions[key]): + an = atomic_numbers[self.symbols[key][i]] + ax.text(*p[:2], + s=self.labels[key][i], + **style, + zorder=p[-1]+0.01 + ) + ax.add_artist(patches.Circle(p[:2], + covalent_radii[an], + facecolor=jmol_colors[an], + edgecolor='k', + alpha=0.95, + zorder=p[-1])) + ax.axis('off') + bounds = [*np.min(self.positions[key], axis=0), * + np.max(self.positions[key], axis=0)] + ax.set_xlim([bounds[0]-1.5, bounds[3]+1.5]) + ax.set_ylim([bounds[1]-1.5, bounds[5]+1.5]) + ax.set_aspect('equal') + fig.savefig(img_name) + fig.clf() + + def show_kernel(self, key1, key2=None, show=True, average=False): + from rascal.models import Kernel + from ase.data import chemical_symbols + """ Function to show pandas dataframe for the comparison kernel + + Author: R. Cersonsky + + Keywords: + key1 - string corresponding to molecule built by + import_molecules + key2 - string corresponding to molecule built by + import_molecules, defaults to key1 + show - boolean, whether to show or return the dataframe + average - boolean, whether to compute the average SOAP vector + for the molecule + """ + key2 = key2 if key2 != None else key1 + average = self.sliders['average'].value == "Average" + + soap=SOAP(**mask_body_order(self.hyperparameters)) + features1=soap.transform(self.frames[key1]) + features2=soap.transform(self.frames[key2]) + + kernel = Kernel(soap, + target_type="Structure" if average else "Atom", + zeta = 2, + **self.hyperparameters) + data = kernel(features2, features1) + + if (average): + + vec1 = np.mean(features1.get_dense_feature_matrix(soap),axis=0) + vec2 = np.mean(features2.get_dense_feature_matrix(soap), axis=0) + if(vec1.shape==vec2.shape): + data = np.dot(vec1, vec2)/(np.linalg.norm(vec1)*np.linalg.norm(vec2)) + df=pd.DataFrame(data=[['%1.3f' %(data)]], + columns =[key2], + index =[key1] + ) + else: + df=pd.DataFrame(data=[['%1.3f' %(data[i][j]) + for i,v in enumerate(features2._frames.numbers) if v!=1] + for j,w in enumerate(features1._frames.numbers) if w!=1], + columns =[chemical_symbols[v] for i,v in enumerate(features2._frames.numbers) if v!=1], + index =[chemical_symbols[v] for i,v in enumerate(features1._frames.numbers) if v!=1] + ) + # + df.name = ("Self-" if key1 == key2 else '') + \ + "Similarity " + ("Kernel" if not average else "") + return df + + def show_molecule(self, key, show=True): + """ Function to either generate or show the image for the given molecule + + Author: R. Cersonsky + + Keywords: + key - string corresponding to molecule built by + import_molecules + show - boolean, whether to show or return the dataframe + """ + import os + img_name = './images/cache/{}.png'.format(key) + if(not os.path.exists(img_name)): + self.make_figure(key, img_name) + if(show): + display(Image(img_name)) + return img_name + + def compute(self, a=None): + """ Function to compute the SOAP vectors for the set hyperparameters + + Author: R. Cersonsky + """ + def wrap_compute(a): + self.get_soap_vectors( + key=self.molecule_buttons[0].value, average=self.sliders['average'].value == "Average") + print("SOAP Vectors for {}: \n\t".format( + self.molecule_buttons[0].value), self.vectors[self.molecule_buttons[0].value]) + + compute_button = widgets.Button(description="Compute", + style=style, + value=False, + ) + compute_button.on_click(wrap_compute) + clear_button = widgets.Button(description="Clear Output", + style=style, + value=False, + ) + clear_button.on_click(lambda a: self.compute(a)) + display(self.molecule_buttons[0]) + display(widgets.widgets.HBox((compute_button, clear_button))) + + def compare(self, a=None): + """ Function to compare the SOAP vectors of two molecules + for the set hyperparameters + + Author: R. Cersonsky + """ + clear_output() + + def wrap_compare(a): + df = self.show_kernel( + key1=self.molecule_buttons[0].value, key2=self.molecule_buttons[1].value, show=False) + m1 = self.show_molecule(self.molecule_buttons[0].value, show=False) + m2 = self.show_molecule(self.molecule_buttons[1].value, show=False) + display(HTML("
{}{}{}
{}
".format( + self.molecule_buttons[0].value, df.name, self.molecule_buttons[1].value, m1, df.to_html(), m2))) + compare_button = widgets.Button(description="Compare", + style=style, + value=False, + ) + + compare_button.on_click(wrap_compare) + clear_button = widgets.Button(description="Clear Output", + style=style, + value=False, + ) + clear_button.on_click(lambda a: self.compare(a)) + display(widgets.widgets.HBox( + (self.molecule_buttons[0], self.molecule_buttons[1]))) + display(widgets.widgets.HBox((compare_button, clear_button))) diff --git a/docs/source/tutorials/utilities/widget_style.json b/docs/source/tutorials/utilities/widget_style.json new file mode 100644 index 000000000..278465f1c --- /dev/null +++ b/docs/source/tutorials/utilities/widget_style.json @@ -0,0 +1 @@ +{"description_width": "initial"} \ No newline at end of file From c47fd419a500f7f3d809f8733d99acb964b6dde4 Mon Sep 17 00:00:00 2001 From: Rose Cersonsky Date: Wed, 4 Dec 2019 16:09:06 +0100 Subject: [PATCH 02/12] Updated QUIP tutorial to new syntax --- docs/source/tutorials/Converting_Quip.ipynb | 97 ++++++--------------- examples/reference_data/.gitignore | 2 - 2 files changed, 25 insertions(+), 74 deletions(-) delete mode 100644 examples/reference_data/.gitignore diff --git a/docs/source/tutorials/Converting_Quip.ipynb b/docs/source/tutorials/Converting_Quip.ipynb index 5138b6447..e29ca6169 100644 --- a/docs/source/tutorials/Converting_Quip.ipynb +++ b/docs/source/tutorials/Converting_Quip.ipynb @@ -34,7 +34,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -56,10 +56,10 @@ "from matplotlib import pyplot as plt\n", "import json\n", "\n", + "from rascal.representations import SphericalInvariants as SOAP\n", "\n", - "wd=!(pwd)\n", - "sys.path.append(f'{wd[0]}/utilities')\n", - "from rascal.representations import SphericalInvariants as SOAP" + "sys.path.append('./utilities')\n", + "reference_dir = '../../../reference_data/'" ] }, { @@ -73,11 +73,11 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "benzene = read(f'{wd[0]}/data/molecules/benzene.xyz')" + "benzene = read(f'{reference_dir}/inputs/benzene.xyz')" ] }, { @@ -91,7 +91,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -100,7 +100,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -109,22 +109,9 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "plt.hist(d['data'])\n", @@ -149,7 +136,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -161,27 +148,16 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "51" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "desc.n_dim" ] }, { "cell_type": "code", - "execution_count": 71, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -190,7 +166,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -208,53 +184,30 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "sv = soap.transform(benzene).get_dense_feature_matrix(soap)\n", - "\n", - "sv_inds = [0,2,4,6,8,10]" + "rep = soap.transform(benzene)\n", + "sv = rep.get_features(soap)" ] }, { "cell_type": "code", - "execution_count": 78, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(6, 51)" - ] - }, - "execution_count": 78, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "d['data'].shape" + "sv_by_species = rep.get_features_by_species(soap)" ] }, { "cell_type": "code", - "execution_count": 80, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Symbols('CHCHCHCHCHCH')" - ] - }, - "execution_count": 80, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "benzene.symbols" + "sv_by_species.keys()" ] }, { @@ -281,7 +234,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.6.8" }, "toc": { "base_numbering": 1, diff --git a/examples/reference_data/.gitignore b/examples/reference_data/.gitignore deleted file mode 100644 index e9322b753..000000000 --- a/examples/reference_data/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Large file, should be downloaded by user instead -CSD-500.xyz From b8ba01c6d5eb8ec1ac11cd9580d84458d949b2bd Mon Sep 17 00:00:00 2001 From: Rose Cersonsky Date: Wed, 4 Dec 2019 16:14:00 +0100 Subject: [PATCH 03/12] Updated Tutorial Template --- docs/source/tutorials/Tutorial_Template.ipynb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/source/tutorials/Tutorial_Template.ipynb b/docs/source/tutorials/Tutorial_Template.ipynb index 9dbae2740..8192a877c 100644 --- a/docs/source/tutorials/Tutorial_Template.ipynb +++ b/docs/source/tutorials/Tutorial_Template.ipynb @@ -44,8 +44,7 @@ "from rascal.representations import SphericalInvariants as SOAP\n", "from rascal.models import Kernel\n", "\n", - "wd=!(pwd)\n", - "sys.path.append(f'{wd[0]}/utilities')\n", + "sys.path.append('./utilities')\n", "from general_utils import *" ] }, @@ -73,7 +72,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.6.8" }, "toc": { "base_numbering": 1, From 4c91dfc7f965919f7e1c98d3b0097ce2fb7b5382 Mon Sep 17 00:00:00 2001 From: Rose Cersonsky Date: Wed, 4 Dec 2019 16:52:21 +0100 Subject: [PATCH 04/12] Verified PP Tutorial Runs --- .../Property_Prediction_Tutorial.ipynb | 228 ++++++------------ 1 file changed, 72 insertions(+), 156 deletions(-) diff --git a/docs/source/tutorials/Property_Prediction_Tutorial.ipynb b/docs/source/tutorials/Property_Prediction_Tutorial.ipynb index 17d79a53f..ad36fb35a 100644 --- a/docs/source/tutorials/Property_Prediction_Tutorial.ipynb +++ b/docs/source/tutorials/Property_Prediction_Tutorial.ipynb @@ -20,7 +20,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -40,13 +40,9 @@ "from matplotlib import pyplot as plt\n", "import json\n", "\n", - "wd=!(pwd)\n", - "sys.path.append(f'{wd[0]}/utilities')\n", + "sys.path.append('./utilities')\n", "\n", - "if('/docs/source/tutorials' in wd[0]):\n", - " ref_dir = '../../../reference_data'\n", - "else:\n", - " ref_dir = '../reference_data'\n", + "reference_dir = '../../../reference_data'\n", " \n", "from general_utils import *\n", "from rascal.representations import SphericalInvariants as SOAP\n", @@ -70,7 +66,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -94,11 +90,11 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "input_file = f'{ref_dir}/inputs/small_molecules-1000.xyz'\n", + "input_file = f'{reference_dir}/inputs/small_molecules-1000.xyz'\n", "property_name = \"dft_formation_energy_per_atom_in_eV\"" ] }, @@ -111,17 +107,9 @@ }, { "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "There are 100 frames.\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "frames = np.array(read(input_file,\":100\"))\n", "number_of_frames = len(frames)\n", @@ -156,7 +144,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -169,7 +157,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -191,7 +179,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -209,7 +197,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -299,7 +287,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -328,7 +316,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -344,41 +332,9 @@ }, { "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Our weights have been calculated and have shape (80,)\n" - ] - }, - { - "data": { - "text/markdown": [ - "
StatisticValue
Mean Average Error0.032
Root Mean Squared Error0.0448
R20.9178
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "y = krr.predict(frames[test_idx])\n", "krr.plot(y_known=property_values[test_idx], y=y, property_name=property_name)" @@ -393,43 +349,11 @@ }, { "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Our weights have been calculated and have shape (80,)\n" - ] - }, - { - "data": { - "text/markdown": [ - "
StatisticValue
Mean Average Error0.0331
Root Mean Squared Error0.0523
R20.904
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "filename=f'{ref_dir}/inputs/small_molecules-1000.xyz'\n", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "filename=f'{reference_dir}/inputs/small_molecules-1000.xyz'\n", "new_frames = read(filename,\":400\")\n", "new_property_values = np.array([cc.info[property_name] for cc in new_frames])\n", "y_pred = krr.predict(new_frames)\n", @@ -450,16 +374,31 @@ "metadata": {}, "source": [ "### Load and Read the Input File\n", - "We'll now look at the [CSD-500.xyz]() file, which contains the chemical shifts (CS) of 500 molecules. Because this is a property of the atoms, we'll want to use the \"Structure\" kernel given by libRascal." + "We'll now look at the [CSD-500.xyz](https://static-content.springer.com/esm/art%3A10.1038%2Fs41467-018-06972-x/MediaObjects/41467_2018_6972_MOESM4_ESM.txt) file, which contains the chemical shifts (CS) of 500 molecules. Because this is a property of the atoms, we'll want to use the \"Structure\" kernel given by libRascal.\n", + "\n", + "Because CSD-500 is a larger file, we don't automatically include it in the rascal repo, but it can be downloaded when needed:" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "input_file = f'{ref_dir}/inputs/CSD-500.xyz'\n", + "download_link = \"https://static-content.springer.com/esm/art%3A10.1038%2Fs41467-018-06972-x/MediaObjects/41467_2018_6972_MOESM4_ESM.txt\"\n", + "if(not os.path.exists(f'{reference_dir}/inputs/CSD-500.xyz')):\n", + " print(\"Downloading CSD-500\")\n", + " import urllib.request\n", + " urllib.request.urlretrieve(download_link, f'{reference_dir}/inputs/CSD-500.xyz')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "input_file = f'{reference_dir}/inputs/CSD-500.xyz'\n", "property_name = \"CS\"" ] }, @@ -474,19 +413,13 @@ }, { "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "There are 100 frames and 13233 environments.\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "frames = np.array(read(input_file,\":100\"))\n", + "for frame in frames:\n", + " frame.wrap()\n", "number_of_frames = len(frames)\n", "property_values = np.array([cc.arrays[property_name] for cc in frames])\n", "print(f\"There are {number_of_frames} frames and {len(np.concatenate(property_values))} environments.\")\n", @@ -510,7 +443,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -520,7 +453,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -538,11 +471,11 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "krr = KRR(features, np.concatenate(property_values[train_idx])[:,0],\n", + "krr = KRR(features, np.concatenate(property_values[train_idx]),\n", " kernel_type=kernel_type, representation=representation,\n", " Lambda=Lambda, jitter=jitter, weights=None,\n", " zeta=zeta, **hyperparameters\n", @@ -558,7 +491,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -567,46 +500,29 @@ }, { "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Our weights have been calculated and have shape (10758,)\n" - ] - }, - { - "data": { - "text/markdown": [ - "
StatisticValue
Mean Average Error11.3622
Root Mean Squared Error21.0806
R20.9145
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAARsAAAEKCAYAAAAip/EfAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4wLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvqOYd8AAAH6dJREFUeJzt3X+U3XV95/HnCyJMqjYhBSEhP2miiJQQOyX0yDmrCUogNcE9bTey2+KP06wriFndY5Pi0VWrxB+tMbR1Gwsu7JKmnFogNUGMiZ6u50ggmASJoAz5sSQhEBcy/mICk7z3j+/3Dt+5uXPnzsy93+/98Xqcc8/c+7nfe+fzheSdz8/3RxGBmVmjnVZ0BcysMzjYmFkuHGzMLBcONmaWCwcbM8uFg42Z5cLBxsxy4WBjZrlwsDGzXIwrugKNdPbZZ8fMmTOLroZZW3vkkUd+FhHnDHddWwebmTNnsmPHjqKrYdbWJB2o5Tp3o8wsF4UFG0ldkh6StFvSHkmfSstnSdouqUfSP0k6Iy0/M33dk74/s6i6m9nIFdmyOQ4siIi5wKXAIkmXA58HvhwRs4EXgPen178feCEt/3J6nZm1iMKCTSR+mb58VfoIYAHwz2n5HcC16fOl6WvS9xdKUk7VNbMxKnTMRtLpknYBzwFbgKeAYxHRn15yEDg/fX4+8DRA+n4v8Fv51tjMRqvQYBMRJyLiUmAqcBlw4Vi/U9JySTsk7Th69OiY62hm9dEUs1ERcQz4LvD7wERJpSn5qcCh9PkhYBpA+v4E4P9V+K51EdEdEd3nnDPs1L+Z5aTI2ahzJE1Mn48H3g48ThJ0/jC97HrgvvT5xvQ16fvbwjlNzepixYadXLBqEys27GzY7yiyZTMZ+K6kR4GHgS0R8U3gz4GPSOohGZO5Lb3+NuC30vKPACsLqLNZW9q4+zAnI/nZKIWtII6IR4F5Fcr3kozflJf3AX+UQ9XMOs6SuVPYuPswS+ZOadjvUDv3RLq7u8PbFcwaS9IjEdE93HVNMUBsZvW3fvsBLr9lK+u317R1CYArVm9l5spNXLF6a93r42Bj1oJqGdBdu62HI7193Lqtp+bvPXisb9DPenKwMWtBtQzo3rRgNpMndPGhBbMHyoZq7ZTKJ45PhnGnTuyqe50dbMxa0JK5UzhNVB3QvW7+DH6waiHXzZ8xUDZUa2f1/U9wpLePkwH7Vy/mg2+bPeIu2HAcbMxa0Jpl89h7y2LWLDtlQreqSq2drNJmw9F0wYbT1smzzGyw6+bPGNTSKVl59YXcuq2HDy2YzYoNO3m2t4+ucRoyKI2Gg42ZDQpCH7/3MQJ46URUDEyj5W6UmQ1Sy3jQaHhRn5mNiRf1mVlTcbAxa2Ej2a2dx87uahxszFrYSHZr57GzuxoHG7MWNpLB3EYN/NbKA8RmNiYeIDazQXuhRrMLvJ68qM+sjWW3HQQMPK/nYr1auWVj1saye6GG2xfVaB6zMWuwFRt2DqTcHOnGyaFcsXorB4/1MXViF99fufCU13nymI1Zk2jElHN5kqvsz0Zl2hsrBxuzBmvElHMpuVX5z5KDx/oamuJzNArrRkmaBtwJnEtyxve6iPiKpEnAPwEzgf3AH0fEC+m53l8BrgF+DbwnIn5Y7Xe4G2WdptSdKrd/9eKG/c5W6Eb1Ax+NiIuAy4EbJF1Ech7U1oiYA2zllfOhrgbmpI/lwFfzr7JZ8SptOyiVdc+cxGkafH0jUnyORpHnRj0DPJM+/4Wkx4HzgaXAW9PL7gC+R3Jw3VLgzvQUzAclTZQ0Of0es7aWHWQujQHduysZA1qzbN6gcaHsGVD1GpCuh6ZYZyNpJsmBdduBczMB5AhJNwuSQPR05mMH07JBwUbScpKWD9OnT29Ync0aLTvDdDjND1wKMCUbdx9mzbJ5pwSYWoJM3jNYhQcbSa8BvgGsiIifJ0MziYgISSMaVIqIdcA6SMZs6llXszxlZ5imTuw6ZSwmO+hca4AZ6vvzUGiwkfQqkkBzV0T8S1r8bKl7JGky8FxafgiYlvn41LTMrC2VAkypZZN17aVj7yJlvz8PhQWbdHbpNuDxiPjrzFsbgeuB1enP+zLlN0raAMwHej1eY62uWlcm+3rFhp2DulD1GIvJe/FfkbNRbwH+BFggaVf6uIYkyLxd0pPAlelrgM3AXqAH+BrwwQLqbFZXtXZl1iybN3DMiqpe2byKnI36PkP/dzsl5KazUDc0tFJmORtJV2ZfA9fK5KHwAWKzTpZ3V6ZIDjZmTa7ITZb15L1RZk0u7ynqRnHLxiwHo22dZDdRNsu2g9FysDHLQbXWSWkrwpQJyXqa7DaD7PWt3IUCd6PMcjFUKohZKzdx765kX9PBY32n5L0Z6nOtyC0bsxx0z5zE4d2H6Z45aVB5pf00JwMu/PhmPvHON7V8aybLwcasgnrPAGV3Ze/Y//ywa2v6+qOwxOSN4m6UWQX1ngEqZeu75PwJNX131zgVlpi8UdyyMaugXpsUy/c07TrYW9PnFl08ua1aNeBgY1bRaLpOlbpeo01yXspT007cjTKrk0rdozNPr33b5GlKUkcUeR53I7llY1YH2XzApa7Xig07ebG/9vxtI8my14ocbMzqINtdKp3dNBKNPP2gWbgbZTZG67cf4IzTNeo8M62an2akHGzMxmjtth76+oPzJnRx7aUjH2tRh0QbBxuzMbppwWy6xolnevtOOf2gklJsGT9ObTsYXInHbKyj1HNlcOm7xo8TfTUOBO9fvZgLVm0iAo6fCPbe0v5jNSVu2VhHqefK4NJ31DrjNHVi16DxnU5p0ZQ42FhHya4IzuaKGet3DadrnPjg22YPGt9p1ynuoRQabCTdLuk5SY9lyiZJ2iLpyfTnWWm5JK2V1CPpUUlvLq7m1krWbz/A5bdsZf32A4O6TrW0brKfzSp1oWpV2lh504LZTJ7Q1Xb7nmpRdMvmfwKLyspWAlsjYg6wNX0NcDUwJ30sB76aUx2txa3d1sOR3j5u3dYDjCxHTPazV6zeysyVm0YcaADGCX51vB+AH6xa2Hb7nmpRaLCJiH8Dni8rXgrckT6/A7g2U35nJB4EJqYnZppVVd6a+P7KhexfvbimAeLsZ8uPwx3O/tWLBx4nAn7e18/N9zw27OfaVTPORp2bOenyCHBu+vx84OnMdQfTMp+KaVVdN3/GqFsS182fwUP7nufj9z7G+HHixf5g6sQuumdO4mA6zd01xGxUaRXx1IldA0my8jx8vtlOZSi6G1VVejDdiP7/SFouaYekHUePHm1QzaxdlY/RrN9+YCBt5/ETMdAiym5PGG7aO9sSyjO9Z7OdytCMLZtnJU2OiGfSbtJzafkhYFrmuqlp2SARsQ5YB9Dd3Z3nPyTW4rJjMaUseWvTcR6AKRO6uGDVJpbMncKSuVPYuPswl5w/gWd/cZwjvX1D/qtYVMuiXjl56qUZg81G4HqSM76vB+7LlN8oaQMwH+jNdLfMxizbAnjxpf5Bmyknjh/H4d5XEpLvvWXxoKnraickFKUZuk5ZRU99/yPwA+ANkg5Kej9JkHm7pCeBK9PXAJuBvUAP8DXggwVU2VrQUNPX5eXZrs6xF/sHXXvsxf6B1J6VFuOtWTaPKROSlsSUDlxDUwslwyLtqbu7O3bs2FF0Naxgl9+ylSO9fUye0MUPVi0cthxOXUeT7QrNWrmJINnjtC+TGiLbErr20uJbNnmR9EhEdA97nYONtbv12w9w67YePrRg9qBZqfXbD3DzPY8RDD+uUuomLZk7ZdBmy9K4iBg8k3Ga6Jh9T7UGm6aejTKrh+vmz6i4kO66+TMGAsRwMzbZo1hKu7aV+Vz5P9mdtu+pFg421tFK4zTjx4kLVm1ixYadrNiwk5krNzFz5aaBdJ+l8ZopE7pQmit43+rFA5/vkJQ0Y+JulLW0bPdmpGMk2UVvpZmmSrIpOy9YtYmTUbmblD22xd2oU7llYy0t272pxYoNOwdaMNlFb7WeglC6rtL1a5bNa+vTEcaqGdfZmNWstLhuuL/c5bNL9+46PGj7QbUxmytWbx0YPC7lrhkqh007n44wVg421tKq/eXOdrEqBZNSoDncW31wuFmW+7e6EXWjJJ0ldUp6Zmt1tXSxDh4beqymklI3aTSJzTvdkMFG0ickXZg+P1PSd4GnSPYuXZlXBc1GK7vit177g9Ysm3fKVgWrzZCzUZL2ABdHREhaDrybZPvA64E7IuKy/Ko5Op6NsqzRJL2CzjhAbizqMRv1UrwSia4CNkTEiYh4HI/1WIsZbaDJrr+xsakWbI5LuljSOcDbgG9n3vuNxlbLrHbZdJ1DvT+aQDN1YhfHT0TNU+vZaXU7VbVgswL4Z+AJ4MsRsQ9A0jWA/2ta06iUJGos+YJLvr9yYdWd3uVGuuan0wzZHUrz/F5YoXwzSboHs6ZQKUnUWLPUlaZcR7JuptY1P52q2gDxR0gSVN1WVv5+4LURsSaH+o2JB4jbX3me3dG0ZCZ0jeNtF75uYKvBcDvAmy23b9HqMUD8H4E7K5T/L+B9o62YWT1lWzDrtx8YVUumt69/0J6m7pmTqo69NFtu31ZRLdiMi4iXywsj4iW8ydWaRDa7XjZf8GiUxmaGG3sZS/Ly4Qaz21m1KezTJJ0bEc9mCyWdO9QHzPKQ7caU/PJ4/4hWAleS3aVdbexlLF2nTm4VVQs2XwQ2Sfoo8MO07HfT8i81umJmQ6n0F7Y8Z/BIlM82NXIzZflgdieN/1SbjbpT0lHg08DFJMnI9gCfiIj7c6qf2SnK/8KOpZXwuXddnOtRuOUBpZNaOlVXAqdBpakCi6RFwFeA04F/iIjVw3zE2kylFkA22XitBIWfud1sZzs1UkttO5B0OvC3wNtJjt99WNLGiPhxsTWzog2Xk6ZcsyS4aveuU1arZeq7DOiJiL3prNgGYGnBdbImJ5LNlNnWg1f65q+lWjbA+cDTmdcHSU7HtDZUbfC0/L2hWjXZHdul78gm1bL8DBls0hXEQ4qIv65/dcYuTYexHGD69OkF18Zg9DMuQ+15yr4uPa/UjSrt2C5Phu7UncWo1rJ5bfrzDcDvkZy1DfBO4KFGVqqKQ8C0zOupadmAiFgHrINku0J+VbOhDDfjUgogE8ePo+uMcVw+axLbnniu6neVCLj0Uw9w7MX+U4JZ6SSEjbsPO7g0gWpT358CkPRvwJsj4hfp6/8OjHzovz4eBuZImkUSZJYB1xVUF6vRcDMupQBy7MV+eLF/YAVv1qWfeoCuM0794xq8ssbm4LE+rli9lcO9fSyZO8UbI5tMLWM25wIvZV6/lJblLiL6Jd0IPEAy9X17ROwpoi5Wu+G6TqVgNHH8OPpePkFffzBOoNPEyyeSqFMKRMMpBa57dx1m/2qn72wmtQSbO4GHJN2Tvr4WuKNxVarOKS7aT3nXB+AksPez19S8i/vaS6dUbBHlqZNWA4/GsFPfEfFZ4L3AC+njvRHxuUZXzDpTebKq769cyP7ViwedarB/9eJBU9lTJ3YNJCIv8vSDTloNPBo1Hb8r6QpgTkR8PU0T+ppS5r5m5nw2lqdObdnUms9m2G6UpE8C3SSzUl8HXgX8b+AtY62kWTvppAAzGrWsIH4XsAT4FUBEHOaVaXGzhlq//QCX37KV9dsPFF0VG6NaBohfSs+OCgBJr25wnawFvfHjm3mxPxg/Tjz+l9fU7XvXbuvhSG8fn7//CdZu6+GmBbML3zxpo1NLy+ZuSX8PTJT0Z8B3gH9obLWs1bzYH4N+jkalo1BuWjCbyRO6COBIbx+3ptn4qrV43BpqTrXMRn2J5EiXb5CM23wiItY2umLWWsaP06Cfo1EpHed182fwg1ULWXn1hUye0MWHFswGXmnx3FohFWi196w4tQwQfz4i/hzYUqHMDKBi12n99gMj6vpUW/F73fwZg77jSG8yvfxM76nTzDctmM2t23oGApM1h1rGbN4OlAeWqyuUmQ3ILsa7dVsPf/fdniGnhbO7sLN5gGHkAQtODUzWHIbsRkn6L5J+BFwo6dHMYx/wo/yqaK0ou7DtQwtmV13wVu00g6G6RCr7ac2vWstmPUlK0FuAlZnyX0TE8w2tlbW87ObL6+bPGNSyKVet+3Tea8/kSG8f5772zEHl+1YvPuVaa27DriCWdDmwJ7Pr+zeBN0bE9hzqNyZeQZyv4bo8w62wzXanShsoS2kiThOndLGsOdTjRMySrwK/zLz+ZVpmNmD99gN8/N7Hqs4CVepKZae7K3WnSnulpkzoqnpKpTW/WoKNItP8iYiTtF46UWuwtdt6BlogQ80CVTpJMhtgyjdhAgMbLA/39uWWN7h0auWslZs69vTKRqgl2OyVdJOkV6WPDwN7G10xay2lxXd/ee3Q5zCVdnBnu1DZlkt5FyqrUiBqlFLLK8pe29jUMmbzOmAtsIDkv/9WYEVEVM7b2EQ8ZtM6mmlspjS2JJI/8J22i3uk6rbrOw0qy+pSK7MhNFMKTweWxhiyZSPpYxHxBUm38kqLckBE3NToyo2VWzbNo1NzvXSCerRsHk9/+m+rjZmz2Fm10xX+Nf1ZWL5hK06tLZFKa2MqlVU6YcGtnc5S7ZC6f6VC96kkIpY0pEbWFGptiZSmru/ddZh7dx1m6sSuQdPUpWBTKZi4tdNZqk19fwn4K2Af8CLwtfTxS+CpsfxSSX8kaY+kk5K6y95bJalH0k8kXZUpX5SW9Uhaeeq3Wj1VWhNTSWlKuuTgsb4hp6nL89XU+jusPdQy9b2jfPCnUtmIfqn0RpLTOv4e+G8RsSMtvwj4R+AyYApJoq7Xpx/7KckO9IMkh9W9OyJ+XO33eIA4P7V0iZppetvqp25T38CrJV0QEXvTL54FjCk1aEQ8nn5X+VtLgQ0RcRzYJ6mHJPAA9GTqsCG9tmqwsfzUMubSTNPblr9ags1/Bb4naS/Jjv4ZwH9uUH3OBx7MvD6YlgE8XVY+v9IXSFoOLAeYPn16A6poo7Vm2TyfUNnBalnU9y1Jc4AL06In0pZHVZK+A5xX4a2bI+K+kVWzdhGxDlgHSTeqUb/HzEamlrSgvwF8BJgREX8maY6kN0TEN6t9LiKuHEV9DgHTMq+npmVUKbc2UWnK3NpHLRsxvw68BPx++voQ8JcNqs9GYJmkM9OxoTnAQyQDwnMkzZJ0Bsn2iY0NqoMVpFrGvkonL1hrqSXY/HZEfAF4GSAifs0YszFKepekgyQBbJOkB9Lv3gPcTTLw+y3ghog4ERH9wI3AAyQrm+9Or7UWVErhUJ66odrO7mqByFpDTYfUSRpPusBP0m8Dw47ZVBMR9wD3DPHeZ4HPVijfDGwey++15jDUYr5qA8ieyWp9tQSbT5K0MqZJuovkjO/3NLJS1t4qbV0YjmeyWl/VYKNkIcwTwL8HLifpPn04In6WQ92sTXkfVGeqGmzSM743R8TvAJtyqpOZtaFaulE/lPR7EfFww2tjTcm7s60eagk284H/JGk/8CuSrlRExCWNrJg1D+/OtnqoJdhcNfwl1s5GM6BrVq5aPpsu4APAbJLjdm9L17tYB3DXyeqtWsvmDpKFfP8HuBq4CPhwHpWyfFUKLO46Wb1VCzYXpbNQSLqNZNuAtaFKgcVdJ6u3asHm5dKTiOivkHvG2kSlwOKuk9VbtWAzV9LP0+cCxqevS7NRv9nw2lkuHFgsD9VOVzg9z4qYWXurZde3mdmY1bLOxtqUp7ctT27ZdDBPb1ueHGw6mM9tsjy5G9XB3HWyPLllY2a5cLAxs1w42JhZLgoJNpK+KOkJSY9KukfSxMx7qyT1SPqJpKsy5YvSsh5JK4uot5mNXlEtmy3AxWkCrp8CqwAkXURyJtSbgEXA30k6XdLpwN/yyu7zd6fXmlmLKCTYRMS3M7lxHiQ54RJgKbAhIo5HxD6gB7gsffRExN6IeAnYkF5rZi2iGcZs3gfcnz4/H3g6897BtGyocjNrEQ1bZyPpO8B5Fd66OSLuS6+5GegH7qrj710OLAeYPn16vb7WzMaoYcEmIq6s9r6k9wB/ACyMiEiLDwHTMpdNTcuoUl7+e9cB6wC6u7uj0jVmlr+iZqMWAR8DlqRnh5dsBJZJOlPSLGAOSYbAh4E5kmZJOoNkEHlj3vU2s9ErarvC3wBnAlvSDIAPRsQHImKPpLuBH5N0r26IiBMAkm4EHgBOB26PiD3FVN3MRkOv9GDaT3d3d+zYsaPoapi1NUmPRET3cNc1w2yUmXUABxszy4WDjZnlwsHGzHLhYGNmuXCwMbNcONiYWS4cbMwsFw42ZpYLBxszy4WDjZnlwudGNZlmORJ3xYadbNx9mCVzp7Bm2bzC6mHtwy2bBrti9VZmrtzEFau31nR9sxyJu3H3YU5G8tOsHhxsGmykwWO4I3FXbNjJBas2sWLDzvpUcAhL5k7hNCU/zerB3agGmzqxa6BbVIvhuk7ZFkcjuzdrls1z98nqysGmweo97rJk7pSBsRSzVuLkWWY2Jk6eZWZNxcHGzHLhYGNmuSjqKJfPSHpU0i5J35Y0JS2XpLWSetL335z5zPWSnkwf1xdR73J5TUObtYOiWjZfjIhLIuJS4JvAJ9Lyq0nOippDcqrlVwEkTQI+CcwnOff7k5LOyr3WZbzwzax2hQSbiPh55uWrgdKU2FLgzkg8CEyUNBm4CtgSEc9HxAvAFmBRrpWuwAvfzGpX2DobSZ8F/hToBd6WFp8PPJ257GBaNlR5oca68K1Z9kGZ5aFhLRtJ35H0WIXHUoCIuDkipgF3ATfW8fcul7RD0o6jR4/W62sboln2QZnloWEtm4i4ssZL7wI2k4zJHAKmZd6bmpYdAt5aVv69IX7vOmAdJIv6RlLnehhJa2WkWxnMWlkh3ShJcyLiyfTlUuCJ9PlG4EZJG0gGg3sj4hlJDwCfywwKvwNYlWulazSS1oq7TtZJihqzWS3pDcBJ4ADwgbR8M3AN0AP8GngvQEQ8L+kzwMPpdZ+OiOfzrXJt3Foxq8x7o8xsTLw3qk15IaG1KgebFuOFhNaqHGxajBcSWqvymE0TcHJxa2Ues2kh7hpZJ3CwaQLuGlkncDfKzMbE3Sgzayodf7pCtb1M3pVtVj8d37KptpfJu7LN6qfjg021EyiHO53SzGrnAWIzGxMPEJtZU3GwMbNcONiYWS4cbMwsFw42ZpYLBxszy4WDjZnlouO3K1TibQpm9eeWTQXepmBWf4UGG0kflRSSzk5fS9JaST2SHpX05sy110t6Mn1c38h6eZuCWf0Vedb3NJLD5v5vpvhqYE76mA98FZgvaRLJiZndQACPSNoYES80om7uOpnVX5Etmy8DHyMJHiVLgTsj8SAwUdJk4CpgS0Q8nwaYLcCi3GtsZqNWSLCRtBQ4FBG7y946H3g68/pgWjZUeaXvXi5ph6QdR48erWOtzWwsGtaNkvQd4LwKb90M/AVJF6ruImIdsA6SXd+N+B1mNnINCzYRcWWlckm/A8wCdksCmAr8UNJlwCFgWubyqWnZIeCtZeXfq3ulzaxhcu9GRcSPIuJ1ETEzImaSdIneHBFHgI3An6azUpcDvRHxDPAA8A5JZ0k6i6RV9EDedTez0Wu2RX2bgWuAHuDXwHsBIuJ5SZ8BHk6v+3REPF9MFc1sNAoPNmnrpvQ8gBuGuO524PacqmVmddbWaUElHQUODPH22cDPcqxOUTrlPsH3WpQZEXHOcBe1dbCpRtKOWvKmtrpOuU/wvTY7740ys1w42JhZLjo52KwrugI56ZT7BN9rU+vYMRszy1cnt2zMLEcdE2yaNXdOPUn6oqQn0vu5R9LEzHur0nv9iaSrMuWL0rIeSSuLqfnYtct9QJJ+RdJ3Jf1Y0h5JH07LJ0nakv653JKupq/6Z7mpRETbP0j2Wz1Asubm7LTsGuB+QMDlwPa0fBKwN/15Vvr8rKLvocb7fAcwLn3+eeDz6fOLgN3AmST70p4CTk8fTwEXAGek11xU9H2M4r7b4j4y9zOZZAsPwGuBn6b/D78ArEzLV2b+/1b8s9xsj05p2XRE7pyI+HZE9KcvHyTZsArJvW6IiOMRsY9kO8hl6aMnIvZGxEvAhvTaVtMu9wFARDwTET9Mn/8CeJwkpcpS4I70sjuAa9PnQ/1ZbiptH2wamTunyb2P5F87aP97bZf7OIWkmcA8YDtwbiQbkwGOAOemz1vi/gvfG1UPReXOKUK1e42I+9Jrbgb6gbvyrJvVl6TXAN8AVkTEz9OULECyj1BSS00lt0WwiQ7KnTPUvZZIeg/wB8DCSDv0DH2vVClvJdXuryVJehVJoLkrIv4lLX5W0uSIeCbtJj2XlrfG/Rc9aJTnA9jPKwPEixk8qPZQWj4J2EcyOHxW+nxS0XWv8f4WAT8GzikrfxODB4j3kgyqjkufz+KVgdU3FX0fo7jvtriPzP0IuBNYU1b+RQYPEH8hfV7xz3KzPdqiZTNK7Zg7529IAsqWtCX3YER8ICL2SLqbJBD1AzdExAkASTeSzNSdDtweEXuKqfroRUR/O9xHxluAPwF+JGlXWvYXwGrgbknvJ5lZ/eP0vYp/lpuNVxCbWS7afjbKzJqDg42Z5cLBxsxy4WBjZrlwsDGzXDjYWGEknSdpg6SnJD0iabOk16c7mB+T9CNJD0uaVXRdbew6eZ2NFUjJQqB7gDsiYllaNhf4D8AU4JKIOClpKvCr4mpq9eKWjRXlbcDLEfE/SgWRbJb9FfBMRJxMyw5GsvveWpyDjRXlYuCRCuV3A++UtEvSX0mal3O9rEEcbKypRMRB4A3AKuAksFXSwmJrZfXgMRsryh7gDyu9ERHHSTYW3i/pWZIkUVtzrJs1gFs2VpRtwJmSlpcKJF0i6d9JmpK+Pg24hKGPULYW4o2YVpg0qKwBfhfoI0kB8i3gPSS71wEeAj4YEX0FVNHqyMHGzHLhbpSZ5cLBxsxy4WBjZrlwsDGzXDjYmFkuHGzMLBcONmaWCwcbM8vF/wdsdWavzH4/nQAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "y = krr.predict(frames[test_idx])\n", - "krr.plot(y_known=np.concatenate(property_values[test_idx])[:,0],\n", + "y = krr.predict(frames[test_idx])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "krr.plot(y_known=np.concatenate(property_values[test_idx]),\n", " y=y, property_name=property_name)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -626,7 +542,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.6.8" }, "toc": { "base_numbering": 1, From ece04d494f21794b2244a24cd988cbe4482a503f Mon Sep 17 00:00:00 2001 From: Rose Cersonsky Date: Wed, 4 Dec 2019 16:53:09 +0100 Subject: [PATCH 05/12] Updating paths in notebooks --- docs/source/tutorials/Hyperparameters.ipynb | 5 ++--- .../tutorials/Introduction_to_Atomic_Descriptors.ipynb | 7 +++---- docs/source/tutorials/Kernels.ipynb | 4 ++-- docs/source/tutorials/Tutorial_Template.ipynb | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/docs/source/tutorials/Hyperparameters.ipynb b/docs/source/tutorials/Hyperparameters.ipynb index f79efd790..920df51d7 100644 --- a/docs/source/tutorials/Hyperparameters.ipynb +++ b/docs/source/tutorials/Hyperparameters.ipynb @@ -46,8 +46,7 @@ "from matplotlib import pyplot as plt\n", "import json\n", "\n", - "wd=!(pwd)\n", - "sys.path.append(f'{wd[0]}/utilities')\n", + "sys.path.append('./utilities')\n", "from general_utils import *\n", "from rascal.representations import SphericalInvariants as SOAP" ] @@ -76,7 +75,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.6.8" }, "toc": { "base_numbering": 1, diff --git a/docs/source/tutorials/Introduction_to_Atomic_Descriptors.ipynb b/docs/source/tutorials/Introduction_to_Atomic_Descriptors.ipynb index b3d35d013..6c8182007 100644 --- a/docs/source/tutorials/Introduction_to_Atomic_Descriptors.ipynb +++ b/docs/source/tutorials/Introduction_to_Atomic_Descriptors.ipynb @@ -17,7 +17,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -37,8 +37,7 @@ "from matplotlib import pyplot as plt\n", "import json\n", "\n", - "wd=!(pwd)\n", - "sys.path.append(f'{wd[0]}/utilities')\n", + "sys.path.append('./utilities')\n", "from general_utils import *\n", "from rascal.representations import SphericalInvariants as SOAP" ] @@ -105,7 +104,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.6.8" }, "toc": { "base_numbering": 1, diff --git a/docs/source/tutorials/Kernels.ipynb b/docs/source/tutorials/Kernels.ipynb index 52d2abf11..f1107f248 100644 --- a/docs/source/tutorials/Kernels.ipynb +++ b/docs/source/tutorials/Kernels.ipynb @@ -47,7 +47,7 @@ "import json\n", "\n", "wd=!(pwd)\n", - "sys.path.append(f'{wd[0]}/utilities')\n", + "sys.path.append('./utilities')\n", "from general_utils import *\n", "from rascal.representations import SphericalInvariants as SOAP" ] @@ -69,7 +69,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.6.8" }, "toc": { "base_numbering": 1, diff --git a/docs/source/tutorials/Tutorial_Template.ipynb b/docs/source/tutorials/Tutorial_Template.ipynb index 8192a877c..816c06a5c 100644 --- a/docs/source/tutorials/Tutorial_Template.ipynb +++ b/docs/source/tutorials/Tutorial_Template.ipynb @@ -26,7 +26,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ From 108d2d942d00f6429ec0478ef8cc3980ee5b3585 Mon Sep 17 00:00:00 2001 From: rosecers Date: Tue, 10 Dec 2019 13:24:20 +0100 Subject: [PATCH 06/12] Adding old tutorial files --- docs/source/tutorials/TutorialEn.rst | 342 ++++++++++++++++++++++++++ docs/source/tutorials/nl-for-user.rst | 109 ++++++++ docs/source/tutorials/tutorials.rst | 29 +++ 3 files changed, 480 insertions(+) create mode 100644 docs/source/tutorials/TutorialEn.rst create mode 100644 docs/source/tutorials/nl-for-user.rst create mode 100644 docs/source/tutorials/tutorials.rst diff --git a/docs/source/tutorials/TutorialEn.rst b/docs/source/tutorials/TutorialEn.rst new file mode 100644 index 000000000..b00852ae7 --- /dev/null +++ b/docs/source/tutorials/TutorialEn.rst @@ -0,0 +1,342 @@ +.. _TutorialEn: + +.. role:: raw-html(raw) + :format: html + +Energy fitting +============== + +Approach used in Rascal can be used for calculating any of the rotationally +invariant properties (such as formation energy), as well as rotationally +covariant properties (such as dipole moment). This example is about fitting the +formation energies of some small molecules. The dataset is located in the +`librascal/examples/data/ <../../../../examples/data>`_ folder, the python +notebook doing the calculation is `librascal/examples/SOAP_example.ipynb +(outbound) +`_. + + +Let's take a look at the code and describe what it do step-by-step. + +Imports +******* + +Just import of the necessary modules, including Rascal itself. + +.. code-block:: python + + from matplotlib import pylab as plt + import os, sys + sys.path.insert(0,"../build/") + import time + import rascal + import json + import ase + from ase.io import read, writex + from ase.build import make_supercell + from ase.visualize import view + import numpy as np + from rascal.representations import SOAP + +Dataset +******* + +Here ASE is used to read the file with information about molecules, then the +size of the feature matrix shown. The number of columns is the number of atoms +in the set of molecules, the number of rows is depend on the max_radial and +max_angular parameters. If the number of columns is big, sparsification needs to +be done to reduce it. + +.. code-block:: python + + frames = read('./data/small_molecules-1000.xyz',':') + hypers = dict(soap_type="PowerSpectrum", + interaction_cutoff=3.5, + max_radial=6, + max_angular=6, + gaussian_sigma_constant=0.4, + gaussian_sigma_type="Constant", + cutoff_smooth_width=0.5, + ) + soap = SOAP(**hypers) + %time representation = soap.transform(frames) + X = representation.get_feature_matrix().T + X.shape + + +Functions +********* + +Here we define the functions, which are needed for the further computations. +Let's describe some of them. compute_representation - creates a feature manager +class using information about structure compute_kernel - compute the matrix of +global similarity using global cosine kernel with a power of zeta to itself +KRR.predict - predicting the energy of the molecules in the set, using trained +model train_krr_model - train the model basing on the given dataset and using +global cosine kernel + +.. code-block:: python + + # Load the small molecules + frames = read('./data/small_molecules-1000.xyz',':600') + + def compute_representation(representation,frames): + expansions = soap.transform(frames) + return expansions + + def compute_kernel(zeta, rep1, rep2=None): + if rep2 is None: + kernel = rep1.cosine_kernel_global(zeta) + else: + kernel = rep1.cosine_kernel_global(rep2,zeta) + return kernel + + def extract_energy(frames): + prop = [[]]*len(frames) + for ii,cc in enumerate(frames): + prop[ii] = cc.info['dft_formation_energy_per_atom_in_eV'] + y = np.array(prop) + return y + + def split_dataset(frames, test_fraction, seed=10): + N = len(frames) + ids = np.arange(N) + np.random.seed(seed) + np.random.shuffle(ids) + Ntrain = int(N*test_fraction) + train = ids[:Ntrain] + test = ids[Ntrain:] + targets = extract_energy(frames) + return [frames[ii] for ii in train],targets[train],[frames[ii] for ii in test],targets[test] + + def get_mae(ypred,y): + return np.mean(np.abs(ypred-y)) + def get_rmse(ypred,y): + return np.sqrt(np.mean((ypred-y)**2)) + def get_sup(ypred,y): + return np.amax(np.abs((ypred-y))) + def get_r2(y_pred,y_true): + weight = 1 + sample_weight = None + numerator = (weight * (y_true - y_pred) ** 2).sum(axis=0,dtype=np.float64) + denominator = (weight * (y_true - np.average(y_true, axis=0, weights=sample_weight)) ** 2).sum(axis=0,dtype=np.float64) + output_scores = 1 - (numerator / denominator) + return np.mean(output_scores) + + score_func = dict( + MAE=get_mae, + RMSE=get_rmse, + SUP=get_sup, + R2=get_r2, + ) + + def get_score(ypred,y): + scores = {} + for k,func in score_func.items(): + scores[k] = func(ypred,y) + return scores + + class KRR(object): + def __init__(self,zeta,weights,representation,X): + self.weights = weights + self.representation = representation + self.zeta = zeta + self.X = X + + def predict(self,frames): + features = compute_representation(self.representation,frames) + kernel = compute_kernel(self.zeta , self.X, features) + return np.dot(self.weights, kernel) + + def train_krr_model(zeta,Lambda,representation,frames,y,jitter=1e-8): + features = compute_representation(representation,frames) + kernel = compute_kernel(zeta,features) + # adjust the kernel so that it is properly scaled + delta = np.std(y) / np.mean(kernel.diagonal()) + kernel[np.diag_indices_from(kernel)] += Lambda**2 / delta **2 + jitter + # train the krr model + weights = np.linalg.solve(kernel,y) + model = KRR(zeta, weights,representation, features) + return model,kernel + + +Full spectrum +************* + +Here the full (with radial and angular parts) energies are computed. Let's +describe the parameters of the soap descriptor, defined in the ``hypers`` +dictionary. + +- **interaction_cutoff**: Maximum pairwise distance for atoms to be considered + in expansion +- **max_radial**: number of radial basis functions +- **max_angular**: highest angular momentum number in the expansion +- **gaussian_sigma_constant**: specifies the atomic Gaussian widths, in the + case where they're fixed. +- **gaussian_sigma_type**: how the Gaussian atom sigmas (smearing widths) are + allowed to vary -- fixed (``Constant``), by species (``PerSpecies``), or by + distance from the central atom (``Radial``) +- **cutoff_smooth_width**: the distance over which the the interaction is + smoothed to zero + +.. code-block:: python + + hypers = dict(soap_type="PowerSpectrum", + interaction_cutoff=3.5, + max_radial=6, + max_angular=6, + gaussian_sigma_constant=0.4, + gaussian_sigma_type="Constant", + cutoff_smooth_width=0.5, + ) + soap = SOAP(**hypers) + + frames_train, y_train, frames_test, y_test = split_dataset(frames,0.8) + + zeta = 2 + Lambda = 5e-3 + krr,k = train_krr_model(zeta, Lambda, soap, frames_train, y_train) + + y_pred = krr.predict(frames_test) + get_score(y_pred, y_test) + + plt.scatter(y_pred, y_test, s=3) + plt.axis('scaled') + plt.xlabel('DFT energy / (eV/atom)') + plt.ylabel('Predicted energy / (eV/atom)') + +The result of this block is: + +.. image:: ../resources/images/R1.png + +The result is quite good. One can try to change the train dataset to see how it +affects the precision of the result. + +Radial spectrum +*************** + +Here we compute the energy, supposing the angular component to be zero. + +.. code-block:: python + + hypers = dict(soap_type="RadialSpectrum", + interaction_cutoff=3.5, + max_radial=6, + max_angular=0, + gaussian_sigma_constant=0.4, + gaussian_sigma_type="Constant", + cutoff_smooth_width=0.5, + ) + soap = SOAP(**hypers) + + frames_train, y_train, frames_test, y_test = split_dataset(frames,0.8) + + zeta = 2 + Lambda = 5e-4 + krr,k = train_krr_model(zeta, Lambda, soap, frames_train, y_train) + + y_pred = krr.predict(frames_test) + get_score(y_pred, y_test) + + plt.scatter(y_pred, y_test, s=3) + plt.axis('scaled') + plt.xlabel('DFT energy / (eV/atom)') + plt.ylabel('Predicted energy / (eV/atom)') + +Comparison of full and radial spectrum: + +.. image:: ../resources/images/Comps.png + +It can be seen that the two spectres are quite similar, but the radial spectrum is much more simple to compute (as feature matrix is much smaller and the set of spherical harmonics doesn't have to be computed). It is quite an inteseting fact, but, unfortunately, this feature is probably not generalizable and should be just the feature of this particular dataset. + +Map of the dataset +******************* +Here we use sklearn to do `kernel principal component analysis (outbound) `_. + +.. code-block:: python + + def compute_representation(representation,frames): + expansions = soap.transform(frames) + return expansions + + def compute_kernel(zeta, rep1, rep2=None): + if rep2 is None: + kernel = rep1.cosine_kernel_global(zeta) + else: + kernel = rep1.cosine_kernel_global(rep2,zeta) + return kernel + + def link_ngl_wdgt_to_ax_pos(ax, pos, ngl_widget): + from matplotlib.widgets import AxesWidget + from scipy.spatial import cKDTree + r""" + Initial idea for this function comes from @arose, the rest is @gph82 and @clonker + """ + + kdtree = cKDTree(pos) + #assert ngl_widget.trajectory_0.n_frames == pos.shape[0] + x, y = pos.T + + lineh = ax.axhline(ax.get_ybound()[0], c="black", ls='--') + linev = ax.axvline(ax.get_xbound()[0], c="black", ls='--') + dot, = ax.plot(pos[0,0],pos[0,1], 'o', c='red', ms=7) + + ngl_widget.isClick = False + + def onclick(event): + linev.set_xdata((event.xdata, event.xdata)) + lineh.set_ydata((event.ydata, event.ydata)) + data = [event.xdata, event.ydata] + _, index = kdtree.query(x=data, k=1) + dot.set_xdata((x[index])) + dot.set_ydata((y[index])) + ngl_widget.isClick = True + ngl_widget.frame = index + + def my_observer(change): + r"""Here comes the code that you want to execute + """ + ngl_widget.isClick = False + _idx = change["new"] + try: + dot.set_xdata((x[_idx])) + dot.set_ydata((y[_idx])) + except IndexError as e: + dot.set_xdata((x[0])) + dot.set_ydata((y[0])) + print("caught index error with index %s (new=%s, old=%s)" % (_idx, change["new"], change["old"])) + + # Connect axes to widget + axes_widget = AxesWidget(ax) + axes_widget.connect_event('button_release_event', onclick) + + # Connect widget to axes + ngl_widget.observe(my_observer, "frame", "change") + + # Load the small molecules + frames = read('./data/small_molecules-1000.xyz',':600') + hypers = dict(soap_type="PowerSpectrum", + interaction_cutoff=3.5, + max_radial=6, + max_angular=6, + gaussian_sigma_constant=0.4, + gaussian_sigma_type="Constant", + cutoff_smooth_width=0.5, + ) + soap = SOAP(**hypers) + zeta = 2 + features = compute_representation(soap, frames) + kernel = compute_kernel(zeta,features) + from sklearn.decomposition import KernelPCA + kpca = KernelPCA(n_components=2,kernel='precomputed') + kpca.fit(kernel) + X = kpca.transform(kernel) + plt.scatter(X[:,0],X[:,1],s=3) + +The result of this block is: + +.. image:: ../resources/images/PCAs.png + +It shows how the structures is located in the abstract 2D map, where similar +structures are located near to each other, and the very different ones far from +each other. diff --git a/docs/source/tutorials/nl-for-user.rst b/docs/source/tutorials/nl-for-user.rst new file mode 100644 index 000000000..dff3e8e2b --- /dev/null +++ b/docs/source/tutorials/nl-for-user.rst @@ -0,0 +1,109 @@ +.. _nl-for-user: + +How to build a neighbor list? +============================= + +Overview +~~~~~~~~ + + +Here we provide a tutorial on how to use the C++ interface for building neighbor lists. + +Rascal comes with a built-in neighborhood manager. The role of a neighborhood manager is to minimize manual handeling of building the neighborhood lists. +The current implementation avoids the explicit use of embedded lists to describe neighborhoods and makes iterations over them more trivial. +The neighborhood manager interface is universal to all the representations of Rascal. It can also be very easily interfaced with MD/MC simulation packages. +We prefer using `Eigen `_ library for the linear algebra operations because of the versatility and flexibility allowed by the library. + +`Eigen` library +~~~~~~~~~~~~~~~ + +`Eigen` is an open source library for linear algebra operatins in C++. It is implemented using expression templates techniques. +We usually use the following templates to describe the positions, the atomic numbers array,..etc + +.. code-block:: cpp + + using Vector_t = Eigen::Matrix; // dim = 1, 2 or 3 + Eigen::MatrixXd MATRIX(NROWS,NCOLUMNS); // + using rascal::VecXi = Eigen::Matrix + +Creating a neighborhood manager +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +First, the neighborhood manager is created and initialized using the :cpp:class:`rascal::NeighborhoodManagerCell`. + +.. code-block:: cpp + + using Manager_t = rascal::NeighbourhoodManagerCell; + Manager_t manager; // initialize the neighborhood manager + +While the neighborhood manager can be built for the first time using :cpp:class:`rascal::NeighborhoodManagerCell::build`, +we recommend updating it using :class:`rascal::NeighborhoodManagerCell::update`. The following inputs should be provided in order: + +- the atomic positions matrix column wise as an `Eigen` matrix object +- an array of the atomic numbers of the species +- an array of centers ids +- the cell vectors column wise as an `Eigen` matrix object +- a boolean array of the periodic boundary conditions over the 3 axes +- the maximum radial cutoff (in the units of the cell vectors and atomic positions) + +The folllowing code is an example of the inputs that need to be customized according to the user's use, as in to provide +cell vectors, atomic positions and numbers and the ids of the centers. + +.. code-block:: cpp + + Eigen::MatrixXd cell(3,3); // the cell vectors matrix + + int number_of_atoms{100}; // the number of atoms in the structure + Eigen::MatrixXd positions(3,number_of_atoms); // atomic postions matrix + rascal::VecXi numbers(22); // atomic numbers array + + std::vector center_ids{}; // a vector containing the atomic centers ids + + std::array pbc{true, false, false}; // for periodic boundary conditions over the x axis only + + double cutoff{3.5}; // a radial cutoff distance of 3.5 angstrom + + manager.update(positions, numbers, center_ids, cell, pbc, cutoff); + +- .. note:: A neighborhood manager can be updated as much as necessary by providing all the upmentioned inputs. + + +Commands of the neighborhood manager: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In the current implementation of the neighborhood manager, the centers and their neighbors are :cpp:class:`rascal::Neighborhood Cell::ClusterRef` objects of order 1 and 2, respectively. +In order to access objects of order 2, we need to iterate over the corresponding order 1 object (the corresponding center). +This implementation has the advantage of not using explicit arrays to deal with center and neighbor properties. + +Several methods are implemented for the :cpp:class:`rascal::NeighborhoodCell::ClusterRef` objects (centers and their neighbors), such as retrieving +the index of the object, its position and its atom type. + +- .. note:: The positions of order 2 are given with a certain offset relative to the position of the corresponding center of order 1. If one atom is included in the neighborhood of two different centers, it will have different positions depending on + the center being iterated over. + +- .. warning:: The relative positions of the neighbors of a center are calculated on the fly and are not stored. If needed they have to be stored manually. + +This is an example of code than can be used to print to the screen the positions, types and indices of the centers and their neighbors. It also calculates the relative shift in the positions of every center's neighbors + and its norm. + +.. code-block:: cpp + + for (auto center : manager) { + + int center_index{center.get_atom_index()}; // get the index of the center atomic + Eigen::MatrixXd position{center.get_position()}; // get the position vector of the center + auto center_type{center.get_atom_type()}; // get the atome type of the center + std::cout << "Neighbors properties : " << endl; + + for (auto neigh : center){ + int neigh_index{center.get_atom_index()}; // get the index of the neighbor + Eigen::MatrixXd position{neigh.get_position()}; // get the position vector of the neighbor + auto neigh_type{center.get_atom_type()}; // get the atome type of the neighbor + auto relative_shift{position - center.get_position()}; // compute the position offset + + std::cout << "This is the position of atom " << neigh_index << " of a type " << neigh_type << endl; + std::cout << "The relative position is : " << neigh_position << endl; + std::cout << "The relative shift is : " << relative_shift << endl; + std::cout << "The norm of the shif is : " << relative_shift.norm() << " ang" << endl; + } + } diff --git a/docs/source/tutorials/tutorials.rst b/docs/source/tutorials/tutorials.rst new file mode 100644 index 000000000..8798b050f --- /dev/null +++ b/docs/source/tutorials/tutorials.rst @@ -0,0 +1,29 @@ +.. _tutorials: + +Tutorials +========= + +Here you will find some tutorial examples for getting started with librascal, +both as a new user of the library and for getting started developing a new +representation. + +To run the ipython notebooks please install the rascal library as it is +explained in :ref:`installation`. + + +Getting started +~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + TutorialEn + SOAP_CSD500.ipynb + +Intro for developers +~~~~~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + nl-for-user From 33ca49a1f47b4fcf1212741ddba06a35a80a4a33 Mon Sep 17 00:00:00 2001 From: rosecers Date: Tue, 10 Dec 2019 13:36:08 +0100 Subject: [PATCH 07/12] Removing deprecated examples and tutorials --- docs/source/tutorials/tutorials.rst | 29 - examples/Prediction_example.ipynb | 330 ---------- examples/SOAP_CSD500.ipynb | 960 ---------------------------- examples/SOAP_example.ipynb | 296 --------- examples/SOAP_small_molecules.ipynb | 694 -------------------- 5 files changed, 2309 deletions(-) delete mode 100644 docs/source/tutorials/tutorials.rst delete mode 100644 examples/Prediction_example.ipynb delete mode 100644 examples/SOAP_CSD500.ipynb delete mode 100644 examples/SOAP_example.ipynb delete mode 100644 examples/SOAP_small_molecules.ipynb diff --git a/docs/source/tutorials/tutorials.rst b/docs/source/tutorials/tutorials.rst deleted file mode 100644 index 8798b050f..000000000 --- a/docs/source/tutorials/tutorials.rst +++ /dev/null @@ -1,29 +0,0 @@ -.. _tutorials: - -Tutorials -========= - -Here you will find some tutorial examples for getting started with librascal, -both as a new user of the library and for getting started developing a new -representation. - -To run the ipython notebooks please install the rascal library as it is -explained in :ref:`installation`. - - -Getting started -~~~~~~~~~~~~~~~ - -.. toctree:: - :maxdepth: 1 - - TutorialEn - SOAP_CSD500.ipynb - -Intro for developers -~~~~~~~~~~~~~~~~~~~~ - -.. toctree:: - :maxdepth: 1 - - nl-for-user diff --git a/examples/Prediction_example.ipynb b/examples/Prediction_example.ipynb deleted file mode 100644 index b760399ab..000000000 --- a/examples/Prediction_example.ipynb +++ /dev/null @@ -1,330 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Using Rascal and SOAP to Predict Properties\n", - "\n", - "This notebook is intended as an introductory how-to on calculating the SOAP vector and train a model for their atomization energies on these vectors. For more information on the variable conventions, derivation, utility, and calculation of SOAP vectors, please refer to (among others): \n", - "- [On representing chemical environments (Bartók 2013)](https://journals.aps.org/prb/abstract/10.1103/PhysRevB.87.184115)\n", - "- [Gaussian approximation potentials: A brief tutorial introduction (Bartók 2015)](https://onlinelibrary.wiley.com/doi/full/10.1002/qua.24927)\n", - "- [Comparing molecules and solids across structural and alchemical space (De 2016)](https://pubs.rsc.org/en/content/articlepdf/2016/cp/c6cp00415f)\n", - "\n", - "Beyond libRascal, the packages used in this tutorial are: [json](https://docs.python.org/2/library/json.html), [numpy](https://numpy.org/), [matplotlib](https://matplotlib.org/), and [ase](https://wiki.fysik.dtu.dk/ase/index.html)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "%reload_ext autoreload\n", - "%autoreload 2\n", - "from tutorial_utils import *\n", - "try:\n", - " from rascal.representations import SphericalInvariants as SOAP\n", - "except:\n", - " from rascal.representations import SOAP\n", - "readme_button()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### First, let's look at how we can use SOAP to represent small molecules.\n", - "We will play around with the SOAP hyperparameters in later examples, but for now we'll use the default hyperparameters." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mySOAP=SOAP_tutorial()\n", - "mySOAP.output_params()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let's look at the SOAP representation of our first frame" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "soap = SOAP(**mySOAP.hyperparameters)\n", - "X = soap.transform(mySOAP.frames[:1])\n", - "\n", - "mySOAP.verbosity_wrap(\"Our first frame has {} environments, thus our soap feature matrix has a shape of {}\".format(len(mySOAP.frames[0].positions), X.get_feature_matrix().T.shape, len(X.get_feature_matrix().T[0])))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Now we know how to retrieve SOAP vectors, let's look at the impact of the hyperparameters on training a Kernel Ridge Regression (KRR)\n", - "This time when we open up the tutorial, you will be able to change the input file, hyperparameters, and property to use for the kernel ridge regression, which are saved to mySOAP as they are changed. We've even included some suggestions for hyperparameters, why not try the Power Spectrum first?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mySOAP=SOAP_tutorial(interactive=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mySOAP.train_krr_model()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mySOAP.predict_test_set()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mySOAP.predict_new_set(filename='../reference_data/inputs/small_molecules-1000.xyz')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Now that we've explained the workflow, let's strip away the SOAP_tutorial wrapper and run the computation again:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from ase.io import read\n", - "import numpy as np\n", - "try:\n", - " from rascal.representations import SphericalInvariants as SOAP\n", - "except:\n", - " from rascal.representations import SOAP\n", - "\n", - "def split_dataset(N, training_percentage, seed=20):\n", - " np.random.seed(seed)\n", - " ids = list(range(N))\n", - " np.random.shuffle(ids)\n", - " return ids[:int(training_percentage*N)], ids[int(training_percentage*N):]\n", - "\n", - "class KRR(object):\n", - " def __init__(self, zeta, weights, representation, X, kernel_type):\n", - " self.weights = weights\n", - " self.representation = representation\n", - " self.zeta = zeta\n", - " self.X = X\n", - " self.kernel_type=kernel_type\n", - "\n", - " def predict(self,frames):\n", - " features = self.representation.transform(frames)\n", - " kernel_function = self.X.cosine_kernel_atomic if self.kernel_type=='atomic' else self.X.cosine_kernel_global\n", - " kernel = kernel_function(features, zeta) \n", - " return np.dot(self.weights, kernel)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### These are the parameters you'll want change, such as we did above with the sliders.\n", - "(Everything else in the workflow is a function of these parameters)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "input_file = '../reference_data/inputs/small_molecules-1000.xyz'\n", - "hyperparameters = dict(soap_type = 'PowerSpectrum', \\\n", - " interaction_cutoff = 3.5, \\\n", - " max_radial = 2, \\\n", - " max_angular = 1, \\\n", - " gaussian_sigma_constant = 0.5, \\\n", - " gaussian_sigma_type = 'Constant', \\\n", - " cutoff_smooth_width = 0.0\n", - " )\n", - "property_to_ml = \"dft_formation_energy_per_atom_in_eV\"\n", - "\n", - "training_percentage = 0.8\n", - "zeta = 2\n", - "Lambda = 5e-3\n", - "jitter=1e-8" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Which are then used to compute:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "frames = np.array(read(input_file,\":\"))\n", - "number_of_frames = len(frames)\n", - "representation = SOAP(**hyperparameters)\n", - "property_values = np.array([cc.info[property_to_ml] for cc in frames])\n", - "train_idx, test_idx = split_dataset(number_of_frames, training_percentage)\n", - "features = representation.transform(frames[train_idx])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Then, you can construct the kernel for ML and feed it into a KRR Model:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "kernel_function = features.cosine_kernel_atomic if property_to_ml == \"ENERGY\" else features.cosine_kernel_global\n", - "kernel = kernel_function(zeta)\n", - "\n", - "delta = np.std(property_values[train_idx]) / np.mean(kernel.diagonal())\n", - "kernel[np.diag_indices_from(kernel)] += Lambda**2 / delta **2 + jitter\n", - "weights = np.linalg.solve(kernel,property_values[train_idx])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "model = KRR(zeta, weights, representation, features, kernel_type='atomic' if property_to_ml==\"ENERGY\" else \"global\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### This model can be in turn used to predict the data from out testing set:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_pred = model.predict(frames[test_idx])\n", - "print(dict(\n", - " mean_average_error= [np.mean(np.abs(y_pred-property_values[test_idx]))],\n", - " root_mean_squared_error=[np.sqrt(np.mean((y_pred-property_values[test_idx])**2))],\n", - " R2 = [np.mean(1 - (((property_values[test_idx] - y_pred) ** 2).sum(axis=0,dtype=np.float64) / ((property_values[test_idx] - np.average(property_values[test_idx], axis=0) ** 2).sum(axis=0,dtype=np.float64))))]\n", - " ))\n", - "plt.scatter(y_pred, property_values[test_idx], s=3)\n", - "plt.axis('scaled')\n", - "plt.xlabel('DFT energy / (eV/atom)')\n", - "plt.ylabel('Predicted energy / (eV/atom)')\n", - "plt.gca().set_aspect('equal')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Alternatively we can use the model to predict properties from a new data set" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "filename='../reference_data/inputs/small_molecules-1000.xyz'\n", - "y_pred = model.predict(np.array(read(filename,\":\")))\n", - "print(dict(\n", - " mean_average_error= [np.mean(np.abs(y_pred-property_values[test_idx]))],\n", - " root_mean_squared_error=[np.sqrt(np.mean((y_pred-property_values[test_idx])**2))],\n", - " R2 = [np.mean(1 - (((property_values[test_idx] - y_pred) ** 2).sum(axis=0,dtype=np.float64) / ((property_values[test_idx] - np.average(property_values[test_idx], axis=0) ** 2).sum(axis=0,dtype=np.float64))))]\n", - " ))\n", - "plt.scatter(y_pred, property_values[test_idx], s=3)\n", - "plt.axis('scaled')\n", - "plt.xlabel('DFT energy / (eV/atom)')\n", - "plt.ylabel('Predicted energy / (eV/atom)')\n", - "plt.gca().set_aspect('equal')" - ] - } - ], - "metadata": { - "celltoolbar": "Raw Cell Format", - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - }, - "toc": { - "base_numbering": 1, - "nav_menu": { - "height": "12px", - "width": "252px" - }, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": "block", - "toc_window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/SOAP_CSD500.ipynb b/examples/SOAP_CSD500.ipynb deleted file mode 100644 index 76309c747..000000000 --- a/examples/SOAP_CSD500.ipynb +++ /dev/null @@ -1,960 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To install rascal:\n", - "(NOTE: See the top-level README for the most up-to-date installation instructions.)\n", - "+ mkdir ../build \n", - "+ cd build\n", - "+ cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON ..\n", - "+ make -j 4\n", - "+ make install" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib notebook\n", - "from matplotlib import pylab as plt\n", - "import os, sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "hide_input" - ] - }, - "outputs": [], - "source": [ - "# Ensure the notebook is running in the proper directory\n", - "# (only needed when compiling from sphinx)\n", - "if \"docs/source/tutorials\" in os.getcwd():\n", - " os.chdir(\"../../../examples\")\n", - "sys.path.insert(0,\"../build/\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import time\n", - "import rascal\n", - "import json\n", - "\n", - "import ase\n", - "from ase.io import read, write\n", - "from ase.build import make_supercell\n", - "from ase.visualize import view\n", - "import numpy as np\n", - "import sys\n", - "#import pandas\n", - "import scipy\n", - "import json\n", - "\n", - "from rascal.representations import SphericalInvariants as SOAP" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import sklearn" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Download data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Run the cell below to dowload the CSD-500 dataset you'll need for this tutorial.\n", - "\n", - "The data is from the paper \"Chemical shifts in molecular solids by machine learning\" by Paruzzo, Hofstetter, Musil, De, Ceriotti and Emsley, available [here](https://www.nature.com/articles/s41467-018-06972-x). (If the cell below doesn't work, try downloading \"Supplementary Data 2\" from the [supplementary info section](https://www.nature.com/articles/s41467-018-06972-x#Sec11) of the paper; be sure to name it `data/CSD-500.xyz` as below)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "download_link = \"https://static-content.springer.com/esm/art%3A10.1038%2Fs41467-018-06972-x/MediaObjects/41467_2018_6972_MOESM4_ESM.txt\"\n", - "import urllib.request\n", - "urllib.request.urlretrieve(download_link, './reference_data/CSD-500.xyz')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#frames = read('./data/small_molecules-1000.xyz',':600')\n", - "frames = read('./reference_data/CSD-500.xyz',':3')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n_atoms = sum(frame.get_number_of_atoms() for frame in frames)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "chem_shifts = []\n", - "for frame in frames:\n", - " chem_shifts.append(frame.arrays['CS'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "chem_shifts[1].shape" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "chem_shifts_atoms = np.concatenate(chem_shifts, axis=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "chem_shifts_atoms.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# SOAP: Power spectrum" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "code_folding": [] - }, - "outputs": [], - "source": [ - "hypers = dict(soap_type=\"PowerSpectrum\",\n", - " interaction_cutoff=3.5, \n", - " max_radial=6, \n", - " max_angular=6, \n", - " gaussian_sigma_constant=0.4,\n", - " gaussian_sigma_type=\"Constant\",\n", - " cutoff_smooth_width=0.5,\n", - " )\n", - "soap = SOAP(**hypers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%time representation = soap.transform(frames)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X = representation.get_features - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Learning the chemical shifts of a set of crystal structures" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "## learning utilities" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "code_folding": [ - 13, - 20, - 31, - 33, - 35, - 37, - 47, - 54 - ], - "hidden": true - }, - "outputs": [], - "source": [ - "def compute_representation(representation, frames):\n", - " result = representation.transform(frames)\n", - " return result\n", - "\n", - "#def compute_representation(frames):\n", - "# expansions = soap.transform(frames)\n", - "# return expansions\n", - "\n", - "def compute_atomic_kernel(zeta, rep1, rep2=None):\n", - " if rep2 is not None:\n", - " kernel = rep1.cosine_kernel_atomic(rep2, zeta)\n", - " else:\n", - " kernel = rep1.cosine_kernel_atomic(zeta)\n", - " return kernel\n", - "\n", - "def extract_energy(frames):\n", - " prop = [[]]*len(frames)\n", - " for ii,cc in enumerate(frames):\n", - " #prop[ii] = cc.info['dft_formation_energy_per_atom_in_eV']\n", - " prop[ii] = cc.info['ENERGY']\n", - " y = np.array(prop)\n", - " return y\n", - "\n", - "def split_dataset(frames, test_fraction, seed=10):\n", - " N = len(frames)\n", - " ids = np.arange(N)\n", - " np.random.seed(seed)\n", - " np.random.shuffle(ids)\n", - " Ntrain = int(N*test_fraction)\n", - " train = ids[:Ntrain]\n", - " test = ids[Ntrain:]\n", - " targets = extract_energy(frames)\n", - " return [frames[ii] for ii in train],targets[train],[frames[ii] for ii in test],targets[test]\n", - "\n", - "def get_mae(ypred,y):\n", - " return np.mean(np.abs(ypred-y))\n", - "def get_rmse(ypred,y):\n", - " return np.sqrt(np.mean((ypred-y)**2))\n", - "def get_sup(ypred,y):\n", - " return np.amax(np.abs((ypred-y)))\n", - "def get_r2(y_pred,y_true):\n", - " weight = 1\n", - " sample_weight = None\n", - " numerator = (weight * (y_true - y_pred) ** 2).sum(axis=0,dtype=np.float64)\n", - " denominator = (weight * (y_true - np.average(\n", - " y_true, axis=0, weights=sample_weight)) ** 2).sum(axis=0,dtype=np.float64)\n", - " output_scores = 1 - (numerator / denominator)\n", - " return np.mean(output_scores)\n", - "\n", - "\n", - "score_func = dict(\n", - " MAE=get_mae,\n", - " RMSE=get_rmse,\n", - " SUP=get_sup,\n", - " R2=get_r2,\n", - ")\n", - "\n", - "def get_score(ypred,y):\n", - " scores = {}\n", - " for k,func in score_func.items():\n", - " scores[k] = func(ypred,y)\n", - " return scores\n", - "\n", - "class KRR(object):\n", - " def __init__(self,zeta,weights,representation,X):\n", - " self.weights = weights\n", - " self.representation = representation\n", - " self.zeta = zeta\n", - " self.X = X\n", - " \n", - " def predict(self,frames):\n", - " features = compute_representation(self.representation,frames)\n", - " kernel = compute_atomic_kernel(self.zeta, self.X, features)\n", - " return np.dot(self.weights, kernel)\n", - "\n", - "def train_krr_model(zeta,Lambda,representation,frames,y,jitter=1e-8):\n", - " features = compute_representation(representation, frames)\n", - " kernel = compute_atomic_kernel(zeta, features, features) \n", - " # adjust the kernel so that it is properly scaled\n", - " delta = np.std(y) / np.mean(kernel.diagonal())\n", - " kernel[np.diag_indices_from(kernel)] += Lambda**2 / delta **2 + jitter\n", - " # train the krr model\n", - " weights = np.linalg.solve(kernel,y)\n", - " model = KRR(zeta, weights,representation, features)\n", - " return model,kernel\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "compute_representation(soap, frames)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "## With the full power spectrum" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "hypers = dict(soap_type=\"PowerSpectrum\",\n", - " interaction_cutoff=3.5, \n", - " max_radial=1, \n", - " max_angular=1, \n", - " gaussian_sigma_constant=0.4,\n", - " gaussian_sigma_type=\"Constant\",\n", - " cutoff_smooth_width=0.5,\n", - " )\n", - "soap = SOAP(**hypers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "frames_train, y_train, frames_test, y_test = split_dataset(frames,0.5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_train = np.concatenate([frame.arrays['CS'] for frame in frames_train], axis=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_train = y_train[:,0]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_test = np.concatenate([frame.arrays['CS'] for frame in frames_test], axis=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_test = y_test[:,0]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n_atoms = sum(frame.get_number_of_atoms() for frame in frames_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "zeta = 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "features = compute_representation(soap, frames_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "features" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "kernel = compute_atomic_kernel(zeta, features, features)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "kernel.shape" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# WTF?\n", - "#for i in range(len(kernel)):\n", - "# kernel[i][0] = np.sqrt(i)/50" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "kernel[191]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# First, try without regularization -- the results will be nonsense\n", - "weights = np.linalg.solve(kernel,y_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "weights.shape" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "model = KRR(zeta, weights, soap, features)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "y_pred = model.predict(frames_test)\n", - "get_score(y_pred, y_test)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "zeta = 2\n", - "Lambda = 10\n", - "krr,k = train_krr_model(zeta, Lambda, soap, frames_train, y_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "y_pred = krr.predict(frames_test)\n", - "get_score(y_pred, y_test)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#sc = plt.scatter(y_pred, y_test, s=3)\n", - "#ax = plt.axis('scaled')\n", - "plt.plot(y_test, y_pred, '.')\n", - "plt.ylabel('DFT shift')\n", - "plt.xlabel('Predicted shift')\n", - "plt.savefig('R1.png', dpi=300)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "## With just the radial spectrum" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "hypers = dict(soap_type=\"RadialSpectrum\",\n", - " interaction_cutoff=3.5, \n", - " max_radial=6, \n", - " max_angular=0, \n", - " gaussian_sigma_constant=0.4,\n", - " gaussian_sigma_type=\"Constant\",\n", - " cutoff_smooth_width=0.5\n", - " )\n", - "soap = SOAP(**hypers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "frames_train, y_train, frames_test, y_testr = split_dataset(frames,0.4)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "zeta = 2\n", - "Lambda = 5e-3\n", - "krr,k = train_krr_model(zeta, Lambda, soap, frames_train, y_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "y_predr = krr.predict(frames_test)\n", - "get_score(y_predr, y_testr)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "#plt.scatter(y_predr, y_testr, s=3)\n", - "#plt.scatter(y_predr, y_testr, s=3)\n", - "#ax = plt.axis('scaled')\n", - "plt.plot(y_pred, y_test, '.b')\n", - "plt.plot(y_predr, y_testr, '.y')\n", - "plt.legend(['Full','Radial'])\n", - "plt.ylabel('DFT energy / (eV/atom)')\n", - "plt.xlabel('Predicted energy / (eV/atom)')\n", - "plt.savefig('R1.png', dpi=300)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Make a map of the dataset" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "## utils" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "def compute_representation(representation,frames):\n", - " expansions = soap.transform(frames)\n", - " return expansions\n", - "\n", - "def compute_kernel(zeta, rep1, rep2=None):\n", - " if rep2 is None:\n", - " kernel = rep1.cosine_kernel_global(zeta)\n", - " else:\n", - " kernel = rep1.cosine_kernel_global(rep2,zeta)\n", - " return kernel" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "code_folding": [ - 0 - ], - "hidden": true - }, - "outputs": [], - "source": [ - "def link_ngl_wdgt_to_ax_pos(ax, pos, ngl_widget):\n", - " from matplotlib.widgets import AxesWidget\n", - " from scipy.spatial import cKDTree\n", - " r\"\"\"\n", - " Initial idea for this function comes from @arose, the rest is @gph82 and @clonker\n", - " \"\"\"\n", - " \n", - " kdtree = cKDTree(pos) \n", - " #assert ngl_widget.trajectory_0.n_frames == pos.shape[0]\n", - " x, y = pos.T\n", - " \n", - " lineh = ax.axhline(ax.get_ybound()[0], c=\"black\", ls='--')\n", - " linev = ax.axvline(ax.get_xbound()[0], c=\"black\", ls='--')\n", - " dot, = ax.plot(pos[0,0],pos[0,1], 'o', c='red', ms=7)\n", - "\n", - " ngl_widget.isClick = False\n", - " \n", - " def onclick(event):\n", - " linev.set_xdata((event.xdata, event.xdata))\n", - " lineh.set_ydata((event.ydata, event.ydata))\n", - " data = [event.xdata, event.ydata]\n", - " _, index = kdtree.query(x=data, k=1)\n", - " dot.set_xdata((x[index]))\n", - " dot.set_ydata((y[index]))\n", - " ngl_widget.isClick = True\n", - " ngl_widget.frame = index\n", - " \n", - " def my_observer(change):\n", - " r\"\"\"Here comes the code that you want to execute\n", - " \"\"\"\n", - " ngl_widget.isClick = False\n", - " _idx = change[\"new\"]\n", - " try:\n", - " dot.set_xdata((x[_idx]))\n", - " dot.set_ydata((y[_idx])) \n", - " except IndexError as e:\n", - " dot.set_xdata((x[0]))\n", - " dot.set_ydata((y[0]))\n", - " print(\"caught index error with index %s (new=%s, old=%s)\" % (_idx, change[\"new\"], change[\"old\"]))\n", - " \n", - " # Connect axes to widget\n", - " axes_widget = AxesWidget(ax)\n", - " axes_widget.connect_event('button_release_event', onclick)\n", - " \n", - " # Connect widget to axes\n", - " ngl_widget.observe(my_observer, \"frame\", \"change\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "## make a map with kernel pca projection" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "# Load the small molecules \n", - "frames = read('./reference_data/small_molecules-1000.xyz',':600')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "hypers = dict(soap_type=\"PowerSpectrum\",\n", - " interaction_cutoff=3.5, \n", - " max_radial=6, \n", - " max_angular=6, \n", - " gaussian_sigma_constant=0.4,\n", - " gaussian_sigma_type=\"Constant\",\n", - " cutoff_smooth_width=0.5,\n", - " )\n", - "soap = SOAP(**hypers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "zeta = 2\n", - "\n", - "features = compute_representation(soap, frames)\n", - "\n", - "kernel = compute_kernel(zeta,features)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "from sklearn.decomposition import KernelPCA" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "kpca = KernelPCA(n_components=2,kernel='precomputed')\n", - "kpca.fit(kernel)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "X = kpca.transform(kernel)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "plt.scatter(X[:,0],X[:,1],s=3)\n", - "#plt.savefig('PCA.png',dpi=300)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## make an interactive map" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# package to visualize the structures in the notebook\n", - "# https://github.com/arose/nglview#released-version\n", - "import nglview" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iwdg = nglview.show_asetraj(frames)\n", - "# set up the visualization\n", - "iwdg.add_unitcell()\n", - "iwdg.add_spacefill()\n", - "iwdg.remove_ball_and_stick()\n", - "iwdg.camera = 'orthographic'\n", - "iwdg.parameters = { \"clipDist\": 0 }\n", - "iwdg.center()\n", - "iwdg.update_spacefill(radiusType='covalent',\n", - " scale=0.6,\n", - " color_scheme='element')\n", - "iwdg._remote_call('setSize', target='Widget',\n", - " args=['%dpx' % (600,), '%dpx' % (400,)])\n", - "iwdg.player.delay = 200.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "link_ngl_wdgt_to_ax_pos(plt.gca(), X, iwdg)\n", - "plt.scatter(X[:,0],X[:,1],s=3)\n", - "iwdg" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.5rc1" - }, - "toc": { - "base_numbering": 1, - "nav_menu": { - "height": "12px", - "width": "252px" - }, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": "block", - "toc_window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/SOAP_example.ipynb b/examples/SOAP_example.ipynb deleted file mode 100644 index b7859a4e4..000000000 --- a/examples/SOAP_example.ipynb +++ /dev/null @@ -1,296 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Using Rascal to Calculate SOAP Vectors\n", - "\n", - "This notebook is intended as an introductory how-to on calculating the SOAP vector and train a model for their atomization energies on these vectors. For more information on the variable conventions, derivation, utility, and calculation of SOAP vectors, please refer to (among others): \n", - "- [On representing chemical environments (Bartók 2013)](https://journals.aps.org/prb/abstract/10.1103/PhysRevB.87.184115)\n", - "- [Gaussian approximation potentials: A brief tutorial introduction (Bartók 2015)](https://onlinelibrary.wiley.com/doi/full/10.1002/qua.24927)\n", - "- [Comparing molecules and solids across structural and alchemical space (De 2016)](https://pubs.rsc.org/en/content/articlepdf/2016/cp/c6cp00415f)\n", - "\n", - "Beyond libRascal, the packages used in this tutorial are: [json](https://docs.python.org/2/library/json.html), [numpy](https://numpy.org/), [matplotlib](https://matplotlib.org/), and [ase](https://wiki.fysik.dtu.dk/ase/index.html)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "%reload_ext autoreload\n", - "%autoreload 2\n", - "import sys\n", - "sys.path.insert(0, '../build')\n", - "from tutorial_utils import *\n", - "try:\n", - " from rascal.representations import SphericalInvariants as SOAP\n", - "except:\n", - " from rascal.representations import SOAP\n", - "readme_button()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### First, let's look at how we can use SOAP to represent small molecules.\n", - "We will play around with the SOAP hyperparameters in later examples, but for now we'll use the default hyperparameters." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mySOAP=SOAP_tutorial()\n", - "mySOAP.output_params()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let's look at the SOAP representation of our first frame" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "soap = SOAP(**mySOAP.hyperparameters)\n", - "X = soap.transform(mySOAP.frames[:1])\n", - "\n", - "mySOAP.verbosity_wrap(\"Our first frame has {} environments, thus our soap feature matrix has a shape of {}\".format(len(mySOAP.frames[0].positions), X.get_features(soap).T.shape, len(X.get_features(soap).T[0])))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Now we know how to retrieve SOAP vectors, let's look at the impact of the hyperparameters on training a Kernel Ridge Regression (KRR)\n", - "This time when we open up the tutorial, you will be able to change the input file, hyperparameters, and property to use for the kernel ridge regression, which are saved to mySOAP as they are changed. We've even included some suggestions for hyperparameters, why not try the Power Spectrum first?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mySOAP=SOAP_tutorial(interactive=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mySOAP.train_krr_model()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mySOAP.plot_prediction_func()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Now that we've explained the workflow, let's strip away the SOAP_tutorial wrapper and run the computation again:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from ase.io import read\n", - "import numpy as np\n", - "try:\n", - " from rascal.representations import SphericalInvariants as SOAP\n", - "except:\n", - " from rascal.representations import SOAP\n", - "\n", - "def split_dataset(N, training_percentage, seed=20):\n", - " np.random.seed(seed)\n", - " ids = list(range(N))\n", - " np.random.shuffle(ids)\n", - " return ids[:int(training_percentage*N)], ids[int(training_percentage*N):]\n", - "\n", - "class KRR(object):\n", - " def __init__(self, zeta, weights, representation, X, kernel_type):\n", - " self.weights = weights\n", - " self.representation = representation\n", - " self.zeta = zeta\n", - " self.X = X\n", - " self.kernel_type=kernel_type\n", - "\n", - " def predict(self,frames):\n", - " features = self.representation.transform(frames)\n", - " kernel_function = self.X.cosine_kernel_atomic if self.kernel_type=='atomic' else self.X.cosine_kernel_global\n", - " kernel = kernel_function(features, zeta) \n", - " return np.dot(self.weights, kernel)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### These are the parameters you'll want change, such as we did above with the sliders.\n", - "(Everything else in the workflow is a function of these parameters)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "input_file = 'reference_data/small_molecules-1000.xyz'\n", - "hyperparameters = dict(soap_type = 'PowerSpectrum', \\\n", - " interaction_cutoff = 3.5, \\\n", - " max_radial = 2, \\\n", - " max_angular = 1, \\\n", - " gaussian_sigma_constant = 0.5, \\\n", - " gaussian_sigma_type = 'Constant', \\\n", - " cutoff_smooth_width = 0.0\n", - " )\n", - "property_to_ml = \"dft_formation_energy_per_atom_in_eV\"\n", - "\n", - "training_percentage = 0.8\n", - "zeta = 2\n", - "Lambda = 5e-3\n", - "jitter=1e-8" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Which are then used to compute:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "frames = np.array(read(input_file,\":\"))\n", - "number_of_frames = len(frames)\n", - "representation = SOAP(**hyperparameters)\n", - "property_values = np.array([cc.info[property_to_ml] for cc in frames])\n", - "train_idx, test_idx = split_dataset(number_of_frames, training_percentage)\n", - "features = representation.transform(frames[train_idx])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Then, you can construct the kernel for ML and feed it into a KRR Model:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "kernel_function = features.cosine_kernel_atomic if property_to_ml == \"ENERGY\" else features.cosine_kernel_global\n", - "kernel = kernel_function(zeta)\n", - "\n", - "delta = np.std(property_values[train_idx]) / np.mean(kernel.diagonal())\n", - "kernel[np.diag_indices_from(kernel)] += Lambda**2 / delta **2 + jitter\n", - "weights = np.linalg.solve(kernel,property_values[train_idx])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "model = KRR(zeta, weights, representation, features, kernel_type='atomic' if property_to_ml==\"ENERGY\" else \"global\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### This model can be in turn used to predict the data from out testing set:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_pred = model.predict(frames[test_idx])\n", - "print(dict(\n", - " mean_average_error= [np.mean(np.abs(y_pred-property_values[test_idx]))],\n", - " root_mean_squared_error=[np.sqrt(np.mean((y_pred-property_values[test_idx])**2))],\n", - " R2 = [np.mean(1 - (((property_values[test_idx] - y_pred) ** 2).sum(axis=0,dtype=np.float64) / ((property_values[test_idx] - np.average(property_values[test_idx], axis=0) ** 2).sum(axis=0,dtype=np.float64))))]\n", - " ))\n", - "plt.scatter(y_pred, property_values[test_idx], s=3)\n", - "plt.axis('scaled')\n", - "plt.xlabel('DFT energy / (eV/atom)')\n", - "plt.ylabel('Predicted energy / (eV/atom)')\n", - "plt.gca().set_aspect('equal')" - ] - } - ], - "metadata": { - "celltoolbar": "Raw Cell Format", - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - }, - "toc": { - "base_numbering": 1, - "nav_menu": { - "height": "12px", - "width": "252px" - }, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": "block", - "toc_window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/SOAP_small_molecules.ipynb b/examples/SOAP_small_molecules.ipynb deleted file mode 100644 index e47ebe7b0..000000000 --- a/examples/SOAP_small_molecules.ipynb +++ /dev/null @@ -1,694 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To install rascal:\n", - "(NOTE: See the top-level README for the most up-to-date installation instructions.)\n", - "+ mkdir ../build \n", - "+ cd build\n", - "+ cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON ..\n", - "+ make -j 4\n", - "+ make install" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib notebook\n", - "from matplotlib import pylab as plt\n", - "\n", - "import os, sys\n", - "from ase.io import read\n", - "sys.path.insert(0,\"../build/\")\n", - "\n", - "import sys\n", - "import time\n", - "import rascal\n", - "import json\n", - "\n", - "import ase\n", - "from ase.io import read, write\n", - "from ase.build import make_supercell\n", - "from ase.visualize import view\n", - "import numpy as np\n", - "import sys\n", - "\n", - "import json\n", - "\n", - "from rascal.representations import SOAP" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "frames = read('../reference_data/inputs/reference_data/small_molecules-1000.xyz',':')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# SOAP: Power spectrum" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "code_folding": [] - }, - "outputs": [], - "source": [ - "hypers = dict(soap_type=\"PowerSpectrum\",\n", - " interaction_cutoff=3.5, \n", - " max_radial=6, \n", - " max_angular=4, \n", - " gaussian_sigma_constant=0.4,\n", - " gaussian_sigma_type=\"Constant\",\n", - " cutoff_smooth_width=0.5,\n", - " )\n", - "soap = SOAP(**hypers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%time representation = soap.transform(frames)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X = representation.get_feature_matrix().T" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Learning the formation energies of small molecules" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "code_folding": [] - }, - "outputs": [], - "source": [ - "# Load the small molecules \n", - "frames = read('../reference_data/inputs/small_molecules-1000.xyz',':600')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "## learning utilities" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "code_folding": [ - 13, - 20, - 31, - 33, - 35, - 37, - 47, - 54 - ], - "hidden": true - }, - "outputs": [], - "source": [ - "def compute_representation(representation,frames):\n", - " expansions = soap.transform(frames)\n", - " return expansions\n", - "\n", - "def compute_kernel(zeta, rep1, rep2=None):\n", - " if rep2 is None:\n", - " kernel = rep1.cosine_kernel_global(zeta)\n", - " else:\n", - " kernel = rep1.cosine_kernel_global(rep2,zeta)\n", - " return kernel\n", - "\n", - "def extract_energy(frames):\n", - " prop = [[]]*len(frames)\n", - " for ii,cc in enumerate(frames):\n", - " prop[ii] = cc.info['dft_formation_energy_per_atom_in_eV']\n", - " y = np.array(prop)\n", - " return y\n", - "\n", - "def split_dataset(frames, test_fraction, seed=10):\n", - " N = len(frames)\n", - " ids = np.arange(N)\n", - " np.random.seed(seed)\n", - " np.random.shuffle(ids)\n", - " Ntrain = int(N*test_fraction)\n", - " train = ids[:Ntrain]\n", - " test = ids[Ntrain:]\n", - " targets = extract_energy(frames)\n", - " return [frames[ii] for ii in train],targets[train],[frames[ii] for ii in test],targets[test]\n", - "\n", - "def get_mae(ypred,y):\n", - " return np.mean(np.abs(ypred-y))\n", - "def get_rmse(ypred,y):\n", - " return np.sqrt(np.mean((ypred-y)**2))\n", - "def get_sup(ypred,y):\n", - " return np.amax(np.abs((ypred-y)))\n", - "def get_r2(y_pred,y_true):\n", - " weight = 1\n", - " sample_weight = None\n", - " numerator = (weight * (y_true - y_pred) ** 2).sum(axis=0,dtype=np.float64)\n", - " denominator = (weight * (y_true - np.average(\n", - " y_true, axis=0, weights=sample_weight)) ** 2).sum(axis=0,dtype=np.float64)\n", - " output_scores = 1 - (numerator / denominator)\n", - " return np.mean(output_scores)\n", - "\n", - "\n", - "score_func = dict(\n", - " MAE=get_mae,\n", - " RMSE=get_rmse,\n", - " SUP=get_sup,\n", - " R2=get_r2,\n", - ")\n", - "\n", - "def get_score(ypred,y):\n", - " scores = {}\n", - " for k,func in score_func.items():\n", - " scores[k] = func(ypred,y)\n", - " return scores\n", - "\n", - "class KRR(object):\n", - " def __init__(self,zeta,weights,representation,X):\n", - " self.weights = weights\n", - " self.representation = representation\n", - " self.zeta = zeta\n", - " self.X = X\n", - " \n", - " def predict(self,frames):\n", - " features = compute_representation(self.representation,frames)\n", - " kernel = compute_kernel(self.zeta , self.X, features)\n", - " return np.dot(self.weights, kernel)\n", - " \n", - "def train_krr_model(zeta,Lambda,representation,frames,y,jitter=1e-8):\n", - " features = compute_representation(representation,frames)\n", - " kernel = compute_kernel(zeta,features) \n", - " # adjust the kernel so that it is properly scaled\n", - " delta = np.std(y) / np.mean(kernel.diagonal())\n", - " kernel[np.diag_indices_from(kernel)] += Lambda**2 / delta **2 + jitter\n", - " # train the krr model\n", - " weights = np.linalg.solve(kernel,y)\n", - " model = KRR(zeta, weights,representation, features)\n", - " return model,kernel\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "## With the full power spectrum" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "hypers = dict(soap_type=\"PowerSpectrum\",\n", - " interaction_cutoff=3.5, \n", - " max_radial=6, \n", - " max_angular=6, \n", - " gaussian_sigma_constant=0.4,\n", - " gaussian_sigma_type=\"Constant\",\n", - " cutoff_smooth_width=0.5,\n", - " )\n", - "soap = SOAP(**hypers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "frames_train, y_train, frames_test, y_test = split_dataset(frames,0.8)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "zeta = 2\n", - "Lambda = 5e-3\n", - "krr,k = train_krr_model(zeta, Lambda, soap, frames_train, y_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "y_pred = krr.predict(frames_test)\n", - "get_score(y_pred, y_test)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "plt.scatter(y_pred, y_test, s=3)\n", - "plt.axis('scaled')\n", - "plt.xlabel('DFT energy / (eV/atom)')\n", - "plt.ylabel('Predicted energy / (eV/atom)')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "## With just the radial spectrum" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "hypers = dict(soap_type=\"RadialSpectrum\",\n", - " interaction_cutoff=3.5, \n", - " max_radial=6, \n", - " max_angular=0, \n", - " gaussian_sigma_constant=0.4,\n", - " gaussian_sigma_type=\"Constant\",\n", - " cutoff_smooth_width=0.5,\n", - " )\n", - "soap = SOAP(**hypers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "frames_train, y_train, frames_test, y_test = split_dataset(frames,0.8)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "zeta = 2\n", - "Lambda = 5e-4\n", - "krr,k = train_krr_model(zeta, Lambda, soap, frames_train, y_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "y_pred = krr.predict(frames_test)\n", - "get_score(y_pred, y_test)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "plt.scatter(y_pred, y_test, s=3)\n", - "plt.axis('scaled')\n", - "plt.xlabel('DFT energy / (eV/atom)')\n", - "plt.ylabel('Predicted energy / (eV/atom)')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Make a map of the dataset" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "## utils" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "def compute_representation(representation,frames):\n", - " expansions = soap.transform(frames)\n", - " return expansions\n", - "\n", - "def compute_kernel(zeta, rep1, rep2=None):\n", - " if rep2 is None:\n", - " kernel = rep1.cosine_kernel_global(zeta)\n", - " else:\n", - " kernel = rep1.cosine_kernel_global(rep2,zeta)\n", - " return kernel" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "code_folding": [ - 0 - ], - "hidden": true - }, - "outputs": [], - "source": [ - "def link_ngl_wdgt_to_ax_pos(ax, pos, ngl_widget):\n", - " from matplotlib.widgets import AxesWidget\n", - " from scipy.spatial import cKDTree\n", - " r\"\"\"\n", - " Initial idea for this function comes from @arose, the rest is @gph82 and @clonker\n", - " \"\"\"\n", - " \n", - " kdtree = cKDTree(pos) \n", - " #assert ngl_widget.trajectory_0.n_frames == pos.shape[0]\n", - " x, y = pos.T\n", - " \n", - " lineh = ax.axhline(ax.get_ybound()[0], c=\"black\", ls='--')\n", - " linev = ax.axvline(ax.get_xbound()[0], c=\"black\", ls='--')\n", - " dot, = ax.plot(pos[0,0],pos[0,1], 'o', c='red', ms=7)\n", - "\n", - " ngl_widget.isClick = False\n", - " \n", - " def onclick(event):\n", - " linev.set_xdata((event.xdata, event.xdata))\n", - " lineh.set_ydata((event.ydata, event.ydata))\n", - " data = [event.xdata, event.ydata]\n", - " _, index = kdtree.query(x=data, k=1)\n", - " dot.set_xdata((x[index]))\n", - " dot.set_ydata((y[index]))\n", - " ngl_widget.isClick = True\n", - " ngl_widget.frame = index\n", - " \n", - " def my_observer(change):\n", - " r\"\"\"Here comes the code that you want to execute\n", - " \"\"\"\n", - " ngl_widget.isClick = False\n", - " _idx = change[\"new\"]\n", - " try:\n", - " dot.set_xdata((x[_idx]))\n", - " dot.set_ydata((y[_idx])) \n", - " except IndexError as e:\n", - " dot.set_xdata((x[0]))\n", - " dot.set_ydata((y[0]))\n", - " print(\"caught index error with index %s (new=%s, old=%s)\" % (_idx, change[\"new\"], change[\"old\"]))\n", - " \n", - " # Connect axes to widget\n", - " axes_widget = AxesWidget(ax)\n", - " axes_widget.connect_event('button_release_event', onclick)\n", - " \n", - " # Connect widget to axes\n", - " ngl_widget.observe(my_observer, \"frame\", \"change\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "## make a map with kernel pca projection" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "# Load the small molecules \n", - "frames = read('./reference_data/small_molecules-1000.xyz',':600')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "hypers = dict(soap_type=\"PowerSpectrum\",\n", - " interaction_cutoff=3.5, \n", - " max_radial=6, \n", - " max_angular=6, \n", - " gaussian_sigma_constant=0.4,\n", - " gaussian_sigma_type=\"Constant\",\n", - " cutoff_smooth_width=0.5,\n", - " )\n", - "soap = SOAP(**hypers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "zeta = 2\n", - "\n", - "features = compute_representation(soap, frames)\n", - "\n", - "kernel = compute_kernel(zeta,features)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "from sklearn.decomposition import KernelPCA" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "kpca = KernelPCA(n_components=2,kernel='precomputed')\n", - "kpca.fit(kernel)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "X = kpca.transform(kernel)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "plt.scatter(X[:,0],X[:,1],s=3)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## make an interactive map" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# package to visualize the structures in the notebook\n", - "# https://github.com/arose/nglview#released-version\n", - "import nglview" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iwdg = nglview.show_asetraj(frames)\n", - "# set up the visualization\n", - "iwdg.add_unitcell()\n", - "iwdg.add_spacefill()\n", - "iwdg.remove_ball_and_stick()\n", - "iwdg.camera = 'orthographic'\n", - "iwdg.parameters = { \"clipDist\": 0 }\n", - "iwdg.center()\n", - "iwdg.update_spacefill(radiusType='covalent',\n", - " scale=0.6,\n", - " color_scheme='element')\n", - "iwdg._remote_call('setSize', target='Widget',\n", - " args=['%dpx' % (600,), '%dpx' % (400,)])\n", - "iwdg.player.delay = 200.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "link_ngl_wdgt_to_ax_pos(plt.gca(), X, iwdg)\n", - "plt.scatter(X[:,0],X[:,1],s=3)\n", - "iwdg" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "celltoolbar": "Initialization Cell", - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - }, - "toc": { - "base_numbering": 1, - "nav_menu": { - "height": "12px", - "width": "252px" - }, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": "block", - "toc_window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From 89e8b08a4f435a22d8e4b4e15bc9e1e46c1f0c16 Mon Sep 17 00:00:00 2001 From: Rose Cersonsky Date: Wed, 11 Dec 2019 11:14:17 +0100 Subject: [PATCH 08/12] Editing QUIP conversion intro --- docs/source/tutorials/Converting_Quip.ipynb | 90 +++++++++++++++++---- 1 file changed, 75 insertions(+), 15 deletions(-) diff --git a/docs/source/tutorials/Converting_Quip.ipynb b/docs/source/tutorials/Converting_Quip.ipynb index e29ca6169..d6c2e53c8 100644 --- a/docs/source/tutorials/Converting_Quip.ipynb +++ b/docs/source/tutorials/Converting_Quip.ipynb @@ -18,7 +18,7 @@ "\n", "Welcome to libRascal!\n", "\n", - "As you've seen in the last section, there is a lot that librascal can do efficiently. Perhaps the most important functionality is computing atomic descriptors. Here, we'll focus on converting a classic QUIP workflow for atomic descriptors to libRascal.\n", + "Here, we'll focus on converting a classic QUIP workflow for atomic descriptors to libRascal.\n", "\n", "\n", "We will be mirroring parts of the [quippy descriptor tutorial](https://libatoms.github.io/QUIP/Tutorials/quippy-descriptor-tutorial.html), albeit with different molecules.\n", @@ -34,7 +34,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -51,8 +51,8 @@ "import numpy as np\n", "import ase\n", "from ase.io import read\n", - "import quippy \n", - "from quippy import descriptors\n", + "# import quippy \n", + "# from quippy import descriptors\n", "from matplotlib import pyplot as plt\n", "import json\n", "\n", @@ -73,7 +73,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -91,27 +91,63 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'descriptors' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdesc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdescriptors\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mDescriptor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"distance_2b Z1=6 Z2=6 cutoff=4\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'descriptors' is not defined" + ] + } + ], "source": [ "desc = descriptors.Descriptor(\"distance_2b Z1=6 Z2=6 cutoff=4\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'desc' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdesc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcalc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbenzene\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'desc' is not defined" + ] + } + ], "source": [ "d=desc.calc(benzene)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'd' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mmatplotlib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpyplot\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'data'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgca\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_ylabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"PDF\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgca\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_xlabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mr\"$\\mathring{A}$\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'd' is not defined" + ] + } + ], "source": [ "import matplotlib.pyplot as plt\n", "plt.hist(d['data'])\n", @@ -136,9 +172,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'descriptors' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m desc = descriptors.Descriptor(\"soap cutoff=3 \\\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0ml_max\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m4\u001b[0m \u001b[0mn_max\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0matom_sigma\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0.5\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m n_Z=1 Z={6} \")\n", + "\u001b[0;31mNameError\u001b[0m: name 'descriptors' is not defined" + ] + } + ], "source": [ "desc = descriptors.Descriptor(\"soap cutoff=3 \\\n", " l_max=4 n_max=4 \\\n", @@ -166,9 +214,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'SOAP' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m soap = SOAP(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0msoap_type\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'PowerSpectrum'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0minteraction_cutoff\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mmax_radial\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mmax_angular\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'SOAP' is not defined" + ] + } + ], "source": [ "soap = SOAP(\n", " soap_type='PowerSpectrum',\n", From 7b28053e76cc355e4403f78f750005230ba7e88a Mon Sep 17 00:00:00 2001 From: Rose Cersonsky Date: Wed, 11 Dec 2019 11:14:41 +0100 Subject: [PATCH 09/12] Omitting tutorial notebooks from nbstripout --- shared_hooks/pre-commit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared_hooks/pre-commit b/shared_hooks/pre-commit index 4fecbbbb6..599161338 100755 --- a/shared_hooks/pre-commit +++ b/shared_hooks/pre-commit @@ -9,7 +9,7 @@ # To use this hook, execute: # git config core.hooksPath shared_hooks -NBS=$(echo $(git diff --full-index --cached $against --name-only) | sort | grep "ipynb") +NBS=$(echo $(git diff --full-index --cached $against --name-only) | sort | grep "ipynb" | grep "docs\/source\/tutorials" -v) if [ ! -z "$NBS" ] ; then command -v nbstripout --is-installed >/dev/null 2>&1 || { echo >&2 "I require nbstripout but it's not installed. Aborting commit."; exit 1; } From e1286a639ce6242ec43c07b84d7e9f5e90543817 Mon Sep 17 00:00:00 2001 From: Rose Cersonsky Date: Wed, 11 Dec 2019 11:29:52 +0100 Subject: [PATCH 10/12] Adding outputs to PPT --- .../Property_Prediction_Tutorial.ipynb | 179 ++++++++++++++---- 1 file changed, 146 insertions(+), 33 deletions(-) diff --git a/docs/source/tutorials/Property_Prediction_Tutorial.ipynb b/docs/source/tutorials/Property_Prediction_Tutorial.ipynb index ad36fb35a..4b361e9e5 100644 --- a/docs/source/tutorials/Property_Prediction_Tutorial.ipynb +++ b/docs/source/tutorials/Property_Prediction_Tutorial.ipynb @@ -20,7 +20,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -66,7 +66,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -90,7 +90,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -107,9 +107,17 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "There are 100 frames.\n" + ] + } + ], "source": [ "frames = np.array(read(input_file,\":100\"))\n", "number_of_frames = len(frames)\n", @@ -144,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -157,7 +165,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -179,7 +187,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -197,7 +205,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -287,7 +295,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -316,7 +324,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -332,9 +340,41 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Our weights have been calculated and have shape (80,)\n" + ] + }, + { + "data": { + "text/markdown": [ + "
StatisticValue
Mean Average Error0.032
Root Mean Squared Error0.0448
R20.9178
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "y = krr.predict(frames[test_idx])\n", "krr.plot(y_known=property_values[test_idx], y=y, property_name=property_name)" @@ -349,9 +389,41 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Our weights have been calculated and have shape (80,)\n" + ] + }, + { + "data": { + "text/markdown": [ + "
StatisticValue
Mean Average Error0.0331
Root Mean Squared Error0.0523
R20.904
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "filename=f'{reference_dir}/inputs/small_molecules-1000.xyz'\n", "new_frames = read(filename,\":400\")\n", @@ -381,7 +453,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -394,7 +466,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -413,9 +485,17 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "There are 100 frames and 13233 environments.\n" + ] + } + ], "source": [ "frames = np.array(read(input_file,\":100\"))\n", "for frame in frames:\n", @@ -443,7 +523,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -453,7 +533,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -471,7 +551,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -491,7 +571,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -500,18 +580,51 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Our weights have been calculated and have shape (10758,)\n" + ] + } + ], "source": [ "y = krr.predict(frames[test_idx])" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "
StatisticValue
Mean Average Error11.3629
Root Mean Squared Error21.0725
R20.9145
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "krr.plot(y_known=np.concatenate(property_values[test_idx]),\n", " y=y, property_name=property_name)" From 95a03be80a0d0a76818d833f34ef2a1abb617439 Mon Sep 17 00:00:00 2001 From: Rose Cersonsky Date: Wed, 11 Dec 2019 11:39:18 +0100 Subject: [PATCH 11/12] Making sure tutorials are properly included in doctree --- docs/source/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index 152b8a6d8..73995cefe 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -58,7 +58,7 @@ Contents :maxdepth: 2 installation - tutorials/tutorials + tutorials/index whitepaper SOAP representation/representations From 85e689d868ad1bd06f8656c7b2919dec1993c817 Mon Sep 17 00:00:00 2001 From: Rose Cersonsky Date: Wed, 11 Dec 2019 11:39:48 +0100 Subject: [PATCH 12/12] New toc for tutorials post dev mtg --- docs/source/tutorials/index.rst | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/docs/source/tutorials/index.rst b/docs/source/tutorials/index.rst index a89fc5345..6c6da0757 100644 --- a/docs/source/tutorials/index.rst +++ b/docs/source/tutorials/index.rst @@ -21,20 +21,15 @@ Introductory Tutorials Benefits_Performance.ipynb Advanced_SOAP.ipynb -Coming from QUIP? +Converting Your Workflow to Rascal ~~~~~~~~~~~~~~~~~ .. toctree:: :maxdepth: 1 - Benefits_Performance.ipynb Converting_Quip.ipynb - Hyperparameters.ipynb - Property_Prediction_Tutorial.ipynb - Kernels.ipynb - Advanced_SOAP.ipynb -Intro for developers +Rascal Cookbook ~~~~~~~~~~~~~~~~~~~~ .. toctree::